Merge pull request #840 from cjkoenig/update_liburcu
authorSteven Barth <steven@midlink.org>
Mon, 2 Feb 2015 11:29:07 +0000 (12:29 +0100)
committerSteven Barth <steven@midlink.org>
Mon, 2 Feb 2015 11:29:07 +0000 (12:29 +0100)
liburcu: Update to 0.8.6

729 files changed:
CONTRIBUTING.md
admin/debootstrap/Makefile
admin/monit/Makefile
admin/muninlite/patches/110-fix-uptime-days.patch [new file with mode: 0644]
admin/sudo/Makefile [new file with mode: 0644]
admin/sudo/files/sudo.init [new file with mode: 0755]
admin/sudo/patches/010-cross-compile-fixes.patch [new file with mode: 0644]
admin/sudo/patches/020-no-owner-change.patch [new file with mode: 0644]
admin/zabbix/Makefile
admin/zabbix/files/zabbix_agentd.init
admin/zabbix/patches/001-cross_compile.patch [deleted file]
devel/gcc/Makefile
devel/gcc/README
devel/gcc/patches/020-disable-check-for-sys-sdt-h.patch [new file with mode: 0644]
devel/patch/Makefile
ipv6/aiccu/Makefile
ipv6/aiccu/files/aiccu.hotplug [new file with mode: 0644]
ipv6/aiccu/files/aiccu.sh
lang/dkjson/Makefile
lang/erlang/Makefile
lang/jamvm/Makefile [new file with mode: 0644]
lang/lua-mosquitto/Makefile [new file with mode: 0644]
lang/lua-penlight/Makefile [new file with mode: 0644]
lang/luaposix/Makefile
lang/luaposix/patches/100-eglibc-compat.patch
lang/luaposix/patches/101-disable-curses.patch [new file with mode: 0644]
lang/luasec/Makefile
lang/luasec/patches/100-luasocket-Makefile.patch [new file with mode: 0644]
lang/luasql/Makefile
lang/micropython-lib/Makefile
lang/micropython/Makefile
lang/perl-compress-bzip2/Makefile
lang/perl-dbi/Makefile
lang/perl-test-harness/Makefile
lang/perl-uri/Makefile
lang/perl-www-mechanize/Makefile
lang/perl/Config.in [new file with mode: 0644]
lang/perl/Makefile
lang/perl/files/config.sh-arm.in
lang/perl/files/config.sh-armeb.in
lang/perl/files/config.sh-avr32.in
lang/perl/files/config.sh-i486.in
lang/perl/files/config.sh-mips.in
lang/perl/files/config.sh-mips64.in [new file with mode: 0644]
lang/perl/files/config.sh-mipsel.in
lang/perl/files/config.sh-powerpc.in
lang/perl/files/config.sh-x86_64.in
lang/perl/files/perl-run_tests.sh [new file with mode: 0755]
lang/perl/perlbase.mk
lang/perl/perlmod.mk
lang/php5/Makefile
lang/php5/files/php5-fpm-www.conf [new file with mode: 0644]
lang/php5/files/php5-fpm.conf [new file with mode: 0644]
lang/php5/files/php5-fpm.config [new file with mode: 0644]
lang/php5/files/php5-fpm.init [new file with mode: 0644]
lang/php5/patches/090-restore-sqlite2.patch [deleted file]
lang/php5/patches/091-fix-sqlite2.patch [deleted file]
lang/php5/patches/800-gd-iconv.patch [new file with mode: 0644]
lang/python-dns/Makefile [new file with mode: 0644]
lang/python-imglib/Makefile [new file with mode: 0644]
lang/python-imglib/patches/010-cross-compile.patch [new file with mode: 0644]
lang/python-imglib/patches/020-freetype-header-include.patch [new file with mode: 0644]
lang/python-mysql/Makefile [new file with mode: 0644]
lang/python-mysql/patches/010-threadsafe.patch [new file with mode: 0644]
lang/python-pip/Makefile [new file with mode: 0644]
lang/python-setuptools/Makefile [new file with mode: 0644]
lang/python-setuptools/patches/0001-remove-windows-support.patch [new file with mode: 0644]
lang/python/Makefile [new file with mode: 0644]
lang/python/files/config.site [new file with mode: 0644]
lang/python/files/python-package.mk [new file with mode: 0644]
lang/python/patches/110-enable-zlib.patch [new file with mode: 0644]
lang/python/patches/120-do-not-add-include-dirs-when-cross-compiling.patch [new file with mode: 0644]
lang/python/patches/130-do-not-run-distutils-tests.patch [new file with mode: 0644]
lang/python/patches/140-do-not-write-bytes-codes.patch [new file with mode: 0644]
lang/python/patches/150-fix-libffi-x86-64-configure.patch [new file with mode: 0644]
lang/python/patches/160-remove-debian-multiarch-support.patch [new file with mode: 0644]
lang/python3/Makefile [new file with mode: 0644]
lang/python3/files/config.site [new file with mode: 0644]
lang/python3/files/python3-package.mk [new file with mode: 0644]
lang/python3/patches/110-enable-zlib.patch [new file with mode: 0644]
lang/python3/patches/120-do-not-add-include-dirs-when-cross-compiling.patch [new file with mode: 0644]
lang/python3/patches/130-do-not-run-distutils-tests.patch [new file with mode: 0644]
lang/python3/patches/140-do-not-write-bytes-codes.patch [new file with mode: 0644]
lang/ruby/Makefile
lang/ruby/files/ruby [new file with mode: 0644]
lang/ruby/patches/001-rdoc-remove_gems_dep.patch [new file with mode: 0644]
lang/ruby/ruby_find_pkgsdeps [new file with mode: 0644]
lang/ruby/ruby_missingfiles [new file with mode: 0644]
lang/simplejson/Makefile [new file with mode: 0644]
lang/vala/Makefile [new file with mode: 0644]
libs/alsa-lib/Makefile
libs/alsa-lib/patches/002-remove_cross_compile_guess.patch [new file with mode: 0644]
libs/apr-util/Makefile
libs/avahi/Makefile
libs/avahi/files/service-http
libs/avahi/files/service-ssh
libs/classpath/Makefile [new file with mode: 0644]
libs/classpath/patches/010-double-memleak.patch [new file with mode: 0644]
libs/cyrus-sasl/Makefile
libs/db47/Makefile
libs/dmx_usb_module/Makefile [new file with mode: 0644]
libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch [new file with mode: 0644]
libs/elfutils/Makefile [new file with mode: 0644]
libs/elfutils/patches/001-elfutils-portability.patch [new file with mode: 0644]
libs/elfutils/patches/002-argp_standalone.patch [new file with mode: 0644]
libs/elfutils/patches/003-libint-stub.patch [new file with mode: 0644]
libs/elfutils/patches/004-maybe-uninitialized.patch [new file with mode: 0644]
libs/elfutils/patches/004-memcpy_def.patch [new file with mode: 0644]
libs/elfutils/patches/005-build_only_libs.patch [new file with mode: 0644]
libs/elfutils/patches/006-libdw_LIBS.patch [new file with mode: 0644]
libs/elfutils/patches/100-musl-compat.patch [new file with mode: 0644]
libs/elfutils/patches/101-no-fts.patch [new file with mode: 0644]
libs/file/Makefile
libs/flac/Makefile
libs/flac/patches/001-no-docs-and-examples.patch
libs/flac/patches/002-no-utility.patch
libs/flac/patches/010-automake-compat.patch
libs/flac/patches/020-libFLAC-remove-altivec-options.patch [deleted file]
libs/freetype/Makefile
libs/glib2/Makefile
libs/glib2/patches/001-automake-compat.patch [new file with mode: 0644]
libs/glib2/patches/100-fix-gio-linking.patch [new file with mode: 0644]
libs/gnutls/Makefile
libs/gperf/Makefile [new file with mode: 0644]
libs/hidapi/Makefile [new file with mode: 0644]
libs/hidapi/patches/010-add-iconv-linkage.patch [new file with mode: 0644]
libs/ibrcommon/Makefile
libs/ibrdtn/Makefile
libs/ibrdtn/patches/100-add_configure_options.patch [deleted file]
libs/jansson/Makefile [new file with mode: 0644]
libs/libaio/Makefile
libs/libaio/patches/001-arches_from_debian_package_0.3.109-4.patch [deleted file]
libs/libaio/patches/001_arches.patch [new file with mode: 0644]
libs/libaio/patches/002-avr32_support.patch [deleted file]
libs/libaio/patches/002_arches_sh.patch [new file with mode: 0644]
libs/libaio/patches/003_arches_sparc64.patch [new file with mode: 0644]
libs/libaio/patches/004_arches_x32.patch [new file with mode: 0644]
libs/libaio/patches/005_arches_mips.patch [new file with mode: 0644]
libs/libaio/patches/006_arches_mips_fix_padding.patch [new file with mode: 0644]
libs/libantlr3c/Makefile [new file with mode: 0644]
libs/libao/Makefile
libs/libartnet/Makefile [new file with mode: 0644]
libs/libartnet/patches/001-bswap_16.patch [new file with mode: 0644]
libs/libavl/Makefile [new file with mode: 0644]
libs/libavl/patches/010-update_GNUmakefile.patch [new file with mode: 0644]
libs/libdaemon/Makefile
libs/libdaq/Makefile [new file with mode: 0644]
libs/libdaq/patches/001-compile.patch [new file with mode: 0644]
libs/libdbi-drivers/Makefile
libs/libdbi/Makefile
libs/libdmapsharing/Makefile
libs/libdmapsharing/patches/001-diable_pixbuf.patch [deleted file]
libs/libdmapsharing/patches/001-disable_pixbuf.patch [new file with mode: 0644]
libs/libdmapsharing/patches/002-disable_tests.patch [new file with mode: 0644]
libs/libdnet/Makefile [new file with mode: 0644]
libs/libdnet/patches/001-compile.patch [new file with mode: 0644]
libs/libdnet/patches/002-config.patch [new file with mode: 0644]
libs/libesmtp/Makefile [new file with mode: 0644]
libs/libevhtp/Makefile [new file with mode: 0644]
libs/libevhtp/patches/010-enable-shared-object-building.patch [new file with mode: 0644]
libs/libevhtp/patches/020-strcmp-endianness-fix.patch [new file with mode: 0644]
libs/libftdi/Makefile
libs/libftdi/patches/100-fix-x86_64-build.patch
libs/libftdi/patches/101-fix-cmake-version-packagekit.patch [new file with mode: 0644]
libs/libftdi1/Makefile
libs/libftdi1/patches/100-fix-x86_64-build.patch
libs/libgd/Makefile
libs/libhttp-parser/Makefile [new file with mode: 0644]
libs/libical/Makefile [new file with mode: 0644]
libs/libidn/Makefile
libs/libimobiledevice/Makefile
libs/liblo/Makefile
libs/libmcrypt/Makefile
libs/libmicrohttpd/Makefile [new file with mode: 0644]
libs/libmpdclient/Makefile
libs/libmpdclient/patches/001-WIP_musl_compatibility.patch [new file with mode: 0644]
libs/libnatpmp/Makefile
libs/libnetfilter-acct/Makefile
libs/libnetfilter-log/Makefile
libs/libnetfilter-queue/Makefile
libs/libnfc/Makefile [new file with mode: 0644]
libs/liboil/Makefile
libs/libowfat/Makefile
libs/libplist/Makefile
libs/libpng/Makefile
libs/libsamplerate/Makefile
libs/libsearpc/Makefile [new file with mode: 0644]
libs/libsodium/Makefile
libs/libsoup/Makefile
libs/libsoxr/Makefile
libs/libtheora/Makefile
libs/libtorrent/Makefile
libs/libtorrent/patches/100-fix_cross_compile.patch
libs/libuecc/Makefile
libs/libunistring/Makefile [new file with mode: 0644]
libs/libupnpp/Makefile [new file with mode: 0644]
libs/libusbmuxd/Makefile
libs/libuvc/Makefile [new file with mode: 0644]
libs/libv4l/Makefile
libs/libvorbisidec/Makefile
libs/libvpx/Makefile [new file with mode: 0644]
libs/libwebsockets/Makefile [new file with mode: 0644]
libs/libwebsockets/patches/0001-cyassl-correct-include-path-for-3.1.x.patch [new file with mode: 0644]
libs/libxerces-c/Makefile [new file with mode: 0644]
libs/libxml2/Makefile
libs/libxml2/patches/0001-threads-use-forward-declarations-only-for-glibc-fixe.patch [new file with mode: 0644]
libs/libzdb/Makefile [new file with mode: 0644]
libs/libzdb/patches/010-cross-compile-fixes.patch [new file with mode: 0644]
libs/libzdb/patches/020-filterh-use-host-built-version.patch [new file with mode: 0644]
libs/mxml/Makefile [new file with mode: 0644]
libs/mxml/patches/001-targets.patch [new file with mode: 0644]
libs/nspr/Makefile
libs/opencv/Makefile [new file with mode: 0644]
libs/opencv/README.md [new file with mode: 0644]
libs/openldap/Makefile
libs/openldap/files/ldap.init
libs/opus/Makefile
libs/pcre/Makefile
libs/postgresql/Makefile
libs/protobuf-c/Makefile
libs/protobuf/Makefile
libs/pthsem/Makefile [new file with mode: 0644]
libs/pthsem/patches/001-linux3x-fix.patch [new file with mode: 0644]
libs/sqlite3/Makefile
libs/tdb/Makefile [new file with mode: 0644]
libs/tdb/patches/001-printf-fix.patch [new file with mode: 0644]
libs/tiff/Makefile
libs/tiff/patches/017-CVE-2014-9330.patch [new file with mode: 0644]
libs/unixodbc/Makefile
libs/vips/Makefile
libs/vips/patches/001-no_cpp.patch
libs/xmlrpc-c/Makefile
mail/alpine/Makefile [new file with mode: 0644]
mail/alpine/patches/100-no-openssl-check-cross-compile.patch [new file with mode: 0644]
mail/bogofilter/Makefile [new file with mode: 0644]
mail/bogofilter/files/postfix-bogofilter [new file with mode: 0755]
mail/dovecot/Makefile
mail/dovecot/files/dovecot.init
mail/dovecot/patches/001-configure_in.patch
mail/fdm/Config.in [new file with mode: 0644]
mail/fdm/Makefile [new file with mode: 0644]
mail/fdm/files/etc/fdm.conf [new file with mode: 0644]
mail/fdm/patches/001-base64-fix.patch [new file with mode: 0644]
mail/fdm/patches/002-base64-fix.patch [new file with mode: 0644]
mail/fdm/src/compat/b64_ntop.c [new file with mode: 0644]
mail/fdm/src/compat/b64_pton.c [new file with mode: 0644]
mail/mailman/Makefile [new file with mode: 0644]
mail/mailman/files/mailman.init [new file with mode: 0644]
mail/mailman/patches/100-postfix.patch [new file with mode: 0644]
mail/mailman/patches/200-nohostdnspython.patch [new file with mode: 0644]
mail/mailman/patches/300-targetpython.patch [new file with mode: 0644]
mail/mailman/patches/400-modules.patch [new file with mode: 0644]
mail/mailsend/Makefile
mail/msmtp/Makefile [new file with mode: 0644]
mail/nail/Makefile [new file with mode: 0644]
mail/nail/patches/100-handle-openssl-without-sslv2.patch [new file with mode: 0644]
mail/postfix/Makefile [new file with mode: 0644]
mail/postfix/files/main.cf.default [new file with mode: 0644]
mail/postfix/files/postfix.init [new file with mode: 0644]
mail/postfix/patches/100-fsstat.patch [new file with mode: 0644]
mail/postfix/patches/200-manpages.patch [new file with mode: 0644]
mail/postfix/patches/300-bdb_hash_segfault.patch [new file with mode: 0644]
mail/postfix/patches/400-cdb.patch [new file with mode: 0644]
mail/postfix/patches/500-crosscompile.patch [new file with mode: 0644]
mail/postfix/patches/600-nopostconf.patch [new file with mode: 0644]
mail/postfix/patches/700-defaultconfig.patch [new file with mode: 0644]
mail/postfix/patches/800-fmt.patch [new file with mode: 0644]
mail/ssmtp/Makefile [new file with mode: 0644]
mail/ssmtp/patches/002-fix_pointer.patch [new file with mode: 0644]
multimedia/ffmpeg/Config.in
multimedia/ffmpeg/Makefile
multimedia/ffmpeg/patches/010-remove_unused_fminf_definition.patch [deleted file]
multimedia/fswebcam/Makefile
multimedia/gst1-libav/Makefile
multimedia/gst1-plugins-bad/Makefile
multimedia/gst1-plugins-base/Makefile
multimedia/gst1-plugins-good/Makefile
multimedia/gst1-plugins-ugly/Makefile
multimedia/gstreamer1/Makefile
multimedia/gstreamer1/patches/010-gstplugin_use_lazy_symbol_binding.patch [new file with mode: 0644]
multimedia/icecast/Makefile
multimedia/minidlna/Makefile
multimedia/minidlna/files/minidlna.init
multimedia/minidlna/patches/020-makefileam-tweaks.patch [deleted file]
multimedia/minidlna/patches/030-upnphttp-fixPhilips.patch [deleted file]
multimedia/mjpg-streamer/Makefile
multimedia/mjpg-streamer/files/mjpg-streamer.config
multimedia/mjpg-streamer/files/mjpg-streamer.init
multimedia/motion/Makefile
multimedia/motion/patches/002-honor_cppflags.patch [deleted file]
multimedia/shairplay/Makefile [new file with mode: 0644]
multimedia/shairplay/files/shairplay.config [new file with mode: 0644]
multimedia/shairplay/files/shairplay.init [new file with mode: 0644]
multimedia/shairplay/patches/001-key_file_dir.patch [new file with mode: 0644]
multimedia/shairplay/patches/002-libavahi-compat-dnssd.patch [new file with mode: 0644]
multimedia/shairplay/patches/003-fix_big-endian.patch [new file with mode: 0644]
multimedia/shairport/Makefile
multimedia/shairport/files/shairport.config
multimedia/shairport/files/shairport.init
multimedia/upmpdcli/Makefile [new file with mode: 0644]
multimedia/upmpdcli/files/upmpdcli.config [new file with mode: 0644]
multimedia/upmpdcli/files/upmpdcli.init [new file with mode: 0644]
multimedia/upmpdcli/files/upmpdcli.png [new file with mode: 0644]
multimedia/upmpdcli/patches/010-Add_icon_config.patch [new file with mode: 0644]
multimedia/xupnpd/Makefile
net/announce/Makefile [new file with mode: 0644]
net/bcp38/Makefile [new file with mode: 0644]
net/bcp38/files/bcp38.config [new file with mode: 0644]
net/bcp38/files/bcp38.defaults [new file with mode: 0644]
net/bcp38/files/run.sh [new file with mode: 0755]
net/bind/Makefile
net/bind/files/named.init
net/bmon/Makefile [new file with mode: 0644]
net/bwm-ng/Config.in [new file with mode: 0644]
net/bwm-ng/Makefile [new file with mode: 0644]
net/coova-chilli/Config.in [new file with mode: 0644]
net/coova-chilli/Makefile [new file with mode: 0644]
net/coova-chilli/files/chilli.hotplug [new file with mode: 0644]
net/coova-chilli/patches/100-fix-sysinfo-redeclaration.patch [new file with mode: 0644]
net/dansguardian/Makefile [new file with mode: 0644]
net/dansguardian/files/dansguardian.config [new file with mode: 0644]
net/dansguardian/files/dansguardian.init [new file with mode: 0644]
net/dansguardian/files/dansguardianf1.conf [new file with mode: 0644]
net/dansguardian/patches/001-compile.patch [new file with mode: 0644]
net/davfs2/Makefile
net/ddns-scripts/Makefile
net/ddns-scripts/files/etc/config/ddns
net/ddns-scripts/files/etc/config/ddns.sample
net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns [deleted file]
net/ddns-scripts/files/etc/hotplug.d/iface/95-ddns [new file with mode: 0644]
net/ddns-scripts/files/etc/init.d/ddns
net/ddns-scripts/files/usr/lib/ddns/create_cert_hashes.sh [deleted file]
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_functions.sh
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh [new file with mode: 0755]
net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh [changed mode: 0755->0644]
net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh [new file with mode: 0755]
net/ddns-scripts/files/usr/lib/ddns/services
net/ddns-scripts/files/usr/lib/ddns/services_ipv6
net/ddns-scripts/files/usr/lib/ddns/tld_names.dat [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/update_cloudflare.sh [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/update_no-ip.sh [new file with mode: 0644]
net/ddns-scripts/files/usr/lib/ddns/update_sample.sh
net/dmapd/Makefile
net/dmapd/files/dmapd.init
net/dnscrypt-proxy/Makefile
net/e2guardian/Makefile [new file with mode: 0644]
net/e2guardian/files/e2guardian.config [new file with mode: 0644]
net/e2guardian/files/e2guardian.init [new file with mode: 0644]
net/e2guardian/files/e2guardianf1.conf [new file with mode: 0644]
net/ethtool/Makefile
net/fastd/Config.in
net/fastd/Makefile
net/fastd/files/fastd.config [deleted file]
net/fastd/files/fastd.init [deleted file]
net/freeradius2/Makefile
net/freeradius2/patches/010-disbale-openssl-check.patch
net/fwknop/Makefile
net/fwknop/patches/001-fix_config.patch
net/git/Makefile
net/git/patches/100-convert_builtin.patch
net/haproxy/Makefile
net/haproxy/patches/0001-DOC-clearly-state-that-the-show-sess-output-format-i.patch [deleted file]
net/haproxy/patches/0002-MINOR-stats-fix-minor-typo-fix-in-stats_dump_errors_.patch [deleted file]
net/haproxy/patches/0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch [deleted file]
net/haproxy/patches/0004-MINOR-Also-accept-SIGHUP-SIGTERM-in-systemd-wrapper.patch [deleted file]
net/haproxy/patches/0005-DOC-indicate-in-the-doc-that-track-sc-can-wait-if-da.patch [deleted file]
net/haproxy/patches/0006-MEDIUM-http-enable-header-manipulation-for-101-respo.patch [deleted file]
net/haproxy/patches/0007-BUG-MEDIUM-config-propagate-frontend-to-backend-proc.patch [deleted file]
net/haproxy/patches/0008-MEDIUM-config-properly-propagate-process-binding-bet.patch [deleted file]
net/haproxy/patches/0009-MEDIUM-config-make-the-frontends-automatically-bind-.patch [deleted file]
net/haproxy/patches/0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch [deleted file]
net/haproxy/patches/0011-MEDIUM-config-only-warn-if-stats-are-attached-to-mul.patch [deleted file]
net/haproxy/patches/0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch [deleted file]
net/haproxy/patches/0013-MINOR-config-detect-the-case-where-a-tcp-request-con.patch [deleted file]
net/haproxy/patches/0014-MEDIUM-systemd-wrapper-support-multiple-executable-v.patch [deleted file]
net/haproxy/patches/0015-BUG-MEDIUM-remove-debugging-code-from-systemd-wrappe.patch [deleted file]
net/haproxy/patches/0016-BUG-MEDIUM-http-adjust-close-mode-when-switching-to-.patch [deleted file]
net/haproxy/patches/0017-BUG-MINOR-config-don-t-propagate-process-binding-on-.patch [deleted file]
net/haproxy/patches/0018-BUG-MEDIUM-check-rule-less-tcp-check-must-detect-con.patch [deleted file]
net/haproxy/patches/0019-BUG-MINOR-tcp-check-report-the-correct-failed-step-i.patch [deleted file]
net/haproxy/patches/0020-BUG-MINOR-config-don-t-propagate-process-binding-for.patch [deleted file]
net/horst/Makefile
net/ibrdtn-tools/Makefile
net/ibrdtn-tools/patches/100-add_configure_options.patch [deleted file]
net/ibrdtnd/Makefile
net/ibrdtnd/files/build-config.sh
net/ibrdtnd/files/ibrdtn.uci
net/ibrdtnd/patches/100-add_configure_options.patch [deleted file]
net/ibrdtnd/patches/110-add_configure_options_docs.patch [deleted file]
net/ipsec-tools/Makefile
net/ipsec-tools/files/racoon.conf [new file with mode: 0644]
net/ipsec-tools/files/racoon.init
net/irssi/Makefile
net/kismet/Makefile [new file with mode: 0644]
net/kismet/files/kismet.conf [new file with mode: 0644]
net/kismet/files/kismet_drone.conf [new file with mode: 0644]
net/kismet/files/kismet_drone.config [new file with mode: 0644]
net/kismet/files/kismet_drone.init [new file with mode: 0755]
net/kismet/files/kismet_server.config [new file with mode: 0644]
net/kismet/files/kismet_server.init [new file with mode: 0755]
net/kismet/patches/010-dont-add-host-include-paths.patch [new file with mode: 0644]
net/knot/Makefile
net/knxd/Makefile [new file with mode: 0644]
net/knxd/files/knxd.config [new file with mode: 0644]
net/knxd/files/knxd.init [new file with mode: 0644]
net/knxd/patches/0099-openwrt.patch [new file with mode: 0644]
net/krb5/Makefile
net/lftp/Makefile
net/lftp/patches/010-main_code_fix.patch [deleted file]
net/lighttpd/Makefile
net/linknx/Makefile [new file with mode: 0644]
net/linknx/files/linknx.config [new file with mode: 0644]
net/linknx/files/linknx.init [new file with mode: 0644]
net/linknx/files/linknx.xml.dist [new file with mode: 0644]
net/luci-app-bcp38/Makefile [new file with mode: 0644]
net/luci-app-bcp38/files/bcp38-cbi.lua [new file with mode: 0644]
net/luci-app-bcp38/files/bcp38-controller.lua [new file with mode: 0644]
net/luci-app-bcp38/files/uci-defaults-bcp38 [new file with mode: 0755]
net/luci-app-ocserv/Makefile [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/controller/ocserv.lua [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/main.lua [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/user-config.lua [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/users.lua [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/view/admin_status/index/ocserv.htm [deleted file]
net/luci-app-ocserv/files/usr/lib/lua/luci/view/ocserv_status.htm [deleted file]
net/luci-app-sqm/Makefile [new file with mode: 0644]
net/luci-app-sqm/files/sqm-cbi.lua [new file with mode: 0644]
net/luci-app-sqm/files/sqm-controller.lua [new file with mode: 0644]
net/luci-app-sqm/files/uci-defaults-sqm [new file with mode: 0644]
net/luci-proto-openconnect/Makefile [deleted file]
net/luci-proto-openconnect/files/usr/lib/lua/luci/model/cbi/admin_network/proto_openconnect.lua [deleted file]
net/luci-proto-openconnect/files/usr/lib/lua/luci/model/network/proto_openconnect.lua [deleted file]
net/mdnsresponder/Makefile
net/mdnsresponder/patches/001-cross_compile.patch
net/mdnsresponder/patches/100-linux_fixes.patch
net/memcached/Makefile
net/mosquitto/Makefile
net/mosquitto/files/mosquitto.init
net/mtr/Makefile
net/mtr/patches/501-dns.patch
net/mtr/patches/502-fix-res_ninit.patch
net/mtr/patches/521-glib-dependency-fixes.patch [deleted file]
net/mwan3/Makefile
net/mwan3/files/etc/hotplug.d/iface/15-mwan3
net/mwan3/files/usr/sbin/mwan3
net/net-snmp/files/snmpd.init
net/netcat/Makefile [new file with mode: 0644]
net/netcat/patches/001-netcat_flag_count.patch [new file with mode: 0644]
net/nfs-kernel-server/Makefile
net/nfs-kernel-server/patches/100-nfs_utils_uclibc.patch [deleted file]
net/nfs-kernel-server/patches/100-no_malloc_h.patch [new file with mode: 0644]
net/nfs-kernel-server/patches/101-no_malloc_h.patch [deleted file]
net/nmap/Makefile
net/ntpd/Makefile
net/ntpd/files/ntpd.init
net/nut/Config.in [new file with mode: 0644]
net/nut/Makefile [new file with mode: 0644]
net/nut/files/nut-monitor.init [new file with mode: 0755]
net/nut/files/nut-server.init [new file with mode: 0755]
net/nut/patches/001-fix-missing-libmath-flags.patch [new file with mode: 0644]
net/nut/patches/010-ignore_automake_k_bug.patch [new file with mode: 0644]
net/ocserv/Config.in
net/ocserv/Makefile
net/ocserv/README
net/ocserv/files/ocserv.conf.template
net/ocserv/files/ocserv.init
net/ocserv/files/ocserv.upgrade [new file with mode: 0644]
net/ocserv/patches/001-add-http-heads.h [new file with mode: 0644]
net/ola/Makefile [new file with mode: 0644]
net/ola/files/olad.init [new file with mode: 0644]
net/openconnect/Config.in
net/openconnect/Makefile
net/openconnect/README
net/openconnect/files/openconnect-wrapper
net/openconnect/files/openconnect.sh
net/openconnect/files/openconnect.upgrade [new file with mode: 0644]
net/openconnect/files/vpnc-script
net/openconnect/patches/001-Added-a-default-timeout-value-in-CSTP-handshake-usin.patch [deleted file]
net/openssh/Makefile
net/openssh/files/sftp-ssh.service [new file with mode: 0644]
net/openssh/files/sshd.init
net/openssh/patches/100-no_cast_fix.patch
net/opentracker/Makefile
net/opentracker/patches/100-makefile.patch
net/openvswitch/Makefile
net/openvswitch/patches/0004-datapath-Use-ccflags-y-instead-of-deprecated-EXTRA_C.patch [new file with mode: 0644]
net/pen/Makefile [new file with mode: 0644]
net/portmap/Makefile
net/portmap/files/portmap.init
net/privoxy/Makefile [new file with mode: 0644]
net/privoxy/files/privoxy.config [new file with mode: 0644]
net/privoxy/files/privoxy.hotplug [new file with mode: 0644]
net/privoxy/files/privoxy.init [new file with mode: 0644]
net/privoxy/files/privoxy.oldconfig [new file with mode: 0644]
net/prosody/Makefile
net/prosody/files/prosody.init
net/prosody/patches/010-fix-randomseed.patch [new file with mode: 0644]
net/radsecproxy/Makefile
net/rsync/Makefile
net/rtorrent/Makefile
net/rtorrent/patches/100-fix-cross_compile.patch
net/seafile-ccnet/Makefile [new file with mode: 0644]
net/seafile-seahub/Makefile [new file with mode: 0644]
net/seafile-seahub/patches/010-default-config.patch [new file with mode: 0644]
net/seafile-server/Makefile [new file with mode: 0644]
net/seafile-server/files/seafile.init [new file with mode: 0755]
net/seafile-server/patches/010-makefile-fix.patch [new file with mode: 0644]
net/seafile-server/patches/020-script-patches.patch [new file with mode: 0644]
net/seafile-server/patches/030-pidfiles-in-same-directory.patch [new file with mode: 0644]
net/seafile-server/patches/040-seafile-admin.patch [new file with mode: 0644]
net/ser2net/Makefile [new file with mode: 0644]
net/ser2net/patches/001-fix_TIOCSRS485_undeclared_error.patch [new file with mode: 0644]
net/snort/Makefile [new file with mode: 0644]
net/snort/files/snort.config [new file with mode: 0644]
net/snort/files/snort.init [new file with mode: 0644]
net/snort/patches/001-compile.patch [new file with mode: 0644]
net/socat/Makefile
net/sqm-scripts/Makefile [new file with mode: 0644]
net/sqm-scripts/files/etc/config/sqm [new file with mode: 0644]
net/sqm-scripts/files/etc/init.d/sqm [new file with mode: 0755]
net/sqm-scripts/files/usr/lib/sqm/functions.sh [new file with mode: 0644]
net/sqm-scripts/files/usr/lib/sqm/run.sh [new file with mode: 0755]
net/sqm-scripts/files/usr/lib/sqm/simple.qos [new file with mode: 0755]
net/sqm-scripts/files/usr/lib/sqm/simple.qos.help [new file with mode: 0644]
net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos [new file with mode: 0755]
net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos.help [new file with mode: 0644]
net/sqm-scripts/files/usr/lib/sqm/simplest.qos [new file with mode: 0755]
net/sqm-scripts/files/usr/lib/sqm/simplest.qos.help [new file with mode: 0644]
net/sqm-scripts/files/usr/lib/sqm/stop.sh [new file with mode: 0755]
net/squid/Makefile [new file with mode: 0644]
net/squid/files/squid.conf [new file with mode: 0644]
net/squid/files/squid.config [new file with mode: 0644]
net/squid/files/squid.init [new file with mode: 0644]
net/squid/patches/001-cross_compile.patch [new file with mode: 0644]
net/squid/patches/100-mime.patch [new file with mode: 0644]
net/sshfs/Makefile [new file with mode: 0644]
net/sstp-client/Makefile [new file with mode: 0644]
net/sstp-client/files/etc/ppp/chap-secrets [new file with mode: 0644]
net/sstp-client/files/etc/ppp/peers/peer-sstp-example-nopty.txt [new file with mode: 0644]
net/sstp-client/files/etc/ppp/peers/peer-sstp-example.txt [new file with mode: 0644]
net/strongswan/Makefile
net/tcpproxy/Makefile
net/tgt/Makefile
net/tinc/Makefile
net/tor/Makefile
net/tor/files/tor.init
net/uanytun/Makefile
net/udpxy/Makefile
net/udpxy/files/udpxy.conf
net/udpxy/files/udpxy.init
net/ulogd/Makefile
net/unbound/Makefile
net/wget/Makefile
net/znc/Makefile
net/znc/patches/002-Uclibcpp_build_fix.patch [deleted file]
net/znc/patches/900-remove_cpp11_usage.patch [deleted file]
sound/espeak/Makefile [new file with mode: 0644]
sound/espeak/patches/101-portaudio.patch [new file with mode: 0644]
sound/forked-daapd/Makefile [new file with mode: 0644]
sound/forked-daapd/files/forked-daapd.conf [new file with mode: 0644]
sound/forked-daapd/files/forked-daapd.init [new file with mode: 0644]
sound/forked-daapd/patches/010-include_pregen.patch [new file with mode: 0644]
sound/madplay/Makefile [new file with mode: 0644]
sound/mocp/Makefile
sound/mpd/Makefile
sound/mpd/files/mpd.service
sound/portaudio/Makefile [new file with mode: 0644]
sound/pulseaudio/Makefile
sound/pulseaudio/files/pulseaudio.init
sound/shairport-sync/Makefile [new file with mode: 0644]
sound/shairport-sync/files/shairport-sync.config [new file with mode: 0644]
sound/shairport-sync/files/shairport-sync.init [new file with mode: 0755]
sound/sox/Makefile
sound/sox/patches/020-ffmpeg-2.x.patch
sound/svox/Makefile [new file with mode: 0644]
sound/svox/patches/0001-autoconf-building-of-library-using-libtool.patch [new file with mode: 0644]
sound/svox/patches/0002-gitignore-for-autotools-files.patch [new file with mode: 0644]
sound/svox/patches/0003-pico2wave-Convert-text-to-.wav-using-svox-text-to-sp.patch [new file with mode: 0644]
sound/svox/patches/0004-add-header-files.patch [new file with mode: 0644]
sound/svox/patches/0005-Install-lang-files.patch [new file with mode: 0644]
sound/svox/patches/0006-Set-picolangdir.patch [new file with mode: 0644]
sound/svox/patches/0008-64bits.patch [new file with mode: 0644]
sound/svox/patches/0009-Fix-link-order.patch [new file with mode: 0644]
sound/svox/patches/0010-platform.patch [new file with mode: 0644]
sound/svox/patches/0011-subdir.patch [new file with mode: 0644]
sound/svox/patches/0012-no-headers.patch [new file with mode: 0644]
utils/acl/Makefile
utils/attr/Makefile
utils/bash/Makefile
utils/bluelog/Makefile [new file with mode: 0644]
utils/bluelog/files/bluelog.init [new file with mode: 0644]
utils/bluez/Makefile [new file with mode: 0644]
utils/bluez/files/bluetooth.config [new file with mode: 0644]
utils/bluez/files/bluetooth.dbus [new file with mode: 0644]
utils/bluez/files/bluez-utils.init [new file with mode: 0644]
utils/bluez/files/givepin [new file with mode: 0644]
utils/bluez/patches/200-uart-speed.patch [new file with mode: 0644]
utils/bluez/patches/201-readline.patch [new file with mode: 0644]
utils/btrfs-progs/Makefile [new file with mode: 0644]
utils/btrfs-progs/files/btrfs-scan.init [new file with mode: 0644]
utils/btrfs-progs/patches/001-fix-xattr-h-include-location.patch [new file with mode: 0644]
utils/ccid/Makefile
utils/cmdpad/Makefile
utils/collectd/Makefile
utils/coreutils/Makefile
utils/coreutils/patches/001-no_docs_man_tests.patch
utils/coreutils/patches/002-fix_compile_with_uclibc.patch
utils/coreutils/patches/010-fix-gets-removal.patch [deleted file]
utils/cryptsetup/Makefile [new file with mode: 0644]
utils/dbus/Makefile
utils/dbus/patches/100-fix-poll-select.patch [new file with mode: 0644]
utils/dump1090/Makefile
utils/dump1090/files/dump1090.config [new file with mode: 0644]
utils/dump1090/files/dump1090.init [new file with mode: 0644]
utils/f2fs-tools/Config.in [new file with mode: 0644]
utils/f2fs-tools/Makefile [new file with mode: 0644]
utils/f2fs-tools/patches/001-compile.patch [new file with mode: 0644]
utils/gammu/Makefile [new file with mode: 0644]
utils/gammu/files/gammurc [new file with mode: 0644]
utils/gammu/patches/001-iconv-disabling-option.patch [new file with mode: 0644]
utils/gammu/patches/002-no-fstack-protector.patch [new file with mode: 0644]
utils/gammu/patches/003-cmake-cross-toolchain.patch [new file with mode: 0644]
utils/gammu/patches/010-utils-shell-fix.patch [new file with mode: 0644]
utils/gnupg/Makefile
utils/grep/Makefile
utils/haserl/Makefile
utils/hd-idle/Makefile
utils/hdparm/Makefile [new file with mode: 0644]
utils/hdparm/patches/001-fix-includes.patch [new file with mode: 0644]
utils/hub-ctrl/Makefile [new file with mode: 0644]
utils/joe/Makefile [new file with mode: 0644]
utils/joe/files/joerc [new file with mode: 0644]
utils/joe/patches/001-mathaway.patch [new file with mode: 0644]
utils/less/Makefile [new file with mode: 0644]
utils/lsof/Makefile
utils/luci-app-lxc/Makefile [new file with mode: 0644]
utils/luci-app-lxc/files/controller/lxc.lua [new file with mode: 0644]
utils/luci-app-lxc/files/lxc.config [new file with mode: 0644]
utils/luci-app-lxc/files/model/cbi/lxc.lua [new file with mode: 0644]
utils/luci-app-lxc/files/view/lxc.htm [new file with mode: 0644]
utils/luci-app-lxc/files/www/luci-static/resources/cbi/green.gif [new file with mode: 0644]
utils/luci-app-lxc/files/www/luci-static/resources/cbi/purple.gif [new file with mode: 0644]
utils/luci-app-lxc/files/www/luci-static/resources/cbi/red.gif [new file with mode: 0644]
utils/lvm2/Makefile [new file with mode: 0644]
utils/lvm2/files/lvm2.init [new file with mode: 0644]
utils/lvm2/patches/000-compile.patch [new file with mode: 0644]
utils/lvm2/patches/001-include_fix.patch [new file with mode: 0644]
utils/lxc/Config.in
utils/lxc/Makefile
utils/lxc/files/lxc.conf [new file with mode: 0644]
utils/lxc/patches/025-remove-unsupported-option.patch [new file with mode: 0644]
utils/lxc/patches/300-fix-lxc-destroy.patch [new file with mode: 0644]
utils/lxc/patches/301-add-openwrt-common-config.patch [new file with mode: 0644]
utils/mc/Config.in [new file with mode: 0644]
utils/mc/Makefile [new file with mode: 0644]
utils/mksh/Makefile [new file with mode: 0644]
utils/mksh/patches/100-dot_mkshrc [new file with mode: 0644]
utils/mpack/Makefile [new file with mode: 0644]
utils/mysql/patches/120-bison-compat.patch [new file with mode: 0644]
utils/ntfs-3g/Makefile
utils/open-plc-utils/Makefile [new file with mode: 0644]
utils/openocd/Makefile [new file with mode: 0644]
utils/opensc/Makefile
utils/opensc/patches/0001-OpenPGP-Detect-and-support-Gnuk-Token.patch
utils/opensc/patches/0002-OpenPGP-Add-Gnuk-in-pkcs15-emulation-layer.patch
utils/opensc/patches/0003-OpenPGP-Include-private-DO-to-filesystem-at-driver-i.patch
utils/opensc/patches/0004-PKCS15-OpenPGP-Declare-DATA-objects.patch
utils/opensc/patches/0005-OpenPGP-Support-erasing-reset-card.patch
utils/opensc/patches/0006-openpgp-tool-Support-deleting-key-in-Gnuk.patch
utils/opensc/patches/0007-OpenPGP-Correct-building-Extended-Header-List-when-i.patch
utils/opensc/patches/0008-OpenPGP-Read-some-empty-DOs-from-Gnuk.patch
utils/opensc/patches/0009-PKCS15-OpenPGP-Do-not-show-empty-DO-in-pkcs15-emu_in.patch
utils/opensc/patches/0010-PKCS15-OpenPGP-Allow-to-store-data-to-pkcs15-data-ob.patch
utils/opensc/patches/0011-OpenPGP-Provide-enough-buffer-to-read-pubkey-from-Gn.patch
utils/opensc/patches/0012-OpenPGP-Support-write-certificate-for-Gnuk.patch
utils/opensc/patches/0013-pkcs15-openpgp-Change-to-sc_put_data-instead-of-sc_u.patch
utils/opensc/patches/0014-OpenPGP-Overcome-the-restriction-of-even-data-length.patch
utils/opensc/patches/0015-OpenPGP-Delete-key-as-file-for-Gnuk.patch
utils/opensc/patches/0016-OpenPGP-Correct-parameter-checking.patch
utils/opensc/patches/0017-OpenPGP-Make-code-neater.patch
utils/opensc/patches/0018-Move-declaration-to-top-of-block.patch
utils/opensc/patches/0019-OpenPGP-Make-indentation-consistent-space-tab.patch [new file with mode: 0644]
utils/opensc/patches/0020-OpenPGP-Don-t-use-sc_log-in-openpgp-tool.patch [new file with mode: 0644]
utils/opensc/patches/0021-OpenPGP-Don-t-reimplement-gnuk_delete_key-in-openpgp.patch [new file with mode: 0644]
utils/opensc/patches/0022-OpenPGP-Use-directly-binary-array-of-APDUs-for-ERASE.patch [new file with mode: 0644]
utils/opensc/patches/0023-OpenPGP-Rename-private-blob-type-to-avoid-confusing-.patch [new file with mode: 0644]
utils/opensc/patches/0024-OpenPGP-Fix-crash-after-accessing-inexistent-file.patch [new file with mode: 0644]
utils/opensc/patches/0025-Replace-hardcode.patch [new file with mode: 0644]
utils/opensc/patches/0026-hardcode-defines-for-DO-s.patch [new file with mode: 0644]
utils/opus-tools/Makefile
utils/pciutils/Makefile
utils/pciutils/patches/101-no-strip.patch
utils/pciutils/patches/103-relative-path-ids.patch
utils/pciutils/patches/104-resolv.patch
utils/pcsc-lite/Makefile
utils/procps/Makefile [new file with mode: 0644]
utils/procps/patches/010-make_fix.patch [new file with mode: 0644]
utils/procps/patches/020_hz_fix.patch [new file with mode: 0644]
utils/procps/patches/030-fix-string-problems.patch [new file with mode: 0644]
utils/rpcd-mod-lxc/Makefile [new file with mode: 0644]
utils/rpcd-mod-lxc/files/CMakeLists.txt [new file with mode: 0644]
utils/rpcd-mod-lxc/files/lxc.c [new file with mode: 0644]
utils/rrdtool1/Makefile
utils/shadow/Makefile
utils/sispmctl/Makefile [new file with mode: 0644]
utils/sispmctl/patches/001-fix-includes.patch [new file with mode: 0644]
utils/smartmontools/Makefile
utils/smstools3/Makefile [new file with mode: 0644]
utils/smstools3/files/smstools3.conf [new file with mode: 0644]
utils/smstools3/files/smstools3.init [new file with mode: 0644]
utils/smstools3/patches/001-smsd.patch [new file with mode: 0644]
utils/smstools3/patches/002-Makefile.patch [new file with mode: 0644]
utils/sockread/Makefile [new file with mode: 0644]
utils/sockread/src/Makefile [new file with mode: 0644]
utils/sockread/src/main.c [new file with mode: 0644]
utils/stm32flash/Makefile
utils/stoken/Makefile [new file with mode: 0644]
utils/sumo/Makefile [new file with mode: 0644]
utils/sumo/files/sumo.sh [new file with mode: 0644]
utils/taskwarrior/Makefile [new file with mode: 0644]
utils/tcsh/Makefile
utils/tmux/Makefile
utils/tracertools/Makefile
utils/triggerhappy/Makefile
utils/unrar/Makefile
utils/unrar/patches/100-makefile_fixes.patch
utils/usbmuxd/Makefile
utils/zile/Makefile
utils/zoneinfo/Makefile [new file with mode: 0644]

index f28aea38f3021a70043954c59f00b9eb24125656..5edacdc2a81ac33073bfc65d8c6b901232fe2788 100644 (file)
@@ -1,12 +1,14 @@
 # Contributing Guidelines  
 (See <http://wiki.openwrt.org/doc/devel/packages> for overall format and construction)
 
+
 All packages you commit or submit by pull-request should follow these simple guidelines:
 
 * Package a version which is still maintained by the upstream author.
 * Will be updated regularly to maintained and supported versions.
 * Have no dependencies outside the OpenWrt core packages or this repository feed.
-* Have been tested to compile with the correct includes and dependencies. Also, test with "Compile with full language support" found under "General Build Settings" set.
+* Have been tested to compile with the correct includes and dependencies. Please also test with "Compile with full language support" found under "General Build Settings" set if language support is relevant to your package.
+* Do NOT use a rolling source file (e.g. foo-latest.tar.gz) or the head of a branch as source for the package since that would create unpredictable builds which change over time.
 * Best of all -- it works as expected!
 
 Makefile contents should contain:
@@ -16,10 +18,10 @@ Makefile contents should contain:
     (E.g.: PKG_MAINTAINER:= Joe D. Hacker `<jdh@jdhs-email-provider.org`>)
 * A PKG_LICENSE tag declaring the main license of the package.
     (E.g.: PKG_LICENSE:=GPL-2.0+) Please use SPDX identifiers if possible (see list at the bottom).
-* An optional PKG_LICENSE_FILE including the filename of the license-file in the source-package.
-    (E.g.: PKG_LICENSE_FILE:=COPYING)
+* An optional PKG_LICENSE_FILES including the filename of the license-file in the source-package.
+    (E.g.: PKG_LICENSE_FILES:=COPYING)
 
-Commits and pull-requests:
+Commits in your pull-requests should:
 
 * Have a useful description prefixed with the package name  
     (E.g.: "foopkg: Add libzot dependency")
index 461e5a4be27890142b404f2c73b33706af3d912e..f2e18d5d8554b748254f04ba45d73475bb276572 100644 (file)
@@ -9,13 +9,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=debootstrap
-PKG_VERSION:=1.0.63
+PKG_VERSION:=1.0.66
 PKG_RELEASE:=1
 PKG_MAINTAINER=Daniel Golle <daniel@makrotopia.org>
 
 PKG_SOURCE:=$(PKG_NAME)-udeb_$(PKG_VERSION)_all.udeb
 PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/d/debootstrap
-PKG_MD5SUM:=7bd6a1ad6721cc7d8c9ac637ae478df4
+PKG_MD5SUM:=bf6370ea0aa80308dfb03a4a35e33ad1
 PKG_LICENSE:=Unique
 PKG_LICENSE_FILES:=debian/copyright
 
@@ -28,7 +28,7 @@ define Package/debootstrap
   CATEGORY:=Administration
   TITLE:=Bootstrap a basic Debian system
   URL:=http://wiki.debian.org/Debootstrap
-  DEPENDS:= +coreutils +coreutils-chroot +coreutils-sha1sum
+  DEPENDS:= +coreutils +coreutils-chroot +coreutils-sha1sum +ar
 endef
 
 define Package/debootstrap/description
index cc56725581c0236f92f47a04f9f30263bd1b0743..bb3cfd09a0d17456dfd2b23760002f3299654bfd 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=monit
-PKG_VERSION:=5.9
+PKG_VERSION:=5.11
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://mmonit.com/monit/dist
-PKG_MD5SUM:=808473ebbacda0c5085d7399e507bfda
+PKG_MD5SUM:=ff00f39d248ed7068932ed82211da9e6
 
 PKG_LICENSE:=AGPL-3.0
 PKG_LICENSE_FILES:=COPYING
diff --git a/admin/muninlite/patches/110-fix-uptime-days.patch b/admin/muninlite/patches/110-fix-uptime-days.patch
new file mode 100644 (file)
index 0000000..17ef208
--- /dev/null
@@ -0,0 +1,9 @@
+--- a/plugins/uptime
++++ b/plugins/uptime
+@@ -7,5 +7,5 @@
+   echo "uptime.cdef uptime,86400,/"
+ }
+ fetch_uptime() {
+-  echo "uptime.value" $(cut -d\  -f1 /proc/uptime)
++  awk '{printf "uptime.value %.2f",$1/86400; print ""}' /proc/uptime
+ }
diff --git a/admin/sudo/Makefile b/admin/sudo/Makefile
new file mode 100644 (file)
index 0000000..f64b1d4
--- /dev/null
@@ -0,0 +1,97 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sudo
+PKG_VERSION:=1.8.11p2
+PKG_RELEASE:=1
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=doc/LICENSE
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.sudo.ws/sudo/dist
+PKG_MD5SUM:=84012b4871b6c775c957cd310d5bad87
+
+PKG_INSTALL:=1
+
+PKG_BUILD_DEPENDS:=sudo/host
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sudo
+  SECTION:=admin
+  CATEGORY:=Administration
+  TITLE:=Delegate authority to run commands
+  URL:=http://www.sudo.ws/
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+endef
+
+define Package/sudo/description
+ Sudo (su "do") allows a system administrator to delegate authority to
+ give certain users (or groups of users) the ability to run some (or
+ all) commands as root or another user while providing an audit trail of
+ the commands and their arguments.
+endef
+
+define Package/sudo/conffiles
+/etc/sudoers
+endef
+
+CONFIGURE_ARGS+= \
+       --without-pam \
+       --disable-pam-session \
+       --with-editor=/bin/vi \
+       --without-lecture \
+       --disable-zlib \
+       --with-rundir=/var/lib/sudo \
+       --with-vardir=/var/lib/sudo
+
+CONFIGURE_VARS+= \
+       sudo_cv_uid_t_len=10 \
+       sudo_cv_func_unsetenv_void=no
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Compile
+       cd $(HOST_BUILD_DIR)/lib/util; \
+           $(MAKE) mksiglist; $(MAKE) mksigname
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+       $(CP) $(HOST_BUILD_DIR)/lib/util/mksig{list,name} $(STAGING_DIR_HOST)/bin/
+endef
+
+$(eval $(call HostBuild))
+
+define Package/sudo/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/sudo $(1)/usr/bin/
+       chmod 4755 $(1)/usr/bin/sudo
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(CP) $(PKG_INSTALL_DIR)/usr/sbin/visudo $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/etc
+       $(CP) $(PKG_INSTALL_DIR)/etc/sudoers $(1)/etc/
+       chmod 0440 $(1)/etc/sudoers
+       $(INSTALL_DIR) $(1)/etc/sudoers.d
+       $(INSTALL_DIR) $(1)/usr/lib/sudo
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/sudo/*.so* $(1)/usr/lib/sudo/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/sudo.init $(1)/etc/init.d/sudo
+endef
+
+define Package/sudo/postinst
+#!/bin/sh
+
+[ -n "$$IPKG_INSTROOT" ] || {
+       /etc/init.d/sudo enable
+       /etc/init.d/sudo start
+}
+endef
+
+$(eval $(call BuildPackage,sudo))
diff --git a/admin/sudo/files/sudo.init b/admin/sudo/files/sudo.init
new file mode 100755 (executable)
index 0000000..705fe84
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=99
+
+start() {
+       [ -d /var/lib/sudo ] || {
+               mkdir -m 0755 -p /var/lib/sudo
+               chmod 0700 /var/lib/sudo
+       }
+}
diff --git a/admin/sudo/patches/010-cross-compile-fixes.patch b/admin/sudo/patches/010-cross-compile-fixes.patch
new file mode 100644 (file)
index 0000000..4e80d4d
--- /dev/null
@@ -0,0 +1,25 @@
+diff -rupN sudo-1.8.11p2.orig/lib/util/Makefile.in sudo-1.8.11p2/lib/util/Makefile.in
+--- sudo-1.8.11p2.orig/lib/util/Makefile.in    2014-10-07 22:26:20.000000000 +0200
++++ sudo-1.8.11p2/lib/util/Makefile.in 2014-12-09 21:44:35.610041162 +0100
+@@ -17,6 +17,8 @@
+ # @configure_input@
+ #
++include $(TOPDIR)/rules.mk
++
+ #### Start of system configuration section. ####
+ srcdir = @srcdir@
+@@ -142,10 +144,10 @@ libsudo_util.la: $(LTOBJS) @LT_LDDEP@
+       esac
+ siglist.c: mksiglist
+-      ./mksiglist > $@
++      $(STAGING_DIR_HOST)/bin/mksiglist > $@
+ signame.c: mksigname
+-      ./mksigname > $@
++      $(STAGING_DIR_HOST)/bin/mksigname > $@
+ mksiglist: $(srcdir)/mksiglist.c $(srcdir)/mksiglist.h $(incdir)/sudo_compat.h $(top_builddir)/config.h
+       $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/mksiglist.c -o $@
diff --git a/admin/sudo/patches/020-no-owner-change.patch b/admin/sudo/patches/020-no-owner-change.patch
new file mode 100644 (file)
index 0000000..417e95d
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rupN sudo-1.8.11p2.orig/Makefile.in sudo-1.8.11p2/Makefile.in
+--- sudo-1.8.11p2.orig/Makefile.in     2014-10-07 22:26:20.000000000 +0200
++++ sudo-1.8.11p2/Makefile.in  2014-12-09 22:00:27.256934143 +0100
+@@ -62,7 +62,7 @@ SHELL = @SHELL@
+ SED = @SED@
+ INSTALL = $(SHELL) $(top_srcdir)/install-sh -c
+-INSTALL_OWNER = -o $(install_uid) -g $(install_gid)
++INSTALL_OWNER =
+ ECHO_N = @ECHO_N@
+ ECHO_C = @ECHO_C@
index 6d4d77965153ee716597e08afba9323c8a955238..c3c618cd1cb0ee609ee0ce38f2c2befa042c06c8 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=zabbix
-PKG_VERSION:=2.4.0
+PKG_VERSION:=2.4.3
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/zabbix
-PKG_MD5SUM:=57d9bf72bf0732971e4540a402bfc6c6
+PKG_MD5SUM:=e8a0699c4e49999a15c63650a2280600
 
 PKG_LICENSE:=GPL-2.0
 PKG_LICENSE_FILES:=COPYING
@@ -32,6 +32,7 @@ define Package/zabbix/Default
   URL:=http://www.zabbix.com/
   SUBMENU:=zabbix
   MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
+  USERID:=zabbix=53:zabbix=53
 endef
 
 define Package/zabbix-agent
index ed9acabb96ee6b1c69ea141af58c2dc04fbfbbb0..c806a9f0b10a99cb549cd8c3e8bebcd7f528f117 100644 (file)
@@ -19,8 +19,6 @@ start() {
        }
 
        grep -q "^AllowRoot=1" ${CONFIG} || {
-               user_exists zabbix 53 || user_add zabbix 53
-               group_exists zabbix 53 || group_add zabbix 53
                touch ${SERVICE_PID_FILE}
                chown zabbix:zabbix ${SERVICE_PID_FILE}
        }
diff --git a/admin/zabbix/patches/001-cross_compile.patch b/admin/zabbix/patches/001-cross_compile.patch
deleted file mode 100644 (file)
index 77b9fe3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -824,25 +824,8 @@ dnl ************************************
- dnl Check for %qu format (FreeBSD 4.x)
- dnl FreeBSD 4.x does not support %llu
--AC_MSG_CHECKING(for long long format)
--AC_TRY_RUN(
--[
--#include <sys/types.h>
--int main()
--{
--        uint64_t i;
--
--        sscanf("200000000010020", "%qu", &i);
--
--        if (i == 200000000010020) return 0;
--        else return -1;
--}
--],
--AC_DEFINE(HAVE_LONG_LONG_QU, 1 ,[Define to 1 if format '%qu' exists.])
--AC_MSG_RESULT(yes),
--AC_MSG_RESULT(no))
--
- dnl option -rdynamic is needed for readable backtraces
-+
- AC_MSG_CHECKING(for -rdynamic linking option)
- saved_LDFLAGS="$LDFLAGS"
- LDFLAGS="-rdynamic $LDFLAGS"
index c8d87335e91c4c685a68edc5998210b46501d8f6..9cdde88dda2f66f208b5e58523fc0c2b59081e9b 100644 (file)
@@ -110,6 +110,7 @@ define Package/gcc/install
        cp -ar $(TOOLCHAIN_DIR)/include $(1)/usr/lib/$(PKG_NAME)/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)
        cp -a $(TOOLCHAIN_DIR)/lib/*.{o,so*} $(1)/usr/lib/$(PKG_NAME)/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)
        cp -a $(TOOLCHAIN_DIR)/lib/*nonshared*.a  $(1)/usr/lib/$(PKG_NAME)/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)
+       grep "GROUP.*-lgcc" $(1)/usr/lib/$(PKG_NAME)/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)/libgcc_s.so && cp -a $(PKG_INSTALL_DIR)/usr/lib/gcc/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)/libgcc.a $(1)/usr/lib/$(PKG_NAME)/$(REAL_GNU_TARGET_NAME)/$(PKG_VERSION)/ ; true
 endef
 
 $(eval $(call BuildPackage,gcc))
index 6cbc80d2b6969569c592466e6ecfc8413a4d8bc9..58db4740ca2989d30d50dadf959f5bbeb287b758 100644 (file)
@@ -1,8 +1,10 @@
 Native GCC that runs on target.
 
 To save disk space, this GCC only supports dynamic linking on the target box,
-there are no static libraries shipped.
+there are no static libraries shipped except libgcc.a on those architectures
+that need it.
 
-For now, this was only tested on a mips target. Others to be done...
+For now, this was only tested on arm (EABI) and mips targets. Others to be
+done...
 
-   Christian Beier <cb@shoutrlabs.com>
\ No newline at end of file
+   Christian Beier <cb@shoutrlabs.com>
diff --git a/devel/gcc/patches/020-disable-check-for-sys-sdt-h.patch b/devel/gcc/patches/020-disable-check-for-sys-sdt-h.patch
new file mode 100644 (file)
index 0000000..afc5cfd
--- /dev/null
@@ -0,0 +1,45 @@
+diff --git a/gcc/configure b/gcc/configure
+index 3793681..bcda752 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -26876,19 +26876,6 @@ $as_echo "#define TARGET_LIBC_PROVIDES_SSP 1" >>confdefs.h
+ fi
+-# Test for <sys/sdt.h> on the target.
+-
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sys/sdt.h in the target C library" >&5
+-$as_echo_n "checking sys/sdt.h in the target C library... " >&6; }
+-have_sys_sdt_h=no
+-if test -f $target_header_dir/sys/sdt.h; then
+-  have_sys_sdt_h=yes
+-
+-$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
+-
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sys_sdt_h" >&5
+-$as_echo "$have_sys_sdt_h" >&6; }
+ # Check if TFmode long double should be used by default or not.
+ # Some glibc targets used DFmode long double, but with glibc 2.4
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index 3ee1d67..e321218 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -4796,16 +4796,6 @@ if test x$gcc_cv_libc_provides_ssp = xyes; then
+           [Define if your target C library provides stack protector support])
+ fi
+-# Test for <sys/sdt.h> on the target.
+-GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
+-AC_MSG_CHECKING(sys/sdt.h in the target C library)
+-have_sys_sdt_h=no
+-if test -f $target_header_dir/sys/sdt.h; then
+-  have_sys_sdt_h=yes
+-  AC_DEFINE(HAVE_SYS_SDT_H, 1,
+-            [Define if your target C library provides sys/sdt.h])
+-fi
+-AC_MSG_RESULT($have_sys_sdt_h)
+ # Check if TFmode long double should be used by default or not.
+ # Some glibc targets used DFmode long double, but with glibc 2.4
index 63809c5b8c92127912a1c463f2d727ba44e4953d..0d59966d516845000b36bff4240be9a3caba96fc 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2008-2014 OpenWrt.org
+# Copyright (C) 2008-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=patch
-PKG_VERSION:=2.7.1
+PKG_VERSION:=2.7.3
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@GNU/patch
-PKG_MD5SUM:=e9ae5393426d3ad783a300a338c09b72
+PKG_MD5SUM:=29b87be845e4662ab0ca0d48a805ecc6
 PKG_LICENSE:=GPL-3.0+
 PKG_LICENSE_FILES:=COPYING
 
index bfa8a83206c2f09c417ea2889a40ced1715fea54..50839f359a3c2794e7a16ac0c295a4c015f4dc19 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=aiccu
 PKG_VERSION:=20070115
-PKG_RELEASE:=11
+PKG_RELEASE:=12
 
 PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.sixxs.net/archive/sixxs/aiccu/unix
@@ -47,9 +47,10 @@ define Package/aiccu/conffiles
 endef
 
 define Package/aiccu/install
-       $(INSTALL_DIR) $(1)/usr/sbin $(1)/lib/netifd/proto
+       $(INSTALL_DIR) $(1)/usr/sbin $(1)/lib/netifd/proto $(1)/etc/hotplug.d/ntp
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/unix-console/$(PKG_NAME) $(1)/usr/sbin/
        $(INSTALL_BIN) ./files/aiccu.sh $(1)/lib/netifd/proto/aiccu.sh
+       $(INSTALL_DATA) ./files/aiccu.hotplug $(1)/etc/hotplug.d/ntp/10-aiccu
 endef
 
 $(eval $(call BuildPackage,aiccu))
diff --git a/ipv6/aiccu/files/aiccu.hotplug b/ipv6/aiccu/files/aiccu.hotplug
new file mode 100644 (file)
index 0000000..b521371
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+NTPSTRATUMFILE="/var/run/aiccu_ntp_stratum"
+echo $stratum > "$NTPSTRATUMFILE"
index 669e0e257fbbc215c7e106d48e82dea481992185..38d8191f502fdc3ab9e3e1508238532081c874c3 100755 (executable)
@@ -14,8 +14,8 @@ proto_aiccu_setup() {
        local iface="$2"
        local link="aiccu-$cfg"
 
-       local username password protocol server ip6prefix tunnelid requiretls defaultroute nat heartbeat verbose sourcerouting ip6addr
-       json_get_vars username password protocol server ip6prefix tunnelid requiretls defaultroute nat heartbeat verbose sourcerouting ip6addr
+       local username password protocol server ip6prefix tunnelid requiretls defaultroute nat heartbeat verbose sourcerouting ip6addr ntpsynctimeout
+       json_get_vars username password protocol server ip6prefix tunnelid requiretls defaultroute nat heartbeat verbose sourcerouting ip6addr ntpsynctimeout
 
        [ -z "$username" -o -z "$password" ] && {
                proto_notify_error "$cfg" "MISSING_USERNAME_OR_PASSWORD"
@@ -27,21 +27,32 @@ proto_aiccu_setup() {
 
        CFGFILE="/var/etc/${link}.conf"
        PIDFILE="/var/run/${link}.pid"
+       NTPSTRATUMFILE="/var/run/aiccu_ntp_stratum"
        mkdir -p /var/run /var/etc
 
        echo "username $username" > "$CFGFILE"
        echo "password $password" >> "$CFGFILE"
-       echo "ipv6_interface $link"   >> "$CFGFILE"
+       echo "ipv6_interface $link" >> "$CFGFILE"
        [ -n "$server" ] && echo "server $server" >> "$CFGFILE"
        [ -n "$protocol" ] && echo "protocol $protocol" >> "$CFGFILE"
-       [ -n "$tunnelid" ] && echo "tunnel_id $tunnelid"          >> "$CFGFILE"
-       [ -n "$requiretls" ] && echo "requiretls $requiretls"      >> "$CFGFILE"
-       [ "$nat" == 1 ] && echo "behindnat true"     >> "$CFGFILE"
-       [ "$heartbeat"  == 1 ] && echo "makebeats true" >> "$CFGFILE"
+       [ -n "$tunnelid" ] && echo "tunnel_id $tunnelid" >> "$CFGFILE"
+       [ -n "$requiretls" ] && echo "requiretls $requiretls" >> "$CFGFILE"
+       [ "$nat" == 1 ] && echo "behindnat true" >> "$CFGFILE"
+       [ "$heartbeat" == 1 ] && echo "makebeats true" >> "$CFGFILE"
        [ "$verbose" == 1 ] && echo "verbose true" >> "$CFGFILE"
        echo "defaultroute false" >> "$CFGFILE"
-       echo "daemonize true"     >> "$CFGFILE"
-       echo "pidfile $PIDFILE"   >> "$CFGFILE"
+       echo "daemonize true" >> "$CFGFILE"
+       echo "pidfile $PIDFILE" >> "$CFGFILE"
+
+       # By default, wait at most 90 seconds for NTP sync
+       [ -z "$ntpsynctimeout" ] && ntpsynctimeout=90
+       for i in $(seq 1 $ntpsynctimeout); do
+               [ -f "$NTPSTRATUMFILE" ] && \
+               [ "$(cat $NTPSTRATUMFILE)" -lt 16 ] && \
+               echo "NTP synced, stratum $(cat $NTPSTRATUMFILE)" && break
+               [ "$(( $i % 10 ))" -eq 0 ] && echo "Waiting ${i} secs for NTP sync..."
+               sleep 1
+       done
 
        aiccu start "$CFGFILE"
 
@@ -78,8 +89,12 @@ proto_aiccu_teardown() {
        local cfg="$1"
        local link="aiccu-$cfg"
        CFGFILE="/var/etc/${link}.conf"
-
-       aiccu stop "$CFGFILE"
+       PIDFILE="/var/run/${link}.pid"
+       [ -f "$CFGFILE" -a -f "$PIDFILE" ] && {
+               local pid="$(cat "$PIDFILE")"
+               [ -d /proc/$pid -a $(cat /proc/$pid/comm) = "aiccu" ] && \
+               aiccu stop "$CFGFILE"
+       }
 }
 
 proto_aiccu_init_config() {
@@ -98,6 +113,7 @@ proto_aiccu_init_config() {
        proto_config_add_boolean "nat"
        proto_config_add_boolean "heartbeat"
        proto_config_add_boolean "verbose"
+       proto_config_add_int "ntpsynctimeout"
 }
 
 [ -n "$INCLUDE_ONLY" ] || {
index c7a7d8729cd848750edf88af2b5ea80b5634cd54..4a6422874bdb2e66db985e15fe707f0fc3f43272 100644 (file)
@@ -13,7 +13,6 @@ PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://dkolf.de/src/dkjson-lua.fsl/tarball/
-PKG_BUILD_DIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_MD5SUM:=dbe706722dd64308172cf8e37395e762
 PKG_LICENSE:=MIT
 
index 1bf17f3347c165f08f0a09a4face7e34bf87d78f..dc4c31670a21572b1ca1bd1e8beb42fcb65aa589 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009-2014 OpenWrt.org
+# Copyright (C) 2009-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=erlang
-PKG_VERSION:=17.1
+PKG_VERSION:=17.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=otp_src_$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:= http://www.erlang.org/download/ \
        http://erlang.mirror.su.se/
-PKG_MD5SUM:=9c90706ce70e01651adde34a2b79bf4c
+PKG_MD5SUM:=3d33c4c6bd7950240dcd7479edd9c7d8
 
 PKG_LICENSE:=ErlPL-1.1
-PKG_LICENSE_FILE:=EPLICENCE
+PKG_LICENSE_FILES:=EPLICENCE
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_BUILD_DEPENDS:=erlang/host openssl
diff --git a/lang/jamvm/Makefile b/lang/jamvm/Makefile
new file mode 100644 (file)
index 0000000..996dfa0
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=jamvm
+PKG_VERSION:=2.0.0
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0+
+PKG_MAINTAINER:=Dana H. Myers <k6jq@comcast.net>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=a6e3321ef4b3cfb4afc20bd75452e11e
+
+PKG_USE_MIPS16:=0
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/jamvm
+  SUBMENU:=Java
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=A compact Java Virtual Machine
+  URL:=http://sourceforge.net/projects/jamvm
+  DEPENDS:=+zlib +libpthread +librt +classpath @!avr32
+endef
+
+define Package/jamvm/description
+ JamVM is a new Java Virtual Machine which conforms to the JVM
+ specification version (blue book). In comparison to most other VM's (free
+ and commercial) it is extremely small.However, unlike other small VMs
+ (e.g. KVM) it is designed to support the full specification, and includes
+ support for object finalisation, Soft/Weak/Phantom References, the Java
+ Native Interface (JNI) and the Reflection API.
+endef
+
+CONFIGURE_ARGS += \
+       --with-java-runtime-library=gnuclasspath \
+       --with-classpath-install-dir=/usr \
+       --disable-int-inlining \
+       --disable-shared \
+       --without-pic
+
+MAKE_FLAGS += \
+       GLIBJ_ZIP=$(STAGING_DIR)/usr/share/classpath/glibj.zip
+
+define Package/jamvm/install
+       $(INSTALL_DIR) $(1)/usr
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/bin \
+               $(PKG_INSTALL_DIR)/usr/share \
+               $(1)/usr/
+endef
+
+define Build/InstallDev
+       $(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+$(eval $(call BuildPackage,jamvm))
diff --git a/lang/lua-mosquitto/Makefile b/lang/lua-mosquitto/Makefile
new file mode 100644 (file)
index 0000000..a8d625f
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=lua-mosquitto
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_SOURCE:=v$(PKG_VERSION).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/flukso/$(PKG_NAME)/archive/
+PKG_MD5SUM:=fd26fa08fc855ba4a66ce521fe5aae13
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/$(PKG_NAME)
+    SUBMENU:=Lua
+    SECTION:=lang
+    CATEGORY:=Languages
+    TITLE:=Lua-mosquitto
+    DEPENDS:=+libmosquitto +lua
+    MAINTAINER:=Karl Palsson <karlp@remake.is>
+endef
+
+define Package/$(PKG_NAME)/description
+       Lua bindings to libmosquitto
+endef
+
+define Package/$(PKG_NAME)/install
+       $(INSTALL_DIR) $(1)/usr/lib/lua
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto.so $(1)/usr/lib/lua
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)))
diff --git a/lang/lua-penlight/Makefile b/lang/lua-penlight/Makefile
new file mode 100644 (file)
index 0000000..e06f4c2
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=lua-penlight
+PKG_VERSION:=1.3.1
+PKG_RELEASE:=1
+PKG_BUILD_DIR:=$(BUILD_DIR)/Penlight-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/stevedonovan/Penlight/archive/
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILE:=LICENSE.md
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/$(PKG_NAME)
+  SUBMENU:=Lua
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Penlight
+  URL:=http://stevedonovan.github.io/Penlight/api/manual/01-introduction.md.html
+  DEPENDS:=+luafilesystem
+  MAINTAINER:= Karl Palsson <karlp@remake.is>
+endef
+
+define Package/$(PKG_NAME)/description
+  It is often said of Lua that it does not include batteries.
+  Penlight is the batteries.
+endef
+
+define Build/Compile
+       echo "Nothing to compile, pure lua package"
+endef
+
+define Package/$(PKG_NAME)/install
+       $(INSTALL_DIR) $(1)/usr/lib/lua
+       $(CP) $(PKG_BUILD_DIR)/lua/pl $(1)/usr/lib/lua
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)))
index 29f1a676fe6d1e63c1183ebd4337409cb5037f0a..4a0d734fd3c439b29a47925996a7751b91fd4d4b 100644 (file)
@@ -8,17 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=luaposix
-PKG_VERSION:=v32
-PKG_RELEASE:=1
+PKG_VERSION:=v33.2.1
+PKG_RELEASE:=3
 
 PKG_SOURCE:=release-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/luaposix/luaposix/archive/
-PKG_MD5SUM:=2bfede7b7cee96c5d0f6c0354e17498c
+PKG_MD5SUM:=aa68b5c07ab1ecea81bb466c81e88056
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-release-$(PKG_VERSION)
 PKG_REMOVE_FILES:=aclocal.m4
 PKG_FIXUP:=autoreconf
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -37,6 +38,8 @@ define Package/luaposix/description
   to various low level libc functions.
 endef
 
+CONFIGURE_VARS += ac_cv_path_LDOC=""
+
 TARGET_CFLAGS += -DLUA_USE_LINUX $(FPIC) -std=gnu99
 
 ifneq ($(CONFIG_USE_EGLIBC),)
@@ -47,9 +50,10 @@ endif
 
 
 define Package/luaposix/install
-       $(INSTALL_DIR) $(1)/usr/lib/lua
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/ext/posix/.libs/posix_c.so $(1)/usr/lib/lua
+       $(INSTALL_DIR) $(1)/usr/lib/lua/posix
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/ext/posix/.libs/posix.so $(1)/usr/lib/lua
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/posix.lua $(1)/usr/lib/lua
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/posix/*.lua $(1)/usr/lib/lua/posix
 endef
 
 $(eval $(call BuildPackage,luaposix))
index 0cdff83d2c351c71b374ebd5428fa9d1c4d62f0f..e4df63bfc15af8e9220ee29be26336fc0065b307 100644 (file)
@@ -1,28 +1,30 @@
---- a/ext/posix/posix.c
-+++ b/ext/posix/posix.c
-@@ -1970,6 +1970,7 @@ static int Pctermid(lua_State *L)
-       return 1;
- }
+diff --git a/ext/posix/unistd.c b/ext/posix/unistd.c
+index 9276640..69c8cef 100644
+--- a/ext/posix/unistd.c
++++ b/ext/posix/unistd.c
+@@ -525,6 +525,7 @@ Pgetgroups(lua_State *L)
+ #endif
  
 +#ifndef NO_GETLOGIN
  /***
  Current logged-in user.
- @see getlogin(3)
-@@ -1980,6 +1981,7 @@ static int Pgetlogin(lua_State *L)
-       lua_pushstring(L, getlogin());
-       return 1;
+ @treturn[1] string username, if successful
+@@ -537,6 +538,7 @@ Pgetlogin(lua_State *L)
+       checknargs(L, 0);
+       return pushstringresult(getlogin());
  }
 +#endif
  
- static void Fgetpasswd(lua_State *L, int i, const void *data)
- {
-@@ -3786,7 +3788,9 @@ static const luaL_Reg R[] =
- #if _POSIX_VERSION >= 200112L
-       MENTRY( Pgetgroups      ),
- #endif
+ /***
+@@ -1044,7 +1046,9 @@ static const luaL_Reg posix_unistd_fns[] =
+       LPOSIX_FUNC( Pgetegid           ),
+       LPOSIX_FUNC( Pgeteuid           ),
+       LPOSIX_FUNC( Pgetgid            ),
 +#ifndef NO_GETLOGIN
-       MENTRY( Pgetlogin       ),
+       LPOSIX_FUNC( Pgetlogin          ),
 +#endif
-       MENTRY( Pgetopt         ),
-       MENTRY( Pgetpasswd      ),
-       MENTRY( Pgetpid         ),
+       LPOSIX_FUNC( Pgetpgrp           ),
+       LPOSIX_FUNC( Pgetpid            ),
+       LPOSIX_FUNC( Pgetppid           ),
diff --git a/lang/luaposix/patches/101-disable-curses.patch b/lang/luaposix/patches/101-disable-curses.patch
new file mode 100644 (file)
index 0000000..6412799
--- /dev/null
@@ -0,0 +1,32 @@
+diff --git a/configure.ac b/configure.ac
+index dfd4199..19924d0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -153,15 +153,6 @@ AC_CHECK_LIB([rt], [clock_gettime])
+ AC_SUBST([LIBRT], [$LIBS])
+ LIBS=$save_LIBS
+-## Curses
+-AX_WITH_CURSES
+-AC_ARG_VAR(CURSES_LIB, [linker flags for curses library])
+-
+-save_LIBS=$LIBS
+-LIBS="$CURSES_LIB $LIBS"
+-AC_CHECK_FUNCS([resizeterm])
+-LIBS=$save_LIBS
+-
+ ## Use system implementation, or bundled replacement?
+ AC_CHECK_FUNCS([strlcpy])
+diff --git a/ext/posix/posix.c b/ext/posix/posix.c
+index 6019df0..2d75487 100644
+--- a/ext/posix/posix.c
++++ b/ext/posix/posix.c
+@@ -12,7 +12,6 @@
+ #include "bit32.c"
+ #include "ctype.c"
+-#include "curses.c"
+ #include "dirent.c"
+ #include "errno.c"
+ #include "fcntl.c"
index 4f2123040f27da9573d9db6dcb17a56df7bb2120..9ed69d24503ffa09db81b1957a486bcc40dc051a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009-2010 OpenWrt.org
+# Copyright (C) 2009-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=luasec
-PKG_VERSION:=0.4
+PKG_VERSION:=0.5
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://files.luaforge.net/releases/luasec/LuaSec/LuaSec0.4/
-PKG_MD5SUM:=712158d60207bdbb6215fc7e07d8db24
+PKG_SOURCE_URL:=https://github.com/brunoos/luasec/archive/
+PKG_MD5SUM:=0518f4524f399f33424c6f450e1d06db
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
+
+MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
 
 PKG_INSTALL:=1
 
@@ -24,8 +29,7 @@ define Package/luasec
   SECTION:=lang
   CATEGORY:=Languages
   TITLE:=LuaSec
-  URL:=http://luasec.luaforge.net/
-  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+  URL:=https://github.com/brunoos/luasec
   DEPENDS:=+lua +libopenssl +luasocket
 endef
 
@@ -36,16 +40,15 @@ endef
 define Build/Configure
 endef
 
-MAKE_PATH = ./src
-
 MAKE_FLAGS += \
-       INCDIR="$(TARGET_CPPFLAGS)" \
-       LIBDIR="$(TARGET_LDFLAGS)" \
-       CC="$(TARGET_CC) $(TARGET_CFLAGS) -std=gnu99" \
-       LD="$(TARGET_CROSS)ld -shared" \
-       LUACPATH="$(PKG_INSTALL_DIR)/usr/lib/lua" \
-       LUAPATH="$(PKG_INSTALL_DIR)/usr/lib/lua" \
-       linux \
+       INCDIR="$(TARGET_CPPFLAGS) -I." \
+       LIBDIR="$(TARGET_LDFLAGS) -L./luasocket" \
+       LUACPATH="/usr/lib/lua" \
+       LUAPATH="/usr/lib/lua"
+
+define Build/Compile
+$(call Build/Compile/Default,linux)
+endef
 
 define Package/luasec/install
        $(INSTALL_DIR) $(1)/usr/lib/lua
diff --git a/lang/luasec/patches/100-luasocket-Makefile.patch b/lang/luasec/patches/100-luasocket-Makefile.patch
new file mode 100644 (file)
index 0000000..24de7fc
--- /dev/null
@@ -0,0 +1,20 @@
+--- luasec-luasec-0.5-old/src/luasocket/Makefile       2014-01-29 21:43:33.000000000 +0100
++++ luasec-luasec-0.5/src/luasocket/Makefile   2014-11-30 13:07:44.850051000 +0100
+@@ -6,7 +6,7 @@
+ CC    ?= cc
+ CFLAGS        += $(MYCFLAGS) -DLUASOCKET_DEBUG
+-AR    := ar rcu
++AR    ?= ar
+ RANLIB        ?= ranlib
+ .PHONY: all clean
+@@ -14,7 +14,7 @@
+ all: libluasocket.a
+ libluasocket.a: $(OBJS)
+-      $(AR) $@ $(OBJS)
++      $(AR) rcu $@ $(OBJS)
+       $(RANLIB) $@
+ clean:
index 513fa247d318068c1e4261796a59b9f90dae6fdc..6df105dc73e2fba075a24568ab607319e56ab11f 100644 (file)
@@ -8,15 +8,15 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=luasql
-PKG_VERSION:=2.1.1
+PKG_VERSION:=2.3.0
 PKG_RELEASE:=1
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://files.luaforge.net/releases/luasql/luasql
-PKG_MD5SUM:=63bdd57de4b9d1be336ba112d8cb69eb
+PKG_SOURCE:=v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/keplerproject/luasql/archive/
+PKG_MD5SUM:=af9f0f3a2313a1fcf88c40700092048d
 
 PKG_LICENSE:=MIT
-PKG_LICENSE_FILE:=docs/us/license.html
+PKG_LICENSE_FILES:=docs/us/license.html
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
index a737192c7c5e46ce625dca8e3c1d324bda3a8a4d..b74ad0e08d70a22a1fb38d34dbaa2f9b56567159 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=micropython-lib
-PKG_VERSION=0.1-20140822-$(PKG_SOURCE_VERSION)
+PKG_VERSION=0.1-20141028-$(PKG_SOURCE_VERSION)
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
@@ -17,7 +17,7 @@ PKG_LICENSE_FILES:=LICENSE
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/micropython/micropython-lib.git
-PKG_SOURCE_VERSION:=46ede279d8fae081319914d00cb4a9bb22102fa1
+PKG_SOURCE_VERSION:=610aa65ceff9f4b0a60514423f543aa807f49f76
 
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION)
 PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
@@ -27,6 +27,7 @@ PKG_BUILD_PARALLEL:=1
 include $(INCLUDE_DIR)/package.mk
 
 define Package/micropython-lib
+    SUBMENU:=Python
     SECTION:=lang
     CATEGORY:=Languages
     TITLE:=micropython-lib
index e73ca7afc2dd1df38b9a00cdc0e15ffc2a1dbcc4..c1904567c1a1d602a330ad5a5e9124cb2cf4b678 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=micropython
-PKG_VERSION=1.3.3-20141006-$(PKG_SOURCE_VERSION)
+PKG_VERSION=1.3.7-20141209-$(PKG_SOURCE_VERSION)
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
@@ -17,7 +17,7 @@ PKG_LICENSE_FILES:=LICENSE
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/micropython/micropython.git
-PKG_SOURCE_VERSION:=67f25dfe6f4b13a3b8d40746d2b2fd720c63caed
+PKG_SOURCE_VERSION:=e6e8ad8ab238cd596a3eedf8f4dd635e2e84f46e
 
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
@@ -27,6 +27,7 @@ PKG_BUILD_PARALLEL:=1
 include $(INCLUDE_DIR)/package.mk
 
 define Package/micropython
+  SUBMENU:=Python
   SECTION:=lang
   CATEGORY:=Languages
   TITLE:=Micro Python
index 9f9430a6782f3e97746874d409fdc57bb794ff66..77af131db81086bf8d4d08936b8048c227fd18ec 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 OpenWrt.org
+# Copyright (C) 2014, 2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-compress-bzip2
-PKG_VERSION:=2.18
+PKG_VERSION:=2.20
 PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/R/RU/RURBAN/
 PKG_SOURCE:=Compress-Bzip2-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=c4a1995df9443cb97c28593cbbb23304
+PKG_MD5SUM:=36b42271d274d941b4a9fed332c6f880
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
index 53c15066f7f852e922dd77d295856478d59aabcc..263359128c44db8d1586ce36d05263c86ede1416 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 OpenWrt.org
+# Copyright (C) 2014, 2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-dbi
-PKG_VERSION:=1.631
-PKG_RELEASE:=2
+PKG_VERSION:=1.633
+PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/T/TI/TIMB/
 PKG_SOURCE:=DBI-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=444d3c305e86597e11092b517794a840
+PKG_MD5SUM:=b4fe13b9a51c1446c5f3cf93e69a2044
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
index 524bbd751d6cdcf1e7c499319dd281f87b85f2b8..9a0f0a5329b6bc790f89b5ff9b15e40b395cc9a4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 OpenWrt.org
+# Copyright (C) 2014, 2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-test-harness
-PKG_VERSION:=3.33
+PKG_VERSION:=3.35
 PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/L/LE/LEONT/
 PKG_SOURCE:=Test-Harness-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=7a72849ee1e67184db098146cc7c8855
+PKG_MD5SUM:=2a6010bca2ad78e094d629eea6afd7d9
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
index d298dd98cd40f6aa1b7a8982d4b77543d33e7867..64cc10f1768ae60d252ea9d07590175fdc39949c 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-uri
-PKG_VERSION:=1.64
+PKG_VERSION:=1.65
 PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/E/ET/ETHER/
 PKG_SOURCE:=URI-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=975b2282bc8f0fd72a6dae5cefc33824
+PKG_MD5SUM:=12c5d612a20ddd42041a5aa426f66269
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
index 4fe85ebc55d63fe8e1c1d27afd9cac9775621ad7..576424cd22aa5eee558287f401ca62d704b7e6ad 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2010-2014 OpenWrt.org
+# Copyright (C) 2010-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl-www-mechanize
-PKG_VERSION:=1.73
+PKG_VERSION:=1.74
 PKG_RELEASE:=1
 
 PKG_SOURCE:=WWW-Mechanize-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/E/ET/ETHER/
-PKG_MD5SUM:=de0a9c528c12793c881151301bc14d1a
+PKG_MD5SUM:=8ec615225037ac66a2d37f4e9693ef86
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
diff --git a/lang/perl/Config.in b/lang/perl/Config.in
new file mode 100644 (file)
index 0000000..3cfa71d
--- /dev/null
@@ -0,0 +1,15 @@
+menu "Configuration"
+       depends on PACKAGE_perl
+
+config PERL_TESTS
+       bool "Include perl tests"
+       default n
+       help
+               Include test suites for all perl packages.
+               This will make perl related packages much bigger, so
+               use with care.
+               
+               Note: Test support is still in development. Some tests
+               still fail, others are just missing completely.
+
+endmenu
index edf3e4534564050d6aff86f160b4495f58211302..8bf42bd7489bae1e10831c729e3e670d072c1561 100644 (file)
@@ -8,8 +8,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=perl
-PKG_VERSION:=5.20.0
-PKG_RELEASE:=5
+PKG_VERSION:=5.20.1
+PKG_RELEASE:=2
 
 PKG_SOURCE_URL:=ftp://ftp.cpan.org/pub/CPAN/src/5.0 \
                http://www.cpan.org/src/5.0/perl-5.20.0.tar.gz \
@@ -20,7 +20,7 @@ PKG_SOURCE_URL:=ftp://ftp.cpan.org/pub/CPAN/src/5.0 \
                ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/5.0 \
                http://ftp.funet.fi/pub/languages/perl/CPAN/src/5.0
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=406ec049ebe3afcc80d9c76ec78ca4f8
+PKG_MD5SUM:=7a195abb7d6769f751e90c7d30dcf2e0
 
 PKG_LICENSE:=GPL-1.0+ Artistic-1.0-Perl
 PKG_LICENSE_FILES:=Copying Artistic README
@@ -44,6 +44,16 @@ endif
 TARGET_CFLAGS_PERL:=$(patsubst -g3,-g,$(TARGET_CFLAGS))
 TARGET_CPPFLAGS_PERL:=$(patsubst -g3,-g,$(TARGET_CPPFLAGS))
 
+# A list of disabled testss
+# ExtUtils tests are disabled for now as we don't support building
+# native extensions on the target machine at the moment
+PERL_DISABLEDTESTS:=cpan/ExtUtils-Constant cpan/ExtUtils-MakeMaker
+# We're on Linux, so don't even package those
+PERL_DISABLEDTESTS+=cpan/Win32API-File cpan/Win32 ext/VMS-DCLsym ext/VMS-Filespec ext/VMS-Stdio ext/Win32CORE
+# NDBM and ODBM not supported
+PERL_DISABLEDTESTS+=ext/NDBM_File ext/ODBM_File
+
+
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/host-build.mk
 include perlmod.mk
@@ -63,6 +73,10 @@ define Package/perl/description
   and is widely used to program web applications of all needs.
 endef
 
+define Package/perl/config
+       source "$(SOURCE)/Config.in"
+endef
+
 # Static host perl
 define Host/Configure
        ( cd $(HOST_BUILD_DIR); ./Configure -der -Uusedl -Duserelocatableinc -Dprefix=$(HOST_PERL_PREFIX) )
@@ -128,3 +142,37 @@ $(eval $(call BuildPackage,perl))
 $(eval $(call HostBuild))
 
 -include perlbase.mk
+
+# A helper package that includes all sort of supplementary files for tests
+define Package/perl-tests-common
+$(call Package/perlbase-template)
+TITLE:=Common test support files
+DEPENDS:=@PERL_TESTS
+endef
+
+define Package/perl-tests-common/install
+       $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)
+       $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/Porting
+       $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/regen
+       $(INSTALL_DIR) $(1)/usr/lib/perl5/5.20/XS
+       $(INSTALL_DIR) $(1)/usr/lib/perl5/5.20/auto/XS
+       $(INSTALL_DIR) $(1)/usr/lib/perl5/5.20/unicore
+       
+       $(CP) $(PKG_BUILD_DIR)/t $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/Porting $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/regen $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/MANIFEST $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/TestInit.pm $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/vutil.c $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/vxs.inc $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/lib/XS $(1)/usr/lib/perl5/5.20/
+       $(CP) $(PKG_BUILD_DIR)/lib/auto/XS $(1)/usr/lib/perl5/5.20/auto
+       $(CP) $(PKG_BUILD_DIR)/lib/vmsish.pm $(1)/usr/lib/perl5/5.20/
+       $(CP) $(PKG_BUILD_DIR)/lib/unicore/TestProp.pl $(1)/usr/lib/perl5/5.20/unicore
+       $(CP) files/perl-run_tests.sh $(1)/$(PERL_TESTSDIR)/run_tests.sh
+       sed -e 's!%%PERL_DISABLEDTESTS%%!$(PERL_DISABLEDTESTS)!' -i $(1)/$(PERL_TESTSDIR)/run_tests.sh
+       $(CP) $(PKG_BUILD_DIR)/config_h.SH $(1)/$(PERL_TESTSDIR)
+       $(CP) $(PKG_BUILD_DIR)/perl.h $(1)/$(PERL_TESTSDIR)
+endef
+
+$(eval $(call BuildPackage,perl-tests-common))
index a23a6fdc6df601b02e68bab7082b034e0ee623d6..1296f30785cba906914b5bdd358ba62d04f56eeb 100644 (file)
@@ -740,12 +740,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -829,7 +829,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -949,7 +949,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1050,8 +1049,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 
 PERL_API_SUBVERSION=0
@@ -1108,8 +1105,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1139,7 +1136,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1150,12 +1147,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index aee8b2af63dbbce3592e8eaa7c8aed8374fb3b53..845be28401a704192f3f8411c121170818af4504 100644 (file)
@@ -32,7 +32,6 @@ alignbytes='4'
 ansi2knr=''
 aphostname='/bin/hostname'
 api_revision='5'
-api_subversion='0'
 
 
 ar='ar'
@@ -740,12 +739,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -829,7 +828,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -1050,8 +1049,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 
 PERL_API_SUBVERSION=0
@@ -1108,8 +1105,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1139,7 +1136,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1150,12 +1147,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+api_subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index 64542e8afda20090f0a8b13682e76cb6eeb58cce..2f65ddaaae45ded66dc7b39cce30319fb5f0d3dd 100644 (file)
@@ -742,12 +742,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -831,7 +831,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -951,7 +951,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1052,8 +1051,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 
 PERL_API_SUBVERSION=0
@@ -1110,8 +1107,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1141,7 +1138,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1152,12 +1149,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index f915fd84c0bfee902ea1779698b52f667ace6d94..5047afee783c5503f63977b156b4a7af4c8f38c0 100644 (file)
@@ -733,12 +733,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -820,7 +820,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -885,8 +885,8 @@ shortsize='2'
 shrpenv=''
 shsharp='true'
 sig_count='64'
-sig_name='ZERO HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS RTMIN NUM33 NUM34 NUM35 NUM36 NUM37 NUM38 NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 NUM45 NUM46 NUM47 NUM48 NUM49 NUM50 NUM51 NUM52 NUM53 NUM54 NUM55 NUM56 NUM57 NUM58 NUM59 NUM60 NUM61 NUM62 RTMAX IOT CLD POLL UNUSED '
-sig_name_init='"ZERO", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "SYS", "RTMIN", "NUM33", "NUM34", "NUM35", "NUM36", "NUM37", "NUM38", "NUM39", "NUM40", "NUM41", "NUM42", "NUM43", "NUM44", "NUM45", "NUM46", "NUM47", "NUM48", "NUM49", "NUM50", "NUM51", "NUM52", "NUM53", "NUM54", "NUM55", "NUM56", "NUM57", "NUM58", "NUM59", "NUM60", "NUM61", "NUM62", "RTMAX", "IOT", "CLD", "POLL", "UNUSED", 0'
+sig_name='ZERO HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS NUM32 NUM33 RTMIN NUM35 NUM36 NUM37 NUM38 NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 NUM45 NUM46 NUM47 NUM48 NUM49 NUM50 NUM51 NUM52 NUM53 NUM54 NUM55 NUM56 NUM57 NUM58 NUM59 NUM60 NUM61 NUM62 RTMAX IOT CLD POLL UNUSED '
+sig_name_init='"ZERO", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "SYS", "NUM32", "NUM33", "RTMIN", "NUM35", "NUM36", "NUM37", "NUM38", "NUM39", "NUM40", "NUM41", "NUM42", "NUM43", "NUM44", "NUM45", "NUM46", "NUM47", "NUM48", "NUM49", "NUM50", "NUM51", "NUM52", "NUM53", "NUM54", "NUM55", "NUM56", "NUM57", "NUM58", "NUM59", "NUM60", "NUM61", "NUM62", "RTMAX", "IOT", "CLD", "POLL", "UNUSED", 0'
 sig_num='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 6 17 29 31 '
 sig_num_init='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, 6, 17, 29, 31, 0'
 sig_size='68'
@@ -938,7 +938,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1037,7 +1036,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 PERL_API_SUBVERSION=0
 PERL_PATCHLEVEL=
@@ -1093,8 +1091,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1124,7 +1122,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1135,12 +1133,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index b0eb0fe06b5b93a088f1838bbac2c04c587d8994..a3eddb6f6bf34bf5192858f9bef6e33bae30ead6 100644 (file)
@@ -740,12 +740,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -829,7 +829,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@merope.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -949,7 +949,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1050,8 +1049,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 
 PERL_API_SUBVERSION=0
@@ -1108,8 +1105,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1139,7 +1136,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1150,12 +1147,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
diff --git a/lang/perl/files/config.sh-mips64.in b/lang/perl/files/config.sh-mips64.in
new file mode 100644 (file)
index 0000000..c8095de
--- /dev/null
@@ -0,0 +1,1161 @@
+#!/bin/sh
+#
+# This file was produced by running the Configure script. It holds all the
+# definitions figured out by Configure. Should you modify one of these values,
+# do not forget to propagate your changes by running "Configure -der". You may
+# instead choose to run each of the .SH files by yourself, or "Configure -S".
+#
+
+# Package name      : perl5
+# Source directory  : .
+# Configuration time: Thu Jan 25 03:12:45 MST 2007
+# Configured by     : root
+# Target system     : linux merope 2.4.30 #1 di 23. jan 15:23:42 cet 2007 mips unknown unknown gnulinux 
+
+Author=''
+Date='$Date'
+Header=''
+Id='$Id'
+Locker=''
+Log='$Log'
+Mcc='Mcc'
+RCSfile='$RCSfile'
+Revision='$Revision'
+Source=''
+State=''
+_a='.a'
+_exe=''
+_o='.o'
+afs='false'
+afsroot='/afs'
+alignbytes='8'
+ansi2knr=''
+aphostname='/bin/hostname'
+api_revision='5'
+api_subversion='0'
+
+
+ar='ar'
+archname64=''
+archname='mips64-linux-uclibc'
+archobjs=''
+asctime_r_proto='0'
+awk='awk'
+baserev='5.0'
+bash=''
+bin='/usr/bin'
+binexp='/usr/bin'
+bison='bison'
+byacc='byacc'
+byteorder='87654321'
+c=''
+castflags='0'
+cat='cat'
+cc='%%CC%%'
+cccdlflags='-fPIC'
+ccflags='%%CFLAGS%%'
+ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
+ccname='gcc'
+ccsymbols=''
+ccversion=''
+cf_by='root'
+cf_email='root@merope.dev.null'
+cf_time='Thu Jan 25 03:12:45 MST 2007'
+chgrp=''
+chmod='chmod'
+chown=''
+clocktype='clock_t'
+comm='comm'
+compress=''
+contains='grep'
+cp='cp'
+cpio=''
+cpp='cpp'
+cpp_stuff='42'
+cppccsymbols=''
+cppflags='%%CFLAGS%%'
+cpplast='-'
+cppminus='-'
+cpprun='%%CPP%%'
+cppstdin='%%CPP%%'
+cppsymbols=''
+crypt_r_proto='0'
+cryptlib=''
+csh='csh'
+ctermid_r_proto='0'
+ctime_r_proto='0'
+d_Gconvert='sprintf((b),"%.*g",(n),(x))'
+d_PRIEUldbl='define'
+d_PRIFUldbl='define'
+d_PRIGUldbl='define'
+d_PRIXU64='define'
+d_PRId64='define'
+d_PRIeldbl='define'
+d_PRIfldbl='define'
+d_PRIgldbl='define'
+d_PRIi64='define'
+d_PRIo64='define'
+d_PRIu64='define'
+d_PRIx64='define'
+d_SCNfldbl='define'
+d__fwalk='undef'
+d_access='define'
+d_accessx='undef'
+d_aintl='undef'
+d_alarm='define'
+d_archlib='undef'
+d_asctime_r='undef'
+d_atolf='undef'
+d_atoll='define'
+d_attribute_format='define'
+d_attribute_malloc='define'
+d_attribute_nonnull='define'
+d_attribute_noreturn='define'
+d_attribute_pure='define'
+d_attribute_unused='define'
+d_attribute_warn_unused_result='define'
+d_bcmp='define'
+d_bcopy='define'
+d_bsd='undef'
+d_bsdgetpgrp='undef'
+d_bsdsetpgrp='undef'
+d_builtin_choose_expr='define'
+d_builtin_expect='undef'
+d_bzero='define'
+d_c99_variadic_macros='define'
+d_casti32='define'
+d_castneg='define'
+d_charvspr='undef'
+d_chown='define'
+d_chroot='define'
+d_chsize='undef'
+d_class='undef'
+d_clearenv='define'
+d_closedir='define'
+d_cmsghdr_s='define'
+d_const='define'
+d_copysignl='undef'
+d_cplusplus='undef'
+d_crypt='define'
+d_crypt_r='undef'
+d_csh='undef'
+d_ctermid='define'
+d_ctermid_r='undef'
+d_ctime_r='undef'
+d_cuserid='define'
+d_dbl_dig='define'
+d_dbminitproto='undef'
+d_difftime='define'
+d_dir_dd_fd='undef'
+d_dirfd='define'
+d_dirnamlen='undef'
+d_dlerror='define'
+d_dlopen='define'
+d_dlsymun='undef'
+d_dosuid='undef'
+d_drand48_r='undef'
+d_drand48proto='define'
+d_dup2='define'
+d_eaccess='undef'
+d_endgrent='define'
+d_endgrent_r='undef'
+d_endhent='define'
+d_endhostent_r='undef'
+d_endnent='define'
+d_endnetent_r='undef'
+d_endpent='define'
+d_endprotoent_r='undef'
+d_endpwent='define'
+d_endpwent_r='undef'
+d_endsent='define'
+d_endservent_r='undef'
+d_eofnblk='define'
+d_eunice='undef'
+d_faststdio='undef'
+d_fchdir='define'
+d_fchmod='define'
+d_fchown='define'
+d_fcntl='define'
+d_fcntl_can_lock='define'
+d_fd_macros='define'
+d_fd_set='define'
+d_fds_bits='undef'
+d_fgetpos='define'
+d_finite='define'
+d_finitel='undef'
+d_flexfnam='define'
+d_flock='define'
+d_flockproto='define'
+d_fork='define'
+d_fp_class='undef'
+d_fpathconf='define'
+d_fpclass='undef'
+d_fpclassify='undef'
+d_fpclassl='undef'
+d_fpos64_t='undef'
+d_frexpl='undef'
+d_fs_data_s='undef'
+d_fseeko='define'
+d_fsetpos='define'
+d_fstatfs='define'
+d_fstatvfs='define'
+d_fsync='define'
+d_ftello='define'
+d_ftime='undef'
+d_futimes='undef'
+d_getcwd='define'
+d_getespwnam='undef'
+d_getfsstat='undef'
+d_getgrent='define'
+d_getgrent_r='undef'
+d_getgrgid_r='undef'
+d_getgrnam_r='undef'
+d_getgrps='define'
+d_gethbyaddr='define'
+d_gethbyname='define'
+d_gethent='define'
+d_gethname='define'
+d_gethostbyaddr_r='undef'
+d_gethostbyname_r='undef'
+d_gethostent_r='undef'
+d_gethostprotos='define'
+d_getitimer='define'
+d_getlogin='define'
+d_getlogin_r='undef'
+d_getmnt='undef'
+d_getmntent='define'
+d_getnbyaddr='define'
+d_getnbyname='define'
+d_getnent='define'
+d_getnetbyaddr_r='undef'
+d_getnetbyname_r='undef'
+d_getnetent_r='undef'
+d_getnetprotos='define'
+d_getpagsz='define'
+d_getpbyname='define'
+d_getpbynumber='define'
+d_getpent='define'
+d_getpgid='define'
+d_getpgrp2='undef'
+d_getpgrp='define'
+d_getppid='define'
+d_getprior='define'
+d_getprotobyname_r='undef'
+d_getprotobynumber_r='undef'
+d_getprotoent_r='undef'
+d_getprotoprotos='define'
+d_getprpwnam='undef'
+d_getpwent='define'
+d_getpwent_r='undef'
+d_getpwnam_r='undef'
+d_getpwuid_r='undef'
+d_getsbyname='define'
+d_getsbyport='define'
+d_getsent='define'
+d_getservbyname_r='undef'
+d_getservbyport_r='undef'
+d_getservent_r='undef'
+d_getservprotos='define'
+d_getspnam='define'
+d_getspnam_r='undef'
+d_gettimeod='define'
+d_gmtime_r='undef'
+d_gnulibc='undef'
+d_grpasswd='define'
+d_hasmntopt='define'
+d_htonl='define'
+d_ilogbl='undef'
+d_inc_version_list='undef'
+d_index='undef'
+d_inetaton='define'
+d_int64_t='define'
+d_isascii='define'
+d_isfinite='undef'
+d_isinf='define'
+d_isnan='define'
+d_isnanl='undef'
+d_killpg='define'
+d_lchown='define'
+d_ldbl_dig='define'
+d_libm_lib_version='define'
+d_link='define'
+d_localtime_r='undef'
+d_localtime_r_needs_tzset='undef'
+d_locconv='define'
+d_lockf='define'
+d_longdbl='define'
+d_longlong='define'
+d_lseekproto='define'
+d_lstat='define'
+d_madvise='define'
+d_malloc_good_size='undef'
+d_malloc_size='undef'
+d_mblen='define'
+d_mbstowcs='define'
+d_mbtowc='define'
+d_memchr='define'
+d_memcmp='define'
+d_memcpy='define'
+d_memmove='define'
+d_memset='define'
+d_mkdir='define'
+d_mkdtemp='define'
+d_mkfifo='define'
+d_mkstemp='define'
+d_mkstemps='undef'
+d_mktime='define'
+d_mmap='define'
+d_modfl='undef'
+d_modfl_pow32_bug='undef'
+d_modflproto='undef'
+d_mprotect='define'
+d_msg='define'
+d_msg_ctrunc='define'
+d_msg_dontroute='define'
+d_msg_oob='define'
+d_msg_peek='define'
+d_msg_proxy='define'
+d_msgctl='define'
+d_msgget='define'
+d_msghdr_s='define'
+d_msgrcv='define'
+d_msgsnd='define'
+d_msync='define'
+d_munmap='define'
+d_mymalloc='undef'
+d_nice='define'
+d_nl_langinfo='define'
+d_nv_preserves_uv='undef'
+d_nv_zero_is_allbits_zero='define'
+d_off64_t='undef'
+d_old_pthread_create_joinable='undef'
+d_oldpthreads='undef'
+d_oldsock='undef'
+d_open3='define'
+d_pathconf='define'
+d_pause='define'
+d_perl_otherlibdirs='undef'
+d_phostname='undef'
+d_pipe='define'
+d_poll='define'
+d_portable='define'
+d_printf_format_null='undef'
+d_procselfexe='define'
+d_pseudofork='undef'
+d_pthread_atfork='undef'
+d_pthread_attr_setscope='define'
+d_pthread_yield='undef'
+d_pwage='undef'
+d_pwchange='undef'
+d_pwclass='undef'
+d_pwcomment='undef'
+d_pwexpire='undef'
+d_pwgecos='define'
+d_pwpasswd='define'
+d_pwquota='undef'
+d_qgcvt='undef'
+d_quad='define'
+d_random_r='undef'
+d_readdir64_r='undef'
+d_readdir='define'
+d_readdir_r='undef'
+d_readlink='define'
+d_readv='define'
+d_recvmsg='define'
+d_rename='define'
+d_rewinddir='define'
+d_rmdir='define'
+d_safebcpy='undef'
+d_safemcpy='undef'
+d_sanemcmp='define'
+d_sbrkproto='define'
+d_scalbnl='undef'
+d_sched_yield='define'
+d_scm_rights='define'
+d_seekdir='define'
+d_select='define'
+d_sem='define'
+d_semctl='define'
+d_semctl_semid_ds='define'
+d_semctl_semun='define'
+d_semget='define'
+d_semop='define'
+d_sendmsg='define'
+d_setegid='define'
+d_seteuid='define'
+d_setgrent='define'
+d_setgrent_r='undef'
+d_setgrps='define'
+d_sethent='define'
+d_sethostent_r='undef'
+d_setitimer='define'
+d_setlinebuf='define'
+d_setlocale='define'
+d_setlocale_r='undef'
+d_setnent='define'
+d_setnetent_r='undef'
+d_setpent='define'
+d_setpgid='define'
+d_setpgrp2='undef'
+d_setpgrp='define'
+d_setprior='define'
+d_setproctitle='undef'
+d_setprotoent_r='undef'
+d_setpwent='define'
+d_setpwent_r='undef'
+d_setregid='define'
+d_setresgid='define'
+d_setresuid='define'
+d_setreuid='define'
+d_setrgid='undef'
+d_setruid='undef'
+d_setsent='define'
+d_setservent_r='undef'
+d_setsid='define'
+d_setvbuf='define'
+d_sfio='undef'
+d_shm='define'
+d_shmat='define'
+d_shmatprototype='define'
+d_shmctl='define'
+d_shmdt='define'
+d_shmget='define'
+d_sigaction='define'
+d_signbit='undef'
+d_sigprocmask='define'
+d_sigsetjmp='define'
+d_sitearch='define'
+d_snprintf='define'
+d_sockatmark='undef'
+d_sockatmarkproto='undef'
+d_socket='define'
+d_socklen_t='define'
+d_sockpair='define'
+d_socks5_init='undef'
+d_sprintf_returns_strlen='define'
+d_sqrtl='undef'
+d_srand48_r='undef'
+d_srandom_r='undef'
+d_sresgproto='undef'
+d_sresuproto='undef'
+d_statblks='define'
+d_statfs_f_flags='undef'
+d_statfs_s='define'
+d_statvfs='define'
+d_stdio_cnt_lval='undef'
+d_stdio_ptr_lval='undef'
+d_stdio_ptr_lval_nochange_cnt='undef'
+d_stdio_ptr_lval_sets_cnt='undef'
+d_stdio_stream_array='undef'
+d_stdiobase='undef'
+d_stdstdio='undef'
+d_strchr='define'
+d_strcoll='define'
+d_strctcpy='define'
+d_strerrm='strerror(e)'
+d_strerror='define'
+d_strerror_r='undef'
+d_strftime='define'
+d_strlcat='define'
+d_strlcpy='define'
+d_strtod='define'
+d_strtol='define'
+d_strtold='define'
+d_strtoll='define'
+d_strtoq='define'
+d_strtoul='define'
+d_strtoull='define'
+d_strtouq='define'
+d_strxfrm='define'
+d_suidsafe='undef'
+d_symlink='define'
+d_syscall='define'
+d_syscallproto='define'
+d_sysconf='define'
+d_sysernlst=''
+d_syserrlst='undef'
+d_system='define'
+d_tcgetpgrp='define'
+d_tcsetpgrp='define'
+d_telldir='define'
+d_telldirproto='define'
+d_time='define'
+d_times='define'
+d_tm_tm_gmtoff='define'
+d_tm_tm_zone='define'
+d_tmpnam_r='undef'
+d_truncate='define'
+d_ttyname_r='undef'
+d_tzname='define'
+d_u32align='define'
+d_ualarm='define'
+d_umask='define'
+d_uname='define'
+d_union_semun='undef'
+d_unordered='undef'
+d_unsetenv='define'
+d_usleep='define'
+d_usleepproto='define'
+d_ustat='define'
+d_vendorarch='undef'
+d_vendorbin='undef'
+d_vendorlib='undef'
+d_vendorscript='undef'
+d_vfork='undef'
+d_void_closedir='undef'
+d_voidsig='define'
+d_voidtty=''
+d_volatile='define'
+d_vprintf='define'
+d_vsnprintf='define'
+d_wait4='define'
+d_waitpid='define'
+d_wcstombs='define'
+d_wctomb='define'
+d_writev='define'
+d_xenix='undef'
+date='date'
+db_hashtype='u_int32_t'
+db_prefixtype='size_t'
+db_version_major=''
+db_version_minor=''
+db_version_patch=''
+defvoidused='15'
+direntrytype='struct dirent'
+dlext='so'
+dlsrc='dl_dlopen.xs'
+doublesize='8'
+drand01='drand48()'
+drand48_r_proto='0'
+
+eagain='EAGAIN'
+ebcdic='undef'
+echo='echo'
+egrep='egrep'
+emacs=''
+endgrent_r_proto='0'
+endhostent_r_proto='0'
+endnetent_r_proto='0'
+endprotoent_r_proto='0'
+endpwent_r_proto='0'
+endservent_r_proto='0'
+eunicefix=':'
+exe_ext=''
+expr='expr'
+extensions='B Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/DProf Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/Glob Filter/Util/Call GDBM_File Hash/Util I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Text/Soundex Time/HiRes Time/Piece Unicode/Normalize XS/APItest XS/Typemap attrs re threads threads/shared Hash/Util/FieldHash Compress/Zlib Errno IO_Compress_Base IO_Compress_Zlib'
+extras=''
+fflushNULL='define'
+fflushall='undef'
+find=''
+firstmakefile='makefile'
+flex=''
+fpossize='24'
+fpostype='fpos_t'
+freetype='void'
+from=':'
+full_ar='%%AR%%'
+full_csh='csh'
+full_sed='sed'
+gccansipedantic=''
+gccosandvers=''
+gccversion='3.4.3'
+getgrent_r_proto='0'
+getgrgid_r_proto='0'
+getgrnam_r_proto='0'
+gethostbyaddr_r_proto='0'
+gethostbyname_r_proto='0'
+gethostent_r_proto='0'
+getlogin_r_proto='0'
+getnetbyaddr_r_proto='0'
+getnetbyname_r_proto='0'
+getnetent_r_proto='0'
+getprotobyname_r_proto='0'
+getprotobynumber_r_proto='0'
+getprotoent_r_proto='0'
+getpwent_r_proto='0'
+getpwnam_r_proto='0'
+getpwuid_r_proto='0'
+getservbyname_r_proto='0'
+getservbyport_r_proto='0'
+getservent_r_proto='0'
+getspnam_r_proto='0'
+gidformat='"u"'
+gidsign='1'
+gidsize='4'
+gidtype='gid_t'
+glibpth='/usr/shlib  /lib /usr/lib /usr/lib/386 /lib/386 /usr/ccs/lib /usr/ucblib /usr/local/lib '
+gmake='gmake'
+gmtime_r_proto='0'
+gnulibc_version=''
+grep='grep'
+groupcat='cat /etc/group'
+groupstype='gid_t'
+gzip='gzip'
+h_fcntl='false'
+h_sysfile='true'
+hint='recommended'
+hostcat='cat /etc/hosts'
+html1dir=' '
+html1direxp=''
+html3dir=' '
+html3direxp=''
+i16size='2'
+i16type='short'
+i32size='4'
+i32type='int'
+i64size='8'
+i64type='long'
+i8size='1'
+i8type='signed char'
+i_arpainet='define'
+i_bsdioctl=''
+i_crypt='define'
+i_db='define'
+i_dbm='undef'
+i_dirent='define'
+i_dld='undef'
+i_dlfcn='define'
+i_fcntl='undef'
+i_float='define'
+i_fp='undef'
+i_fp_class='undef'
+i_gdbm='define'
+i_grp='define'
+i_ieeefp='undef'
+i_inttypes='define'
+i_langinfo='define'
+i_libutil='undef'
+i_limits='define'
+i_locale='define'
+i_machcthr='undef'
+i_malloc='define'
+i_math='define'
+i_memory='undef'
+i_mntent='define'
+i_ndbm='undef'
+i_netdb='define'
+i_neterrno='undef'
+i_netinettcp='define'
+i_niin='define'
+i_poll='define'
+i_prot='undef'
+i_pthread='define'
+i_pwd='define'
+i_rpcsvcdbm='undef'
+i_sfio='undef'
+i_sgtty='undef'
+i_shadow='define'
+i_socks='undef'
+i_stdarg='define'
+i_stddef='define'
+i_stdlib='define'
+i_string='define'
+i_sunmath='undef'
+i_sysaccess='undef'
+i_sysdir='define'
+i_sysfile='define'
+i_sysfilio='undef'
+i_sysin='undef'
+i_sysioctl='define'
+i_syslog='define'
+i_sysmman='define'
+i_sysmode='undef'
+i_sysmount='define'
+i_sysndir='undef'
+i_sysparam='define'
+i_sysresrc='define'
+i_syssecrt='undef'
+i_sysselct='define'
+i_syssockio='undef'
+i_sysstat='define'
+i_sysstatfs='define'
+i_sysstatvfs='define'
+i_systime='define'
+i_systimek='undef'
+i_systimes='define'
+i_systypes='define'
+i_sysuio='define'
+i_sysun='define'
+i_sysutsname='define'
+i_sysvfs='define'
+i_syswait='define'
+i_termio='undef'
+i_termios='define'
+i_time='define'
+i_unistd='define'
+i_ustat='define'
+i_utime='define'
+i_values='define'
+i_varargs='undef'
+i_varhdr='stdarg.h'
+i_vfork='undef'
+ignore_versioned_solibs='y'
+inc_version_list=' '
+inc_version_list_init='0'
+incpath=''
+inews=''
+
+installbin='/usr/bin'
+initialinstalllocation='/usr/bin'
+installhtml1dir=''
+installhtml3dir=''
+installman1dir=''
+installman3dir=''
+installprefix='/usr'
+installprefixexp='/usr'
+
+installscript='/usr/bin'
+
+installsitebin='/usr/bin'
+installsitehtml1dir=''
+installsitehtml3dir=''
+
+installsiteman1dir=''
+installsiteman3dir=''
+installsitescript='/usr/bin'
+installstyle='lib/perl5'
+installusrbinperl='define'
+installvendorarch=''
+installvendorbin=''
+installvendorhtml1dir=''
+installvendorhtml3dir=''
+installvendorlib=''
+installvendorman1dir=''
+installvendorman3dir=''
+installvendorscript=''
+intsize='4'
+issymlink='test -h'
+ivdformat='"ld"'
+ivsize='8'
+ivtype='long'
+known_extensions='B Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/DProf Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/Glob Filter/Util/Call GDBM_File Hash/Util I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc NDBM_File ODBM_File Opcode POSIX PerlIO/encoding PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Text/Soundex Time/HiRes Time/Piece Unicode/Normalize Win32 Win32API/File Win32CORE XS/APItest XS/Typemap attrs re threads threads/shared Hash/Util/FieldHash'
+ksh=''
+ld='%%LD%%'
+lddlflags='-shared %%LDFLAGS%%'
+ldflags='%%EXTRA_PERLLIBDIRS%%'
+ldflags_uselargefiles=''
+ldlibpthname='LD_LIBRARY_PATH'
+less='less'
+lib_ext='.a'
+libc=''
+libperl='libperl.so'
+libpth='%%LIBDIRS%%'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
+libsdirs='%%LIBDIRS%%'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libspath='%%LIBDIRS%%'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted_uselargefiles=''
+line=''
+lint=''
+lkflags=''
+ln='ln'
+lns='/bin/ln -s'
+localtime_r_proto='0'
+locincpth=' '
+loclibpth=' '
+longdblsize='16'
+longlongsize='8'
+longsize='8'
+lp=''
+lpr=''
+ls='ls'
+lseeksize='8'
+lseektype='off_t'
+mad='undef'
+madlyh=''
+madlyobj=''
+madlysrc=''
+mail=''
+mailx=''
+make='make'
+make_set_make='#'
+mallocobj=''
+mallocsrc=''
+malloctype='void *'
+man1dir=' '
+man1direxp=''
+man1ext='0'
+man3dir=' '
+man3direxp=''
+man3ext='0'
+mips_type=''
+mistrustnm=''
+mkdir='mkdir'
+mmaptype='void *'
+modetype='mode_t'
+more='more'
+multiarch='undef'
+mv=''
+myarchname='mips64-linux-uclibc'
+mydomain='.dev.null'
+myhostname='merope'
+myuname='linux merope 2.4.30 #1 di 23. jan 15:23:42 cet 2007 mips64 unknown unknown gnulinux '
+n='-n'
+need_va_copy='define'
+netdb_hlen_type='size_t'
+netdb_host_type='char *'
+netdb_name_type='const char *'
+netdb_net_type='in_addr_t'
+nm='nm'
+nm_opt=''
+nm_so_opt='--dynamic'
+
+nroff='nroff'
+nvEUformat='"E"'
+nvFUformat='"F"'
+nvGUformat='"G"'
+nv_preserves_uv_bits='53'
+nveformat='"e"'
+nvfformat='"f"'
+nvgformat='"g"'
+nvsize='8'
+nvtype='double'
+o_nonblock='O_NONBLOCK'
+obj_ext='.o'
+old_pthread_create_joinable=''
+optimize='-O2'
+orderlib='false'
+osname='linux'
+osvers='2.4.30'
+otherlibdirs=' '
+package='perl5'
+pager='/usr/bin/less'
+passcat='cat /etc/passwd'
+
+path_sep=':'
+perl5=''
+perl=''
+perl_patchlevel=''
+perladmin='root@merope.dev.null'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perlpath='/usr/bin/perl'
+pg='pg'
+phostname='hostname'
+pidtype='pid_t'
+plibpth=''
+pmake=''
+pr=''
+prefix='/usr'
+prefixexp='/usr'
+
+
+procselfexe='"/proc/self/exe"'
+prototype='define'
+ptrsize='8'
+quadkind='2'
+quadtype='long'
+randbits='48'
+randfunc='drand48'
+random_r_proto='0'
+randseedtype='long'
+ranlib=':'
+rd_nodata='-1'
+readdir64_r_proto='0'
+readdir_r_proto='0'
+revision='5'
+rm='rm'
+rm_try='/bin/rm -f try try a.out .out try.[cho] try..o core core.try* try.core*'
+rmail=''
+run=''
+runnm='false'
+sPRIEUldbl='"E"'
+sPRIFUldbl='"F"'
+sPRIGUldbl='"G"'
+sPRIXU64='"lX"'
+sPRId64='"ld"'
+sPRIeldbl='"e"'
+sPRIfldbl='"f"'
+sPRIgldbl='"g"'
+sPRIi64='"li"'
+sPRIo64='"lo"'
+sPRIu64='"lu"'
+sPRIx64='"lx"'
+sSCNfldbl='"f"'
+sched_yield='sched_yield()'
+scriptdir='/usr/bin'
+scriptdirexp='/usr/bin'
+sed='sed'
+seedfunc='srand48'
+selectminbits='64'
+selecttype='fd_set *'
+sendmail=''
+setgrent_r_proto='0'
+sethostent_r_proto='0'
+setlocale_r_proto='0'
+setnetent_r_proto='0'
+setprotoent_r_proto='0'
+setpwent_r_proto='0'
+setservent_r_proto='0'
+sh='/bin/sh'
+shar=''
+sharpbang='#!'
+shmattype='void *'
+shortsize='2'
+shrpenv=''
+shsharp='true'
+sig_count='128'
+sig_name='ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1 USR2 CHLD PWR WINCH URG IO STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU XFSZ RTMIN NUM33 NUM34 NUM35 NUM36 NUM37 NUM38 NUM39 NUM40 NUM41 NUM42 NUM43 NUM44 NUM45 NUM46 NUM47 NUM48 NUM49 NUM50 NUM51 NUM52 NUM53 NUM54 NUM55 NUM56 NUM57 NUM58 NUM59 NUM60 NUM61 NUM62 NUM63 NUM64 NUM65 NUM66 NUM67 NUM68 NUM69 NUM70 NUM71 NUM72 NUM73 NUM74 NUM75 NUM76 NUM77 NUM78 NUM79 NUM80 NUM81 NUM82 NUM83 NUM84 NUM85 NUM86 NUM87 NUM88 NUM89 NUM90 NUM91 NUM92 NUM93 NUM94 NUM95 NUM96 NUM97 NUM98 NUM99 NUM100 NUM101 NUM102 NUM103 NUM104 NUM105 NUM106 NUM107 NUM108 NUM109 NUM110 NUM111 NUM112 NUM113 NUM114 NUM115 NUM116 NUM117 NUM118 NUM119 NUM120 NUM121 NUM122 NUM123 NUM124 NUM125 NUM126 RTMAX IOT CLD POLL '
+sig_name_init='"ZERO", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", "USR1", "USR2", "CHLD", "PWR", "WINCH", "URG", "IO", "STOP", "TSTP", "CONT", "TTIN", "TTOU", "VTALRM", "PROF", "XCPU", "XFSZ", "RTMIN", "NUM33", "NUM34", "NUM35", "NUM36", "NUM37", "NUM38", "NUM39", "NUM40", "NUM41", "NUM42", "NUM43", "NUM44", "NUM45", "NUM46", "NUM47", "NUM48", "NUM49", "NUM50", "NUM51", "NUM52", "NUM53", "NUM54", "NUM55", "NUM56", "NUM57", "NUM58", "NUM59", "NUM60", "NUM61", "NUM62", "NUM63", "NUM64", "NUM65", "NUM66", "NUM67", "NUM68", "NUM69", "NUM70", "NUM71", "NUM72", "NUM73", "NUM74", "NUM75", "NUM76", "NUM77", "NUM78", "NUM79", "NUM80", "NUM81", "NUM82", "NUM83", "NUM84", "NUM85", "NUM86", "NUM87", "NUM88", "NUM89", "NUM90", "NUM91", "NUM92", "NUM93", "NUM94", "NUM95", "NUM96", "NUM97", "NUM98", "NUM99", "NUM100", "NUM101", "NUM102", "NUM103", "NUM104", "NUM105", "NUM106", "NUM107", "NUM108", "NUM109", "NUM110", "NUM 111", "NUM112", "NUM113", "NUM114", "NUM115", "NUM116", "NUM117", "NUM118", "NUM119", "NUM120", "NUM121", "NUM122", "NUM123", "NUM124", "NUM125", "NUM126", "RTMAX", "IOT", "CLD", "POLL", 0'
+sig_num='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 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 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 6 18 22 '
+sig_num_init='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, 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, 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, 6, 18, 22, 0'
+sig_size='131'
+signal_t='void'
+sitearch=''
+sitearchexp=''
+sitebin='/usr/bin'
+sitebinexp='/usr/bin'
+sitehtml1dir=''
+sitehtml1direxp=''
+sitehtml3dir=''
+sitehtml3direxp=''
+sitelib=''
+#sitelib_stem='/usr/lib/perl5/site_perl'
+sitelibexp=''
+siteman1dir=''
+siteman1direxp=''
+siteman3dir=''
+siteman3direxp=''
+siteprefix='/usr'
+siteprefixexp='/usr'
+sitescript='/usr/bin'
+sitescriptexp='/usr/bin'
+sizesize='8'
+sizetype='size_t'
+sleep=''
+smail=''
+so='so'
+sockethdr=''
+socketlib=''
+socksizetype='socklen_t'
+sort='sort'
+spackage='Perl5'
+spitshell='cat'
+srand48_r_proto='0'
+srandom_r_proto='0'
+src='.'
+ssizetype='ssize_t'
+startperl='#!/usr/bin/perl'
+startsh='#!/bin/sh'
+static_ext=' '
+stdchar='char'
+stdio_base='((fp)->_base)'
+stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)'
+stdio_cnt='((fp)->_cnt)'
+stdio_filbuf=''
+stdio_ptr='((fp)->_ptr)'
+stdio_stream_array=''
+strerror_r_proto='0'
+#strings='/usr/include/string.h'
+submit=''
+sysman='/usr/share/man/man1'
+tail=''
+tar=''
+targetarch='mips64-linux-uclibc'
+tbl=''
+tee=''
+test='test'
+#timeincl='/usr/include/sys/time.h /usr/include/time.h '
+timetype='time_t'
+tmpnam_r_proto='0'
+to=':'
+touch='touch'
+tr='tr'
+trnl='\n'
+troff=''
+ttyname_r_proto='0'
+u16size='2'
+u16type='unsigned short'
+u32size='4'
+u32type='unsigned int'
+u64size='8'
+u64type='unsigned long'
+u8size='1'
+u8type='unsigned char'
+uidformat='"u"'
+uidsign='1'
+uidsize='4'
+uidtype='uid_t'
+uname='uname'
+uniq='uniq'
+uquadtype='unsigned long'
+use5005threads='undef'
+use64bitall='define'
+use64bitint='undef'
+usecrosscompile='define'
+usedl='define'
+usefaststdio='undef'
+useithreads='undef'
+uselargefiles='define'
+uselongdouble='undef'
+usemallocwrap='define'
+usemorebits='undef'
+usemultiplicity='undef'
+usemymalloc='n'
+usenm='true'
+useopcode='true'
+useperlio='define'
+useposix='true'
+usereentrant='undef'
+userelocatableinc='undef'
+usesfio='false'
+useshrplib='true'
+usesitecustomize='undef'
+usesocks='undef'
+usethreads='undef'
+usevendorprefix='undef'
+usevfork='false'
+usrinc='%%INCDIRS%%'
+uuname=''
+uvXUformat='"lX"'
+uvoformat='"lo"'
+uvsize='8'
+uvtype='unsigned long'
+uvuformat='"lu"'
+uvxformat='"lx"'
+vendorarch=''
+vendorarchexp=''
+vendorbin=''
+vendorbinexp=''
+vendorhtml1dir=' '
+vendorhtml1direxp=''
+vendorhtml3dir=' '
+vendorhtml3direxp=''
+vendorlib=''
+vendorlib_stem=''
+vendorlibexp=''
+vendorman1dir=' '
+vendorman1direxp=''
+vendorman3dir=' '
+vendorman3direxp=''
+vendorprefix=''
+vendorprefixexp=''
+vendorscript=''
+vendorscriptexp=''
+
+
+versiononly='undef'
+vi=''
+voidflags='15'
+xlibpth='/usr/lib/386 /lib/386'
+yacc='yacc'
+yaccflags=''
+zcat=''
+zip='zip'
+# Configure command line arguments.
+config_arg0='./Configure'
+config_args='-der'
+config_argc=1
+config_arg1='-der'
+PERL_REVISION=5
+PERL_API_REVISION=5
+
+PERL_API_SUBVERSION=0
+PERL_PATCHLEVEL=
+PERL_CONFIG_SH=true
+# Fix problem with HiRes timer.
+d_nanosleep='define'
+d_clock_gettime='define'
+d_clock_getres='define'
+d_clock_nanosleep='define'
+d_clock='define'
+
+# New symbols for perl 5.20.0
+bin_ELF='define'
+bootstrap_charset='undef'
+charbits='8'
+charsize='1'
+d_asctime64='undef'
+d_attribute_deprecated='define'
+d_ctime64='undef'
+d_difftime64='undef'
+d_gdbm_ndbm_h_uses_prototypes='undef'
+d_gdbmndbm_h_uses_prototypes='undef'
+d_getaddrinfo='define'
+d_getnameinfo='define'
+d_gmtime64='undef'
+d_inetntop='define'
+d_inetpton='define'
+d_ip_mreq='define'
+d_ip_mreq_source='define'
+d_ipv6_mreq='%%IPV6%%'
+d_ipv6_mreq_source='undef'
+d_isblank='define'
+d_libname_unique='undef'
+d_localtime64='undef'
+d_mktime64='undef'
+d_ndbm='undef'
+d_ndbm_h_uses_prototypes='undef'
+d_prctl='define'
+d_prctl_set_name='define'
+d_sin6_scope_id='%%IPV6%%'
+d_sockaddr_in6='%%IPV6%%'
+d_sockaddr_sa_len='undef'
+d_static_inline='define'
+d_timegm='define'
+dtrace=''
+extern_C='extern'
+hostosname=''
+i_assert='define'
+i_gdbm_ndbm='undef'
+i_gdbmndbm='undef'
+i_mallocmalloc='undef'
+i_stdbool='define'
+i_syspoll='define'
+#incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
+ld_can_script='define'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
+perl_static_inline='static __inline__'
+sGMTIME_max='67768036191676799'
+sGMTIME_min='-62167219200'
+sLOCALTIME_max='67768036191673199'
+sLOCALTIME_min='-62167222408'
+#sitelib_stem='/usr/local/lib/perl5/site_perl'
+st_ino_sign='1'
+st_ino_size='8'
+#strings='/usr/include/string.h'
+sysroot=''
+targetdir=''
+targetenv=''
+targethost=''
+targetmkdir=''
+targetport=''
+targetsh='/bin/sh'
+#timeincl='/usr/include/sys/time.h /usr/include/time.h '
+usedevel='undef'
+usedtrace='undef'
+usekernprocpathname='undef'
+usensgetexecutablepath='undef'
+useversionedarchname='undef'
+vaproto='define'
+libdb_needs_pthread='N'
+
+# These symbols changed from perl 5.10.0 to 5.20.0 and probably will
+# change again for new versions, so they're included here for
+# future reference
+api_version='20'
+api_versionstring='5.20.0'
+dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
+installarchlib='/usr/lib/perl5/5.20'
+installprivlib='/usr/lib/perl5/5.20'
+installsitearch='/usr/lib/perl5/5.20'
+installsitelib='/usr/lib/perl5/5.20'
+nonxs_ext='Archive/Tar Attribute/Handlers AutoLoader B/Debug CGI CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Carp Config/Perl/V Devel/SelfStubber Digest Dumpvalue Env Errno Exporter ExtUtils/CBuilder ExtUtils/Command ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS File/Fetch File/Find File/Path File/Temp FileCache Filter/Simple Getopt/Long HTTP/Tiny I18N/Collate I18N/LangTags IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 JSON/PP Locale/Codes Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigRat Math/Complex Memoize Module/Build Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata NEXT Net/Ping Package/Constants Params/Check Parse/CPAN/Meta Perl/OSType PerlIO/via/QuotedPrint Pod/Checker Pod/Escapes Pod/Functions Pod/Html Pod/Parser Pod/Perldoc Pod/Simple Pod/Usage Safe Search/Dict SelfLoader Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue Thread/Semaphore Tie/File Tie/Memoize Tie/RefHash Time/Local XSLoader autodie autouse base bignum constant encoding/warnings experimental if lib libnet parent perlfaq podlators version'
+privlib='/usr/lib/perl5/5.20'
+privlibexp='/usr/lib/perl5/5.20'
+archlib='/usr/lib/perl5/5.20'
+archlibexp='/usr/lib/perl5/5.20'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
+PERL_VERSION=20
+PERL_API_VERSION=20
+PERL_SUBVERSION=1
+patchlevel='20'
+ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
+
+# Make perl use these tools instead of the target binaries during build.
+hostgenerate='%%HOSTGENERATE%%'
+hostperl='%%HOSTMINIPERL%%'
index 557d9a19993464917f09871382472d0e0c42d312..4cda9ee18a59a6e65f996eb043c9cc1ba89de12f 100644 (file)
@@ -733,12 +733,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -820,7 +820,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@merope.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -938,7 +938,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1037,7 +1036,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 PERL_API_SUBVERSION=0
 PERL_PATCHLEVEL=
@@ -1093,8 +1091,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1124,7 +1122,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1135,12 +1133,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index 39b595516a94aa5ff8b18aee33eab5f9f71f2ef1..2214b6f30e3ba71bc4adb5a3a4eb5b4b0722a791 100644 (file)
@@ -600,13 +600,13 @@ html1direxp=''
 html3dir=' '
 html3direxp=''
 i16size='2'
-i16type='short'
+i16type='signed short'
 i32size='4'
-i32type='long'
+i32type='signed long'
 i64size='8'
-i64type='long long'
+i64type='signed long long'
 i8size='1'
-i8type='char'
+i8type='signed char'
 i_arpainet='define'
 i_bsdioctl=''
 i_crypt='define'
@@ -740,12 +740,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -829,7 +829,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -949,7 +949,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1050,8 +1049,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 
 PERL_API_SUBVERSION=0
@@ -1108,8 +1105,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='2147483647'
 sGMTIME_min='-2147483648'
@@ -1139,7 +1136,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1150,12 +1147,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
index 6ec080f5867076fc4b24a20217bad137b07b520c..423590ed9a328746cd2c0d8a78e7041b34a8798a 100644 (file)
@@ -733,12 +733,12 @@ lib_ext='.a'
 libc=''
 libperl='libperl.so'
 libpth='%%LIBDIRS%%'
-libs='-lgdbm -ldb -lnsl -ldl -lm -lcrypt -lutil -lc'
+libs='-lgdbm -ldb -ldl -lm -lcrypt -lutil -lc'
 libsdirs='%%LIBDIRS%%'
-libsfiles=' libnsl.so libdl.so libm.so libcrypt.so libutil.so libc.so'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+libsfiles=' libdl.so libm.so libcrypt.so libutil.so libc.so'
+#libsfound=' /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
 libspath='%%LIBDIRS%%'
-libswanted='sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
+libswanted='sfio socket inet nm ndbm gdbm dbm db malloc dl dld ld sun m crypt sec util c cposix posix ucb BSD'
 libswanted_uselargefiles=''
 line=''
 lint=''
@@ -820,7 +820,7 @@ perl5=''
 perl=''
 perl_patchlevel=''
 perladmin='root@maia.dev.null'
-perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
+perllibs='-ldl -lm -lcrypt -lutil -lc %%EXTRA_PERLLIBS%%'
 perlpath='/usr/bin/perl'
 pg='pg'
 phostname='hostname'
@@ -938,7 +938,6 @@ stdio_stream_array=''
 strerror_r_proto='0'
 #strings='/usr/include/string.h'
 submit=''
-subversion='0'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1037,7 +1036,6 @@ config_args='-der'
 config_argc=1
 config_arg1='-der'
 PERL_REVISION=5
-PERL_SUBVERSION=0
 PERL_API_REVISION=5
 PERL_API_SUBVERSION=0
 PERL_PATCHLEVEL=
@@ -1093,8 +1091,8 @@ i_stdbool='define'
 i_syspoll='define'
 #incpth='/usr/lib/gcc/i486-slackware-linux/4.8.2/include /usr/local/include /usr/lib/gcc/i486-slackware-linux/4.8.2/include-fixed /usr/include'
 ld_can_script='define'
-#libsfound=' /usr/lib/libnsl.so /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
-nv_overflows_integers_at='0'
+#libsfound=' /usr/lib/libgdbm.so /usr/lib/libdb.so /usr/lib/libdl.so /usr/lib/libm.so /usr/lib/libcrypt.so /usr/lib/libutil.so /usr/lib/libc.so'
+nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 perl_static_inline='static __inline__'
 sGMTIME_max='67768036191676799'
 sGMTIME_min='-62167219200'
@@ -1124,7 +1122,7 @@ libdb_needs_pthread='N'
 # change again for new versions, so they're included here for
 # future reference
 api_version='20'
-api_versionstring='5.20.0'
+api_versionstring='5.20.1'
 dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
 installarchlib='/usr/lib/perl5/5.20'
 installprivlib='/usr/lib/perl5/5.20'
@@ -1135,12 +1133,14 @@ privlib='/usr/lib/perl5/5.20'
 privlibexp='/usr/lib/perl5/5.20'
 archlib='/usr/lib/perl5/5.20'
 archlibexp='/usr/lib/perl5/5.20'
-version='5.20.0'
-version_patchlevel_string='version 20 subversion 0'
+version='5.20.1'
+version_patchlevel_string='version 20 subversion 1'
 PERL_VERSION=20
 PERL_API_VERSION=20
+PERL_SUBVERSION=1
 patchlevel='20'
 ccdlflags='-fPIC -Wl,-rpath,/usr/lib/perl5/5.20/CORE'
+subversion='1'
 
 # Make perl use these tools instead of the target binaries during build.
 hostgenerate='%%HOSTGENERATE%%'
diff --git a/lang/perl/files/perl-run_tests.sh b/lang/perl/files/perl-run_tests.sh
new file mode 100755 (executable)
index 0000000..af6a39c
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+PERL_TESTSDIR="/usr/share/perl/perl-tests"
+PERL_LIBDIR="/usr/lib/perl5/5.20/"
+PERL_DISABLEDTESTS="%%PERL_DISABLEDTESTS%%"
+
+if [ ! -f "$PERL_TESTSDIR/__prepared" ]; then
+       ln -s "$PERL_LIBDIR" "$PERL_TESTSDIR/lib"
+       ln -s /usr/bin/perl "$PERL_TESTSDIR/perl"
+       ln -s /usr/bin/perl "$PERL_TESTSDIR/t/perl"
+       touch "$PERL_TESTSDIR/__prepared"
+       
+       for i in $PERL_DISABLEDTESTS; do
+               echo "Disabling $i tests"
+               sed 's!^'$i'.*$!!' -i $PERL_TESTSDIR/MANIFEST
+       done
+       
+       cat $PERL_TESTSDIR/MANIFEST | grep -v '^$' > $PERL_TESTSDIR/MANIFEST_NEW
+       rm $PERL_TESTSDIR/MANIFEST
+       mv $PERL_TESTSDIR/MANIFEST_NEW $PERL_TESTSDIR/MANIFEST
+fi
+
+cd "$PERL_TESTSDIR/t"
+./perl TEST
index cc9169076ea6fac9bd59cfaa59d0e02303adb597..ab08b386068501a32742af1bb0aa97680f3d796f 100644 (file)
@@ -19,6 +19,19 @@ endef
 $(eval $(call BuildPackage,perlbase-anydbm-file))
 
 
+define Package/perlbase-app
+$(call Package/perlbase-template)
+TITLE:=app perl module
+DEPENDS+=+perlbase-autouse +perlbase-base +perlbase-config +perlbase-cpan +perlbase-essential +perlbase-file +perlbase-getopt +perlbase-if +perlbase-tap +perlbase-text
+endef
+
+define Package/perlbase-app/install
+$(call perlmod/Install,$(1),App,)
+endef
+
+$(eval $(call BuildPackage,perlbase-app))
+
+
 define Package/perlbase-archive
 $(call Package/perlbase-template)
 TITLE:=Archive perl module
@@ -27,11 +40,25 @@ endef
 
 define Package/perlbase-archive/install
 $(call perlmod/Install,$(1),Archive,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Archive-Tar/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-archive))
 
 
+define Package/perlbase-arybase
+$(call Package/perlbase-template)
+TITLE:=arybase perl module
+endef
+
+define Package/perlbase-arybase/install
+$(call perlmod/Install,$(1),arybase.pm auto/arybase,)
+$(call perlmod/InstallBaseTests,$(1),ext/arybase/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-arybase))
+
+
 define Package/perlbase-attribute
 $(call Package/perlbase-template)
 TITLE:=Attribute perl module
@@ -40,6 +67,7 @@ endef
 
 define Package/perlbase-attribute/install
 $(call perlmod/Install,$(1),Attribute,)
+$(call perlmod/InstallBaseTests,$(1),dist/Attribute-Handlers/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-attribute))
@@ -52,12 +80,26 @@ DEPENDS+=+perlbase-essential
 endef
 
 define Package/perlbase-attributes/install
-$(call perlmod/Install,$(1),attributes.pm,)
+$(call perlmod/Install,$(1),attributes.pm auto/attributes,)
 endef
 
 $(eval $(call BuildPackage,perlbase-attributes))
 
 
+define Package/perlbase-autodie
+$(call Package/perlbase-template)
+TITLE:=autodie perl module
+DEPENDS+=+perlbase-base +perlbase-essential +perlbase-fatal +perlbase-if
+endef
+
+define Package/perlbase-autodie/install
+$(call perlmod/Install,$(1),autodie autodie.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/autodie/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-autodie))
+
+
 define Package/perlbase-autoloader
 $(call Package/perlbase-template)
 TITLE:=AutoLoader perl module
@@ -66,6 +108,7 @@ endef
 
 define Package/perlbase-autoloader/install
 $(call perlmod/Install,$(1),AutoLoader.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/AutoLoader/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-autoloader))
@@ -78,7 +121,7 @@ DEPENDS+=+perlbase-config +perlbase-essential +perlbase-file
 endef
 
 define Package/perlbase-autosplit/install
-$(call perlmod/Install,$(1),AutoSplit.pm,)
+$(call perlmod/Install/NoStrip,$(1),AutoSplit.pm,)
 endef
 
 $(eval $(call BuildPackage,perlbase-autosplit))
@@ -91,6 +134,7 @@ endef
 
 define Package/perlbase-autouse/install
 $(call perlmod/Install,$(1),autouse.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/autouse/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-autouse))
@@ -104,6 +148,7 @@ endef
 
 define Package/perlbase-b/install
 $(call perlmod/Install,$(1),B B.pm auto/B,)
+$(call perlmod/InstallBaseTests,$(1),cpan/B-Debug/t ext/B/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-b))
@@ -117,6 +162,7 @@ endef
 
 define Package/perlbase-base/install
 $(call perlmod/Install,$(1),base.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/base/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-base))
@@ -155,7 +201,8 @@ DEPENDS+=+perlbase-bigint +perlbase-essential
 endef
 
 define Package/perlbase-bignum/install
-$(call perlmod/Install,$(1),bignum.pm,)
+$(call perlmod/Install,$(1),bignum.pm bigrat.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/bignum/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-bignum))
@@ -194,6 +241,7 @@ endef
 
 define Package/perlbase-cgi/install
 $(call perlmod/Install,$(1),CGI CGI.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/CGI/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-cgi))
@@ -202,11 +250,11 @@ $(eval $(call BuildPackage,perlbase-cgi))
 define Package/perlbase-charnames
 $(call Package/perlbase-template)
 TITLE:=charnames perl module
-DEPENDS+=+perlbase-bytes +perlbase-essential +perlbase-re +perlbase-unicore
+DEPENDS+=+perlbase-bytes +perlbase-essential +perlbase-file +perlbase-re +perlbase-unicore
 endef
 
 define Package/perlbase-charnames/install
-$(call perlmod/Install,$(1),charnames.pm,)
+$(call perlmod/Install,$(1),_charnames.pm charnames.pm,)
 endef
 
 $(eval $(call BuildPackage,perlbase-charnames))
@@ -233,6 +281,7 @@ endef
 
 define Package/perlbase-compress/install
 $(call perlmod/Install,$(1),Compress auto/Compress,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Compress-Raw-Bzip2/t cpan/Compress-Raw-Zlib/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-compress))
@@ -241,10 +290,12 @@ $(eval $(call BuildPackage,perlbase-compress))
 define Package/perlbase-config
 $(call Package/perlbase-template)
 TITLE:=Config perl module
+DEPENDS+=+perlbase-essential
 endef
 
 define Package/perlbase-config/install
-$(call perlmod/Install,$(1),Config Config.pm Config_heavy.pl,)
+$(call perlmod/Install,$(1),Config Config.pm Config_git.pl Config_heavy.pl,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Config-Perl-V/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-config))
@@ -253,11 +304,13 @@ $(eval $(call BuildPackage,perlbase-config))
 define Package/perlbase-cpan
 $(call Package/perlbase-template)
 TITLE:=CPAN perl module
-DEPENDS+=+perlbase-b +perlbase-config +perlbase-cwd +perlbase-dirhandle +perlbase-essential +perlbase-extutils +perlbase-fcntl +perlbase-file +perlbase-filehandle +perlbase-list +perlbase-net +perlbase-safe +perlbase-scalar +perlbase-sys +perlbase-text +perlbase-version
+DEPENDS+=+perlbase-b +perlbase-config +perlbase-cwd +perlbase-dirhandle +perlbase-essential +perlbase-extutils +perlbase-fcntl +perlbase-file +perlbase-filehandle +perlbase-http-tiny +perlbase-list +perlbase-net +perlbase-safe +perlbase-scalar +perlbase-sys +perlbase-text +perlbase-version
 endef
 
 define Package/perlbase-cpan/install
-$(call perlmod/Install,$(1),CPAN CPAN.pm,)
+$(call perlmod/Install,$(1),CPAN CPAN.pm Parse/CPAN/Meta.pm,CPAN/FirstTime.pm)
+$(call perlmod/Install/NoStrip,$(1),CPAN/FirstTime.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/CPAN-Meta-Requirements/t cpan/CPAN-Meta-YAML/t cpan/CPAN-Meta/t cpan/CPAN/t cpan/Parse-CPAN-Meta/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-cpan))
@@ -284,6 +337,7 @@ endef
 
 define Package/perlbase-data/install
 $(call perlmod/Install,$(1),Data auto/Data,)
+$(call perlmod/InstallBaseTests,$(1),dist/Data-Dumper/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-data))
@@ -310,6 +364,7 @@ endef
 
 define Package/perlbase-db-file/install
 $(call perlmod/Install,$(1),DB_File.pm auto/DB_File,)
+$(call perlmod/InstallBaseTests,$(1),cpan/DB_File/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-db-file))
@@ -335,7 +390,9 @@ DEPENDS+=+perlbase-essential +perlbase-file
 endef
 
 define Package/perlbase-devel/install
-$(call perlmod/Install,$(1),Devel auto/Devel,)
+$(call perlmod/Install,$(1),Devel auto/Devel,Devel/PPPort.pm)
+$(call perlmod/Install/NoStrip,$(1),Devel/PPPort.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Devel-PPPort/t dist/Devel-SelfStubber/t ext/Devel-Peek/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-devel))
@@ -362,6 +419,8 @@ endef
 
 define Package/perlbase-digest/install
 $(call perlmod/Install,$(1),Digest Digest.pm auto/Digest,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Digest-MD5/MD5.xs cpan/Digest-MD5/t cpan/Digest-SHA/t cpan/Digest/t)
+       $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/cpan/Digest-SHA/src
 endef
 
 $(eval $(call BuildPackage,perlbase-digest))
@@ -388,6 +447,7 @@ endef
 
 define Package/perlbase-dumpvalue/install
 $(call perlmod/Install,$(1),Dumpvalue.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/Dumpvalue/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-dumpvalue))
@@ -413,6 +473,7 @@ endef
 
 define Package/perlbase-dynaloader/install
 $(call perlmod/Install,$(1),DynaLoader.pm,)
+$(call perlmod/InstallBaseTests,$(1),ext/DynaLoader/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-dynaloader))
@@ -426,6 +487,7 @@ endef
 
 define Package/perlbase-encode/install
 $(call perlmod/Install,$(1),Encode Encode.pm auto/Encode,Encode/PerlIO.pod Encode/Supported.pod)
+$(call perlmod/InstallBaseTests,$(1),cpan/Encode/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-encode))
@@ -439,6 +501,7 @@ endef
 
 define Package/perlbase-encoding/install
 $(call perlmod/Install,$(1),encoding encoding.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/encoding-warnings/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-encoding))
@@ -464,6 +527,7 @@ endef
 
 define Package/perlbase-env/install
 $(call perlmod/Install,$(1),Env.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/Env/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-env))
@@ -477,6 +541,7 @@ endef
 
 define Package/perlbase-errno/install
 $(call perlmod/Install,$(1),Errno.pm,)
+$(call perlmod/InstallBaseTests,$(1),ext/Errno/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-errno))
@@ -485,24 +550,40 @@ $(eval $(call BuildPackage,perlbase-errno))
 define Package/perlbase-essential
 $(call Package/perlbase-template)
 TITLE:=essential perl module
-DEPENDS+=+perlbase-config
 endef
 
 define Package/perlbase-essential/install
-$(call perlmod/Install,$(1),Carp Carp.pm Exporter Exporter.pm constant.pm lib.pm locale.pm overload.pm overloading.pm parent.pm strict.pm subs.pm vars.pm warnings warnings.pm,)
+$(call perlmod/Install,$(1),Carp Carp.pm Exporter Exporter.pm constant.pm deprecate.pm lib.pm locale.pm overload.pm overloading.pm parent.pm strict.pm subs.pm vars.pm warnings warnings.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/parent/t dist/Carp/t dist/Exporter/t dist/constant/t dist/lib/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-essential))
 
 
+define Package/perlbase-experimental
+$(call Package/perlbase-template)
+TITLE:=perl module to enable/disable experimental features
+DEPENDS+=+perlbase-essential +perlbase-feature
+endef
+
+define Package/perlbase-experimental/install
+$(call perlmod/Install,$(1),experimental.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/experimental/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-experimental))
+
+
 define Package/perlbase-extutils
 $(call Package/perlbase-template)
 TITLE:=ExtUtils perl module
-DEPENDS+=+perlbase-autosplit +perlbase-config +perlbase-cwd +perlbase-dirhandle +perlbase-essential +perlbase-file +perlbase-io +perlbase-ipc +perlbase-symbol +perlbase-text
+DEPENDS+=+perlbase-autosplit +perlbase-config +perlbase-cwd +perlbase-dirhandle +perlbase-essential +perlbase-file +perlbase-io +perlbase-ipc +perlbase-ostype +perlbase-symbol +perlbase-text
 endef
 
 define Package/perlbase-extutils/install
-$(call perlmod/Install,$(1),ExtUtils,ExtUtils/MakeMaker/FAQ.pod ExtUtils/MakeMaker/Tutorial.pod)
+$(call perlmod/Install,$(1),ExtUtils,ExtUtils/MakeMaker/FAQ.pod ExtUtils/MakeMaker/Tutorial.pod ExtUtils/ParseXS.pm ExtUtils/ParseXS/Utilities.pm)
+$(call perlmod/Install/NoStrip,$(1),ExtUtils/ParseXS.pm ExtUtils/ParseXS/Utilities.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/ExtUtils-Constant/t cpan/ExtUtils-MakeMaker/t dist/ExtUtils-CBuilder/t dist/ExtUtils-Command/t dist/ExtUtils-Install/t dist/ExtUtils-Manifest/t dist/ExtUtils-ParseXS/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-extutils))
@@ -529,6 +610,7 @@ endef
 
 define Package/perlbase-fcntl/install
 $(call perlmod/Install,$(1),Fcntl.pm auto/Fcntl,)
+$(call perlmod/InstallBaseTests,$(1),ext/Fcntl/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-fcntl))
@@ -566,7 +648,9 @@ DEPENDS+=+perlbase-class +perlbase-config +perlbase-cwd +perlbase-errno +perlbas
 endef
 
 define Package/perlbase-file/install
-$(call perlmod/Install,$(1),File auto/File,)
+$(call perlmod/Install,$(1),File auto/File,File/Find.pm)
+$(call perlmod/Install/NoStrip,$(1),File/Find.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/File-Fetch/t cpan/File-Path/t cpan/File-Temp/t dist/PathTools/t ext/File-DosGlob/t ext/File-Find/t ext/File-Glob/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-file))
@@ -580,6 +664,7 @@ endef
 
 define Package/perlbase-filecache/install
 $(call perlmod/Install,$(1),FileCache.pm,)
+$(call perlmod/InstallBaseTests,$(1),ext/FileCache/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-filecache))
@@ -618,6 +703,7 @@ endef
 
 define Package/perlbase-filter/install
 $(call perlmod/Install,$(1),Filter auto/Filter,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Filter-Util-Call/filter-util.pl cpan/Filter-Util-Call/t dist/Filter-Simple/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-filter))
@@ -644,6 +730,7 @@ endef
 
 define Package/perlbase-gdbm-file/install
 $(call perlmod/Install,$(1),GDBM_File.pm auto/GDBM_File,)
+$(call perlmod/InstallBaseTests,$(1),ext/GDBM_File/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-gdbm-file))
@@ -657,6 +744,7 @@ endef
 
 define Package/perlbase-getopt/install
 $(call perlmod/Install,$(1),Getopt,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Getopt-Long/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-getopt))
@@ -670,11 +758,26 @@ endef
 
 define Package/perlbase-hash/install
 $(call perlmod/Install,$(1),Hash auto/Hash,)
+$(call perlmod/InstallBaseTests,$(1),ext/Hash-Util-FieldHash/t ext/Hash-Util/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-hash))
 
 
+define Package/perlbase-http-tiny
+$(call Package/perlbase-template)
+TITLE:=http-tiny perl module
+DEPENDS+=+perlbase-errno +perlbase-essential +perlbase-io
+endef
+
+define Package/perlbase-http-tiny/install
+$(call perlmod/Install,$(1),HTTP/Tiny.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/HTTP-Tiny/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-http-tiny))
+
+
 define Package/perlbase-i18n
 $(call Package/perlbase-template)
 TITLE:=I18N perl module
@@ -682,7 +785,9 @@ DEPENDS+=+perlbase-essential +perlbase-posix
 endef
 
 define Package/perlbase-i18n/install
-$(call perlmod/Install,$(1),I18N auto/I18N,)
+$(call perlmod/Install,$(1),I18N auto/I18N,I18N/LangTags/List.pm)
+$(call perlmod/InstallBaseTests,$(1),dist/I18N-Collate/t dist/I18N-LangTags/t ext/I18N-Langinfo/t)
+$(call perlmod/Install/NoStrip,$(1),I18N/LangTags/List.pm)
 endef
 
 $(eval $(call BuildPackage,perlbase-i18n))
@@ -695,6 +800,7 @@ endef
 
 define Package/perlbase-if/install
 $(call perlmod/Install,$(1),if.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/if/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-if))
@@ -720,6 +826,7 @@ endef
 
 define Package/perlbase-io/install
 $(call perlmod/Install,$(1),IO IO.pm auto/IO,)
+$(call perlmod/InstallBaseTests,$(1),cpan/IO-Compress/t cpan/IO-Socket-IP/t cpan/IO-Zlib/t dist/IO/Makefile.PL dist/IO/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-io))
@@ -733,11 +840,26 @@ endef
 
 define Package/perlbase-ipc/install
 $(call perlmod/Install,$(1),IPC auto/IPC,)
+$(call perlmod/InstallBaseTests,$(1),cpan/IPC-Cmd/t cpan/IPC-SysV/t ext/IPC-Open3/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-ipc))
 
 
+define Package/perlbase-json-pp
+$(call Package/perlbase-template)
+TITLE:=json-pp perl module
+DEPENDS+=+perlbase-b +perlbase-base +perlbase-essential
+endef
+
+define Package/perlbase-json-pp/install
+$(call perlmod/Install,$(1),JSON/PP JSON/PP.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/JSON-PP/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-json-pp))
+
+
 define Package/perlbase-less
 $(call Package/perlbase-template)
 TITLE:=less perl module
@@ -772,6 +894,7 @@ endef
 
 define Package/perlbase-locale/install
 $(call perlmod/Install,$(1),Locale,Locale/Constants.pod Locale/Country.pod Locale/Currency.pod Locale/Language.pod Locale/Maketext.pod Locale/Maketext/TPJ13.pod Locale/Script.pod)
+$(call perlmod/InstallBaseTests,$(1),cpan/Locale-Codes/t cpan/Locale-Maketext-Simple/t dist/Locale-Maketext/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-locale))
@@ -785,6 +908,7 @@ endef
 
 define Package/perlbase-math/install
 $(call perlmod/Install,$(1),Math auto/Math,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Math-Complex/t dist/Math-BigInt-FastCalc/t dist/Math-BigInt/t dist/Math-BigRat/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-math))
@@ -798,6 +922,7 @@ endef
 
 define Package/perlbase-memoize/install
 $(call perlmod/Install,$(1),Memoize Memoize.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Memoize/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-memoize))
@@ -811,6 +936,7 @@ endef
 
 define Package/perlbase-mime/install
 $(call perlmod/Install,$(1),MIME auto/MIME,)
+$(call perlmod/InstallBaseTests,$(1),cpan/MIME-Base64/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-mime))
@@ -819,11 +945,13 @@ $(eval $(call BuildPackage,perlbase-mime))
 define Package/perlbase-module
 $(call Package/perlbase-template)
 TITLE:=Module perl module
-DEPENDS+=+perlbase-config +perlbase-cwd +perlbase-data +perlbase-essential +perlbase-extutils +perlbase-file +perlbase-filehandle +perlbase-if +perlbase-io +perlbase-locale +perlbase-params +perlbase-text +perlbase-version
+DEPENDS+=+perlbase-config +perlbase-cwd +perlbase-data +perlbase-essential +perlbase-extutils +perlbase-file +perlbase-filehandle +perlbase-if +perlbase-io +perlbase-locale +perlbase-ostype +perlbase-params +perlbase-text +perlbase-version
 endef
 
 define Package/perlbase-module/install
-$(call perlmod/Install,$(1),Module,Module/Build/API.pod Module/Build/Authoring.pod)
+$(call perlmod/Install,$(1),Module,Module/Build Module/Build.pm Module/Build/API.pod Module/Build/Authoring.pod)
+$(call perlmod/Install/NoStrip,$(1),Module/Build Module/Build.pm,Module/Build/API.pod Module/Build/Authoring.pod)
+$(call perlmod/InstallBaseTests,$(1),cpan/Module-Build/lib cpan/Module-Build/t cpan/Module-Load-Conditional/t cpan/Module-Load/t cpan/Module-Loaded/t cpan/Module-Metadata/lib cpan/Module-Metadata/t dist/Module-CoreList/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-module))
@@ -836,7 +964,7 @@ DEPENDS+=+perlbase-essential
 endef
 
 define Package/perlbase-mro/install
-$(call perlmod/Install,$(1),mro.pm,)
+$(call perlmod/Install,$(1),auto/mro mro.pm,)
 endef
 
 $(eval $(call BuildPackage,perlbase-mro))
@@ -850,6 +978,7 @@ endef
 
 define Package/perlbase-net/install
 $(call perlmod/Install,$(1),Net,Net/libnetFAQ.pod)
+$(call perlmod/InstallBaseTests,$(1),cpan/libnet/t dist/Net-Ping/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-net))
@@ -863,6 +992,7 @@ endef
 
 define Package/perlbase-next/install
 $(call perlmod/Install,$(1),NEXT.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/NEXT/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-next))
@@ -888,7 +1018,9 @@ DEPENDS+=+perlbase-essential +perlbase-xsloader
 endef
 
 define Package/perlbase-opcode/install
-$(call perlmod/Install,$(1),Opcode.pm auto/Opcode,)
+$(call perlmod/Install,$(1),auto/Opcode,)
+$(call perlmod/Install/NoStrip,$(1),Opcode.pm,)
+$(call perlmod/InstallBaseTests,$(1),ext/Opcode/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-opcode))
@@ -920,6 +1052,20 @@ endef
 $(eval $(call BuildPackage,perlbase-ops))
 
 
+define Package/perlbase-ostype
+$(call Package/perlbase-template)
+TITLE:=OSType perl module
+DEPENDS+=+perlbase-essential
+endef
+
+define Package/perlbase-ostype/install
+$(call perlmod/Install,$(1),Perl/OSType.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Perl-OSType/t)
+endef
+
+$(eval $(call BuildPackage,perlbase-ostype))
+
+
 define Package/perlbase-package
 $(call Package/perlbase-template)
 TITLE:=Package perl module
@@ -928,6 +1074,7 @@ endef
 
 define Package/perlbase-package/install
 $(call perlmod/Install,$(1),Package,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Package-Constants/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-package))
@@ -941,6 +1088,7 @@ endef
 
 define Package/perlbase-params/install
 $(call perlmod/Install,$(1),Params,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Params-Check/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-params))
@@ -967,6 +1115,7 @@ endef
 
 define Package/perlbase-perlio/install
 $(call perlmod/Install,$(1),PerlIO PerlIO.pm auto/PerlIO,)
+$(call perlmod/InstallBaseTests,$(1),cpan/PerlIO-via-QuotedPrint/t ext/PerlIO-encoding/t ext/PerlIO-scalar/t ext/PerlIO-via/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-perlio))
@@ -979,7 +1128,12 @@ DEPENDS+=+perlbase-config +perlbase-cwd +perlbase-encode +perlbase-essential +pe
 endef
 
 define Package/perlbase-pod/install
-$(call perlmod/Install,$(1),Pod,)
+$(call perlmod/Install,$(1),Pod,Pod/Usage.pm)
+$(call perlmod/Install/NoStrip,$(1),Pod/Usage.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Pod-Checker/t cpan/Pod-Escapes/t cpan/Pod-Parser/lib cpan/Pod-Parser/scripts cpan/Pod-Parser/t cpan/Pod-Perldoc/t cpan/Pod-Simple/t cpan/Pod-Usage/scripts cpan/Pod-Usage/t cpan/podlators/t ext/Pod-Functions/Functions.pm ext/Pod-Functions/t ext/Pod-Html/t)
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/pod2man $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/pod2text $(1)/usr/bin/
 endef
 
 $(eval $(call BuildPackage,perlbase-pod))
@@ -993,6 +1147,7 @@ endef
 
 define Package/perlbase-posix/install
 $(call perlmod/Install,$(1),POSIX.pm auto/POSIX,)
+$(call perlmod/InstallBaseTests,$(1),ext/POSIX/Makefile.PL ext/POSIX/POSIX.xs ext/POSIX/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-posix))
@@ -1006,6 +1161,7 @@ endef
 
 define Package/perlbase-re/install
 $(call perlmod/Install,$(1),auto/re re.pm,)
+$(call perlmod/InstallBaseTests,$(1),ext/re/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-re))
@@ -1019,6 +1175,7 @@ endef
 
 define Package/perlbase-safe/install
 $(call perlmod/Install,$(1),Safe.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/Safe/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-safe))
@@ -1032,6 +1189,8 @@ endef
 
 define Package/perlbase-scalar/install
 $(call perlmod/Install,$(1),Scalar,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Scalar-List-Utils/t)
+       $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/cpan/Scalar-List-Utils/blib
 endef
 
 $(eval $(call BuildPackage,perlbase-scalar))
@@ -1045,6 +1204,7 @@ endef
 
 define Package/perlbase-sdbm-file/install
 $(call perlmod/Install,$(1),SDBM_File.pm auto/SDBM_File,)
+$(call perlmod/InstallBaseTests,$(1),ext/SDBM_File/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-sdbm-file))
@@ -1058,6 +1218,7 @@ endef
 
 define Package/perlbase-search/install
 $(call perlmod/Install,$(1),Search,)
+$(call perlmod/InstallBaseTests,$(1),dist/Search-Dict/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-search))
@@ -1084,6 +1245,7 @@ endef
 
 define Package/perlbase-selfloader/install
 $(call perlmod/Install,$(1),SelfLoader.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/SelfLoader/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-selfloader))
@@ -1110,6 +1272,7 @@ endef
 
 define Package/perlbase-socket/install
 $(call perlmod/Install,$(1),Socket.pm auto/Socket,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Socket/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-socket))
@@ -1136,6 +1299,7 @@ endef
 
 define Package/perlbase-storable/install
 $(call perlmod/Install,$(1),Storable.pm auto/Storable,)
+$(call perlmod/InstallBaseTests,$(1),dist/Storable/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-storable))
@@ -1161,11 +1325,25 @@ endef
 
 define Package/perlbase-sys/install
 $(call perlmod/Install,$(1),Sys auto/Sys,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Sys-Syslog/t ext/Sys-Hostname/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-sys))
 
 
+define Package/perlbase-tap
+$(call Package/perlbase-template)
+TITLE:=TAP perl module
+DEPENDS+=+perlbase-base +perlbase-benchmark +perlbase-config +perlbase-essential +perlbase-file +perlbase-io +perlbase-posix +perlbase-text
+endef
+
+define Package/perlbase-tap/install
+$(call perlmod/Install,$(1),TAP,)
+endef
+
+$(eval $(call BuildPackage,perlbase-tap))
+
+
 define Package/perlbase-term
 $(call Package/perlbase-template)
 TITLE:=Term perl module
@@ -1174,6 +1352,7 @@ endef
 
 define Package/perlbase-term/install
 $(call perlmod/Install,$(1),Term,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Term-ANSIColor/t cpan/Term-Cap/test.pl dist/Term-Complete/t dist/Term-ReadLine/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-term))
@@ -1182,11 +1361,13 @@ $(eval $(call BuildPackage,perlbase-term))
 define Package/perlbase-test
 $(call Package/perlbase-template)
 TITLE:=Test perl module
-DEPENDS+=+perlbase-base +perlbase-config +perlbase-essential +perlbase-symbol +perlbase-text
+DEPENDS+=+perlbase-base +perlbase-config +perlbase-essential +perlbase-symbol +perlbase-tap +perlbase-text
 endef
 
 define Package/perlbase-test/install
-$(call perlmod/Install,$(1),Test Test.pm,Test/Harness/TAP.pod Test/Tutorial.pod)
+$(call perlmod/Install,$(1),Test Test.pm,Test/Builder.pm Test/Harness/TAP.pod Test/More.pm Test/Tutorial.pod)
+$(call perlmod/Install/NoStrip,$(1),Test/Builder.pm Test/More.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Test-Harness/t cpan/Test-Simple/t cpan/Test/t)
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/prove $(1)/usr/bin
 endef
@@ -1197,11 +1378,12 @@ $(eval $(call BuildPackage,perlbase-test))
 define Package/perlbase-text
 $(call Package/perlbase-template)
 TITLE:=Text perl module
-DEPENDS+=+perlbase-essential
+DEPENDS+=+perlbase-essential +perlbase-selfloader
 endef
 
 define Package/perlbase-text/install
 $(call perlmod/Install,$(1),Text,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Text-Balanced/t cpan/Text-ParseWords/t cpan/Text-Tabs/t dist/Text-Abbrev/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-text))
@@ -1215,6 +1397,7 @@ endef
 
 define Package/perlbase-thread/install
 $(call perlmod/Install,$(1),Thread Thread.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/Thread-Queue/t dist/Thread-Semaphore/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-thread))
@@ -1228,6 +1411,7 @@ endef
 
 define Package/perlbase-threads/install
 $(call perlmod/Install,$(1),auto/threads threads threads.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/threads-shared/t dist/threads/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-threads))
@@ -1240,7 +1424,8 @@ DEPENDS+=+perlbase-essential +perlbase-fcntl +perlbase-posix
 endef
 
 define Package/perlbase-tie/install
-$(call perlmod/Install,$(1),Tie,)
+$(call perlmod/Install,$(1),Tie auto/Tie,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Tie-RefHash/t dist/Tie-File/t ext/Tie-Hash-NamedCapture/t ext/Tie-Memoize/lib/Tie/Memoize.pm ext/Tie-Memoize/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-tie))
@@ -1254,6 +1439,7 @@ endef
 
 define Package/perlbase-time/install
 $(call perlmod/Install,$(1),Time auto/Time,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Time-HiRes/t cpan/Time-Local/t cpan/Time-Piece/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-time))
@@ -1267,6 +1453,7 @@ endef
 
 define Package/perlbase-unicode/install
 $(call perlmod/Install,$(1),Unicode auto/Unicode,)
+$(call perlmod/InstallBaseTests,$(1),cpan/Unicode-Collate/t cpan/Unicode-Normalize/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-unicode))
@@ -1325,11 +1512,12 @@ $(eval $(call BuildPackage,perlbase-utf8))
 define Package/perlbase-version
 $(call Package/perlbase-template)
 TITLE:=version perl module
-DEPENDS+=+perlbase-essential
+DEPENDS+=+perlbase-config +perlbase-essential
 endef
 
 define Package/perlbase-version/install
-$(call perlmod/Install,$(1),version.pm,)
+$(call perlmod/Install,$(1),version version.pm,)
+$(call perlmod/InstallBaseTests,$(1),cpan/version/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-version))
@@ -1342,6 +1530,10 @@ endef
 
 define Package/perlbase-xsloader/install
 $(call perlmod/Install,$(1),XSLoader.pm,)
+$(call perlmod/InstallBaseTests,$(1),dist/XSLoader/t ext/XS-APItest/t ext/XS-Typemap/t)
 endef
 
 $(eval $(call BuildPackage,perlbase-xsloader))
+
+
+# Generated Mon Oct 13 10:06:15 2014
index 3c3d56720a63a6c53e7bacbcbd9c3b80432d1f13..e8706dc6a087e81b4f5fd95ecde79c58f4f74caa 100644 (file)
@@ -11,6 +11,9 @@ PERL_CMD:=$(STAGING_DIR_HOST)/usr/bin/perl5.20.0
 
 # Module install prefix
 PERL_SITELIB:=/usr/lib/perl5/5.20
+PERL_TESTSDIR:=/usr/share/perl/perl-tests
+PERLBASE_TESTSDIR:=/usr/share/perl/perlbase-tests
+PERLMOD_TESTSDIR:=/usr/share/perl/perlmod-tests
 
 define perlmod/host/relink
        rm -f $(1)/Makefile.aperl
@@ -105,7 +108,7 @@ define perlmod/Compile
                install
 endef
 
-define perlmod/Install
+define perlmod/Install/NoStrip
        $(INSTALL_DIR) $(strip $(1))$(PERL_SITELIB)
        (cd $(PKG_INSTALL_DIR)$(PERL_SITELIB) && \
        rsync --relative -rlHp --itemize-changes \
@@ -116,12 +119,37 @@ define perlmod/Install
                $(strip $(2)) $(strip $(1))$(PERL_SITELIB))
 
        chmod -R u+w $(strip $(1))$(PERL_SITELIB)
+endef
+
+
+define perlmod/Install
+       $(call perlmod/Install/NoStrip,$(1),$(2),$(3))
 
        @echo "---> Stripping modules in: $(strip $(1))$(PERL_SITELIB)"
        find $(strip $(1))$(PERL_SITELIB) -name \*.pm -or -name \*.pl | \
        xargs -r sed -i \
-               -e '/^=\(head\|pod\|item\|over\|back\|encoding\)/,/^=cut/d' \
-               -e '/^=\(head\|pod\|item\|over\|back\|encoding\)/,$$$$d' \
+               -e '/^=\(head\|pod\|item\|over\|back\|encoding\|begin\|end\|for\)/,/^=cut/d' \
+               -e '/^=\(head\|pod\|item\|over\|back\|encoding\|begin\|end\|for\)/,$$$$d' \
                -e '/^#$$$$/d' \
                -e '/^#[^!"'"'"']/d'
 endef
+
+# You probably don't want to use this directly. Look at perlmod/InstallTests
+define perlmod/_InstallTests
+       $(INSTALL_DIR) $(strip $(1))
+       (cd $(PKG_BUILD_DIR)/$(2) && \
+       rsync --relative -rlHp --itemize-changes \
+               --exclude=.packlist \
+               --prune-empty-dirs \
+               $(strip $(3)) $(strip $(1)))
+
+       chmod -R u+w $(strip $(1))
+endef
+
+define perlmod/InstallBaseTests
+       $(if $(CONFIG_PERL_TESTS),$(call perlmod/_InstallTests,$(1)$(PERL_TESTSDIR),,$(2)))
+endef
+
+define perlmod/InstallTests
+       $(if $(CONFIG_PERL_TESTS),$(call perlmod/_InstallTests,$(1)$(PERL_TESTSDIR),$(2),$(3)))
+endef
index 8216fdf80987d02c84cccc8366c3783d819986e0..5449dc3f54ba0294a503d914c68214940e9e8084 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,20 +8,21 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=php
-PKG_VERSION:=5.4.33
+PKG_VERSION:=5.4.37
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
-PKG_LICENSE=PHPv3.01
-PKG_LICENSE_FILE=LICENSE
+PKG_LICENSE:=PHPv3.01
+PKG_LICENSE_FILES:=LICENSE
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://www.php.net/distributions/
-PKG_MD5SUM:=c6878bb1cdb46bfc1e1a5cd67a024737
+PKG_MD5SUM:=1962086593e8e39342674be0483db439
 
 PKG_FIXUP:=libtool no-autoreconf
 PKG_BUILD_PARALLEL:=1
+PKG_USE_MIPS16:=0
 
 PHP5_MODULES = \
        calendar ctype curl \
@@ -37,7 +38,7 @@ PHP5_MODULES = \
        mbstring mcrypt mysql mysqli \
        openssl \
        pcntl pdo pdo-mysql pdo-pgsql pdo-sqlite pgsql \
-       session shmop simplexml soap sockets sqlite sqlite3 sysvmsg sysvsem sysvshm \
+       session shmop simplexml soap sockets sqlite3 sysvmsg sysvsem sysvshm \
        tokenizer \
        xml xmlreader xmlwriter zip \
 
@@ -127,9 +128,21 @@ define Package/php5-fastcgi/description
   on the php5-cgi package, containing just the startup script.
 endef
 
+define Package/php5-fpm
+  $(call Package/php5/Default)
+  DEPENDS+= +php5-cgi
+  TITLE+= (FPM)
+endef
+
+define Package/php5-fpm/description
+  $(call Package/php5/Default/description)
+  This package contains the FastCGI Process Manager of the PHP5 interpreter.
+endef
+
 CONFIGURE_ARGS+= \
        --enable-cli \
        --enable-cgi \
+       --enable-fpm \
        --enable-shared \
        --disable-static \
        --disable-rpath \
@@ -225,7 +238,7 @@ else
   CONFIGURE_ARGS+= --without-iconv
 endif
 
-ifneq ($(CONFIG_PACKAGE_php5-mod-json),)
+ifneq ($(SDK)$(CONFIG_PACKAGE_php5-mod-json),)
   CONFIGURE_ARGS+= --enable-json=shared
 else
   CONFIGURE_ARGS+= --disable-json
@@ -335,12 +348,6 @@ else
   CONFIGURE_ARGS+= --disable-sockets
 endif
 
-ifneq ($(SDK)$(CONFIG_PACKAGE_php5-mod-sqlite),)
-  CONFIGURE_ARGS+= --with-sqlite=shared,"$(STAGING_DIR)/usr"
-else
-  CONFIGURE_ARGS+= --without-sqlite
-endif
-
 ifneq ($(SDK)$(CONFIG_PACKAGE_php5-mod-sqlite3),)
   CONFIGURE_ARGS+= --with-sqlite3=shared,"$(STAGING_DIR)/usr"
 else
@@ -453,6 +460,23 @@ define Package/php5-fastcgi/install
        $(INSTALL_BIN) ./files/php5-fastcgi.init $(1)/etc/init.d/php5-fastcgi
 endef
 
+define Package/php5-fpm/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/sapi/fpm/php-fpm $(1)/usr/bin/php-fpm
+
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) ./files/php5-fpm.conf $(1)/etc/php5-fpm.conf
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/php5-fpm.config $(1)/etc/config/php5-fpm
+
+       $(INSTALL_DIR) $(1)/etc/php5-fpm.d
+       $(INSTALL_DATA) ./files/php5-fpm-www.conf $(1)/etc/php5-fpm.d/www.conf
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/php5-fpm.init $(1)/etc/init.d/php5-fpm
+endef
+
 define Build/Prepare
        $(call Build/Prepare/Default)
        ( cd $(PKG_BUILD_DIR); touch configure.in; ./buildconf --force )
@@ -492,23 +516,24 @@ define BuildModule
 endef
 
 $(eval $(call BuildPackage,php5))
-$(eval $(call BuildPackage,php5-cli))
 $(eval $(call BuildPackage,php5-cgi))
+$(eval $(call BuildPackage,php5-cli))
 $(eval $(call BuildPackage,php5-fastcgi))
+$(eval $(call BuildPackage,php5-fpm))
 
 #$(eval $(call BuildModule,NAME,TITLE[,PKG DEPENDS]))
 $(eval $(call BuildModule,calendar,Calendar))
 $(eval $(call BuildModule,ctype,Ctype))
 $(eval $(call BuildModule,curl,cURL,+PACKAGE_php5-mod-curl:libcurl))
-$(eval $(call BuildModule,fileinfo,Fileinfo,+PACKAGE_php5-mod-fileinfo:libmagic))
 $(eval $(call BuildModule,dom,DOM,+@PHP5_LIBXML +PACKAGE_php5-mod-dom:libxml2))
 $(eval $(call BuildModule,exif,EXIF))
+$(eval $(call BuildModule,fileinfo,Fileinfo))
 $(eval $(call BuildModule,ftp,FTP,+PACKAGE_php5-mod-ftp:libopenssl))
-$(eval $(call BuildModule,gettext,Gettext,+PACKAGE_php5-mod-gettext:libintl-full))
 $(eval $(call BuildModule,gd,GD graphics,+PACKAGE_php5-mod-gd:libjpeg +PACKAGE_php5-mod-gd:libpng))
+$(eval $(call BuildModule,gettext,Gettext,+PACKAGE_php5-mod-gettext:libintl-full))
 $(eval $(call BuildModule,gmp,GMP,+PACKAGE_php5-mod-gmp:libgmp))
 $(eval $(call BuildModule,hash,Hash))
-$(eval $(call BuildModule,iconv,iConv,+PACKAGE_php5-mod-iconv:libiconv))
+$(eval $(call BuildModule,iconv,iConv,$(ICONV_DEPENDS)))
 $(eval $(call BuildModule,json,JSON))
 $(eval $(call BuildModule,ldap,LDAP,+PACKAGE_php5-mod-ldap:libopenldap +PACKAGE_php5-mod-ldap:libsasl2))
 $(eval $(call BuildModule,mbstring,MBString))
@@ -520,19 +545,19 @@ $(eval $(call BuildModule,pcntl,PCNTL))
 $(eval $(call BuildModule,pdo,PHP Data Objects))
 $(eval $(call BuildModule,pdo-mysql,PDO driver for MySQL,+php5-mod-pdo +PACKAGE_php5-mod-pdo-mysql:libmysqlclient))
 $(eval $(call BuildModule,pdo-pgsql,PDO driver for PostgreSQL,+php5-mod-pdo +PACKAGE_php5-mod-pdo-pgsql:libpq))
-$(eval $(call BuildModule,pdo-sqlite,PDO driver for SQLite 3.x,+php5-mod-pdo +PACKAGE_php5-mod-pdo-sqlite:libsqlite3 +PACKAGE_php5-mod-pdo-sqlite:libpthread +PACKAGE_php5-mod-pdo-sqlite:librt))
+$(eval $(call BuildModule,pdo-sqlite,PDO driver for SQLite 3.x,+php5-mod-pdo +PACKAGE_php5-mod-pdo-sqlite:libsqlite3 +PACKAGE_php5-mod-pdo-sqlite:librt))
 $(eval $(call BuildModule,pgsql,PostgreSQL,+PACKAGE_php5-mod-pgsql:libpq))
 $(eval $(call BuildModule,session,Session))
 $(eval $(call BuildModule,shmop,Shared Memory))
 $(eval $(call BuildModule,simplexml,SimpleXML,+@PHP5_LIBXML +PACKAGE_php5-mod-simplexml:libxml2))
 $(eval $(call BuildModule,soap,SOAP,+@PHP5_LIBXML +PACKAGE_php5-mod-soap:libxml2))
 $(eval $(call BuildModule,sockets,Sockets))
-$(eval $(call BuildModule,sqlite3,SQLite3,+PACKAGE_php5-mod-sqlite3:libsqlite3 +PACKAGE_php5-mod-sqlite3:libpthread))
+$(eval $(call BuildModule,sqlite3,SQLite3,+PACKAGE_php5-mod-sqlite3:libsqlite3))
 $(eval $(call BuildModule,sysvmsg,System V messages))
 $(eval $(call BuildModule,sysvsem,System V shared memory))
 $(eval $(call BuildModule,sysvshm,System V semaphore))
 $(eval $(call BuildModule,tokenizer,Tokenizer))
 $(eval $(call BuildModule,xml,XML,+PHP5_LIBXML:libxml2 +!PHP5_LIBXML:libexpat))
-$(eval $(call BuildModule,xmlreader,XMLReader,+@PHP5_LIBXML +PACKAGE_php5-mod-xmlreader:libxml2 +PACKAGE_php5-mod-xmlreader:libiconv))
-$(eval $(call BuildModule,xmlwriter,XMLWriter,+@PHP5_LIBXML +PACKAGE_php5-mod-xmlwriter:libxml2 +PACKAGE_php5-mod-xmlwriter:libiconv))
+$(eval $(call BuildModule,xmlreader,XMLReader,+@PHP5_LIBXML +PACKAGE_php5-mod-xmlreader:libxml2))
+$(eval $(call BuildModule,xmlwriter,XMLWriter,+@PHP5_LIBXML +PACKAGE_php5-mod-xmlwriter:libxml2))
 $(eval $(call BuildModule,zip,ZIP,+PACKAGE_php5-mod-zip:zlib))
diff --git a/lang/php5/files/php5-fpm-www.conf b/lang/php5/files/php5-fpm-www.conf
new file mode 100644 (file)
index 0000000..4776bba
--- /dev/null
@@ -0,0 +1,392 @@
+; Start a new pool named 'www'.
+; the variable $pool can we used in any directive and will be replaced by the
+; pool name ('www' here)
+[www]
+
+; Per pool prefix
+; It only applies on the following directives:
+; - 'slowlog'
+; - 'listen' (unixsocket)
+; - 'chroot'
+; - 'chdir'
+; - 'php_values'
+; - 'php_admin_values'
+; When not set, the global prefix (or /usr) applies instead.
+; Note: This directive can also be relative to the global prefix.
+; Default Value: none
+;prefix = /path/to/pools/$pool
+
+; Unix user/group of processes
+; Note: The user is mandatory. If the group is not set, the default user's group
+;       will be used.
+user = nobody
+;group =
+
+; The address on which to accept FastCGI requests.
+; Valid syntaxes are:
+;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on
+;                            a specific port;
+;   'port'                 - to listen on a TCP socket to all addresses on a
+;                            specific port;
+;   '/path/to/unix/socket' - to listen on a unix socket.
+; Note: This value is mandatory.
+listen = /var/run/php5-fpm.sock
+
+; Set listen(2) backlog.
+; Default Value: 128 (-1 on FreeBSD and OpenBSD)
+;listen.backlog = 128
+
+; Set permissions for unix socket, if one is used. In Linux, read/write
+; permissions must be set in order to allow connections from a web server. Many
+; BSD-derived systems allow connections regardless of permissions. 
+; Default Values: user and group are set as the running user
+;                 mode is set to 0666
+;listen.owner = www-data
+;listen.group = www-data
+;listen.mode = 0666
+
+; List of ipv4 addresses of FastCGI clients which are allowed to connect.
+; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
+; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
+; must be separated by a comma. If this value is left blank, connections will be
+; accepted from any ip address.
+; Default Value: any
+;listen.allowed_clients = 127.0.0.1
+
+; Specify the nice(2) priority to apply to the pool processes (only if set)
+; The value can vary from -19 (highest priority) to 20 (lower priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool processes will inherit the master process priority
+;         unless it specified otherwise
+; Default Value: no set
+; priority = -19
+
+; Choose how the process manager will control the number of child processes.
+; Possible Values:
+;   static  - a fixed number (pm.max_children) of child processes;
+;   dynamic - the number of child processes are set dynamically based on the
+;             following directives. With this process management, there will be
+;             always at least 1 children.
+;             pm.max_children      - the maximum number of children that can
+;                                    be alive at the same time.
+;             pm.start_servers     - the number of children created on startup.
+;             pm.min_spare_servers - the minimum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is less than this
+;                                    number then some children will be created.
+;             pm.max_spare_servers - the maximum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is greater than this
+;                                    number then some children will be killed.
+;  ondemand - no children are created at startup. Children will be forked when
+;             new requests will connect. The following parameter are used:
+;             pm.max_children           - the maximum number of children that
+;                                         can be alive at the same time.
+;             pm.process_idle_timeout   - The number of seconds after which
+;                                         an idle process will be killed.
+; Note: This value is mandatory.
+pm = dynamic
+
+; The number of child processes to be created when pm is set to 'static' and the
+; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
+; This value sets the limit on the number of simultaneous requests that will be
+; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
+; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
+; CGI. The below defaults are based on a server without much resources. Don't
+; forget to tweak pm.* to fit your needs.
+; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
+; Note: This value is mandatory.
+pm.max_children = 5
+
+; The number of child processes created on startup.
+; Note: Used only when pm is set to 'dynamic'
+; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
+pm.start_servers = 2
+
+; The desired minimum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.min_spare_servers = 1
+
+; The desired maximum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.max_spare_servers = 3
+
+; The number of seconds after which an idle process will be killed.
+; Note: Used only when pm is set to 'ondemand'
+; Default Value: 10s
+;pm.process_idle_timeout = 10s;
+
+; The number of requests each child process should execute before respawning.
+; This can be useful to work around memory leaks in 3rd party libraries. For
+; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
+; Default Value: 0
+;pm.max_requests = 500
+
+; The URI to view the FPM status page. If this value is not set, no URI will be
+; recognized as a status page. It shows the following informations:
+;   pool                 - the name of the pool;
+;   process manager      - static, dynamic or ondemand;
+;   start time           - the date and time FPM has started;
+;   start since          - number of seconds since FPM has started;
+;   accepted conn        - the number of request accepted by the pool;
+;   listen queue         - the number of request in the queue of pending
+;                          connections (see backlog in listen(2));
+;   max listen queue     - the maximum number of requests in the queue
+;                          of pending connections since FPM has started;
+;   listen queue len     - the size of the socket queue of pending connections;
+;   idle processes       - the number of idle processes;
+;   active processes     - the number of active processes;
+;   total processes      - the number of idle + active processes;
+;   max active processes - the maximum number of active processes since FPM
+;                          has started;
+;   max children reached - number of times, the process limit has been reached,
+;                          when pm tries to start more children (works only for
+;                          pm 'dynamic' and 'ondemand');
+; Value are updated in real time.
+; Example output:
+;   pool:                 www
+;   process manager:      static
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          62636
+;   accepted conn:        190460
+;   listen queue:         0
+;   max listen queue:     1
+;   listen queue len:     42
+;   idle processes:       4
+;   active processes:     11
+;   total processes:      15
+;   max active processes: 12
+;   max children reached: 0
+;
+; By default the status page output is formatted as text/plain. Passing either
+; 'html', 'xml' or 'json' in the query string will return the corresponding
+; output syntax. Example:
+;   http://www.foo.bar/status
+;   http://www.foo.bar/status?json
+;   http://www.foo.bar/status?html
+;   http://www.foo.bar/status?xml
+;
+; By default the status page only outputs short status. Passing 'full' in the
+; query string will also return status for each pool process.
+; Example: 
+;   http://www.foo.bar/status?full
+;   http://www.foo.bar/status?json&full
+;   http://www.foo.bar/status?html&full
+;   http://www.foo.bar/status?xml&full
+; The Full status returns for each process:
+;   pid                  - the PID of the process;
+;   state                - the state of the process (Idle, Running, ...);
+;   start time           - the date and time the process has started;
+;   start since          - the number of seconds since the process has started;
+;   requests             - the number of requests the process has served;
+;   request duration     - the duration in µs of the requests;
+;   request method       - the request method (GET, POST, ...);
+;   request URI          - the request URI with the query string;
+;   content length       - the content length of the request (only with POST);
+;   user                 - the user (PHP_AUTH_USER) (or '-' if not set);
+;   script               - the main script called (or '-' if not set);
+;   last request cpu     - the %cpu the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because CPU calculation is done when the request
+;                          processing has terminated;
+;   last request memory  - the max amount of memory the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because memory calculation is done when the request
+;                          processing has terminated;
+; If the process is in Idle state, then informations are related to the
+; last request the process has served. Otherwise informations are related to
+; the current request being served.
+; Example output:
+;   ************************
+;   pid:                  31330
+;   state:                Running
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          63087
+;   requests:             12808
+;   request duration:     1250261
+;   request method:       GET
+;   request URI:          /test_mem.php?N=10000
+;   content length:       0
+;   user:                 -
+;   script:               /home/fat/web/docs/php/test_mem.php
+;   last request cpu:     0.00
+;   last request memory:  0
+;
+; Note: There is a real-time FPM status monitoring sample web page available
+;       It's available in: ${prefix}/share/fpm/status.html
+;
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set 
+;pm.status_path = /status
+
+; The ping URI to call the monitoring page of FPM. If this value is not set, no
+; URI will be recognized as a ping page. This could be used to test from outside
+; that FPM is alive and responding, or to
+; - create a graph of FPM availability (rrd or such);
+; - remove a server from a group if it is not responding (load balancing);
+; - trigger alerts for the operating team (24/7).
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set
+;ping.path = /ping
+
+; This directive may be used to customize the response of a ping request. The
+; response is formatted as text/plain with a 200 response code.
+; Default Value: pong
+;ping.response = pong
+
+; The access log file
+; Default: not set
+;access.log = log/$pool.access.log
+
+; The access log format.
+; The following syntax is allowed
+;  %%: the '%' character
+;  %C: %CPU used by the request
+;      it can accept the following format:
+;      - %{user}C for user CPU only
+;      - %{system}C for system CPU only
+;      - %{total}C  for user + system CPU (default)
+;  %d: time taken to serve the request
+;      it can accept the following format:
+;      - %{seconds}d (default)
+;      - %{miliseconds}d
+;      - %{mili}d
+;      - %{microseconds}d
+;      - %{micro}d
+;  %e: an environment variable (same as $_ENV or $_SERVER)
+;      it must be associated with embraces to specify the name of the env
+;      variable. Some exemples:
+;      - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
+;      - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
+;  %f: script filename
+;  %l: content-length of the request (for POST request only)
+;  %m: request method
+;  %M: peak of memory allocated by PHP
+;      it can accept the following format:
+;      - %{bytes}M (default)
+;      - %{kilobytes}M
+;      - %{kilo}M
+;      - %{megabytes}M
+;      - %{mega}M
+;  %n: pool name
+;  %o: ouput header
+;      it must be associated with embraces to specify the name of the header:
+;      - %{Content-Type}o
+;      - %{X-Powered-By}o
+;      - %{Transfert-Encoding}o
+;      - ....
+;  %p: PID of the child that serviced the request
+;  %P: PID of the parent of the child that serviced the request
+;  %q: the query string 
+;  %Q: the '?' character if query string exists
+;  %r: the request URI (without the query string, see %q and %Q)
+;  %R: remote IP address
+;  %s: status (response code)
+;  %t: server time the request was received
+;      it can accept a strftime(3) format:
+;      %d/%b/%Y:%H:%M:%S %z (default)
+;  %T: time the log has been written (the request has finished)
+;      it can accept a strftime(3) format:
+;      %d/%b/%Y:%H:%M:%S %z (default)
+;  %u: remote user
+;
+; Default: "%R - %u %t \"%m %r\" %s"
+;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
+
+; The log file for slow requests
+; Default Value: not set
+; Note: slowlog is mandatory if request_slowlog_timeout is set
+;slowlog = log/$pool.log.slow
+
+; The timeout for serving a single request after which a PHP backtrace will be
+; dumped to the 'slowlog' file. A value of '0s' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_slowlog_timeout = 0
+
+; The timeout for serving a single request after which the worker process will
+; be killed. This option should be used when the 'max_execution_time' ini option
+; does not stop script execution for some reason. A value of '0' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_terminate_timeout = 0
+
+; Set open file descriptor rlimit.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Chroot to this directory at the start. This value must be defined as an
+; absolute path. When this value is not set, chroot is not used.
+; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
+; of its subdirectories. If the pool prefix is not set, the global prefix
+; will be used instead.
+; Note: chrooting is a great security feature and should be used whenever
+;       possible. However, all PHP paths will be relative to the chroot
+;       (error_log, sessions.save_path, ...).
+; Default Value: not set
+;chroot =
+
+; Chdir to this directory at the start.
+; Note: relative path can be used.
+; Default Value: current directory or / when chroot
+chdir = /
+
+; Redirect worker stdout and stderr into main error log. If not set, stdout and
+; stderr will be redirected to /dev/null according to FastCGI specs.
+; Note: on highloaded environement, this can cause some delay in the page
+; process time (several ms).
+; Default Value: no
+;catch_workers_output = yes
+
+; Limits the extensions of the main script FPM will allow to parse. This can
+; prevent configuration mistakes on the web server side. You should only limit
+; FPM to .php extensions to prevent malicious users to use other extensions to
+; exectute php code.
+; Note: set an empty value to allow all extensions.
+; Default Value: .php
+;security.limit_extensions = .php .php3 .php4 .php5
+
+; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
+; the current environment.
+; Default Value: clean env
+;env[HOSTNAME] = $HOSTNAME
+;env[PATH] = /usr/local/bin:/usr/bin:/bin
+;env[TMP] = /tmp
+;env[TMPDIR] = /tmp
+;env[TEMP] = /tmp
+
+; Additional php.ini defines, specific to this pool of workers. These settings
+; overwrite the values previously defined in the php.ini. The directives are the
+; same as the PHP SAPI:
+;   php_value/php_flag             - you can set classic ini defines which can
+;                                    be overwritten from PHP call 'ini_set'. 
+;   php_admin_value/php_admin_flag - these directives won't be overwritten by
+;                                     PHP call 'ini_set'
+; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
+
+; Defining 'extension' will load the corresponding shared extension from
+; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
+; overwrite previously defined php.ini values, but will append the new value
+; instead.
+
+; Note: path INI options can be relative and will be expanded with the prefix
+; (pool, global or /usr)
+
+; Default Value: nothing is defined by default except the values in php.ini and
+;                specified at startup with the -d argument
+;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
+;php_flag[display_errors] = off
+;php_admin_value[error_log] = /var/log/fpm-php.www.log
+;php_admin_flag[log_errors] = on
+;php_admin_value[memory_limit] = 32M
diff --git a/lang/php5/files/php5-fpm.conf b/lang/php5/files/php5-fpm.conf
new file mode 100644 (file)
index 0000000..00c8e4f
--- /dev/null
@@ -0,0 +1,121 @@
+;;;;;;;;;;;;;;;;;;;;;
+; FPM Configuration ;
+;;;;;;;;;;;;;;;;;;;;;
+
+; All relative paths in this configuration file are relative to PHP's install
+; prefix (/usr). This prefix can be dynamically changed by using the
+; '-p' argument from the command line.
+
+; Include one or more files. If glob(3) exists, it is used to include a bunch of
+; files from a glob(3) pattern. This directive can be used everywhere in the
+; file.
+; Relative path can also be used. They will be prefixed by:
+;  - the global prefix if it's been set (-p argument)
+;  - /usr otherwise
+;include=/etc/php5/fpm/*.conf
+
+;;;;;;;;;;;;;;;;;;
+; Global Options ;
+;;;;;;;;;;;;;;;;;;
+
+[global]
+; Pid file
+; Note: the default prefix is /var
+; Default Value: none
+pid = /var/run/php5-fpm.pid
+
+; Error log file
+; If it's set to "syslog", log is sent to syslogd instead of being written
+; in a local file.
+; Note: the default prefix is /var
+; Default Value: log/php-fpm.log
+error_log = /var/log/php5-fpm.log
+
+; syslog_facility is used to specify what type of program is logging the
+; message. This lets syslogd specify that messages from different facilities
+; will be handled differently.
+; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
+; Default Value: daemon
+;syslog.facility = daemon
+
+; syslog_ident is prepended to every message. If you have multiple FPM
+; instances running on the same server, you can change the default value
+; which must suit common needs.
+; Default Value: php-fpm
+;syslog.ident = php-fpm
+
+; Log level
+; Possible Values: alert, error, warning, notice, debug
+; Default Value: notice
+;log_level = notice
+
+; If this number of child processes exit with SIGSEGV or SIGBUS within the time
+; interval set by emergency_restart_interval then FPM will restart. A value
+; of '0' means 'Off'.
+; Default Value: 0
+;emergency_restart_threshold = 0
+
+; Interval of time used by emergency_restart_interval to determine when 
+; a graceful restart will be initiated.  This can be useful to work around
+; accidental corruptions in an accelerator's shared memory.
+; Available Units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;emergency_restart_interval = 0
+
+; Time limit for child processes to wait for a reaction on signals from master.
+; Available units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;process_control_timeout = 0
+
+; The maximum number of processes FPM will fork. This has been design to control
+; the global number of processes when using dynamic PM within a lot of pools.
+; Use it with caution.
+; Note: A value of 0 indicates no limit
+; Default Value: 0
+; process.max = 128
+
+; Specify the nice(2) priority to apply to the master process (only if set)
+; The value can vary from -19 (highest priority) to 20 (lower priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool process will inherit the master process priority
+;         unless it specified otherwise
+; Default Value: no set
+; process.priority = -19
+
+; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
+; Default Value: yes
+;daemonize = yes
+
+; Set open file descriptor rlimit for the master process.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit for the master process.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Specify the event mechanism FPM will use. The following is available:
+; - select     (any POSIX os)
+; - poll       (any POSIX os)
+; - epoll      (linux >= 2.5.44)
+; - kqueue     (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
+; - /dev/poll  (Solaris >= 7)
+; - port       (Solaris >= 10)
+; Default Value: not set (auto detection)
+; events.mechanism = epoll
+
+;;;;;;;;;;;;;;;;;;;;
+; Pool Definitions ;
+;;;;;;;;;;;;;;;;;;;;
+
+; Multiple pools of child processes may be started with different listening
+; ports and different management options.  The name of the pool will be
+; used in logs and stats. There is no limitation on the number of pools which
+; FPM can handle. Your system will tell you anyway :)
+
+; To configure the pools it is recommended to have one .conf file per
+; pool in the following directory:
+include=/etc/php5-fpm.d/*.conf
diff --git a/lang/php5/files/php5-fpm.config b/lang/php5/files/php5-fpm.config
new file mode 100644 (file)
index 0000000..4f40c92
--- /dev/null
@@ -0,0 +1,2 @@
+config php5-fpm
+       option enabled 1
diff --git a/lang/php5/files/php5-fpm.init b/lang/php5/files/php5-fpm.init
new file mode 100644 (file)
index 0000000..aa5397a
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=50
+
+PROG=/usr/bin/php-fpm
+CONFIG=/etc/php5-fpm.conf
+
+SERVICE_PID_FILE=/var/run/php5-fpm.pid
+
+start_instance() {
+       local section="$1"
+       local enabled
+
+       config_get_bool enabled "$section" 'enabled' 0
+
+       [ $enabled -gt 0 ] || return 1
+
+       service_start $PROG -y $CONFIG -g $SERVICE_PID_FILE
+}
+
+start() {
+       config_load 'php5-fpm'
+       config_foreach start_instance 'php5-fpm'
+}
+
+stop() {
+       service_stop $PROG
+}
diff --git a/lang/php5/patches/090-restore-sqlite2.patch b/lang/php5/patches/090-restore-sqlite2.patch
deleted file mode 100644 (file)
index 27bcec5..0000000
+++ /dev/null
@@ -1,50845 +0,0 @@
---- /dev/null
-+++ b/ext/sqlite/config.m4
-@@ -0,0 +1,157 @@
-+dnl $Id$
-+dnl config.m4 for extension sqlite
-+dnl vim:et:ts=2:sw=2
-+
-+PHP_ARG_WITH(sqlite, for sqlite support,
-+[  --without-sqlite=DIR    Do not include sqlite support.  DIR is the sqlite base
-+                          install directory [BUNDLED]], yes)
-+
-+PHP_ARG_ENABLE(sqlite-utf8, whether to enable UTF-8 support in sqlite (default: ISO-8859-1),
-+[  --enable-sqlite-utf8      SQLite: Enable UTF-8 support for SQLite], no, no)
-+
-+
-+
-+dnl
-+dnl PHP_PROG_LEMON
-+dnl
-+dnl Search for lemon binary and check its version
-+dnl
-+AC_DEFUN([PHP_PROG_LEMON],[
-+  # we only support certain lemon versions
-+  lemon_version_list="1.0"
-+
-+  AC_CHECK_PROG(LEMON, lemon, lemon)
-+  if test "$LEMON"; then
-+    AC_CACHE_CHECK([for lemon version], php_cv_lemon_version, [
-+      lemon_version=`$LEMON -x 2>/dev/null | $SED -e 's/^.* //'`
-+      php_cv_lemon_version=invalid
-+      for lemon_check_version in $lemon_version_list; do
-+        if test "$lemon_version" = "$lemon_check_version"; then
-+          php_cv_lemon_version="$lemon_check_version (ok)"
-+        fi
-+      done
-+    ])
-+  else
-+    lemon_version=none
-+  fi
-+  case $php_cv_lemon_version in
-+    ""|invalid[)]
-+      lemon_msg="lemon versions supported for regeneration of libsqlite parsers: $lemon_version_list (found: $lemon_version)."
-+      AC_MSG_WARN([$lemon_msg])
-+      LEMON="exit 0;"
-+      ;;
-+  esac
-+  PHP_SUBST(LEMON)
-+])
-+
-+
-+if test "$PHP_SQLITE" != "no"; then
-+  if test "$PHP_PDO" != "no"; then
-+    PHP_CHECK_PDO_INCLUDES([], [AC_MSG_WARN([Cannot find php_pdo_driver.h.])])
-+    if test -n "$pdo_inc_path"; then
-+      AC_DEFINE([PHP_SQLITE2_HAVE_PDO], [1], [Have PDO])
-+      pdo_inc_path="-I$pdo_inc_path"
-+    fi
-+  fi  
-+
-+  if test "$PHP_SQLITE" != "yes"; then
-+    SEARCH_PATH="/usr/local /usr"
-+    SEARCH_FOR="/include/sqlite.h"
-+    if test -r $PHP_SQLITE/; then # path given as parameter
-+      SQLITE_DIR=$PHP_SQLITE
-+    else # search default path list
-+      AC_MSG_CHECKING([for sqlite files in default path])
-+      for i in $SEARCH_PATH ; do
-+        if test -r $i/$SEARCH_FOR; then
-+          SQLITE_DIR=$i
-+          AC_MSG_RESULT(found in $i)
-+        fi
-+      done
-+    fi
-+  
-+    if test -z "$SQLITE_DIR"; then
-+      AC_MSG_RESULT([not found])
-+      AC_MSG_ERROR([Please reinstall the sqlite distribution from http://www.sqlite.org])
-+    fi
-+
-+    PHP_CHECK_LIBRARY(sqlite, sqlite_open, [
-+      PHP_ADD_LIBRARY_WITH_PATH(sqlite, $SQLITE_DIR/$PHP_LIBDIR, SQLITE_SHARED_LIBADD)
-+      PHP_ADD_INCLUDE($SQLITE_DIR/include)
-+    ],[
-+      AC_MSG_ERROR([wrong sqlite lib version or lib not found])
-+    ],[
-+      -L$SQLITE_DIR/$PHP_LIBDIR -lm
-+    ])
-+    SQLITE_MODULE_TYPE=external
-+    PHP_SQLITE_CFLAGS=$pdo_inc_path
-+    sqlite_extra_sources="libsqlite/src/encode.c"
-+  else
-+    # use bundled library
-+    PHP_PROG_LEMON
-+    SQLITE_MODULE_TYPE=builtin
-+    PHP_SQLITE_CFLAGS="-I@ext_srcdir@/libsqlite/src -I@ext_builddir@/libsqlite/src $pdo_inc_path"
-+    sqlite_extra_sources="libsqlite/src/opcodes.c \
-+        libsqlite/src/parse.c libsqlite/src/encode.c \
-+        libsqlite/src/auth.c libsqlite/src/btree.c libsqlite/src/build.c \
-+        libsqlite/src/delete.c libsqlite/src/expr.c libsqlite/src/func.c \
-+        libsqlite/src/hash.c libsqlite/src/insert.c libsqlite/src/main.c \
-+        libsqlite/src/os.c libsqlite/src/pager.c \
-+        libsqlite/src/printf.c libsqlite/src/random.c \
-+        libsqlite/src/select.c libsqlite/src/table.c libsqlite/src/tokenize.c \
-+        libsqlite/src/update.c libsqlite/src/util.c libsqlite/src/vdbe.c \
-+        libsqlite/src/attach.c libsqlite/src/btree_rb.c libsqlite/src/pragma.c \
-+        libsqlite/src/vacuum.c libsqlite/src/copy.c \
-+        libsqlite/src/vdbeaux.c libsqlite/src/date.c \
-+        libsqlite/src/where.c libsqlite/src/trigger.c"
-+  fi
-+  dnl
-+  dnl Common for both bundled/external
-+  dnl
-+  sqlite_sources="sqlite.c sess_sqlite.c pdo_sqlite2.c $sqlite_extra_sources" 
-+  PHP_NEW_EXTENSION(sqlite, $sqlite_sources, $ext_shared,,$PHP_SQLITE_CFLAGS)
-+  PHP_ADD_EXTENSION_DEP(sqlite, spl, true)
-+  PHP_ADD_EXTENSION_DEP(sqlite, pdo, true)
-+
-+  PHP_ADD_MAKEFILE_FRAGMENT
-+  PHP_SUBST(SQLITE_SHARED_LIBADD)
-+  PHP_INSTALL_HEADERS([$ext_builddir/libsqlite/src/sqlite.h])
-+  
-+  if test "$SQLITE_MODULE_TYPE" = "builtin"; then
-+    PHP_ADD_BUILD_DIR($ext_builddir/libsqlite/src, 1)
-+    AC_CHECK_SIZEOF(char *, 4)
-+    AC_DEFINE(SQLITE_PTR_SZ, SIZEOF_CHAR_P, [Size of a pointer])
-+    dnl use latin 1 for SQLite older than 2.8.9; the utf-8 handling 
-+    dnl in funcs.c uses assert(), which is a bit silly and something 
-+    dnl we want to avoid. This assert() was removed in SQLite 2.8.9.
-+    if test "$PHP_SQLITE_UTF8" = "yes"; then
-+      SQLITE_ENCODING="UTF8"
-+      AC_DEFINE(SQLITE_UTF8, 1, [ ])
-+    else
-+      SQLITE_ENCODING="ISO8859"
-+    fi
-+    PHP_SUBST(SQLITE_ENCODING)
-+
-+    SQLITE_VERSION=`cat $ext_srcdir/libsqlite/VERSION`
-+    PHP_SUBST(SQLITE_VERSION)
-+
-+    sed -e s/--VERS--/$SQLITE_VERSION/ -e s/--ENCODING--/$SQLITE_ENCODING/ $ext_srcdir/libsqlite/src/sqlite.h.in > $ext_builddir/libsqlite/src/sqlite.h
-+
-+    if test "$ext_shared" = "no" || test "$ext_srcdir" != "$abs_srcdir"; then
-+      echo '#include <php_config.h>' > $ext_builddir/libsqlite/src/config.h
-+    else
-+      echo "#include \"$abs_builddir/config.h\"" > $ext_builddir/libsqlite/src/config.h
-+    fi
-+    
-+    cat >> $ext_builddir/libsqlite/src/config.h <<EOF
-+#if ZTS
-+# define THREADSAFE 1
-+#endif
-+#if !ZEND_DEBUG
-+# define NDEBUG
-+#endif
-+EOF
-+  fi
-+  
-+  AC_CHECK_FUNCS(usleep nanosleep)
-+  AC_CHECK_HEADERS(time.h)
-+fi
---- /dev/null
-+++ b/ext/sqlite/config.w32
-@@ -0,0 +1,39 @@
-+// $Id$
-+// vim:ft=javascript
-+
-+ARG_WITH("sqlite", "SQLite support", "no");
-+
-+if (PHP_SQLITE != "no") {
-+      copy_and_subst(configure_module_dirname + "\\libsqlite\\src\\sqlite.h.in",
-+              configure_module_dirname + "\\libsqlite\\src\\sqlite.h", new Array(
-+                      "--VERS--", file_get_contents(configure_module_dirname + "\\libsqlite\\VERSION").replace(new RegExp("[\r\n]+", "g"), ""),
-+                      "--ENCODING--", "ISO8859"
-+              ));
-+      
-+      FSO.CopyFile(configure_module_dirname + "\\libsqlite\\src\\sqlite_config.w32.h",
-+              configure_module_dirname + "\\libsqlite\\src\\config.h");
-+
-+      if (FSO.FileExists(configure_module_dirname + "\\..\\pdo\\php_pdo_driver.h")) {
-+              PHP_SQLITE2_PDO_CFLAGS = " /DPHP_SQLITE2_HAVE_PDO=1 /I " + configure_module_dirname + "\\..";
-+              ADD_EXTENSION_DEP('sqlite', 'pdo')
-+      } else {
-+              PHP_SQLITE2_PDO_CFLAGS = "";
-+      }
-+      
-+      EXTENSION("sqlite", "sqlite.c sess_sqlite.c pdo_sqlite2.c", null,
-+              "/D PHP_SQLITE_EXPORTS /I " + configure_module_dirname + "/libsqlite/src" +
-+              PHP_SQLITE2_PDO_CFLAGS);
-+              
-+      
-+      ADD_SOURCES(configure_module_dirname + "/libsqlite/src", "opcodes.c parse.c encode.c \
-+              auth.c btree.c build.c delete.c expr.c func.c hash.c insert.c \
-+              main.c os.c pager.c printf.c random.c select.c table.c tokenize.c \
-+              update.c util.c vdbe.c attach.c btree_rb.c pragma.c vacuum.c \
-+              copy.c where.c trigger.c vdbeaux.c date.c", "sqlite");
-+
-+      AC_DEFINE("HAVE_SQLITE", 1, "SQLite support");
-+      if (!PHP_SQLITE_SHARED) {
-+              ADD_DEF_FILE(configure_module_dirname + "\\php_sqlite.def");
-+      }
-+      ADD_EXTENSION_DEP('sqlite', 'spl')
-+}
---- /dev/null
-+++ b/ext/sqlite/CREDITS
-@@ -0,0 +1,2 @@
-+SQLite
-+Wez Furlong, Tal Peer, Marcus Boerger, Ilia Alshanetsky
---- /dev/null
-+++ b/ext/sqlite/libsqlite/README
-@@ -0,0 +1,37 @@
-+This directory contains source code to 
-+
-+    SQLite: An Embeddable SQL Database Engine
-+
-+To compile the project, first create a directory in which to place
-+the build products.  It is recommended, but not required, that the
-+build directory be separate from the source directory.  Cd into the
-+build directory and then from the build directory run the configure
-+script found at the root of the source tree.  Then run "make".
-+
-+For example:
-+
-+    tar xzf sqlite.tar.gz    ;#  Unpack the source tree into "sqlite"
-+    mkdir bld                ;#  Build will occur in a sibling directory
-+    cd bld                   ;#  Change to the build directory
-+    ../sqlite/configure      ;#  Run the configure script
-+    make                     ;#  Run the makefile.
-+
-+The configure script uses autoconf 2.50 and libtool.  If the configure
-+script does not work out for you, there is a generic makefile named
-+"Makefile.linux-gcc" in the top directory of the source tree that you
-+can copy and edit to suite your needs.  Comments on the generic makefile
-+show what changes are needed.
-+
-+The linux binaries on the website are created using the generic makefile,
-+not the configure script.  The configure script is unmaintained.  (You
-+can volunteer to take over maintenance of the configure script, if you want!)
-+The windows binaries on the website are created using MinGW32 configured
-+as a cross-compiler running under Linux.  For details, see the ./publish.sh
-+script at the top-level of the source tree.
-+
-+Contacts:
-+
-+   http://www.sqlite.org/
-+   http://www.hwaci.com/sw/sqlite/
-+   http://groups.yahoo.com/group/sqlite/
-+   drh@hwaci.com
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/attach.c
-@@ -0,0 +1,311 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** This routine is called by the parser to process an ATTACH statement:
-+**
-+**     ATTACH DATABASE filename AS dbname
-+**
-+** The pFilename and pDbname arguments are the tokens that define the
-+** filename and dbname in the ATTACH statement.
-+*/
-+void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
-+  Db *aNew;
-+  int rc, i;
-+  char *zFile, *zName;
-+  sqlite *db;
-+  Vdbe *v;
-+
-+  v = sqliteGetVdbe(pParse);
-+  sqliteVdbeAddOp(v, OP_Halt, 0, 0);
-+  if( pParse->explain ) return;
-+  db = pParse->db;
-+  if( db->file_format<4 ){
-+    sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
-+       "older format master database", 0);
-+    pParse->rc = SQLITE_ERROR;
-+    return;
-+  }
-+  if( db->nDb>=MAX_ATTACHED+2 ){
-+    sqliteErrorMsg(pParse, "too many attached databases - max %d", 
-+       MAX_ATTACHED);
-+    pParse->rc = SQLITE_ERROR;
-+    return;
-+  }
-+
-+  zFile = 0;
-+  sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
-+  if( zFile==0 ) return;
-+  sqliteDequote(zFile);
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
-+    sqliteFree(zFile);
-+    return;
-+  }
-+#endif /* SQLITE_OMIT_AUTHORIZATION */
-+
-+  zName = 0;
-+  sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
-+  if( zName==0 ) return;
-+  sqliteDequote(zName);
-+  for(i=0; i<db->nDb; i++){
-+    if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
-+      sqliteErrorMsg(pParse, "database %z is already in use", zName);
-+      pParse->rc = SQLITE_ERROR;
-+      sqliteFree(zFile);
-+      return;
-+    }
-+  }
-+
-+  if( db->aDb==db->aDbStatic ){
-+    aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
-+    if( aNew==0 ) return;
-+    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
-+  }else{
-+    aNew = sqliteRealloc(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));
-+  sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
-+  sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
-+  sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
-+  sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
-+  aNew->zName = zName;
-+  rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
-+  if( rc ){
-+    sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
-+  }
-+#if SQLITE_HAS_CODEC
-+  {
-+    extern int sqliteCodecAttach(sqlite*, int, void*, int);
-+    char *zKey = 0;
-+    int nKey;
-+    if( pKey && pKey->z && pKey->n ){
-+      sqliteSetNString(&zKey, pKey->z, pKey->n, 0);
-+      sqliteDequote(zKey);
-+      nKey = strlen(zKey);
-+    }else{
-+      zKey = 0;
-+      nKey = 0;
-+    }
-+    sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
-+  }
-+#endif
-+  sqliteFree(zFile);
-+  db->flags &= ~SQLITE_Initialized;
-+  if( pParse->nErr ) return;
-+  if( rc==SQLITE_OK ){
-+    rc = sqliteInit(pParse->db, &pParse->zErrMsg);
-+  }
-+  if( rc ){
-+    int i = db->nDb - 1;
-+    assert( i>=2 );
-+    if( db->aDb[i].pBt ){
-+      sqliteBtreeClose(db->aDb[i].pBt);
-+      db->aDb[i].pBt = 0;
-+    }
-+    sqliteResetInternalSchema(db, 0);
-+    pParse->nErr++;
-+    pParse->rc = SQLITE_ERROR;
-+  }
-+}
-+
-+/*
-+** This routine is called by the parser to process a DETACH statement:
-+**
-+**    DETACH DATABASE dbname
-+**
-+** The pDbname argument is the name of the database in the DETACH statement.
-+*/
-+void sqliteDetach(Parse *pParse, Token *pDbname){
-+  int i;
-+  sqlite *db;
-+  Vdbe *v;
-+  Db *pDb;
-+
-+  v = sqliteGetVdbe(pParse);
-+  sqliteVdbeAddOp(v, OP_Halt, 0, 0);
-+  if( pParse->explain ) return;
-+  db = pParse->db;
-+  for(i=0; i<db->nDb; i++){
-+    pDb = &db->aDb[i];
-+    if( pDb->pBt==0 || pDb->zName==0 ) continue;
-+    if( strlen(pDb->zName)!=pDbname->n ) continue;
-+    if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
-+  }
-+  if( i>=db->nDb ){
-+    sqliteErrorMsg(pParse, "no such database: %T", pDbname);
-+    return;
-+  }
-+  if( i<2 ){
-+    sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
-+    return;
-+  }
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
-+    return;
-+  }
-+#endif /* SQLITE_OMIT_AUTHORIZATION */
-+  sqliteBtreeClose(pDb->pBt);
-+  pDb->pBt = 0;
-+  sqliteFree(pDb->zName);
-+  sqliteResetInternalSchema(db, i);
-+  if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
-+  db->nDb--;
-+  if( i<db->nDb ){
-+    db->aDb[i] = db->aDb[db->nDb];
-+    memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
-+    sqliteResetInternalSchema(db, i);
-+  }
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteFixInit(
-+  DbFixer *pFix,      /* The fixer to be initialized */
-+  Parse *pParse,      /* Error messages will be written here */
-+  int iDb,            /* This is the database that must must be used */
-+  const char *zType,  /* "view", "trigger", or "index" */
-+  const Token *pName  /* Name of the view, trigger, or index */
-+){
-+  sqlite *db;
-+
-+  if( 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 sqliteFixInit().
-+**
-+** 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.
-+*/
-+int sqliteFixSrcList(
-+  DbFixer *pFix,       /* Context of the fixation */
-+  SrcList *pList       /* The Source list to check and modify */
-+){
-+  int i;
-+  const char *zDb;
-+
-+  if( pList==0 ) return 0;
-+  zDb = pFix->zDb;
-+  for(i=0; i<pList->nSrc; i++){
-+    if( pList->a[i].zDatabase==0 ){
-+      pList->a[i].zDatabase = sqliteStrDup(zDb);
-+    }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
-+      sqliteErrorMsg(pFix->pParse,
-+         "%s %z cannot reference objects in database %s",
-+         pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
-+         pList->a[i].zDatabase);
-+      return 1;
-+    }
-+    if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
-+    if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
-+  }
-+  return 0;
-+}
-+int sqliteFixSelect(
-+  DbFixer *pFix,       /* Context of the fixation */
-+  Select *pSelect      /* The SELECT statement to be fixed to one database */
-+){
-+  while( pSelect ){
-+    if( sqliteFixExprList(pFix, pSelect->pEList) ){
-+      return 1;
-+    }
-+    if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
-+      return 1;
-+    }
-+    if( sqliteFixExpr(pFix, pSelect->pWhere) ){
-+      return 1;
-+    }
-+    if( sqliteFixExpr(pFix, pSelect->pHaving) ){
-+      return 1;
-+    }
-+    pSelect = pSelect->pPrior;
-+  }
-+  return 0;
-+}
-+int sqliteFixExpr(
-+  DbFixer *pFix,     /* Context of the fixation */
-+  Expr *pExpr        /* The expression to be fixed to one database */
-+){
-+  while( pExpr ){
-+    if( sqliteFixSelect(pFix, pExpr->pSelect) ){
-+      return 1;
-+    }
-+    if( sqliteFixExprList(pFix, pExpr->pList) ){
-+      return 1;
-+    }
-+    if( sqliteFixExpr(pFix, pExpr->pRight) ){
-+      return 1;
-+    }
-+    pExpr = pExpr->pLeft;
-+  }
-+  return 0;
-+}
-+int sqliteFixExprList(
-+  DbFixer *pFix,     /* Context of the fixation */
-+  ExprList *pList    /* The expression to be fixed to one database */
-+){
-+  int i;
-+  if( pList==0 ) return 0;
-+  for(i=0; i<pList->nExpr; i++){
-+    if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
-+      return 1;
-+    }
-+  }
-+  return 0;
-+}
-+int sqliteFixTriggerStep(
-+  DbFixer *pFix,     /* Context of the fixation */
-+  TriggerStep *pStep /* The trigger step be fixed to one database */
-+){
-+  while( pStep ){
-+    if( sqliteFixSelect(pFix, pStep->pSelect) ){
-+      return 1;
-+    }
-+    if( sqliteFixExpr(pFix, pStep->pWhere) ){
-+      return 1;
-+    }
-+    if( sqliteFixExprList(pFix, pStep->pExprList) ){
-+      return 1;
-+    }
-+    pStep = pStep->pNext;
-+  }
-+  return 0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/auth.c
-@@ -0,0 +1,219 @@
-+/*
-+** 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 sqlite_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$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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_COPY
-+**       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 sqlite_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.
-+*/
-+int sqlite_set_authorizer(
-+  sqlite *db,
-+  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
-+  void *pArg
-+){
-+  db->xAuth = xAuth;
-+  db->pAuthArg = pArg;
-+  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, int rc){
-+  sqliteErrorMsg(pParse, "illegal return value (%d) from the "
-+    "authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
-+    "or SQLITE_DENY", rc);
-+  pParse->rc = SQLITE_MISUSE;
-+}
-+
-+/*
-+** 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.
-+*/
-+void sqliteAuthRead(
-+  Parse *pParse,        /* The parser context */
-+  Expr *pExpr,          /* The expression to check authorization on */
-+  SrcList *pTabList     /* All table that pExpr might refer to */
-+){
-+  sqlite *db = pParse->db;
-+  int rc;
-+  Table *pTab;          /* 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 */
-+  TriggerStack *pStack; /* The stack of current triggers */
-+
-+  if( db->xAuth==0 ) return;
-+  assert( pExpr->op==TK_COLUMN );
-+  for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
-+    if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
-+  }
-+  if( iSrc>=0 && iSrc<pTabList->nSrc ){
-+    pTab = pTabList->a[iSrc].pTab;
-+  }else if( (pStack = pParse->trigStack)!=0 ){
-+    /* This must be an attempt to read the NEW or OLD pseudo-tables
-+    ** of a trigger.
-+    */
-+    assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
-+    pTab = pStack->pTab;
-+  }else{
-+    return;
-+  }
-+  if( pTab==0 ) return;
-+  if( pExpr->iColumn>=0 ){
-+    assert( pExpr->iColumn<pTab->nCol );
-+    zCol = pTab->aCol[pExpr->iColumn].zName;
-+  }else if( pTab->iPKey>=0 ){
-+    assert( pTab->iPKey<pTab->nCol );
-+    zCol = pTab->aCol[pTab->iPKey].zName;
-+  }else{
-+    zCol = "ROWID";
-+  }
-+  assert( pExpr->iDb<db->nDb );
-+  zDBase = db->aDb[pExpr->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 || pExpr->iDb!=0 ){
-+      sqliteErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
-+         zDBase, pTab->zName, zCol);
-+    }else{
-+      sqliteErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
-+    }
-+    pParse->rc = SQLITE_AUTH;
-+  }else if( rc!=SQLITE_OK ){
-+    sqliteAuthBadReturnCode(pParse, rc);
-+  }
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteAuthCheck(
-+  Parse *pParse,
-+  int code,
-+  const char *zArg1,
-+  const char *zArg2,
-+  const char *zArg3
-+){
-+  sqlite *db = pParse->db;
-+  int rc;
-+
-+  if( db->init.busy || db->xAuth==0 ){
-+    return SQLITE_OK;
-+  }
-+  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
-+  if( rc==SQLITE_DENY ){
-+    sqliteErrorMsg(pParse, "not authorized");
-+    pParse->rc = SQLITE_AUTH;
-+  }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
-+    rc = SQLITE_DENY;
-+    sqliteAuthBadReturnCode(pParse, rc);
-+  }
-+  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.
-+*/
-+void sqliteAuthContextPush(
-+  Parse *pParse,
-+  AuthContext *pContext, 
-+  const char *zContext
-+){
-+  pContext->pParse = pParse;
-+  if( pParse ){
-+    pContext->zAuthContext = pParse->zAuthContext;
-+    pParse->zAuthContext = zContext;
-+  }
-+}
-+
-+/*
-+** Pop an authorization context that was previously pushed
-+** by sqliteAuthContextPush
-+*/
-+void sqliteAuthContextPop(AuthContext *pContext){
-+  if( pContext->pParse ){
-+    pContext->pParse->zAuthContext = pContext->zAuthContext;
-+    pContext->pParse = 0;
-+  }
-+}
-+
-+#endif /* SQLITE_OMIT_AUTHORIZATION */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/btree.c
-@@ -0,0 +1,3584 @@
-+/*
-+** 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.
-+**
-+*************************************************************************
-+** $Id$
-+**
-+** 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) | Ptr(N+1) |
-+**   ----------------------------------------------------------------
-+**
-+** 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+1) and its subpages have values greater than Key(N).  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".  Up to
-+** MX_LOCAL_PAYLOAD bytes of payload can be carried directly on the
-+** database page.  If the payload is larger than MX_LOCAL_PAYLOAD bytes
-+** 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+1) pointer.
-+**
-+** The first page of the file contains a magic string used to verify that
-+** the file really is a valid BTree database, a pointer to a list of unused
-+** pages in the file, and some meta information.  The root of the first
-+** BTree begins on page 2 of the file.  (Pages are numbered beginning with
-+** 1, not 0.)  Thus a minimum database contains 2 pages.
-+*/
-+#include "sqliteInt.h"
-+#include "pager.h"
-+#include "btree.h"
-+#include <assert.h>
-+
-+/* Forward declarations */
-+static BtOps sqliteBtreeOps;
-+static BtCursorOps sqliteBtreeCursorOps;
-+
-+/*
-+** Macros used for byteswapping.  B is a pointer to the Btree
-+** structure.  This is needed to access the Btree.needSwab boolean
-+** in order to tell if byte swapping is needed or not.
-+** X is an unsigned integer.  SWAB16 byte swaps a 16-bit integer.
-+** SWAB32 byteswaps a 32-bit integer.
-+*/
-+#define SWAB16(B,X)   ((B)->needSwab? swab16((u16)X) : ((u16)X))
-+#define SWAB32(B,X)   ((B)->needSwab? swab32(X) : (X))
-+#define SWAB_ADD(B,X,A) \
-+   if((B)->needSwab){ X=swab32(swab32(X)+A); }else{ X += (A); }
-+
-+/*
-+** The following global variable - available only if SQLITE_TEST is
-+** defined - is used to determine whether new databases are created in
-+** native byte order or in non-native byte order.  Non-native byte order
-+** databases are created for testing purposes only.  Under normal operation,
-+** only native byte-order databases should be created, but we should be
-+** able to read or write existing databases regardless of the byteorder.
-+*/
-+#ifdef SQLITE_TEST
-+int btree_native_byte_order = 1;
-+#else
-+# define btree_native_byte_order 1
-+#endif
-+
-+/*
-+** Forward declarations of structures used only in this file.
-+*/
-+typedef struct PageOne PageOne;
-+typedef struct MemPage MemPage;
-+typedef struct PageHdr PageHdr;
-+typedef struct Cell Cell;
-+typedef struct CellHdr CellHdr;
-+typedef struct FreeBlk FreeBlk;
-+typedef struct OverflowPage OverflowPage;
-+typedef struct FreelistInfo FreelistInfo;
-+
-+/*
-+** All structures on a database page are aligned to 4-byte boundries.
-+** This routine rounds up a number of bytes to the next multiple of 4.
-+**
-+** This might need to change for computer architectures that require
-+** and 8-byte alignment boundry for structures.
-+*/
-+#define ROUNDUP(X)  ((X+3) & ~3)
-+
-+/*
-+** This is a magic string that appears at the beginning of every
-+** SQLite database in order to identify the file as a real database.
-+*/
-+static const char zMagicHeader[] = 
-+   "** This file contains an SQLite 2.1 database **";
-+#define MAGIC_SIZE (sizeof(zMagicHeader))
-+
-+/*
-+** This is a magic integer also used to test the integrity of the database
-+** file.  This integer is used in addition to the string above so that
-+** if the file is written on a little-endian architecture and read
-+** on a big-endian architectures (or vice versa) we can detect the
-+** problem.
-+**
-+** The number used was obtained at random and has no special
-+** significance other than the fact that it represents a different
-+** integer on little-endian and big-endian machines.
-+*/
-+#define MAGIC 0xdae37528
-+
-+/*
-+** The first page of the database file contains a magic header string
-+** to identify the file as an SQLite database file.  It also contains
-+** a pointer to the first free page of the file.  Page 2 contains the
-+** root of the principle BTree.  The file might contain other BTrees
-+** rooted on pages above 2.
-+**
-+** The first page also contains SQLITE_N_BTREE_META integers that
-+** can be used by higher-level routines.
-+**
-+** Remember that pages are numbered beginning with 1.  (See pager.c
-+** for additional information.)  Page 0 does not exist and a page
-+** number of 0 is used to mean "no such page".
-+*/
-+struct PageOne {
-+  char zMagic[MAGIC_SIZE]; /* String that identifies the file as a database */
-+  int iMagic;              /* Integer to verify correct byte order */
-+  Pgno freeList;           /* First free page in a list of all free pages */
-+  int nFree;               /* Number of pages on the free list */
-+  int aMeta[SQLITE_N_BTREE_META-1];  /* User defined integers */
-+};
-+
-+/*
-+** Each database page has a header that is an instance of this
-+** structure.
-+**
-+** PageHdr.firstFree is 0 if there is no free space on this page.
-+** Otherwise, PageHdr.firstFree is the index in MemPage.u.aDisk[] of a 
-+** FreeBlk structure that describes the first block of free space.  
-+** All free space is defined by a linked list of FreeBlk structures.
-+**
-+** Data is stored in a linked list of Cell structures.  PageHdr.firstCell
-+** is the index into MemPage.u.aDisk[] of the first cell on the page.  The
-+** Cells are kept in sorted order.
-+**
-+** A Cell contains all information about a database entry and a pointer
-+** to a child page that contains other entries less than itself.  In
-+** other words, the i-th Cell contains both Ptr(i) and Key(i).  The
-+** right-most pointer of the page is contained in PageHdr.rightChild.
-+*/
-+struct PageHdr {
-+  Pgno rightChild;  /* Child page that comes after all cells on this page */
-+  u16 firstCell;    /* Index in MemPage.u.aDisk[] of the first cell */
-+  u16 firstFree;    /* Index in MemPage.u.aDisk[] of the first free block */
-+};
-+
-+/*
-+** Entries on a page of the database are called "Cells".  Each Cell
-+** has a header and data.  This structure defines the header.  The
-+** key and data (collectively the "payload") follow this header on
-+** the database page.
-+**
-+** A definition of the complete Cell structure is given below.  The
-+** header for the cell must be defined first in order to do some
-+** of the sizing #defines that follow.
-+*/
-+struct CellHdr {
-+  Pgno leftChild; /* Child page that comes before this cell */
-+  u16 nKey;       /* Number of bytes in the key */
-+  u16 iNext;      /* Index in MemPage.u.aDisk[] of next cell in sorted order */
-+  u8 nKeyHi;      /* Upper 8 bits of key size for keys larger than 64K bytes */
-+  u8 nDataHi;     /* Upper 8 bits of data size when the size is more than 64K */
-+  u16 nData;      /* Number of bytes of data */
-+};
-+
-+/*
-+** The key and data size are split into a lower 16-bit segment and an
-+** upper 8-bit segment in order to pack them together into a smaller
-+** space.  The following macros reassembly a key or data size back
-+** into an integer.
-+*/
-+#define NKEY(b,h)  (SWAB16(b,h.nKey) + h.nKeyHi*65536)
-+#define NDATA(b,h) (SWAB16(b,h.nData) + h.nDataHi*65536)
-+
-+/*
-+** The minimum size of a complete Cell.  The Cell must contain a header
-+** and at least 4 bytes of payload.
-+*/
-+#define MIN_CELL_SIZE  (sizeof(CellHdr)+4)
-+
-+/*
-+** The maximum number of database entries that can be held in a single
-+** page of the database. 
-+*/
-+#define MX_CELL ((SQLITE_USABLE_SIZE-sizeof(PageHdr))/MIN_CELL_SIZE)
-+
-+/*
-+** The amount of usable space on a single page of the BTree.  This is the
-+** page size minus the overhead of the page header.
-+*/
-+#define USABLE_SPACE  (SQLITE_USABLE_SIZE - sizeof(PageHdr))
-+
-+/*
-+** The maximum amount of payload (in bytes) that can be stored locally for
-+** a database entry.  If the entry contains more data than this, the
-+** extra goes onto overflow pages.
-+**
-+** This number is chosen so that at least 4 cells will fit on every page.
-+*/
-+#define MX_LOCAL_PAYLOAD ((USABLE_SPACE/4-(sizeof(CellHdr)+sizeof(Pgno)))&~3)
-+
-+/*
-+** Data on a database page is stored as a linked list of Cell structures.
-+** Both the key and the data are stored in aPayload[].  The key always comes
-+** first.  The aPayload[] field grows as necessary to hold the key and data,
-+** up to a maximum of MX_LOCAL_PAYLOAD bytes.  If the size of the key and
-+** data combined exceeds MX_LOCAL_PAYLOAD bytes, then Cell.ovfl is the
-+** page number of the first overflow page.
-+**
-+** Though this structure is fixed in size, the Cell on the database
-+** page varies in size.  Every cell has a CellHdr and at least 4 bytes
-+** of payload space.  Additional payload bytes (up to the maximum of
-+** MX_LOCAL_PAYLOAD) and the Cell.ovfl value are allocated only as
-+** needed.
-+*/
-+struct Cell {
-+  CellHdr h;                        /* The cell header */
-+  char aPayload[MX_LOCAL_PAYLOAD];  /* Key and data */
-+  Pgno ovfl;                        /* The first overflow page */
-+};
-+
-+/*
-+** Free space on a page is remembered using a linked list of the FreeBlk
-+** structures.  Space on a database page is allocated in increments of
-+** at least 4 bytes and is always aligned to a 4-byte boundry.  The
-+** linked list of FreeBlks is always kept in order by address.
-+*/
-+struct FreeBlk {
-+  u16 iSize;      /* Number of bytes in this block of free space */
-+  u16 iNext;      /* Index in MemPage.u.aDisk[] of the next free block */
-+};
-+
-+/*
-+** The number of bytes of payload that will fit on a single overflow page.
-+*/
-+#define OVERFLOW_SIZE (SQLITE_USABLE_SIZE-sizeof(Pgno))
-+
-+/*
-+** When the key and data for a single entry in the BTree will not fit in
-+** the MX_LOCAL_PAYLOAD bytes of space available on the database page,
-+** then all extra bytes are written to a linked list of overflow pages.
-+** Each overflow page is an instance of the following structure.
-+**
-+** Unused pages in the database are also represented by instances of
-+** the OverflowPage structure.  The PageOne.freeList field is the
-+** page number of the first page in a linked list of unused database
-+** pages.
-+*/
-+struct OverflowPage {
-+  Pgno iNext;
-+  char aPayload[OVERFLOW_SIZE];
-+};
-+
-+/*
-+** The PageOne.freeList field points to a linked list of overflow pages
-+** hold information about free pages.  The aPayload section of each
-+** overflow page contains an instance of the following structure.  The
-+** aFree[] array holds the page number of nFree unused pages in the disk
-+** file.
-+*/
-+struct FreelistInfo {
-+  int nFree;
-+  Pgno aFree[(OVERFLOW_SIZE-sizeof(int))/sizeof(Pgno)];
-+};
-+
-+/*
-+** For every page in the database file, an instance of the following structure
-+** is stored in memory.  The u.aDisk[] array contains the raw bits read from
-+** the disk.  The rest is auxiliary information held in memory only. The
-+** auxiliary info is only valid for regular database pages - it is not
-+** used for overflow pages and pages on the freelist.
-+**
-+** Of particular interest in the auxiliary info is the apCell[] entry.  Each
-+** apCell[] entry is a pointer to a Cell structure in u.aDisk[].  The cells are
-+** put in this array so that they can be accessed in constant time, rather
-+** than in linear time which would be needed if we had to walk the linked 
-+** list on every access.
-+**
-+** Note that apCell[] contains enough space to hold up to two more Cells
-+** than can possibly fit on one page.  In the steady state, every apCell[]
-+** points to memory inside u.aDisk[].  But in the middle of an insert
-+** operation, some apCell[] entries may temporarily point to data space
-+** outside of u.aDisk[].  This is a transient situation that is quickly
-+** resolved.  But while it is happening, it is possible for a database
-+** page to hold as many as two more cells than it might otherwise hold.
-+** The extra two entries in apCell[] are an allowance for this situation.
-+**
-+** 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.
-+*/
-+struct MemPage {
-+  union u_page_data {
-+    char aDisk[SQLITE_PAGE_SIZE];  /* Page data stored on disk */
-+    PageHdr hdr;                   /* Overlay page header */
-+  } u;
-+  u8 isInit;                     /* True if auxiliary data is initialized */
-+  u8 idxShift;                   /* True if apCell[] indices have changed */
-+  u8 isOverfull;                 /* Some apCell[] points outside u.aDisk[] */
-+  MemPage *pParent;              /* The parent of this page.  NULL for root */
-+  int idxParent;                 /* Index in pParent->apCell[] of this node */
-+  int nFree;                     /* Number of free bytes in u.aDisk[] */
-+  int nCell;                     /* Number of entries on this page */
-+  Cell *apCell[MX_CELL+2];       /* All data entires in sorted order */
-+};
-+
-+/*
-+** 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)-sizeof(union u_page_data))
-+
-+/*
-+** Everything we need to know about an open database
-+*/
-+struct Btree {
-+  BtOps *pOps;          /* Function table */
-+  Pager *pPager;        /* The page cache */
-+  BtCursor *pCursor;    /* A list of all open cursors */
-+  PageOne *page1;       /* First page of the database */
-+  u8 inTrans;           /* True if a transaction is in progress */
-+  u8 inCkpt;            /* True if there is a checkpoint on the transaction */
-+  u8 readOnly;          /* True if the underlying file is readonly */
-+  u8 needSwab;          /* Need to byte-swapping */
-+};
-+typedef Btree Bt;
-+
-+/*
-+** A cursor is a pointer to a particular entry in the BTree.
-+** The entry is identified by its MemPage and the index in
-+** MemPage.apCell[] of the entry.
-+*/
-+struct BtCursor {
-+  BtCursorOps *pOps;        /* Function table */
-+  Btree *pBt;               /* The Btree to which this cursor belongs */
-+  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
-+  BtCursor *pShared;        /* Loop of cursors with the same root page */
-+  Pgno pgnoRoot;            /* The root page of this tree */
-+  MemPage *pPage;           /* Page that contains the entry */
-+  int idx;                  /* Index of the entry in pPage->apCell[] */
-+  u8 wrFlag;                /* True if writable */
-+  u8 eSkip;                 /* Determines if next step operation is a no-op */
-+  u8 iMatch;                /* compare result from last sqliteBtreeMoveto() */
-+};
-+
-+/*
-+** Legal values for BtCursor.eSkip.
-+*/
-+#define SKIP_NONE     0   /* Always step the cursor */
-+#define SKIP_NEXT     1   /* The next sqliteBtreeNext() is a no-op */
-+#define SKIP_PREV     2   /* The next sqliteBtreePrevious() is a no-op */
-+#define SKIP_INVALID  3   /* Calls to Next() and Previous() are invalid */
-+
-+/* Forward declarations */
-+static int fileBtreeCloseCursor(BtCursor *pCur);
-+
-+/*
-+** Routines for byte swapping.
-+*/
-+u16 swab16(u16 x){
-+  return ((x & 0xff)<<8) | ((x>>8)&0xff);
-+}
-+u32 swab32(u32 x){
-+  return ((x & 0xff)<<24) | ((x & 0xff00)<<8) |
-+         ((x>>8) & 0xff00) | ((x>>24)&0xff);
-+}
-+
-+/*
-+** Compute the total number of bytes that a Cell needs on the main
-+** database page.  The number returned includes the Cell header,
-+** local payload storage, and the pointer to overflow pages (if
-+** applicable).  Additional space allocated on overflow pages
-+** is NOT included in the value returned from this routine.
-+*/
-+static int cellSize(Btree *pBt, Cell *pCell){
-+  int n = NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h);
-+  if( n>MX_LOCAL_PAYLOAD ){
-+    n = MX_LOCAL_PAYLOAD + sizeof(Pgno);
-+  }else{
-+    n = ROUNDUP(n);
-+  }
-+  n += sizeof(CellHdr);
-+  return n;
-+}
-+
-+/*
-+** Defragment the page given.  All Cells are moved to the
-+** beginning of the page and all free space is collected 
-+** into one big FreeBlk at the end of the page.
-+*/
-+static void defragmentPage(Btree *pBt, MemPage *pPage){
-+  int pc, i, n;
-+  FreeBlk *pFBlk;
-+  char newPage[SQLITE_USABLE_SIZE];
-+
-+  assert( sqlitepager_iswriteable(pPage) );
-+  assert( pPage->isInit );
-+  pc = sizeof(PageHdr);
-+  pPage->u.hdr.firstCell = SWAB16(pBt, pc);
-+  memcpy(newPage, pPage->u.aDisk, pc);
-+  for(i=0; i<pPage->nCell; i++){
-+    Cell *pCell = pPage->apCell[i];
-+
-+    /* This routine should never be called on an overfull page.  The
-+    ** following asserts verify that constraint. */
-+    assert( Addr(pCell) > Addr(pPage) );
-+    assert( Addr(pCell) < Addr(pPage) + SQLITE_USABLE_SIZE );
-+
-+    n = cellSize(pBt, pCell);
-+    pCell->h.iNext = SWAB16(pBt, pc + n);
-+    memcpy(&newPage[pc], pCell, n);
-+    pPage->apCell[i] = (Cell*)&pPage->u.aDisk[pc];
-+    pc += n;
-+  }
-+  assert( pPage->nFree==SQLITE_USABLE_SIZE-pc );
-+  memcpy(pPage->u.aDisk, newPage, pc);
-+  if( pPage->nCell>0 ){
-+    pPage->apCell[pPage->nCell-1]->h.iNext = 0;
-+  }
-+  pFBlk = (FreeBlk*)&pPage->u.aDisk[pc];
-+  pFBlk->iSize = SWAB16(pBt, SQLITE_USABLE_SIZE - pc);
-+  pFBlk->iNext = 0;
-+  pPage->u.hdr.firstFree = SWAB16(pBt, pc);
-+  memset(&pFBlk[1], 0, SQLITE_USABLE_SIZE - pc - sizeof(FreeBlk));
-+}
-+
-+/*
-+** Allocate nByte bytes of space on a page.  nByte must be a 
-+** multiple of 4.
-+**
-+** Return the index into pPage->u.aDisk[] of the first byte of
-+** the new allocation. Or return 0 if there is not enough free
-+** space on the page to satisfy the allocation request.
-+**
-+** If the page contains nBytes of free space but does not contain
-+** nBytes of contiguous free space, then this routine automatically
-+** calls defragementPage() to consolidate all free space before 
-+** allocating the new chunk.
-+*/
-+static int allocateSpace(Btree *pBt, MemPage *pPage, int nByte){
-+  FreeBlk *p;
-+  u16 *pIdx;
-+  int start;
-+  int iSize;
-+#ifndef NDEBUG
-+  int cnt = 0;
-+#endif
-+
-+  assert( sqlitepager_iswriteable(pPage) );
-+  assert( nByte==ROUNDUP(nByte) );
-+  assert( pPage->isInit );
-+  if( pPage->nFree<nByte || pPage->isOverfull ) return 0;
-+  pIdx = &pPage->u.hdr.firstFree;
-+  p = (FreeBlk*)&pPage->u.aDisk[SWAB16(pBt, *pIdx)];
-+  while( (iSize = SWAB16(pBt, p->iSize))<nByte ){
-+    assert( cnt++ < SQLITE_USABLE_SIZE/4 );
-+    if( p->iNext==0 ){
-+      defragmentPage(pBt, pPage);
-+      pIdx = &pPage->u.hdr.firstFree;
-+    }else{
-+      pIdx = &p->iNext;
-+    }
-+    p = (FreeBlk*)&pPage->u.aDisk[SWAB16(pBt, *pIdx)];
-+  }
-+  if( iSize==nByte ){
-+    start = SWAB16(pBt, *pIdx);
-+    *pIdx = p->iNext;
-+  }else{
-+    FreeBlk *pNew;
-+    start = SWAB16(pBt, *pIdx);
-+    pNew = (FreeBlk*)&pPage->u.aDisk[start + nByte];
-+    pNew->iNext = p->iNext;
-+    pNew->iSize = SWAB16(pBt, iSize - nByte);
-+    *pIdx = SWAB16(pBt, start + nByte);
-+  }
-+  pPage->nFree -= nByte;
-+  return start;
-+}
-+
-+/*
-+** Return a section of the MemPage.u.aDisk[] to the freelist.
-+** The first byte of the new free block is pPage->u.aDisk[start]
-+** and the size of the block is "size" bytes.  Size must be
-+** a multiple of 4.
-+**
-+** Most of the effort here is involved in coalesing adjacent
-+** free blocks into a single big free block.
-+*/
-+static void freeSpace(Btree *pBt, MemPage *pPage, int start, int size){
-+  int end = start + size;
-+  u16 *pIdx, idx;
-+  FreeBlk *pFBlk;
-+  FreeBlk *pNew;
-+  FreeBlk *pNext;
-+  int iSize;
-+
-+  assert( sqlitepager_iswriteable(pPage) );
-+  assert( size == ROUNDUP(size) );
-+  assert( start == ROUNDUP(start) );
-+  assert( pPage->isInit );
-+  pIdx = &pPage->u.hdr.firstFree;
-+  idx = SWAB16(pBt, *pIdx);
-+  while( idx!=0 && idx<start ){
-+    pFBlk = (FreeBlk*)&pPage->u.aDisk[idx];
-+    iSize = SWAB16(pBt, pFBlk->iSize);
-+    if( idx + iSize == start ){
-+      pFBlk->iSize = SWAB16(pBt, iSize + size);
-+      if( idx + iSize + size == SWAB16(pBt, pFBlk->iNext) ){
-+        pNext = (FreeBlk*)&pPage->u.aDisk[idx + iSize + size];
-+        if( pBt->needSwab ){
-+          pFBlk->iSize = swab16((u16)swab16(pNext->iSize)+iSize+size);
-+        }else{
-+          pFBlk->iSize += pNext->iSize;
-+        }
-+        pFBlk->iNext = pNext->iNext;
-+      }
-+      pPage->nFree += size;
-+      return;
-+    }
-+    pIdx = &pFBlk->iNext;
-+    idx = SWAB16(pBt, *pIdx);
-+  }
-+  pNew = (FreeBlk*)&pPage->u.aDisk[start];
-+  if( idx != end ){
-+    pNew->iSize = SWAB16(pBt, size);
-+    pNew->iNext = SWAB16(pBt, idx);
-+  }else{
-+    pNext = (FreeBlk*)&pPage->u.aDisk[idx];
-+    pNew->iSize = SWAB16(pBt, size + SWAB16(pBt, pNext->iSize));
-+    pNew->iNext = pNext->iNext;
-+  }
-+  *pIdx = SWAB16(pBt, start);
-+  pPage->nFree += size;
-+}
-+
-+/*
-+** Initialize the auxiliary information for a disk block.
-+**
-+** The pParent parameter must be a pointer to the MemPage which
-+** is the parent of the page being initialized.  The root of the
-+** BTree (usually page 2) has no parent and so for that page, 
-+** pParent==NULL.
-+**
-+** 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 initPage(Bt *pBt, MemPage *pPage, Pgno pgnoThis, MemPage *pParent){
-+  int idx;           /* An index into pPage->u.aDisk[] */
-+  Cell *pCell;       /* A pointer to a Cell in pPage->u.aDisk[] */
-+  FreeBlk *pFBlk;    /* A pointer to a free block in pPage->u.aDisk[] */
-+  int sz;            /* The size of a Cell in bytes */
-+  int freeSpace;     /* Amount of free space on the page */
-+
-+  if( pPage->pParent ){
-+    assert( pPage->pParent==pParent );
-+    return SQLITE_OK;
-+  }
-+  if( pParent ){
-+    pPage->pParent = pParent;
-+    sqlitepager_ref(pParent);
-+  }
-+  if( pPage->isInit ) return SQLITE_OK;
-+  pPage->isInit = 1;
-+  pPage->nCell = 0;
-+  freeSpace = USABLE_SPACE;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstCell);
-+  while( idx!=0 ){
-+    if( idx>SQLITE_USABLE_SIZE-MIN_CELL_SIZE ) goto page_format_error;
-+    if( idx<sizeof(PageHdr) ) goto page_format_error;
-+    if( idx!=ROUNDUP(idx) ) goto page_format_error;
-+    pCell = (Cell*)&pPage->u.aDisk[idx];
-+    sz = cellSize(pBt, pCell);
-+    if( idx+sz > SQLITE_USABLE_SIZE ) goto page_format_error;
-+    freeSpace -= sz;
-+    pPage->apCell[pPage->nCell++] = pCell;
-+    idx = SWAB16(pBt, pCell->h.iNext);
-+  }
-+  pPage->nFree = 0;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstFree);
-+  while( idx!=0 ){
-+    int iNext;
-+    if( idx>SQLITE_USABLE_SIZE-sizeof(FreeBlk) ) goto page_format_error;
-+    if( idx<sizeof(PageHdr) ) goto page_format_error;
-+    pFBlk = (FreeBlk*)&pPage->u.aDisk[idx];
-+    pPage->nFree += SWAB16(pBt, pFBlk->iSize);
-+    iNext = SWAB16(pBt, pFBlk->iNext);
-+    if( iNext>0 && iNext <= idx ) goto page_format_error;
-+    idx = iNext;
-+  }
-+  if( pPage->nCell==0 && pPage->nFree==0 ){
-+    /* As a special case, an uninitialized root page appears to be
-+    ** an empty database */
-+    return SQLITE_OK;
-+  }
-+  if( pPage->nFree!=freeSpace ) goto page_format_error;
-+  return SQLITE_OK;
-+
-+page_format_error:
-+  return SQLITE_CORRUPT;
-+}
-+
-+/*
-+** Set up a raw page so that it looks like a database page holding
-+** no entries.
-+*/
-+static void zeroPage(Btree *pBt, MemPage *pPage){
-+  PageHdr *pHdr;
-+  FreeBlk *pFBlk;
-+  assert( sqlitepager_iswriteable(pPage) );
-+  memset(pPage, 0, SQLITE_USABLE_SIZE);
-+  pHdr = &pPage->u.hdr;
-+  pHdr->firstCell = 0;
-+  pHdr->firstFree = SWAB16(pBt, sizeof(*pHdr));
-+  pFBlk = (FreeBlk*)&pHdr[1];
-+  pFBlk->iNext = 0;
-+  pPage->nFree = SQLITE_USABLE_SIZE - sizeof(*pHdr);
-+  pFBlk->iSize = SWAB16(pBt, pPage->nFree);
-+  pPage->nCell = 0;
-+  pPage->isOverfull = 0;
-+}
-+
-+/*
-+** This routine is called when the reference count for a page
-+** reaches zero.  We need to unref the pParent pointer when that
-+** happens.
-+*/
-+static void pageDestructor(void *pData){
-+  MemPage *pPage = (MemPage*)pData;
-+  if( pPage->pParent ){
-+    MemPage *pParent = pPage->pParent;
-+    pPage->pParent = 0;
-+    sqlitepager_unref(pParent);
-+  }
-+}
-+
-+/*
-+** Open a new database.
-+**
-+** Actually, this routine just sets up the internal data structures
-+** for accessing the database.  We do not open the database file 
-+** until the first page is loaded.
-+**
-+** 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 sqliteBtreeClose() is called.
-+*/
-+int sqliteBtreeOpen(
-+  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 */
-+  Btree **ppBtree           /* Pointer to new Btree object written here */
-+){
-+  Btree *pBt;
-+  int rc;
-+
-+  /*
-+  ** 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(u32)==4 );
-+  assert( sizeof(u16)==2 );
-+  assert( sizeof(Pgno)==4 );
-+  assert( sizeof(PageHdr)==8 );
-+  assert( sizeof(CellHdr)==12 );
-+  assert( sizeof(FreeBlk)==4 );
-+  assert( sizeof(OverflowPage)==SQLITE_USABLE_SIZE );
-+  assert( sizeof(FreelistInfo)==OVERFLOW_SIZE );
-+  assert( sizeof(ptr)==sizeof(char*) );
-+  assert( sizeof(uptr)==sizeof(ptr) );
-+
-+  pBt = sqliteMalloc( sizeof(*pBt) );
-+  if( pBt==0 ){
-+    *ppBtree = 0;
-+    return SQLITE_NOMEM;
-+  }
-+  if( nCache<10 ) nCache = 10;
-+  rc = sqlitepager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
-+                        !omitJournal);
-+  if( rc!=SQLITE_OK ){
-+    if( pBt->pPager ) sqlitepager_close(pBt->pPager);
-+    sqliteFree(pBt);
-+    *ppBtree = 0;
-+    return rc;
-+  }
-+  sqlitepager_set_destructor(pBt->pPager, pageDestructor);
-+  pBt->pCursor = 0;
-+  pBt->page1 = 0;
-+  pBt->readOnly = sqlitepager_isreadonly(pBt->pPager);
-+  pBt->pOps = &sqliteBtreeOps;
-+  *ppBtree = pBt;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Close an open database and invalidate all cursors.
-+*/
-+static int fileBtreeClose(Btree *pBt){
-+  while( pBt->pCursor ){
-+    fileBtreeCloseCursor(pBt->pCursor);
-+  }
-+  sqlitepager_close(pBt->pPager);
-+  sqliteFree(pBt);
-+  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.
-+*/
-+static int fileBtreeSetCacheSize(Btree *pBt, int mxPage){
-+  sqlitepager_set_cachesize(pBt->pPager, mxPage);
-+  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.
-+*/
-+static int fileBtreeSetSafetyLevel(Btree *pBt, int level){
-+  sqlitepager_set_safety_level(pBt->pPager, level);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Get a reference to page1 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.  SQLITE_PROTOCOL is returned
-+** if there is a locking protocol violation.
-+*/
-+static int lockBtree(Btree *pBt){
-+  int rc;
-+  if( pBt->page1 ) return SQLITE_OK;
-+  rc = sqlitepager_get(pBt->pPager, 1, (void**)&pBt->page1);
-+  if( rc!=SQLITE_OK ) return rc;
-+
-+  /* Do some checking to help insure the file we opened really is
-+  ** a valid database file. 
-+  */
-+  if( sqlitepager_pagecount(pBt->pPager)>0 ){
-+    PageOne *pP1 = pBt->page1;
-+    if( strcmp(pP1->zMagic,zMagicHeader)!=0 ||
-+          (pP1->iMagic!=MAGIC && swab32(pP1->iMagic)!=MAGIC) ){
-+      rc = SQLITE_NOTADB;
-+      goto page1_init_failed;
-+    }
-+    pBt->needSwab = pP1->iMagic!=MAGIC;
-+  }
-+  return rc;
-+
-+page1_init_failed:
-+  sqlitepager_unref(pBt->page1);
-+  pBt->page1 = 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 are any outstanding cursors, this routine is a no-op.
-+**
-+** If there is a transaction in progress, this routine is a no-op.
-+*/
-+static void unlockBtreeIfUnused(Btree *pBt){
-+  if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){
-+    sqlitepager_unref(pBt->page1);
-+    pBt->page1 = 0;
-+    pBt->inTrans = 0;
-+    pBt->inCkpt = 0;
-+  }
-+}
-+
-+/*
-+** Create a new database by initializing the first two pages of the
-+** file.
-+*/
-+static int newDatabase(Btree *pBt){
-+  MemPage *pRoot;
-+  PageOne *pP1;
-+  int rc;
-+  if( sqlitepager_pagecount(pBt->pPager)>1 ) return SQLITE_OK;
-+  pP1 = pBt->page1;
-+  rc = sqlitepager_write(pBt->page1);
-+  if( rc ) return rc;
-+  rc = sqlitepager_get(pBt->pPager, 2, (void**)&pRoot);
-+  if( rc ) return rc;
-+  rc = sqlitepager_write(pRoot);
-+  if( rc ){
-+    sqlitepager_unref(pRoot);
-+    return rc;
-+  }
-+  strcpy(pP1->zMagic, zMagicHeader);
-+  if( btree_native_byte_order ){
-+    pP1->iMagic = MAGIC;
-+    pBt->needSwab = 0;
-+  }else{
-+    pP1->iMagic = swab32(MAGIC);
-+    pBt->needSwab = 1;
-+  }
-+  zeroPage(pBt, pRoot);
-+  sqlitepager_unref(pRoot);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Attempt to start a new transaction.
-+**
-+** A transaction must be started before attempting any changes
-+** to the database.  None of the following routines will work
-+** unless a transaction is started first:
-+**
-+**      sqliteBtreeCreateTable()
-+**      sqliteBtreeCreateIndex()
-+**      sqliteBtreeClearTable()
-+**      sqliteBtreeDropTable()
-+**      sqliteBtreeInsert()
-+**      sqliteBtreeDelete()
-+**      sqliteBtreeUpdateMeta()
-+*/
-+static int fileBtreeBeginTrans(Btree *pBt){
-+  int rc;
-+  if( pBt->inTrans ) return SQLITE_ERROR;
-+  if( pBt->readOnly ) return SQLITE_READONLY;
-+  if( pBt->page1==0 ){
-+    rc = lockBtree(pBt);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-+    }
-+  }
-+  rc = sqlitepager_begin(pBt->page1);
-+  if( rc==SQLITE_OK ){
-+    rc = newDatabase(pBt);
-+  }
-+  if( rc==SQLITE_OK ){
-+    pBt->inTrans = 1;
-+    pBt->inCkpt = 0;
-+  }else{
-+    unlockBtreeIfUnused(pBt);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Commit the transaction currently in progress.
-+**
-+** This will release the write lock on the database file.  If there
-+** are no active cursors, it also releases the read lock.
-+*/
-+static int fileBtreeCommit(Btree *pBt){
-+  int rc;
-+  rc = pBt->readOnly ? SQLITE_OK : sqlitepager_commit(pBt->pPager);
-+  pBt->inTrans = 0;
-+  pBt->inCkpt = 0;
-+  unlockBtreeIfUnused(pBt);
-+  return rc;
-+}
-+
-+/*
-+** 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.
-+*/
-+static int fileBtreeRollback(Btree *pBt){
-+  int rc;
-+  BtCursor *pCur;
-+  if( pBt->inTrans==0 ) return SQLITE_OK;
-+  pBt->inTrans = 0;
-+  pBt->inCkpt = 0;
-+  rc = pBt->readOnly ? SQLITE_OK : sqlitepager_rollback(pBt->pPager);
-+  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-+    if( pCur->pPage && pCur->pPage->isInit==0 ){
-+      sqlitepager_unref(pCur->pPage);
-+      pCur->pPage = 0;
-+    }
-+  }
-+  unlockBtreeIfUnused(pBt);
-+  return rc;
-+}
-+
-+/*
-+** Set the checkpoint for the current transaction.  The checkpoint serves
-+** as a sub-transaction that can be rolled back independently of the
-+** main transaction.  You must start a transaction before starting a
-+** checkpoint.  The checkpoint is ended automatically if the transaction
-+** commits or rolls back.
-+**
-+** Only one checkpoint may be active at a time.  It is an error to try
-+** to start a new checkpoint if another checkpoint is already active.
-+*/
-+static int fileBtreeBeginCkpt(Btree *pBt){
-+  int rc;
-+  if( !pBt->inTrans || pBt->inCkpt ){
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  rc = pBt->readOnly ? SQLITE_OK : sqlitepager_ckpt_begin(pBt->pPager);
-+  pBt->inCkpt = 1;
-+  return rc;
-+}
-+
-+
-+/*
-+** Commit a checkpoint to transaction currently in progress.  If no
-+** checkpoint is active, this is a no-op.
-+*/
-+static int fileBtreeCommitCkpt(Btree *pBt){
-+  int rc;
-+  if( pBt->inCkpt && !pBt->readOnly ){
-+    rc = sqlitepager_ckpt_commit(pBt->pPager);
-+  }else{
-+    rc = SQLITE_OK;
-+  }
-+  pBt->inCkpt = 0;
-+  return rc;
-+}
-+
-+/*
-+** Rollback the checkpoint to the current transaction.  If there
-+** is no active checkpoint or transaction, this routine is a no-op.
-+**
-+** 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.
-+*/
-+static int fileBtreeRollbackCkpt(Btree *pBt){
-+  int rc;
-+  BtCursor *pCur;
-+  if( pBt->inCkpt==0 || pBt->readOnly ) return SQLITE_OK;
-+  rc = sqlitepager_ckpt_rollback(pBt->pPager);
-+  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-+    if( pCur->pPage && pCur->pPage->isInit==0 ){
-+      sqlitepager_unref(pCur->pPage);
-+      pCur->pPage = 0;
-+    }
-+  }
-+  pBt->inCkpt = 0;
-+  return rc;
-+}
-+
-+/*
-+** Create a new cursor for the BTree whose root is on the page
-+** iTable.  The act of acquiring a cursor gets a read lock on 
-+** the database file.
-+**
-+** 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:  No other cursors may be open with wrFlag==0 on the same table
-+**
-+** 3:  The database must be writable (not on read-only media)
-+**
-+** 4:  There must be an active transaction.
-+**
-+** Condition 2 warrants further discussion.  If any cursor is opened
-+** on a table with wrFlag==0, that prevents all other cursors from
-+** writing to that table.  This is a kind of "read-lock".  When a cursor
-+** is opened with wrFlag==0 it is guaranteed that the table will not
-+** change as long as the cursor is open.  This allows the cursor to
-+** do a sequential scan of the table without having to worry about
-+** entries being inserted or deleted during the scan.  Cursors should
-+** be opened with wrFlag==0 only if this read-lock property is needed.
-+** That is to say, cursors should be opened with wrFlag==0 only if they
-+** intend to use the sqliteBtreeNext() system call.  All other cursors
-+** should be opened with wrFlag==1 even if they never really intend
-+** to write.
-+** 
-+** 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.
-+*/
-+static 
-+int fileBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){
-+  int rc;
-+  BtCursor *pCur, *pRing;
-+
-+  if( pBt->readOnly && wrFlag ){
-+    *ppCur = 0;
-+    return SQLITE_READONLY;
-+  }
-+  if( pBt->page1==0 ){
-+    rc = lockBtree(pBt);
-+    if( rc!=SQLITE_OK ){
-+      *ppCur = 0;
-+      return rc;
-+    }
-+  }
-+  pCur = sqliteMalloc( sizeof(*pCur) );
-+  if( pCur==0 ){
-+    rc = SQLITE_NOMEM;
-+    goto create_cursor_exception;
-+  }
-+  pCur->pgnoRoot = (Pgno)iTable;
-+  rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, (void**)&pCur->pPage);
-+  if( rc!=SQLITE_OK ){
-+    goto create_cursor_exception;
-+  }
-+  rc = initPage(pBt, pCur->pPage, pCur->pgnoRoot, 0);
-+  if( rc!=SQLITE_OK ){
-+    goto create_cursor_exception;
-+  }
-+  pCur->pOps = &sqliteBtreeCursorOps;
-+  pCur->pBt = pBt;
-+  pCur->wrFlag = wrFlag;
-+  pCur->idx = 0;
-+  pCur->eSkip = SKIP_INVALID;
-+  pCur->pNext = pBt->pCursor;
-+  if( pCur->pNext ){
-+    pCur->pNext->pPrev = pCur;
-+  }
-+  pCur->pPrev = 0;
-+  pRing = pBt->pCursor;
-+  while( pRing && pRing->pgnoRoot!=pCur->pgnoRoot ){ pRing = pRing->pNext; }
-+  if( pRing ){
-+    pCur->pShared = pRing->pShared;
-+    pRing->pShared = pCur;
-+  }else{
-+    pCur->pShared = pCur;
-+  }
-+  pBt->pCursor = pCur;
-+  *ppCur = pCur;
-+  return SQLITE_OK;
-+
-+create_cursor_exception:
-+  *ppCur = 0;
-+  if( pCur ){
-+    if( pCur->pPage ) sqlitepager_unref(pCur->pPage);
-+    sqliteFree(pCur);
-+  }
-+  unlockBtreeIfUnused(pBt);
-+  return rc;
-+}
-+
-+/*
-+** Close a cursor.  The read lock on the database file is released
-+** when the last cursor is closed.
-+*/
-+static int fileBtreeCloseCursor(BtCursor *pCur){
-+  Btree *pBt = pCur->pBt;
-+  if( pCur->pPrev ){
-+    pCur->pPrev->pNext = pCur->pNext;
-+  }else{
-+    pBt->pCursor = pCur->pNext;
-+  }
-+  if( pCur->pNext ){
-+    pCur->pNext->pPrev = pCur->pPrev;
-+  }
-+  if( pCur->pPage ){
-+    sqlitepager_unref(pCur->pPage);
-+  }
-+  if( pCur->pShared!=pCur ){
-+    BtCursor *pRing = pCur->pShared;
-+    while( pRing->pShared!=pCur ){ pRing = pRing->pShared; }
-+    pRing->pShared = pCur->pShared;
-+  }
-+  unlockBtreeIfUnused(pBt);
-+  sqliteFree(pCur);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Make a temporary cursor by filling in the fields of pTempCur.
-+** The temporary cursor is not on the cursor list for the Btree.
-+*/
-+static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
-+  memcpy(pTempCur, pCur, sizeof(*pCur));
-+  pTempCur->pNext = 0;
-+  pTempCur->pPrev = 0;
-+  if( pTempCur->pPage ){
-+    sqlitepager_ref(pTempCur->pPage);
-+  }
-+}
-+
-+/*
-+** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
-+** function above.
-+*/
-+static void releaseTempCursor(BtCursor *pCur){
-+  if( pCur->pPage ){
-+    sqlitepager_unref(pCur->pPage);
-+  }
-+}
-+
-+/*
-+** Set *pSize to the number of bytes of key in the entry the
-+** cursor currently points to.  Always return SQLITE_OK.
-+** Failure is not possible.  If the cursor is not currently
-+** pointing to an entry (which can happen, for example, if
-+** the database is empty) then *pSize is set to 0.
-+*/
-+static int fileBtreeKeySize(BtCursor *pCur, int *pSize){
-+  Cell *pCell;
-+  MemPage *pPage;
-+
-+  pPage = pCur->pPage;
-+  assert( pPage!=0 );
-+  if( pCur->idx >= pPage->nCell ){
-+    *pSize = 0;
-+  }else{
-+    pCell = pPage->apCell[pCur->idx];
-+    *pSize = NKEY(pCur->pBt, pCell->h);
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Read payload information from the entry that the pCur cursor is
-+** pointing to.  Begin reading the payload at "offset" and read
-+** a total of "amt" bytes.  Put the result in zBuf.
-+**
-+** This routine does not make a distinction between key and data.
-+** It just reads bytes from the payload area.
-+*/
-+static int getPayload(BtCursor *pCur, int offset, int amt, char *zBuf){
-+  char *aPayload;
-+  Pgno nextPage;
-+  int rc;
-+  Btree *pBt = pCur->pBt;
-+  assert( pCur!=0 && pCur->pPage!=0 );
-+  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-+  aPayload = pCur->pPage->apCell[pCur->idx]->aPayload;
-+  if( offset<MX_LOCAL_PAYLOAD ){
-+    int a = amt;
-+    if( a+offset>MX_LOCAL_PAYLOAD ){
-+      a = MX_LOCAL_PAYLOAD - offset;
-+    }
-+    memcpy(zBuf, &aPayload[offset], a);
-+    if( a==amt ){
-+      return SQLITE_OK;
-+    }
-+    offset = 0;
-+    zBuf += a;
-+    amt -= a;
-+  }else{
-+    offset -= MX_LOCAL_PAYLOAD;
-+  }
-+  if( amt>0 ){
-+    nextPage = SWAB32(pBt, pCur->pPage->apCell[pCur->idx]->ovfl);
-+  }
-+  while( amt>0 && nextPage ){
-+    OverflowPage *pOvfl;
-+    rc = sqlitepager_get(pBt->pPager, nextPage, (void**)&pOvfl);
-+    if( rc!=0 ){
-+      return rc;
-+    }
-+    nextPage = SWAB32(pBt, pOvfl->iNext);
-+    if( offset<OVERFLOW_SIZE ){
-+      int a = amt;
-+      if( a + offset > OVERFLOW_SIZE ){
-+        a = OVERFLOW_SIZE - offset;
-+      }
-+      memcpy(zBuf, &pOvfl->aPayload[offset], a);
-+      offset = 0;
-+      amt -= a;
-+      zBuf += a;
-+    }else{
-+      offset -= OVERFLOW_SIZE;
-+    }
-+    sqlitepager_unref(pOvfl);
-+  }
-+  if( amt>0 ){
-+    return SQLITE_CORRUPT;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Read part of the key associated with cursor pCur.  A maximum
-+** of "amt" bytes will be transfered into zBuf[].  The transfer
-+** begins at "offset".  The number of bytes actually read is
-+** returned. 
-+**
-+** Change:  It used to be that the amount returned will be smaller
-+** than the amount requested if there are not enough bytes in the key
-+** to satisfy the request.  But now, it must be the case that there
-+** is enough data available to satisfy the request.  If not, an exception
-+** is raised.  The change was made in an effort to boost performance
-+** by eliminating unneeded tests.
-+*/
-+static int fileBtreeKey(BtCursor *pCur, int offset, int amt, char *zBuf){
-+  MemPage *pPage;
-+
-+  assert( amt>=0 );
-+  assert( offset>=0 );
-+  assert( pCur->pPage!=0 );
-+  pPage = pCur->pPage;
-+  if( pCur->idx >= pPage->nCell ){
-+    return 0;
-+  }
-+  assert( amt+offset <= NKEY(pCur->pBt, pPage->apCell[pCur->idx]->h) );
-+  getPayload(pCur, offset, amt, zBuf);
-+  return amt;
-+}
-+
-+/*
-+** Set *pSize to the number of bytes of data in the entry the
-+** cursor currently points to.  Always return SQLITE_OK.
-+** Failure is not possible.  If the cursor is not currently
-+** pointing to an entry (which can happen, for example, if
-+** the database is empty) then *pSize is set to 0.
-+*/
-+static int fileBtreeDataSize(BtCursor *pCur, int *pSize){
-+  Cell *pCell;
-+  MemPage *pPage;
-+
-+  pPage = pCur->pPage;
-+  assert( pPage!=0 );
-+  if( pCur->idx >= pPage->nCell ){
-+    *pSize = 0;
-+  }else{
-+    pCell = pPage->apCell[pCur->idx];
-+    *pSize = NDATA(pCur->pBt, pCell->h);
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Read part of the data associated with cursor pCur.  A maximum
-+** of "amt" bytes will be transfered into zBuf[].  The transfer
-+** begins at "offset".  The number of bytes actually read is
-+** returned.  The amount returned will be smaller than the
-+** amount requested if there are not enough bytes in the data
-+** to satisfy the request.
-+*/
-+static int fileBtreeData(BtCursor *pCur, int offset, int amt, char *zBuf){
-+  Cell *pCell;
-+  MemPage *pPage;
-+
-+  assert( amt>=0 );
-+  assert( offset>=0 );
-+  assert( pCur->pPage!=0 );
-+  pPage = pCur->pPage;
-+  if( pCur->idx >= pPage->nCell ){
-+    return 0;
-+  }
-+  pCell = pPage->apCell[pCur->idx];
-+  assert( amt+offset <= NDATA(pCur->pBt, pCell->h) );
-+  getPayload(pCur, offset + NKEY(pCur->pBt, pCell->h), amt, zBuf);
-+  return amt;
-+}
-+
-+/*
-+** Compare an external key against the key on the entry that pCur points to.
-+**
-+** The external key is pKey and is nKey bytes long.  The last nIgnore bytes
-+** of the key associated with pCur are ignored, as if they do not exist.
-+** (The normal case is for nIgnore to be zero in which case the entire
-+** internal key is used in the comparison.)
-+**
-+** The comparison result is written to *pRes as follows:
-+**
-+**    *pRes<0    This means pCur<pKey
-+**
-+**    *pRes==0   This means pCur==pKey for all nKey bytes
-+**
-+**    *pRes>0    This means pCur>pKey
-+**
-+** When one key is an exact prefix of the other, the shorter key is
-+** considered less than the longer one.  In order to be equal the
-+** keys must be exactly the same length. (The length of the pCur key
-+** is the actual key length minus nIgnore bytes.)
-+*/
-+static int fileBtreeKeyCompare(
-+  BtCursor *pCur,       /* Pointer to entry to compare against */
-+  const void *pKey,     /* Key to compare against entry that pCur points to */
-+  int nKey,             /* Number of bytes in pKey */
-+  int nIgnore,          /* Ignore this many bytes at the end of pCur */
-+  int *pResult          /* Write the result here */
-+){
-+  Pgno nextPage;
-+  int n, c, rc, nLocal;
-+  Cell *pCell;
-+  Btree *pBt = pCur->pBt;
-+  const char *zKey  = (const char*)pKey;
-+
-+  assert( pCur->pPage );
-+  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-+  pCell = pCur->pPage->apCell[pCur->idx];
-+  nLocal = NKEY(pBt, pCell->h) - nIgnore;
-+  if( nLocal<0 ) nLocal = 0;
-+  n = nKey<nLocal ? nKey : nLocal;
-+  if( n>MX_LOCAL_PAYLOAD ){
-+    n = MX_LOCAL_PAYLOAD;
-+  }
-+  c = memcmp(pCell->aPayload, zKey, n);
-+  if( c!=0 ){
-+    *pResult = c;
-+    return SQLITE_OK;
-+  }
-+  zKey += n;
-+  nKey -= n;
-+  nLocal -= n;
-+  nextPage = SWAB32(pBt, pCell->ovfl);
-+  while( nKey>0 && nLocal>0 ){
-+    OverflowPage *pOvfl;
-+    if( nextPage==0 ){
-+      return SQLITE_CORRUPT;
-+    }
-+    rc = sqlitepager_get(pBt->pPager, nextPage, (void**)&pOvfl);
-+    if( rc ){
-+      return rc;
-+    }
-+    nextPage = SWAB32(pBt, pOvfl->iNext);
-+    n = nKey<nLocal ? nKey : nLocal;
-+    if( n>OVERFLOW_SIZE ){
-+      n = OVERFLOW_SIZE;
-+    }
-+    c = memcmp(pOvfl->aPayload, zKey, n);
-+    sqlitepager_unref(pOvfl);
-+    if( c!=0 ){
-+      *pResult = c;
-+      return SQLITE_OK;
-+    }
-+    nKey -= n;
-+    nLocal -= n;
-+    zKey += n;
-+  }
-+  if( c==0 ){
-+    c = nLocal - nKey;
-+  }
-+  *pResult = c;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Move the cursor down to a new child page.  The newPgno argument is the
-+** page number of the child page in the byte order of the disk image.
-+*/
-+static int moveToChild(BtCursor *pCur, int newPgno){
-+  int rc;
-+  MemPage *pNewPage;
-+  Btree *pBt = pCur->pBt;
-+
-+  newPgno = SWAB32(pBt, newPgno);
-+  rc = sqlitepager_get(pBt->pPager, newPgno, (void**)&pNewPage);
-+  if( rc ) return rc;
-+  rc = initPage(pBt, pNewPage, newPgno, pCur->pPage);
-+  if( rc ) return rc;
-+  assert( pCur->idx>=pCur->pPage->nCell
-+          || pCur->pPage->apCell[pCur->idx]->h.leftChild==SWAB32(pBt,newPgno) );
-+  assert( pCur->idx<pCur->pPage->nCell
-+          || pCur->pPage->u.hdr.rightChild==SWAB32(pBt,newPgno) );
-+  pNewPage->idxParent = pCur->idx;
-+  pCur->pPage->idxShift = 0;
-+  sqlitepager_unref(pCur->pPage);
-+  pCur->pPage = pNewPage;
-+  pCur->idx = 0;
-+  if( pNewPage->nCell<1 ){
-+    return SQLITE_CORRUPT;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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){
-+  Pgno oldPgno;
-+  MemPage *pParent;
-+  MemPage *pPage;
-+  int idxParent;
-+  pPage = pCur->pPage;
-+  assert( pPage!=0 );
-+  pParent = pPage->pParent;
-+  assert( pParent!=0 );
-+  idxParent = pPage->idxParent;
-+  sqlitepager_ref(pParent);
-+  sqlitepager_unref(pPage);
-+  pCur->pPage = pParent;
-+  assert( pParent->idxShift==0 );
-+  if( pParent->idxShift==0 ){
-+    pCur->idx = idxParent;
-+#ifndef NDEBUG  
-+    /* Verify that pCur->idx is the correct index to point back to the child
-+    ** page we just came from 
-+    */
-+    oldPgno = SWAB32(pCur->pBt, sqlitepager_pagenumber(pPage));
-+    if( pCur->idx<pParent->nCell ){
-+      assert( pParent->apCell[idxParent]->h.leftChild==oldPgno );
-+    }else{
-+      assert( pParent->u.hdr.rightChild==oldPgno );
-+    }
-+#endif
-+  }else{
-+    /* The MemPage.idxShift flag indicates that cell indices might have 
-+    ** changed since idxParent was set and hence idxParent might be out
-+    ** of date.  So recompute the parent cell index by scanning all cells
-+    ** and locating the one that points to the child we just came from.
-+    */
-+    int i;
-+    pCur->idx = pParent->nCell;
-+    oldPgno = SWAB32(pCur->pBt, sqlitepager_pagenumber(pPage));
-+    for(i=0; i<pParent->nCell; i++){
-+      if( pParent->apCell[i]->h.leftChild==oldPgno ){
-+        pCur->idx = i;
-+        break;
-+      }
-+    }
-+  }
-+}
-+
-+/*
-+** Move the cursor to the root page
-+*/
-+static int moveToRoot(BtCursor *pCur){
-+  MemPage *pNew;
-+  int rc;
-+  Btree *pBt = pCur->pBt;
-+
-+  rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, (void**)&pNew);
-+  if( rc ) return rc;
-+  rc = initPage(pBt, pNew, pCur->pgnoRoot, 0);
-+  if( rc ) return rc;
-+  sqlitepager_unref(pCur->pPage);
-+  pCur->pPage = pNew;
-+  pCur->idx = 0;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Move the cursor down to the left-most leaf entry beneath the
-+** entry to which it is currently pointing.
-+*/
-+static int moveToLeftmost(BtCursor *pCur){
-+  Pgno pgno;
-+  int rc;
-+
-+  while( (pgno = pCur->pPage->apCell[pCur->idx]->h.leftChild)!=0 ){
-+    rc = moveToChild(pCur, pgno);
-+    if( rc ) return rc;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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*.
-+*/
-+static int moveToRightmost(BtCursor *pCur){
-+  Pgno pgno;
-+  int rc;
-+
-+  while( (pgno = pCur->pPage->u.hdr.rightChild)!=0 ){
-+    pCur->idx = pCur->pPage->nCell;
-+    rc = moveToChild(pCur, pgno);
-+    if( rc ) return rc;
-+  }
-+  pCur->idx = pCur->pPage->nCell - 1;
-+  return SQLITE_OK;
-+}
-+
-+/* 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.
-+*/
-+static int fileBtreeFirst(BtCursor *pCur, int *pRes){
-+  int rc;
-+  if( pCur->pPage==0 ) return SQLITE_ABORT;
-+  rc = moveToRoot(pCur);
-+  if( rc ) return rc;
-+  if( pCur->pPage->nCell==0 ){
-+    *pRes = 1;
-+    return SQLITE_OK;
-+  }
-+  *pRes = 0;
-+  rc = moveToLeftmost(pCur);
-+  pCur->eSkip = SKIP_NONE;
-+  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.
-+*/
-+static int fileBtreeLast(BtCursor *pCur, int *pRes){
-+  int rc;
-+  if( pCur->pPage==0 ) return SQLITE_ABORT;
-+  rc = moveToRoot(pCur);
-+  if( rc ) return rc;
-+  assert( pCur->pPage->isInit );
-+  if( pCur->pPage->nCell==0 ){
-+    *pRes = 1;
-+    return SQLITE_OK;
-+  }
-+  *pRes = 0;
-+  rc = moveToRightmost(pCur);
-+  pCur->eSkip = SKIP_NONE;
-+  return rc;
-+}
-+
-+/* Move the cursor so that it points to an entry near pKey.
-+** Return a success code.
-+**
-+** 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.
-+**
-+** The result of comparing the key with the entry to which the
-+** cursor is left pointing is stored in pCur->iMatch.  The same
-+** value is also written to *pRes if pRes!=NULL.  The meaning of
-+** this value is as follows:
-+**
-+**     *pRes<0      The cursor is left pointing at an entry that
-+**                  is smaller than pKey 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 pKey.
-+**
-+**     *pRes>0      The cursor is left pointing at an entry that
-+**                  is larger than pKey.
-+*/
-+static
-+int fileBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
-+  int rc;
-+  if( pCur->pPage==0 ) return SQLITE_ABORT;
-+  pCur->eSkip = SKIP_NONE;
-+  rc = moveToRoot(pCur);
-+  if( rc ) return rc;
-+  for(;;){
-+    int lwr, upr;
-+    Pgno chldPg;
-+    MemPage *pPage = pCur->pPage;
-+    int c = -1;  /* pRes return if table is empty must be -1 */
-+    lwr = 0;
-+    upr = pPage->nCell-1;
-+    while( lwr<=upr ){
-+      pCur->idx = (lwr+upr)/2;
-+      rc = fileBtreeKeyCompare(pCur, pKey, nKey, 0, &c);
-+      if( rc ) return rc;
-+      if( c==0 ){
-+        pCur->iMatch = c;
-+        if( pRes ) *pRes = 0;
-+        return SQLITE_OK;
-+      }
-+      if( c<0 ){
-+        lwr = pCur->idx+1;
-+      }else{
-+        upr = pCur->idx-1;
-+      }
-+    }
-+    assert( lwr==upr+1 );
-+    assert( pPage->isInit );
-+    if( lwr>=pPage->nCell ){
-+      chldPg = pPage->u.hdr.rightChild;
-+    }else{
-+      chldPg = pPage->apCell[lwr]->h.leftChild;
-+    }
-+    if( chldPg==0 ){
-+      pCur->iMatch = c;
-+      if( pRes ) *pRes = c;
-+      return SQLITE_OK;
-+    }
-+    pCur->idx = lwr;
-+    rc = moveToChild(pCur, chldPg);
-+    if( rc ) return rc;
-+  }
-+  /* NOT REACHED */
-+}
-+
-+/*
-+** 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.
-+*/
-+static int fileBtreeNext(BtCursor *pCur, int *pRes){
-+  int rc;
-+  MemPage *pPage = pCur->pPage;
-+  assert( pRes!=0 );
-+  if( pPage==0 ){
-+    *pRes = 1;
-+    return SQLITE_ABORT;
-+  }
-+  assert( pPage->isInit );
-+  assert( pCur->eSkip!=SKIP_INVALID );
-+  if( pPage->nCell==0 ){
-+    *pRes = 1;
-+    return SQLITE_OK;
-+  }
-+  assert( pCur->idx<pPage->nCell );
-+  if( pCur->eSkip==SKIP_NEXT ){
-+    pCur->eSkip = SKIP_NONE;
-+    *pRes = 0;
-+    return SQLITE_OK;
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+  pCur->idx++;
-+  if( pCur->idx>=pPage->nCell ){
-+    if( pPage->u.hdr.rightChild ){
-+      rc = moveToChild(pCur, pPage->u.hdr.rightChild);
-+      if( rc ) return rc;
-+      rc = moveToLeftmost(pCur);
-+      *pRes = 0;
-+      return rc;
-+    }
-+    do{
-+      if( pPage->pParent==0 ){
-+        *pRes = 1;
-+        return SQLITE_OK;
-+      }
-+      moveToParent(pCur);
-+      pPage = pCur->pPage;
-+    }while( pCur->idx>=pPage->nCell );
-+    *pRes = 0;
-+    return SQLITE_OK;
-+  }
-+  *pRes = 0;
-+  if( pPage->u.hdr.rightChild==0 ){
-+    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.
-+*/
-+static int fileBtreePrevious(BtCursor *pCur, int *pRes){
-+  int rc;
-+  Pgno pgno;
-+  MemPage *pPage;
-+  pPage = pCur->pPage;
-+  if( pPage==0 ){
-+    *pRes = 1;
-+    return SQLITE_ABORT;
-+  }
-+  assert( pPage->isInit );
-+  assert( pCur->eSkip!=SKIP_INVALID );
-+  if( pPage->nCell==0 ){
-+    *pRes = 1;
-+    return SQLITE_OK;
-+  }
-+  if( pCur->eSkip==SKIP_PREV ){
-+    pCur->eSkip = SKIP_NONE;
-+    *pRes = 0;
-+    return SQLITE_OK;
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+  assert( pCur->idx>=0 );
-+  if( (pgno = pPage->apCell[pCur->idx]->h.leftChild)!=0 ){
-+    rc = moveToChild(pCur, pgno);
-+    if( rc ) return rc;
-+    rc = moveToRightmost(pCur);
-+  }else{
-+    while( pCur->idx==0 ){
-+      if( pPage->pParent==0 ){
-+        if( pRes ) *pRes = 1;
-+        return SQLITE_OK;
-+      }
-+      moveToParent(pCur);
-+      pPage = pCur->pPage;
-+    }
-+    pCur->idx--;
-+    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, sqlitepager_write()
-+** has already been called on the new page.)  The new page has also
-+** been referenced and the calling routine is responsible for calling
-+** sqlitepager_unref() 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 sqlitepager_unref() 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.
-+*/
-+static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){
-+  PageOne *pPage1 = pBt->page1;
-+  int rc;
-+  if( pPage1->freeList ){
-+    OverflowPage *pOvfl;
-+    FreelistInfo *pInfo;
-+
-+    rc = sqlitepager_write(pPage1);
-+    if( rc ) return rc;
-+    SWAB_ADD(pBt, pPage1->nFree, -1);
-+    rc = sqlitepager_get(pBt->pPager, SWAB32(pBt, pPage1->freeList),
-+                        (void**)&pOvfl);
-+    if( rc ) return rc;
-+    rc = sqlitepager_write(pOvfl);
-+    if( rc ){
-+      sqlitepager_unref(pOvfl);
-+      return rc;
-+    }
-+    pInfo = (FreelistInfo*)pOvfl->aPayload;
-+    if( pInfo->nFree==0 ){
-+      *pPgno = SWAB32(pBt, pPage1->freeList);
-+      pPage1->freeList = pOvfl->iNext;
-+      *ppPage = (MemPage*)pOvfl;
-+    }else{
-+      int closest, n;
-+      n = SWAB32(pBt, pInfo->nFree);
-+      if( n>1 && nearby>0 ){
-+        int i, dist;
-+        closest = 0;
-+        dist = SWAB32(pBt, pInfo->aFree[0]) - nearby;
-+        if( dist<0 ) dist = -dist;
-+        for(i=1; i<n; i++){
-+          int d2 = SWAB32(pBt, pInfo->aFree[i]) - nearby;
-+          if( d2<0 ) d2 = -d2;
-+          if( d2<dist ) closest = i;
-+        }
-+      }else{
-+        closest = 0;
-+      }
-+      SWAB_ADD(pBt, pInfo->nFree, -1);
-+      *pPgno = SWAB32(pBt, pInfo->aFree[closest]);
-+      pInfo->aFree[closest] = pInfo->aFree[n-1];
-+      rc = sqlitepager_get(pBt->pPager, *pPgno, (void**)ppPage);
-+      sqlitepager_unref(pOvfl);
-+      if( rc==SQLITE_OK ){
-+        sqlitepager_dont_rollback(*ppPage);
-+        rc = sqlitepager_write(*ppPage);
-+      }
-+    }
-+  }else{
-+    *pPgno = sqlitepager_pagecount(pBt->pPager) + 1;
-+    rc = sqlitepager_get(pBt->pPager, *pPgno, (void**)ppPage);
-+    if( rc ) return rc;
-+    rc = sqlitepager_write(*ppPage);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Add a page of the database file to the freelist.  Either pgno or
-+** pPage but not both may be 0. 
-+**
-+** sqlitepager_unref() is NOT called for pPage.
-+*/
-+static int freePage(Btree *pBt, void *pPage, Pgno pgno){
-+  PageOne *pPage1 = pBt->page1;
-+  OverflowPage *pOvfl = (OverflowPage*)pPage;
-+  int rc;
-+  int needUnref = 0;
-+  MemPage *pMemPage;
-+
-+  if( pgno==0 ){
-+    assert( pOvfl!=0 );
-+    pgno = sqlitepager_pagenumber(pOvfl);
-+  }
-+  assert( pgno>2 );
-+  assert( sqlitepager_pagenumber(pOvfl)==pgno );
-+  pMemPage = (MemPage*)pPage;
-+  pMemPage->isInit = 0;
-+  if( pMemPage->pParent ){
-+    sqlitepager_unref(pMemPage->pParent);
-+    pMemPage->pParent = 0;
-+  }
-+  rc = sqlitepager_write(pPage1);
-+  if( rc ){
-+    return rc;
-+  }
-+  SWAB_ADD(pBt, pPage1->nFree, 1);
-+  if( pPage1->nFree!=0 && pPage1->freeList!=0 ){
-+    OverflowPage *pFreeIdx;
-+    rc = sqlitepager_get(pBt->pPager, SWAB32(pBt, pPage1->freeList),
-+                        (void**)&pFreeIdx);
-+    if( rc==SQLITE_OK ){
-+      FreelistInfo *pInfo = (FreelistInfo*)pFreeIdx->aPayload;
-+      int n = SWAB32(pBt, pInfo->nFree);
-+      if( n<(sizeof(pInfo->aFree)/sizeof(pInfo->aFree[0])) ){
-+        rc = sqlitepager_write(pFreeIdx);
-+        if( rc==SQLITE_OK ){
-+          pInfo->aFree[n] = SWAB32(pBt, pgno);
-+          SWAB_ADD(pBt, pInfo->nFree, 1);
-+          sqlitepager_unref(pFreeIdx);
-+          sqlitepager_dont_write(pBt->pPager, pgno);
-+          return rc;
-+        }
-+      }
-+      sqlitepager_unref(pFreeIdx);
-+    }
-+  }
-+  if( pOvfl==0 ){
-+    assert( pgno>0 );
-+    rc = sqlitepager_get(pBt->pPager, pgno, (void**)&pOvfl);
-+    if( rc ) return rc;
-+    needUnref = 1;
-+  }
-+  rc = sqlitepager_write(pOvfl);
-+  if( rc ){
-+    if( needUnref ) sqlitepager_unref(pOvfl);
-+    return rc;
-+  }
-+  pOvfl->iNext = pPage1->freeList;
-+  pPage1->freeList = SWAB32(pBt, pgno);
-+  memset(pOvfl->aPayload, 0, OVERFLOW_SIZE);
-+  if( needUnref ) rc = sqlitepager_unref(pOvfl);
-+  return rc;
-+}
-+
-+/*
-+** Erase all the data out of a cell.  This involves returning overflow
-+** pages back the freelist.
-+*/
-+static int clearCell(Btree *pBt, Cell *pCell){
-+  Pager *pPager = pBt->pPager;
-+  OverflowPage *pOvfl;
-+  Pgno ovfl, nextOvfl;
-+  int rc;
-+
-+  if( NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h) <= MX_LOCAL_PAYLOAD ){
-+    return SQLITE_OK;
-+  }
-+  ovfl = SWAB32(pBt, pCell->ovfl);
-+  pCell->ovfl = 0;
-+  while( ovfl ){
-+    rc = sqlitepager_get(pPager, ovfl, (void**)&pOvfl);
-+    if( rc ) return rc;
-+    nextOvfl = SWAB32(pBt, pOvfl->iNext);
-+    rc = freePage(pBt, pOvfl, ovfl);
-+    if( rc ) return rc;
-+    sqlitepager_unref(pOvfl);
-+    ovfl = nextOvfl;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Create a new cell from key and data.  Overflow pages are allocated as
-+** necessary and linked to this cell.  
-+*/
-+static int fillInCell(
-+  Btree *pBt,              /* The whole Btree.  Needed to allocate pages */
-+  Cell *pCell,             /* Populate this Cell structure */
-+  const void *pKey, int nKey,    /* The key */
-+  const void *pData,int nData    /* The data */
-+){
-+  OverflowPage *pOvfl, *pPrior;
-+  Pgno *pNext;
-+  int spaceLeft;
-+  int n, rc;
-+  int nPayload;
-+  const char *pPayload;
-+  char *pSpace;
-+  Pgno nearby = 0;
-+
-+  pCell->h.leftChild = 0;
-+  pCell->h.nKey = SWAB16(pBt, nKey & 0xffff);
-+  pCell->h.nKeyHi = nKey >> 16;
-+  pCell->h.nData = SWAB16(pBt, nData & 0xffff);
-+  pCell->h.nDataHi = nData >> 16;
-+  pCell->h.iNext = 0;
-+
-+  pNext = &pCell->ovfl;
-+  pSpace = pCell->aPayload;
-+  spaceLeft = MX_LOCAL_PAYLOAD;
-+  pPayload = pKey;
-+  pKey = 0;
-+  nPayload = nKey;
-+  pPrior = 0;
-+  while( nPayload>0 ){
-+    if( spaceLeft==0 ){
-+      rc = allocatePage(pBt, (MemPage**)&pOvfl, pNext, nearby);
-+      if( rc ){
-+        *pNext = 0;
-+      }else{
-+        nearby = *pNext;
-+      }
-+      if( pPrior ) sqlitepager_unref(pPrior);
-+      if( rc ){
-+        clearCell(pBt, pCell);
-+        return rc;
-+      }
-+      if( pBt->needSwab ) *pNext = swab32(*pNext);
-+      pPrior = pOvfl;
-+      spaceLeft = OVERFLOW_SIZE;
-+      pSpace = pOvfl->aPayload;
-+      pNext = &pOvfl->iNext;
-+    }
-+    n = nPayload;
-+    if( n>spaceLeft ) n = spaceLeft;
-+    memcpy(pSpace, pPayload, n);
-+    nPayload -= n;
-+    if( nPayload==0 && pData ){
-+      pPayload = pData;
-+      nPayload = nData;
-+      pData = 0;
-+    }else{
-+      pPayload += n;
-+    }
-+    spaceLeft -= n;
-+    pSpace += n;
-+  }
-+  *pNext = 0;
-+  if( pPrior ){
-+    sqlitepager_unref(pPrior);
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Change the MemPage.pParent pointer on the page whose number is
-+** given in the second argument so that MemPage.pParent holds the
-+** pointer in the third argument.
-+*/
-+static void reparentPage(Pager *pPager, Pgno pgno, MemPage *pNewParent,int idx){
-+  MemPage *pThis;
-+
-+  if( pgno==0 ) return;
-+  assert( pPager!=0 );
-+  pThis = sqlitepager_lookup(pPager, pgno);
-+  if( pThis && pThis->isInit ){
-+    if( pThis->pParent!=pNewParent ){
-+      if( pThis->pParent ) sqlitepager_unref(pThis->pParent);
-+      pThis->pParent = pNewParent;
-+      if( pNewParent ) sqlitepager_ref(pNewParent);
-+    }
-+    pThis->idxParent = idx;
-+    sqlitepager_unref(pThis);
-+  }
-+}
-+
-+/*
-+** Reparent all children of the given page to be the given page.
-+** In other words, for every child of pPage, invoke reparentPage()
-+** to make sure that each child knows that pPage is its parent.
-+**
-+** This routine gets called after you memcpy() one page into
-+** another.
-+*/
-+static void reparentChildPages(Btree *pBt, MemPage *pPage){
-+  int i;
-+  Pager *pPager = pBt->pPager;
-+  for(i=0; i<pPage->nCell; i++){
-+    reparentPage(pPager, SWAB32(pBt, pPage->apCell[i]->h.leftChild), pPage, i);
-+  }
-+  reparentPage(pPager, SWAB32(pBt, pPage->u.hdr.rightChild), pPage, i);
-+  pPage->idxShift = 0;
-+}
-+
-+/*
-+** 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.
-+**
-+** Do not bother maintaining the integrity of the linked list of Cells.
-+** Only the pPage->apCell[] array is important.  The relinkCellList() 
-+** routine will be called soon after this routine in order to rebuild 
-+** the linked list.
-+*/
-+static void dropCell(Btree *pBt, MemPage *pPage, int idx, int sz){
-+  int j;
-+  assert( idx>=0 && idx<pPage->nCell );
-+  assert( sz==cellSize(pBt, pPage->apCell[idx]) );
-+  assert( sqlitepager_iswriteable(pPage) );
-+  freeSpace(pBt, pPage, Addr(pPage->apCell[idx]) - Addr(pPage), sz);
-+  for(j=idx; j<pPage->nCell-1; j++){
-+    pPage->apCell[j] = pPage->apCell[j+1];
-+  }
-+  pPage->nCell--;
-+  pPage->idxShift = 1;
-+}
-+
-+/*
-+** 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 just make pPage->apCell[i] point to the content
-+** and set pPage->isOverfull.  
-+**
-+** Do not bother maintaining the integrity of the linked list of Cells.
-+** Only the pPage->apCell[] array is important.  The relinkCellList() 
-+** routine will be called soon after this routine in order to rebuild 
-+** the linked list.
-+*/
-+static void insertCell(Btree *pBt, MemPage *pPage, int i, Cell *pCell, int sz){
-+  int idx, j;
-+  assert( i>=0 && i<=pPage->nCell );
-+  assert( sz==cellSize(pBt, pCell) );
-+  assert( sqlitepager_iswriteable(pPage) );
-+  idx = allocateSpace(pBt, pPage, sz);
-+  for(j=pPage->nCell; j>i; j--){
-+    pPage->apCell[j] = pPage->apCell[j-1];
-+  }
-+  pPage->nCell++;
-+  if( idx<=0 ){
-+    pPage->isOverfull = 1;
-+    pPage->apCell[i] = pCell;
-+  }else{
-+    memcpy(&pPage->u.aDisk[idx], pCell, sz);
-+    pPage->apCell[i] = (Cell*)&pPage->u.aDisk[idx];
-+  }
-+  pPage->idxShift = 1;
-+}
-+
-+/*
-+** Rebuild the linked list of cells on a page so that the cells
-+** occur in the order specified by the pPage->apCell[] array.  
-+** Invoke this routine once to repair damage after one or more
-+** invocations of either insertCell() or dropCell().
-+*/
-+static void relinkCellList(Btree *pBt, MemPage *pPage){
-+  int i;
-+  u16 *pIdx;
-+  assert( sqlitepager_iswriteable(pPage) );
-+  pIdx = &pPage->u.hdr.firstCell;
-+  for(i=0; i<pPage->nCell; i++){
-+    int idx = Addr(pPage->apCell[i]) - Addr(pPage);
-+    assert( idx>0 && idx<SQLITE_USABLE_SIZE );
-+    *pIdx = SWAB16(pBt, idx);
-+    pIdx = &pPage->apCell[i]->h.iNext;
-+  }
-+  *pIdx = 0;
-+}
-+
-+/*
-+** Make a copy of the contents of pFrom into pTo.  The pFrom->apCell[]
-+** pointers that point into pFrom->u.aDisk[] must be adjusted to point
-+** into pTo->u.aDisk[] instead.  But some pFrom->apCell[] entries might
-+** not point to pFrom->u.aDisk[].  Those are unchanged.
-+*/
-+static void copyPage(MemPage *pTo, MemPage *pFrom){
-+  uptr from, to;
-+  int i;
-+  memcpy(pTo->u.aDisk, pFrom->u.aDisk, SQLITE_USABLE_SIZE);
-+  pTo->pParent = 0;
-+  pTo->isInit = 1;
-+  pTo->nCell = pFrom->nCell;
-+  pTo->nFree = pFrom->nFree;
-+  pTo->isOverfull = pFrom->isOverfull;
-+  to = Addr(pTo);
-+  from = Addr(pFrom);
-+  for(i=0; i<pTo->nCell; i++){
-+    uptr x = Addr(pFrom->apCell[i]);
-+    if( x>from && x<from+SQLITE_USABLE_SIZE ){
-+      *((uptr*)&pTo->apCell[i]) = x + to - from;
-+    }else{
-+      pTo->apCell[i] = pFrom->apCell[i];
-+    }
-+  }
-+}
-+
-+/*
-+** 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 */
-+
-+/*
-+** This routine redistributes Cells on pPage and up to two siblings
-+** of pPage so that all pages have about the same amount of free space.
-+** Usually one sibling on either side of pPage is used in the balancing,
-+** though both siblings might come from one side if pPage is the first
-+** or last child of its parent.  If pPage has fewer than two siblings
-+** (something which can only happen if pPage is the root page or a 
-+** child of root) then all available siblings participate in the balancing.
-+**
-+** The number of siblings of pPage might be increased or decreased by
-+** one in an effort to keep pages between 66% and 100% full. The root page
-+** is special and is allowed to be less than 66% full. If pPage is 
-+** the root page, then the depth of the tree might be increased
-+** or decreased by one, as necessary, to keep the root page from being
-+** overfull or empty.
-+**
-+** This routine calls relinkCellList() on its input page regardless of
-+** whether or not it does any real balancing.  Client routines will typically
-+** invoke insertCell() or dropCell() before calling this routine, so we
-+** need to call relinkCellList() to clean up the mess that those other
-+** routines left behind.
-+**
-+** pCur is left pointing to the same cell as when this routine was called
-+** even if that cell gets moved to a different page.  pCur may be NULL.
-+** Set the pCur parameter to NULL if you do not care about keeping track
-+** of a cell as that will save this routine the work of keeping track of it.
-+**
-+** Note that when this routine is called, some of the Cells on pPage
-+** might not actually be stored in pPage->u.aDisk[].  This can happen
-+** if the page is overfull.  Part of the job of this routine is to
-+** make sure all Cells for pPage once again fit in pPage->u.aDisk[].
-+**
-+** In the course of balancing the siblings of pPage, the parent of pPage
-+** might become overfull or underfull.  If that happens, then this routine
-+** is called recursively on the parent.
-+**
-+** 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.
-+*/
-+static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
-+  MemPage *pParent;            /* The parent of pPage */
-+  int nCell;                   /* Number of cells in apCell[] */
-+  int nOld;                    /* Number of pages in apOld[] */
-+  int nNew;                    /* Number of pages in apNew[] */
-+  int nDiv;                    /* Number of cells in apDiv[] */
-+  int i, j, k;                 /* Loop counters */
-+  int idx;                     /* Index of pPage in pParent->apCell[] */
-+  int nxDiv;                   /* Next divider slot in pParent->apCell[] */
-+  int rc;                      /* The return code */
-+  int iCur;                    /* apCell[iCur] is the cell of the cursor */
-+  MemPage *pOldCurPage;        /* The cursor originally points to this page */
-+  int subtotal;                /* Subtotal of bytes in cells on one page */
-+  MemPage *extraUnref = 0;     /* A page that needs to be unref-ed */
-+  MemPage *apOld[NB];          /* pPage and up to two siblings */
-+  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
-+  MemPage *apNew[NB+1];        /* pPage and up to NB siblings after balancing */
-+  Pgno pgnoNew[NB+1];          /* Page numbers for each page in apNew[] */
-+  int idxDiv[NB];              /* Indices of divider cells in pParent */
-+  Cell *apDiv[NB];             /* Divider cells in pParent */
-+  Cell aTemp[NB];              /* Temporary holding area for apDiv[] */
-+  int cntNew[NB+1];            /* Index in apCell[] of cell after i-th page */
-+  int szNew[NB+1];             /* Combined size of cells place on i-th page */
-+  MemPage aOld[NB];            /* Temporary copies of pPage and its siblings */
-+  Cell *apCell[(MX_CELL+2)*NB]; /* All cells from pages being balanced */
-+  int szCell[(MX_CELL+2)*NB];  /* Local size of all cells */
-+
-+  /* 
-+  ** Return without doing any work if pPage is neither overfull nor
-+  ** underfull.
-+  */
-+  assert( sqlitepager_iswriteable(pPage) );
-+  if( !pPage->isOverfull && pPage->nFree<SQLITE_USABLE_SIZE/2 
-+        && pPage->nCell>=2){
-+    relinkCellList(pBt, pPage);
-+    return SQLITE_OK;
-+  }
-+
-+  /*
-+  ** Find the parent of the page to be balanceed.
-+  ** If there is no parent, it means this page is the root page and
-+  ** special rules apply.
-+  */
-+  pParent = pPage->pParent;
-+  if( pParent==0 ){
-+    Pgno pgnoChild;
-+    MemPage *pChild;
-+    assert( pPage->isInit );
-+    if( pPage->nCell==0 ){
-+      if( pPage->u.hdr.rightChild ){
-+        /*
-+        ** The root page is empty.  Copy the one child page
-+        ** into the root page and return.  This reduces the depth
-+        ** of the BTree by one.
-+        */
-+        pgnoChild = SWAB32(pBt, pPage->u.hdr.rightChild);
-+        rc = sqlitepager_get(pBt->pPager, pgnoChild, (void**)&pChild);
-+        if( rc ) return rc;
-+        memcpy(pPage, pChild, SQLITE_USABLE_SIZE);
-+        pPage->isInit = 0;
-+        rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0);
-+        assert( rc==SQLITE_OK );
-+        reparentChildPages(pBt, pPage);
-+        if( pCur && pCur->pPage==pChild ){
-+          sqlitepager_unref(pChild);
-+          pCur->pPage = pPage;
-+          sqlitepager_ref(pPage);
-+        }
-+        freePage(pBt, pChild, pgnoChild);
-+        sqlitepager_unref(pChild);
-+      }else{
-+        relinkCellList(pBt, pPage);
-+      }
-+      return SQLITE_OK;
-+    }
-+    if( !pPage->isOverfull ){
-+      /* It is OK for the root page to be less than half full.
-+      */
-+      relinkCellList(pBt, pPage);
-+      return SQLITE_OK;
-+    }
-+    /*
-+    ** If we get to here, it means the root page is overfull.
-+    ** When this happens, Create a new child page and copy the
-+    ** contents of the root into the child.  Then make the root
-+    ** page an empty page with rightChild pointing to the new
-+    ** child.  Then fall thru to the code below which will cause
-+    ** the overfull child page to be split.
-+    */
-+    rc = sqlitepager_write(pPage);
-+    if( rc ) return rc;
-+    rc = allocatePage(pBt, &pChild, &pgnoChild, sqlitepager_pagenumber(pPage));
-+    if( rc ) return rc;
-+    assert( sqlitepager_iswriteable(pChild) );
-+    copyPage(pChild, pPage);
-+    pChild->pParent = pPage;
-+    pChild->idxParent = 0;
-+    sqlitepager_ref(pPage);
-+    pChild->isOverfull = 1;
-+    if( pCur && pCur->pPage==pPage ){
-+      sqlitepager_unref(pPage);
-+      pCur->pPage = pChild;
-+    }else{
-+      extraUnref = pChild;
-+    }
-+    zeroPage(pBt, pPage);
-+    pPage->u.hdr.rightChild = SWAB32(pBt, pgnoChild);
-+    pParent = pPage;
-+    pPage = pChild;
-+  }
-+  rc = sqlitepager_write(pParent);
-+  if( rc ) return rc;
-+  assert( pParent->isInit );
-+  
-+  /*
-+  ** Find the Cell in the parent page whose h.leftChild points back
-+  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
-+  ** is the rightmost child of pParent then set idx to pParent->nCell 
-+  */
-+  if( pParent->idxShift ){
-+    Pgno pgno, swabPgno;
-+    pgno = sqlitepager_pagenumber(pPage);
-+    swabPgno = SWAB32(pBt, pgno);
-+    for(idx=0; idx<pParent->nCell; idx++){
-+      if( pParent->apCell[idx]->h.leftChild==swabPgno ){
-+        break;
-+      }
-+    }
-+    assert( idx<pParent->nCell || pParent->u.hdr.rightChild==swabPgno );
-+  }else{
-+    idx = pPage->idxParent;
-+  }
-+
-+  /*
-+  ** Initialize variables so that it will be safe to jump
-+  ** directly to balance_cleanup at any moment.
-+  */
-+  nOld = nNew = 0;
-+  sqlitepager_ref(pParent);
-+
-+  /*
-+  ** Find sibling pages to pPage and 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
-+  ** pPage there are fewer than NN siblings on the other side.  If pParent
-+  ** has NB or fewer children then all children of pParent are taken.
-+  */
-+  nxDiv = idx - NN;
-+  if( nxDiv + NB > pParent->nCell ){
-+    nxDiv = pParent->nCell - NB + 1;
-+  }
-+  if( nxDiv<0 ){
-+    nxDiv = 0;
-+  }
-+  nDiv = 0;
-+  for(i=0, k=nxDiv; i<NB; i++, k++){
-+    if( k<pParent->nCell ){
-+      idxDiv[i] = k;
-+      apDiv[i] = pParent->apCell[k];
-+      nDiv++;
-+      pgnoOld[i] = SWAB32(pBt, apDiv[i]->h.leftChild);
-+    }else if( k==pParent->nCell ){
-+      pgnoOld[i] = SWAB32(pBt, pParent->u.hdr.rightChild);
-+    }else{
-+      break;
-+    }
-+    rc = sqlitepager_get(pBt->pPager, pgnoOld[i], (void**)&apOld[i]);
-+    if( rc ) goto balance_cleanup;
-+    rc = initPage(pBt, apOld[i], pgnoOld[i], pParent);
-+    if( rc ) goto balance_cleanup;
-+    apOld[i]->idxParent = k;
-+    nOld++;
-+  }
-+
-+  /*
-+  ** Set iCur to be the index in apCell[] of the cell that the cursor
-+  ** is pointing to.  We will need this later on in order to keep the
-+  ** cursor pointing at the same cell.  If pCur points to a page that
-+  ** has no involvement with this rebalancing, then set iCur to a large
-+  ** number so that the iCur==j tests always fail in the main cell
-+  ** distribution loop below.
-+  */
-+  if( pCur ){
-+    iCur = 0;
-+    for(i=0; i<nOld; i++){
-+      if( pCur->pPage==apOld[i] ){
-+        iCur += pCur->idx;
-+        break;
-+      }
-+      iCur += apOld[i]->nCell;
-+      if( i<nOld-1 && pCur->pPage==pParent && pCur->idx==idxDiv[i] ){
-+        break;
-+      }
-+      iCur++;
-+    }
-+    pOldCurPage = pCur->pPage;
-+  }
-+
-+  /*
-+  ** Make copies of the content of pPage and its siblings into aOld[].
-+  ** 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.
-+  */
-+  for(i=0; i<nOld; i++){
-+    copyPage(&aOld[i], apOld[i]);
-+  }
-+
-+  /*
-+  ** Load pointers to all cells on sibling pages and the divider cells
-+  ** into the local apCell[] array.  Make copies of the divider cells
-+  ** into aTemp[] and remove the the divider Cells from pParent.
-+  */
-+  nCell = 0;
-+  for(i=0; i<nOld; i++){
-+    MemPage *pOld = &aOld[i];
-+    for(j=0; j<pOld->nCell; j++){
-+      apCell[nCell] = pOld->apCell[j];
-+      szCell[nCell] = cellSize(pBt, apCell[nCell]);
-+      nCell++;
-+    }
-+    if( i<nOld-1 ){
-+      szCell[nCell] = cellSize(pBt, apDiv[i]);
-+      memcpy(&aTemp[i], apDiv[i], szCell[nCell]);
-+      apCell[nCell] = &aTemp[i];
-+      dropCell(pBt, pParent, nxDiv, szCell[nCell]);
-+      assert( SWAB32(pBt, apCell[nCell]->h.leftChild)==pgnoOld[i] );
-+      apCell[nCell]->h.leftChild = pOld->u.hdr.rightChild;
-+      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 path i from path i+1.  
-+  ** cntNew[k] should equal nCell.
-+  **
-+  ** This little patch of code is critical for keeping the tree
-+  ** balanced. 
-+  */
-+  for(subtotal=k=i=0; i<nCell; i++){
-+    subtotal += szCell[i];
-+    if( subtotal > USABLE_SPACE ){
-+      szNew[k] = subtotal - szCell[i];
-+      cntNew[k] = i;
-+      subtotal = 0;
-+      k++;
-+    }
-+  }
-+  szNew[k] = subtotal;
-+  cntNew[k] = nCell;
-+  k++;
-+  for(i=k-1; i>0; i--){
-+    while( szNew[i]<USABLE_SPACE/2 ){
-+      cntNew[i-1]--;
-+      assert( cntNew[i-1]>0 );
-+      szNew[i] += szCell[cntNew[i-1]];
-+      szNew[i-1] -= szCell[cntNew[i-1]-1];
-+    }
-+  }
-+  assert( cntNew[0]>0 );
-+
-+  /*
-+  ** Allocate k new pages.  Reuse old pages where possible.
-+  */
-+  for(i=0; i<k; i++){
-+    if( i<nOld ){
-+      apNew[i] = apOld[i];
-+      pgnoNew[i] = pgnoOld[i];
-+      apOld[i] = 0;
-+      sqlitepager_write(apNew[i]);
-+    }else{
-+      rc = allocatePage(pBt, &apNew[i], &pgnoNew[i], pgnoNew[i-1]);
-+      if( rc ) goto balance_cleanup;
-+    }
-+    nNew++;
-+    zeroPage(pBt, apNew[i]);
-+    apNew[i]->isInit = 1;
-+  }
-+
-+  /* Free any old pages that were not reused as new pages.
-+  */
-+  while( i<nOld ){
-+    rc = freePage(pBt, apOld[i], pgnoOld[i]);
-+    if( rc ) goto balance_cleanup;
-+    sqlitepager_unref(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 = pgnoNew[i];
-+    int minI = i;
-+    for(j=i+1; j<k; j++){
-+      if( pgnoNew[j]<(unsigned)minV ){
-+        minI = j;
-+        minV = pgnoNew[j];
-+      }
-+    }
-+    if( minI>i ){
-+      int t;
-+      MemPage *pT;
-+      t = pgnoNew[i];
-+      pT = apNew[i];
-+      pgnoNew[i] = pgnoNew[minI];
-+      apNew[i] = apNew[minI];
-+      pgnoNew[minI] = t;
-+      apNew[minI] = pT;
-+    }
-+  }
-+
-+  /*
-+  ** 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++){
-+    MemPage *pNew = apNew[i];
-+    while( j<cntNew[i] ){
-+      assert( pNew->nFree>=szCell[j] );
-+      if( pCur && iCur==j ){ pCur->pPage = pNew; pCur->idx = pNew->nCell; }
-+      insertCell(pBt, pNew, pNew->nCell, apCell[j], szCell[j]);
-+      j++;
-+    }
-+    assert( pNew->nCell>0 );
-+    assert( !pNew->isOverfull );
-+    relinkCellList(pBt, pNew);
-+    if( i<nNew-1 && j<nCell ){
-+      pNew->u.hdr.rightChild = apCell[j]->h.leftChild;
-+      apCell[j]->h.leftChild = SWAB32(pBt, pgnoNew[i]);
-+      if( pCur && iCur==j ){ pCur->pPage = pParent; pCur->idx = nxDiv; }
-+      insertCell(pBt, pParent, nxDiv, apCell[j], szCell[j]);
-+      j++;
-+      nxDiv++;
-+    }
-+  }
-+  assert( j==nCell );
-+  apNew[nNew-1]->u.hdr.rightChild = aOld[nOld-1].u.hdr.rightChild;
-+  if( nxDiv==pParent->nCell ){
-+    pParent->u.hdr.rightChild = SWAB32(pBt, pgnoNew[nNew-1]);
-+  }else{
-+    pParent->apCell[nxDiv]->h.leftChild = SWAB32(pBt, pgnoNew[nNew-1]);
-+  }
-+  if( pCur ){
-+    if( j<=iCur && pCur->pPage==pParent && pCur->idx>idxDiv[nOld-1] ){
-+      assert( pCur->pPage==pOldCurPage );
-+      pCur->idx += nNew - nOld;
-+    }else{
-+      assert( pOldCurPage!=0 );
-+      sqlitepager_ref(pCur->pPage);
-+      sqlitepager_unref(pOldCurPage);
-+    }
-+  }
-+
-+  /*
-+  ** Reparent children of all cells.
-+  */
-+  for(i=0; i<nNew; i++){
-+    reparentChildPages(pBt, apNew[i]);
-+  }
-+  reparentChildPages(pBt, pParent);
-+
-+  /*
-+  ** balance the parent page.
-+  */
-+  rc = balance(pBt, pParent, pCur);
-+
-+  /*
-+  ** Cleanup before returning.
-+  */
-+balance_cleanup:
-+  if( extraUnref ){
-+    sqlitepager_unref(extraUnref);
-+  }
-+  for(i=0; i<nOld; i++){
-+    if( apOld[i]!=0 && apOld[i]!=&aOld[i] ) sqlitepager_unref(apOld[i]);
-+  }
-+  for(i=0; i<nNew; i++){
-+    sqlitepager_unref(apNew[i]);
-+  }
-+  if( pCur && pCur->pPage==0 ){
-+    pCur->pPage = pParent;
-+    pCur->idx = 0;
-+  }else{
-+    sqlitepager_unref(pParent);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** This routine checks all cursors that point to the same table
-+** as pCur points to.  If any of those cursors were opened with
-+** wrFlag==0 then this routine returns SQLITE_LOCKED.  If all
-+** cursors point to the same table were opened with wrFlag==1
-+** then this routine returns SQLITE_OK.
-+**
-+** In addition to checking for read-locks (where a read-lock 
-+** means a cursor opened with wrFlag==0) this routine also moves
-+** all cursors other than pCur so that they are pointing to the 
-+** first Cell on root page.  This is necessary because an insert 
-+** or delete might change the number of cells on a page or delete
-+** a page entirely and we do not want to leave any cursors 
-+** pointing to non-existant pages or cells.
-+*/
-+static int checkReadLocks(BtCursor *pCur){
-+  BtCursor *p;
-+  assert( pCur->wrFlag );
-+  for(p=pCur->pShared; p!=pCur; p=p->pShared){
-+    assert( p );
-+    assert( p->pgnoRoot==pCur->pgnoRoot );
-+    if( p->wrFlag==0 ) return SQLITE_LOCKED;
-+    if( sqlitepager_pagenumber(p->pPage)!=p->pgnoRoot ){
-+      moveToRoot(p);
-+    }
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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 database the record should be inserted into.  The cursor
-+** is left pointing at the new record.
-+*/
-+static int fileBtreeInsert(
-+  BtCursor *pCur,                /* Insert data into the table of this cursor */
-+  const void *pKey, int nKey,    /* The key of the new record */
-+  const void *pData, int nData   /* The data of the new record */
-+){
-+  Cell newCell;
-+  int rc;
-+  int loc;
-+  int szNew;
-+  MemPage *pPage;
-+  Btree *pBt = pCur->pBt;
-+
-+  if( pCur->pPage==0 ){
-+    return SQLITE_ABORT;  /* A rollback destroyed this cursor */
-+  }
-+  if( !pBt->inTrans || nKey+nData==0 ){
-+    /* Must start a transaction before doing an insert */
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  assert( !pBt->readOnly );
-+  if( !pCur->wrFlag ){
-+    return SQLITE_PERM;   /* Cursor not open for writing */
-+  }
-+  if( checkReadLocks(pCur) ){
-+    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
-+  }
-+  rc = fileBtreeMoveto(pCur, pKey, nKey, &loc);
-+  if( rc ) return rc;
-+  pPage = pCur->pPage;
-+  assert( pPage->isInit );
-+  rc = sqlitepager_write(pPage);
-+  if( rc ) return rc;
-+  rc = fillInCell(pBt, &newCell, pKey, nKey, pData, nData);
-+  if( rc ) return rc;
-+  szNew = cellSize(pBt, &newCell);
-+  if( loc==0 ){
-+    newCell.h.leftChild = pPage->apCell[pCur->idx]->h.leftChild;
-+    rc = clearCell(pBt, pPage->apCell[pCur->idx]);
-+    if( rc ) return rc;
-+    dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pPage->apCell[pCur->idx]));
-+  }else if( loc<0 && pPage->nCell>0 ){
-+    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
-+    pCur->idx++;
-+  }else{
-+    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
-+  }
-+  insertCell(pBt, pPage, pCur->idx, &newCell, szNew);
-+  rc = balance(pCur->pBt, pPage, pCur);
-+  /* sqliteBtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
-+  /* fflush(stdout); */
-+  pCur->eSkip = SKIP_INVALID;
-+  return rc;
-+}
-+
-+/*
-+** Delete the entry that the cursor is pointing to.
-+**
-+** The cursor is left pointing at either the next or the previous
-+** entry.  If the cursor is left pointing to the next entry, then 
-+** the pCur->eSkip flag is set to SKIP_NEXT which forces the next call to 
-+** sqliteBtreeNext() to be a no-op.  That way, you can always call
-+** sqliteBtreeNext() after a delete and the cursor will be left
-+** pointing to the first entry after the deleted entry.  Similarly,
-+** pCur->eSkip is set to SKIP_PREV is the cursor is left pointing to
-+** the entry prior to the deleted entry so that a subsequent call to
-+** sqliteBtreePrevious() will always leave the cursor pointing at the
-+** entry immediately before the one that was deleted.
-+*/
-+static int fileBtreeDelete(BtCursor *pCur){
-+  MemPage *pPage = pCur->pPage;
-+  Cell *pCell;
-+  int rc;
-+  Pgno pgnoChild;
-+  Btree *pBt = pCur->pBt;
-+
-+  assert( pPage->isInit );
-+  if( pCur->pPage==0 ){
-+    return SQLITE_ABORT;  /* A rollback destroyed this cursor */
-+  }
-+  if( !pBt->inTrans ){
-+    /* Must start a transaction before doing a delete */
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  assert( !pBt->readOnly );
-+  if( pCur->idx >= pPage->nCell ){
-+    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
-+  }
-+  if( !pCur->wrFlag ){
-+    return SQLITE_PERM;   /* Did not open this cursor for writing */
-+  }
-+  if( checkReadLocks(pCur) ){
-+    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
-+  }
-+  rc = sqlitepager_write(pPage);
-+  if( rc ) return rc;
-+  pCell = pPage->apCell[pCur->idx];
-+  pgnoChild = SWAB32(pBt, pCell->h.leftChild);
-+  clearCell(pBt, pCell);
-+  if( pgnoChild ){
-+    /*
-+    ** The entry we are about to delete is not a leaf so if we do not
-+    ** do something we will leave a hole on an internal page.
-+    ** We have to fill the hole by moving in a cell from a leaf.  The
-+    ** next Cell after the one to be deleted is guaranteed to exist and
-+    ** to be a leaf so we can use it.
-+    */
-+    BtCursor leafCur;
-+    Cell *pNext;
-+    int szNext;
-+    int notUsed;
-+    getTempCursor(pCur, &leafCur);
-+    rc = fileBtreeNext(&leafCur, &notUsed);
-+    if( rc!=SQLITE_OK ){
-+      if( rc!=SQLITE_NOMEM ) rc = SQLITE_CORRUPT;
-+      return rc;
-+    }
-+    rc = sqlitepager_write(leafCur.pPage);
-+    if( rc ) return rc;
-+    dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pCell));
-+    pNext = leafCur.pPage->apCell[leafCur.idx];
-+    szNext = cellSize(pBt, pNext);
-+    pNext->h.leftChild = SWAB32(pBt, pgnoChild);
-+    insertCell(pBt, pPage, pCur->idx, pNext, szNext);
-+    rc = balance(pBt, pPage, pCur);
-+    if( rc ) return rc;
-+    pCur->eSkip = SKIP_NEXT;
-+    dropCell(pBt, leafCur.pPage, leafCur.idx, szNext);
-+    rc = balance(pBt, leafCur.pPage, pCur);
-+    releaseTempCursor(&leafCur);
-+  }else{
-+    dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pCell));
-+    if( pCur->idx>=pPage->nCell ){
-+      pCur->idx = pPage->nCell-1;
-+      if( pCur->idx<0 ){ 
-+        pCur->idx = 0;
-+        pCur->eSkip = SKIP_NEXT;
-+      }else{
-+        pCur->eSkip = SKIP_PREV;
-+      }
-+    }else{
-+      pCur->eSkip = SKIP_NEXT;
-+    }
-+    rc = balance(pBt, pPage, pCur);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Create a new BTree table.  Write into *piTable the page
-+** number for the root page of the new table.
-+**
-+** In the current implementation, BTree tables and BTree indices are the 
-+** the same.  In the future, we may change this so that BTree tables
-+** are restricted to having a 4-byte integer key and arbitrary data and
-+** BTree indices are restricted to having an arbitrary key and no data.
-+** But for now, this routine also serves to create indices.
-+*/
-+static int fileBtreeCreateTable(Btree *pBt, int *piTable){
-+  MemPage *pRoot;
-+  Pgno pgnoRoot;
-+  int rc;
-+  if( !pBt->inTrans ){
-+    /* Must start a transaction first */
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  if( pBt->readOnly ){
-+    return SQLITE_READONLY;
-+  }
-+  rc = allocatePage(pBt, &pRoot, &pgnoRoot, 0);
-+  if( rc ) return rc;
-+  assert( sqlitepager_iswriteable(pRoot) );
-+  zeroPage(pBt, pRoot);
-+  sqlitepager_unref(pRoot);
-+  *piTable = (int)pgnoRoot;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Erase the given database page and all its children.  Return
-+** the page to the freelist.
-+*/
-+static int clearDatabasePage(Btree *pBt, Pgno pgno, int freePageFlag){
-+  MemPage *pPage;
-+  int rc;
-+  Cell *pCell;
-+  int idx;
-+
-+  rc = sqlitepager_get(pBt->pPager, pgno, (void**)&pPage);
-+  if( rc ) return rc;
-+  rc = sqlitepager_write(pPage);
-+  if( rc ) return rc;
-+  rc = initPage(pBt, pPage, pgno, 0);
-+  if( rc ) return rc;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstCell);
-+  while( idx>0 ){
-+    pCell = (Cell*)&pPage->u.aDisk[idx];
-+    idx = SWAB16(pBt, pCell->h.iNext);
-+    if( pCell->h.leftChild ){
-+      rc = clearDatabasePage(pBt, SWAB32(pBt, pCell->h.leftChild), 1);
-+      if( rc ) return rc;
-+    }
-+    rc = clearCell(pBt, pCell);
-+    if( rc ) return rc;
-+  }
-+  if( pPage->u.hdr.rightChild ){
-+    rc = clearDatabasePage(pBt, SWAB32(pBt, pPage->u.hdr.rightChild), 1);
-+    if( rc ) return rc;
-+  }
-+  if( freePageFlag ){
-+    rc = freePage(pBt, pPage, pgno);
-+  }else{
-+    zeroPage(pBt, pPage);
-+  }
-+  sqlitepager_unref(pPage);
-+  return rc;
-+}
-+
-+/*
-+** Delete all information from a single table in the database.
-+*/
-+static int fileBtreeClearTable(Btree *pBt, int iTable){
-+  int rc;
-+  BtCursor *pCur;
-+  if( !pBt->inTrans ){
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-+    if( pCur->pgnoRoot==(Pgno)iTable ){
-+      if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
-+      moveToRoot(pCur);
-+    }
-+  }
-+  rc = clearDatabasePage(pBt, (Pgno)iTable, 0);
-+  if( rc ){
-+    fileBtreeRollback(pBt);
-+  }
-+  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 2) is never added to the freelist.
-+*/
-+static int fileBtreeDropTable(Btree *pBt, int iTable){
-+  int rc;
-+  MemPage *pPage;
-+  BtCursor *pCur;
-+  if( !pBt->inTrans ){
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
-+    if( pCur->pgnoRoot==(Pgno)iTable ){
-+      return SQLITE_LOCKED;  /* Cannot drop a table that has a cursor */
-+    }
-+  }
-+  rc = sqlitepager_get(pBt->pPager, (Pgno)iTable, (void**)&pPage);
-+  if( rc ) return rc;
-+  rc = fileBtreeClearTable(pBt, iTable);
-+  if( rc ) return rc;
-+  if( iTable>2 ){
-+    rc = freePage(pBt, pPage, iTable);
-+  }else{
-+    zeroPage(pBt, pPage);
-+  }
-+  sqlitepager_unref(pPage);
-+  return rc;  
-+}
-+
-+#if 0 /* UNTESTED */
-+/*
-+** Copy all cell data from one database file into another.
-+** pages back the freelist.
-+*/
-+static int copyCell(Btree *pBtFrom, BTree *pBtTo, Cell *pCell){
-+  Pager *pFromPager = pBtFrom->pPager;
-+  OverflowPage *pOvfl;
-+  Pgno ovfl, nextOvfl;
-+  Pgno *pPrev;
-+  int rc = SQLITE_OK;
-+  MemPage *pNew, *pPrevPg;
-+  Pgno new;
-+
-+  if( NKEY(pBtTo, pCell->h) + NDATA(pBtTo, pCell->h) <= MX_LOCAL_PAYLOAD ){
-+    return SQLITE_OK;
-+  }
-+  pPrev = &pCell->ovfl;
-+  pPrevPg = 0;
-+  ovfl = SWAB32(pBtTo, pCell->ovfl);
-+  while( ovfl && rc==SQLITE_OK ){
-+    rc = sqlitepager_get(pFromPager, ovfl, (void**)&pOvfl);
-+    if( rc ) return rc;
-+    nextOvfl = SWAB32(pBtFrom, pOvfl->iNext);
-+    rc = allocatePage(pBtTo, &pNew, &new, 0);
-+    if( rc==SQLITE_OK ){
-+      rc = sqlitepager_write(pNew);
-+      if( rc==SQLITE_OK ){
-+        memcpy(pNew, pOvfl, SQLITE_USABLE_SIZE);
-+        *pPrev = SWAB32(pBtTo, new);
-+        if( pPrevPg ){
-+          sqlitepager_unref(pPrevPg);
-+        }
-+        pPrev = &pOvfl->iNext;
-+        pPrevPg = pNew;
-+      }
-+    }
-+    sqlitepager_unref(pOvfl);
-+    ovfl = nextOvfl;
-+  }
-+  if( pPrevPg ){
-+    sqlitepager_unref(pPrevPg);
-+  }
-+  return rc;
-+}
-+#endif
-+
-+
-+#if 0 /* UNTESTED */
-+/*
-+** Copy a page of data from one database over to another.
-+*/
-+static int copyDatabasePage(
-+  Btree *pBtFrom,
-+  Pgno pgnoFrom,
-+  Btree *pBtTo,
-+  Pgno *pTo
-+){
-+  MemPage *pPageFrom, *pPage;
-+  Pgno to;
-+  int rc;
-+  Cell *pCell;
-+  int idx;
-+
-+  rc = sqlitepager_get(pBtFrom->pPager, pgno, (void**)&pPageFrom);
-+  if( rc ) return rc;
-+  rc = allocatePage(pBt, &pPage, pTo, 0);
-+  if( rc==SQLITE_OK ){
-+    rc = sqlitepager_write(pPage);
-+  }
-+  if( rc==SQLITE_OK ){
-+    memcpy(pPage, pPageFrom, SQLITE_USABLE_SIZE);
-+    idx = SWAB16(pBt, pPage->u.hdr.firstCell);
-+    while( idx>0 ){
-+      pCell = (Cell*)&pPage->u.aDisk[idx];
-+      idx = SWAB16(pBt, pCell->h.iNext);
-+      if( pCell->h.leftChild ){
-+        Pgno newChld;
-+        rc = copyDatabasePage(pBtFrom, SWAB32(pBtFrom, pCell->h.leftChild),
-+                              pBtTo, &newChld);
-+        if( rc ) return rc;
-+        pCell->h.leftChild = SWAB32(pBtFrom, newChld);
-+      }
-+      rc = copyCell(pBtFrom, pBtTo, pCell);
-+      if( rc ) return rc;
-+    }
-+    if( pPage->u.hdr.rightChild ){
-+      Pgno newChld;
-+      rc = copyDatabasePage(pBtFrom, SWAB32(pBtFrom, pPage->u.hdr.rightChild), 
-+                            pBtTo, &newChld);
-+      if( rc ) return rc;
-+      pPage->u.hdr.rightChild = SWAB32(pBtTo, newChild);
-+    }
-+  }
-+  sqlitepager_unref(pPage);
-+  return rc;
-+}
-+#endif
-+
-+/*
-+** Read the meta-information out of a database file.
-+*/
-+static int fileBtreeGetMeta(Btree *pBt, int *aMeta){
-+  PageOne *pP1;
-+  int rc;
-+  int i;
-+
-+  rc = sqlitepager_get(pBt->pPager, 1, (void**)&pP1);
-+  if( rc ) return rc;
-+  aMeta[0] = SWAB32(pBt, pP1->nFree);
-+  for(i=0; i<sizeof(pP1->aMeta)/sizeof(pP1->aMeta[0]); i++){
-+    aMeta[i+1] = SWAB32(pBt, pP1->aMeta[i]);
-+  }
-+  sqlitepager_unref(pP1);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Write meta-information back into the database.
-+*/
-+static int fileBtreeUpdateMeta(Btree *pBt, int *aMeta){
-+  PageOne *pP1;
-+  int rc, i;
-+  if( !pBt->inTrans ){
-+    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-+  }
-+  pP1 = pBt->page1;
-+  rc = sqlitepager_write(pP1);
-+  if( rc ) return rc;   
-+  for(i=0; i<sizeof(pP1->aMeta)/sizeof(pP1->aMeta[0]); i++){
-+    pP1->aMeta[i] = SWAB32(pBt, aMeta[i+1]);
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/******************************************************************************
-+** The complete implementation of the BTree subsystem is above this line.
-+** All the code the follows is for testing and troubleshooting the BTree
-+** subsystem.  None of the code that follows is used during normal operation.
-+******************************************************************************/
-+
-+/*
-+** Print a disassembly of the given page on standard output.  This routine
-+** is used for debugging and testing only.
-+*/
-+#ifdef SQLITE_TEST
-+static int fileBtreePageDump(Btree *pBt, int pgno, int recursive){
-+  int rc;
-+  MemPage *pPage;
-+  int i, j;
-+  int nFree;
-+  u16 idx;
-+  char range[20];
-+  unsigned char payload[20];
-+  rc = sqlitepager_get(pBt->pPager, (Pgno)pgno, (void**)&pPage);
-+  if( rc ){
-+    return rc;
-+  }
-+  if( recursive ) printf("PAGE %d:\n", pgno);
-+  i = 0;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstCell);
-+  while( idx>0 && idx<=SQLITE_USABLE_SIZE-MIN_CELL_SIZE ){
-+    Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
-+    int sz = cellSize(pBt, pCell);
-+    sprintf(range,"%d..%d", idx, idx+sz-1);
-+    sz = NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h);
-+    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
-+    memcpy(payload, pCell->aPayload, sz);
-+    for(j=0; j<sz; j++){
-+      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
-+    }
-+    payload[sz] = 0;
-+    printf(
-+      "cell %2d: i=%-10s chld=%-4d nk=%-4d nd=%-4d payload=%s\n",
-+      i, range, (int)pCell->h.leftChild, 
-+      NKEY(pBt, pCell->h), NDATA(pBt, pCell->h),
-+      payload
-+    );
-+    if( pPage->isInit && pPage->apCell[i]!=pCell ){
-+      printf("**** apCell[%d] does not match on prior entry ****\n", i);
-+    }
-+    i++;
-+    idx = SWAB16(pBt, pCell->h.iNext);
-+  }
-+  if( idx!=0 ){
-+    printf("ERROR: next cell index out of range: %d\n", idx);
-+  }
-+  printf("right_child: %d\n", SWAB32(pBt, pPage->u.hdr.rightChild));
-+  nFree = 0;
-+  i = 0;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstFree);
-+  while( idx>0 && idx<SQLITE_USABLE_SIZE ){
-+    FreeBlk *p = (FreeBlk*)&pPage->u.aDisk[idx];
-+    sprintf(range,"%d..%d", idx, idx+p->iSize-1);
-+    nFree += SWAB16(pBt, p->iSize);
-+    printf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
-+       i, range, SWAB16(pBt, p->iSize), nFree);
-+    idx = SWAB16(pBt, p->iNext);
-+    i++;
-+  }
-+  if( idx!=0 ){
-+    printf("ERROR: next freeblock index out of range: %d\n", idx);
-+  }
-+  if( recursive && pPage->u.hdr.rightChild!=0 ){
-+    idx = SWAB16(pBt, pPage->u.hdr.firstCell);
-+    while( idx>0 && idx<SQLITE_USABLE_SIZE-MIN_CELL_SIZE ){
-+      Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
-+      fileBtreePageDump(pBt, SWAB32(pBt, pCell->h.leftChild), 1);
-+      idx = SWAB16(pBt, pCell->h.iNext);
-+    }
-+    fileBtreePageDump(pBt, SWAB32(pBt, pPage->u.hdr.rightChild), 1);
-+  }
-+  sqlitepager_unref(pPage);
-+  return SQLITE_OK;
-+}
-+#endif
-+
-+#ifdef SQLITE_TEST
-+/*
-+** Fill aResult[] with information about the entry and page that the
-+** cursor is pointing to.
-+** 
-+**   aResult[0] =  The page number
-+**   aResult[1] =  The entry number
-+**   aResult[2] =  Total number of entries on this page
-+**   aResult[3] =  Size of this entry
-+**   aResult[4] =  Number of free bytes on this page
-+**   aResult[5] =  Number of free blocks on the page
-+**   aResult[6] =  Page number of the left child of this entry
-+**   aResult[7] =  Page number of the right child for the whole page
-+**
-+** This routine is used for testing and debugging only.
-+*/
-+static int fileBtreeCursorDump(BtCursor *pCur, int *aResult){
-+  int cnt, idx;
-+  MemPage *pPage = pCur->pPage;
-+  Btree *pBt = pCur->pBt;
-+  aResult[0] = sqlitepager_pagenumber(pPage);
-+  aResult[1] = pCur->idx;
-+  aResult[2] = pPage->nCell;
-+  if( pCur->idx>=0 && pCur->idx<pPage->nCell ){
-+    aResult[3] = cellSize(pBt, pPage->apCell[pCur->idx]);
-+    aResult[6] = SWAB32(pBt, pPage->apCell[pCur->idx]->h.leftChild);
-+  }else{
-+    aResult[3] = 0;
-+    aResult[6] = 0;
-+  }
-+  aResult[4] = pPage->nFree;
-+  cnt = 0;
-+  idx = SWAB16(pBt, pPage->u.hdr.firstFree);
-+  while( idx>0 && idx<SQLITE_USABLE_SIZE ){
-+    cnt++;
-+    idx = SWAB16(pBt, ((FreeBlk*)&pPage->u.aDisk[idx])->iNext);
-+  }
-+  aResult[5] = cnt;
-+  aResult[7] = SWAB32(pBt, pPage->u.hdr.rightChild);
-+  return SQLITE_OK;
-+}
-+#endif
-+
-+/*
-+** Return the pager associated with a BTree.  This routine is used for
-+** testing and debugging only.
-+*/
-+static Pager *fileBtreePager(Btree *pBt){
-+  return pBt->pPager;
-+}
-+
-+/*
-+** 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 {
-+  Btree *pBt;    /* The tree being checked out */
-+  Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
-+  int nPage;     /* Number of pages in the database */
-+  int *anRef;    /* Number of times each page is referenced */
-+  char *zErrMsg; /* An error message.  NULL of no errors seen. */
-+};
-+
-+/*
-+** Append a message to the error message string.
-+*/
-+static void checkAppendMsg(IntegrityCk *pCheck, char *zMsg1, char *zMsg2){
-+  if( pCheck->zErrMsg ){
-+    char *zOld = pCheck->zErrMsg;
-+    pCheck->zErrMsg = 0;
-+    sqliteSetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
-+    sqliteFree(zOld);
-+  }else{
-+    sqliteSetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
-+  }
-+}
-+
-+/*
-+** 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, int iPage, char *zContext){
-+  if( iPage==0 ) return 1;
-+  if( iPage>pCheck->nPage || iPage<0 ){
-+    char zBuf[100];
-+    sprintf(zBuf, "invalid page number %d", iPage);
-+    checkAppendMsg(pCheck, zContext, zBuf);
-+    return 1;
-+  }
-+  if( pCheck->anRef[iPage]==1 ){
-+    char zBuf[100];
-+    sprintf(zBuf, "2nd reference to page %d", iPage);
-+    checkAppendMsg(pCheck, zContext, zBuf);
-+    return 1;
-+  }
-+  return  (pCheck->anRef[iPage]++)>1;
-+}
-+
-+/*
-+** 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;
-+  char zMsg[100];
-+  while( N-- > 0 ){
-+    OverflowPage *pOvfl;
-+    if( iPage<1 ){
-+      sprintf(zMsg, "%d pages missing from overflow list", N+1);
-+      checkAppendMsg(pCheck, zContext, zMsg);
-+      break;
-+    }
-+    if( checkRef(pCheck, iPage, zContext) ) break;
-+    if( sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
-+      sprintf(zMsg, "failed to get page %d", iPage);
-+      checkAppendMsg(pCheck, zContext, zMsg);
-+      break;
-+    }
-+    if( isFreeList ){
-+      FreelistInfo *pInfo = (FreelistInfo*)pOvfl->aPayload;
-+      int n = SWAB32(pCheck->pBt, pInfo->nFree);
-+      for(i=0; i<n; i++){
-+        checkRef(pCheck, SWAB32(pCheck->pBt, pInfo->aFree[i]), zContext);
-+      }
-+      N -= n;
-+    }
-+    iPage = SWAB32(pCheck->pBt, pOvfl->iNext);
-+    sqlitepager_unref(pOvfl);
-+  }
-+}
-+
-+/*
-+** Return negative if zKey1<zKey2.
-+** Return zero if zKey1==zKey2.
-+** Return positive if zKey1>zKey2.
-+*/
-+static int keyCompare(
-+  const char *zKey1, int nKey1,
-+  const char *zKey2, int nKey2
-+){
-+  int min = nKey1>nKey2 ? nKey2 : nKey1;
-+  int c = memcmp(zKey1, zKey2, min);
-+  if( c==0 ){
-+    c = nKey1 - nKey2;
-+  }
-+  return c;
-+}
-+
-+/*
-+** 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.
-+**      2.  Make sure cell keys are in order.
-+**      3.  Make sure no key is less than or equal to zLowerBound.
-+**      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 */
-+  MemPage *pParent,     /* Parent page */
-+  char *zParentContext, /* Parent context */
-+  char *zLowerBound,    /* All keys should be greater than this, if not NULL */
-+  int nLower,           /* Number of characters in zLowerBound */
-+  char *zUpperBound,    /* All keys should be less than this, if not NULL */
-+  int nUpper            /* Number of characters in zUpperBound */
-+){
-+  MemPage *pPage;
-+  int i, rc, depth, d2, pgno;
-+  char *zKey1, *zKey2;
-+  int nKey1, nKey2;
-+  BtCursor cur;
-+  Btree *pBt;
-+  char zMsg[100];
-+  char zContext[100];
-+  char hit[SQLITE_USABLE_SIZE];
-+
-+  /* Check that the page exists
-+  */
-+  cur.pBt = pBt = pCheck->pBt;
-+  if( iPage==0 ) return 0;
-+  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
-+  sprintf(zContext, "On tree page %d: ", iPage);
-+  if( (rc = sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pPage))!=0 ){
-+    sprintf(zMsg, "unable to get the page. error code=%d", rc);
-+    checkAppendMsg(pCheck, zContext, zMsg);
-+    return 0;
-+  }
-+  if( (rc = initPage(pBt, pPage, (Pgno)iPage, pParent))!=0 ){
-+    sprintf(zMsg, "initPage() returns error code %d", rc);
-+    checkAppendMsg(pCheck, zContext, zMsg);
-+    sqlitepager_unref(pPage);
-+    return 0;
-+  }
-+
-+  /* Check out all the cells.
-+  */
-+  depth = 0;
-+  if( zLowerBound ){
-+    zKey1 = sqliteMalloc( nLower+1 );
-+    memcpy(zKey1, zLowerBound, nLower);
-+    zKey1[nLower] = 0;
-+  }else{
-+    zKey1 = 0;
-+  }
-+  nKey1 = nLower;
-+  cur.pPage = pPage;
-+  for(i=0; i<pPage->nCell; i++){
-+    Cell *pCell = pPage->apCell[i];
-+    int sz;
-+
-+    /* Check payload overflow pages
-+    */
-+    nKey2 = NKEY(pBt, pCell->h);
-+    sz = nKey2 + NDATA(pBt, pCell->h);
-+    sprintf(zContext, "On page %d cell %d: ", iPage, i);
-+    if( sz>MX_LOCAL_PAYLOAD ){
-+      int nPage = (sz - MX_LOCAL_PAYLOAD + OVERFLOW_SIZE - 1)/OVERFLOW_SIZE;
-+      checkList(pCheck, 0, SWAB32(pBt, pCell->ovfl), nPage, zContext);
-+    }
-+
-+    /* Check that keys are in the right order
-+    */
-+    cur.idx = i;
-+    zKey2 = sqliteMallocRaw( nKey2+1 );
-+    getPayload(&cur, 0, nKey2, zKey2);
-+    if( zKey1 && keyCompare(zKey1, nKey1, zKey2, nKey2)>=0 ){
-+      checkAppendMsg(pCheck, zContext, "Key is out of order");
-+    }
-+
-+    /* Check sanity of left child page.
-+    */
-+    pgno = SWAB32(pBt, pCell->h.leftChild);
-+    d2 = checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zKey2,nKey2);
-+    if( i>0 && d2!=depth ){
-+      checkAppendMsg(pCheck, zContext, "Child page depth differs");
-+    }
-+    depth = d2;
-+    sqliteFree(zKey1);
-+    zKey1 = zKey2;
-+    nKey1 = nKey2;
-+  }
-+  pgno = SWAB32(pBt, pPage->u.hdr.rightChild);
-+  sprintf(zContext, "On page %d at right child: ", iPage);
-+  checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zUpperBound,nUpper);
-+  sqliteFree(zKey1);
-+ 
-+  /* Check for complete coverage of the page
-+  */
-+  memset(hit, 0, sizeof(hit));
-+  memset(hit, 1, sizeof(PageHdr));
-+  for(i=SWAB16(pBt, pPage->u.hdr.firstCell); i>0 && i<SQLITE_USABLE_SIZE; ){
-+    Cell *pCell = (Cell*)&pPage->u.aDisk[i];
-+    int j;
-+    for(j=i+cellSize(pBt, pCell)-1; j>=i; j--) hit[j]++;
-+    i = SWAB16(pBt, pCell->h.iNext);
-+  }
-+  for(i=SWAB16(pBt,pPage->u.hdr.firstFree); i>0 && i<SQLITE_USABLE_SIZE; ){
-+    FreeBlk *pFBlk = (FreeBlk*)&pPage->u.aDisk[i];
-+    int j;
-+    for(j=i+SWAB16(pBt,pFBlk->iSize)-1; j>=i; j--) hit[j]++;
-+    i = SWAB16(pBt,pFBlk->iNext);
-+  }
-+  for(i=0; i<SQLITE_USABLE_SIZE; i++){
-+    if( hit[i]==0 ){
-+      sprintf(zMsg, "Unused space at byte %d of page %d", i, iPage);
-+      checkAppendMsg(pCheck, zMsg, 0);
-+      break;
-+    }else if( hit[i]>1 ){
-+      sprintf(zMsg, "Multiple uses for byte %d of page %d", i, iPage);
-+      checkAppendMsg(pCheck, zMsg, 0);
-+      break;
-+    }
-+  }
-+
-+  /* Check that free space is kept to a minimum
-+  */
-+#if 0
-+  if( pParent && pParent->nCell>2 && pPage->nFree>3*SQLITE_USABLE_SIZE/4 ){
-+    sprintf(zMsg, "free space (%d) greater than max (%d)", pPage->nFree,
-+       SQLITE_USABLE_SIZE/3);
-+    checkAppendMsg(pCheck, zContext, zMsg);
-+  }
-+#endif
-+
-+  sqlitepager_unref(pPage);
-+  return depth;
-+}
-+
-+/*
-+** 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.
-+**
-+** If everything checks out, this routine returns NULL.  If something is
-+** amiss, an error message is written into memory obtained from malloc()
-+** and a pointer to that error message is returned.  The calling function
-+** is responsible for freeing the error message when it is done.
-+*/
-+char *fileBtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
-+  int i;
-+  int nRef;
-+  IntegrityCk sCheck;
-+
-+  nRef = *sqlitepager_stats(pBt->pPager);
-+  if( lockBtree(pBt)!=SQLITE_OK ){
-+    return sqliteStrDup("Unable to acquire a read lock on the database");
-+  }
-+  sCheck.pBt = pBt;
-+  sCheck.pPager = pBt->pPager;
-+  sCheck.nPage = sqlitepager_pagecount(sCheck.pPager);
-+  if( sCheck.nPage==0 ){
-+    unlockBtreeIfUnused(pBt);
-+    return 0;
-+  }
-+  sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
-+  sCheck.anRef[1] = 1;
-+  for(i=2; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
-+  sCheck.zErrMsg = 0;
-+
-+  /* Check the integrity of the freelist
-+  */
-+  checkList(&sCheck, 1, SWAB32(pBt, pBt->page1->freeList),
-+            SWAB32(pBt, pBt->page1->nFree), "Main freelist: ");
-+
-+  /* Check all the tables.
-+  */
-+  for(i=0; i<nRoot; i++){
-+    if( aRoot[i]==0 ) continue;
-+    checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
-+  }
-+
-+  /* Make sure every page in the file is referenced
-+  */
-+  for(i=1; i<=sCheck.nPage; i++){
-+    if( sCheck.anRef[i]==0 ){
-+      char zBuf[100];
-+      sprintf(zBuf, "Page %d is never used", i);
-+      checkAppendMsg(&sCheck, zBuf, 0);
-+    }
-+  }
-+
-+  /* Make sure this analysis did not leave any unref() pages
-+  */
-+  unlockBtreeIfUnused(pBt);
-+  if( nRef != *sqlitepager_stats(pBt->pPager) ){
-+    char zBuf[100];
-+    sprintf(zBuf, 
-+      "Outstanding page count goes from %d to %d during this analysis",
-+      nRef, *sqlitepager_stats(pBt->pPager)
-+    );
-+    checkAppendMsg(&sCheck, zBuf, 0);
-+  }
-+
-+  /* Clean  up and report errors.
-+  */
-+  sqliteFree(sCheck.anRef);
-+  return sCheck.zErrMsg;
-+}
-+
-+/*
-+** Return the full pathname of the underlying database file.
-+*/
-+static const char *fileBtreeGetFilename(Btree *pBt){
-+  assert( pBt->pPager!=0 );
-+  return sqlitepager_filename(pBt->pPager);
-+}
-+
-+/*
-+** Copy the complete content of pBtFrom into pBtTo.  A transaction
-+** must be active for both files.
-+**
-+** The size of file pBtFrom may be reduced by this operation.
-+** If anything goes wrong, the transaction on pBtFrom is rolled back.
-+*/
-+static int fileBtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
-+  int rc = SQLITE_OK;
-+  Pgno i, nPage, nToPage;
-+
-+  if( !pBtTo->inTrans || !pBtFrom->inTrans ) return SQLITE_ERROR;
-+  if( pBtTo->needSwab!=pBtFrom->needSwab ) return SQLITE_ERROR;
-+  if( pBtTo->pCursor ) return SQLITE_BUSY;
-+  memcpy(pBtTo->page1, pBtFrom->page1, SQLITE_USABLE_SIZE);
-+  rc = sqlitepager_overwrite(pBtTo->pPager, 1, pBtFrom->page1);
-+  nToPage = sqlitepager_pagecount(pBtTo->pPager);
-+  nPage = sqlitepager_pagecount(pBtFrom->pPager);
-+  for(i=2; rc==SQLITE_OK && i<=nPage; i++){
-+    void *pPage;
-+    rc = sqlitepager_get(pBtFrom->pPager, i, &pPage);
-+    if( rc ) break;
-+    rc = sqlitepager_overwrite(pBtTo->pPager, i, pPage);
-+    if( rc ) break;
-+    sqlitepager_unref(pPage);
-+  }
-+  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
-+    void *pPage;
-+    rc = sqlitepager_get(pBtTo->pPager, i, &pPage);
-+    if( rc ) break;
-+    rc = sqlitepager_write(pPage);
-+    sqlitepager_unref(pPage);
-+    sqlitepager_dont_write(pBtTo->pPager, i);
-+  }
-+  if( !rc && nPage<nToPage ){
-+    rc = sqlitepager_truncate(pBtTo->pPager, nPage);
-+  }
-+  if( rc ){
-+    fileBtreeRollback(pBtTo);
-+  }
-+  return rc;  
-+}
-+
-+/*
-+** The following tables contain pointers to all of the interface
-+** routines for this implementation of the B*Tree backend.  To
-+** substitute a different implemention of the backend, one has merely
-+** to provide pointers to alternative functions in similar tables.
-+*/
-+static BtOps sqliteBtreeOps = {
-+    fileBtreeClose,
-+    fileBtreeSetCacheSize,
-+    fileBtreeSetSafetyLevel,
-+    fileBtreeBeginTrans,
-+    fileBtreeCommit,
-+    fileBtreeRollback,
-+    fileBtreeBeginCkpt,
-+    fileBtreeCommitCkpt,
-+    fileBtreeRollbackCkpt,
-+    fileBtreeCreateTable,
-+    fileBtreeCreateTable,  /* Really sqliteBtreeCreateIndex() */
-+    fileBtreeDropTable,
-+    fileBtreeClearTable,
-+    fileBtreeCursor,
-+    fileBtreeGetMeta,
-+    fileBtreeUpdateMeta,
-+    fileBtreeIntegrityCheck,
-+    fileBtreeGetFilename,
-+    fileBtreeCopyFile,
-+    fileBtreePager,
-+#ifdef SQLITE_TEST
-+    fileBtreePageDump,
-+#endif
-+};
-+static BtCursorOps sqliteBtreeCursorOps = {
-+    fileBtreeMoveto,
-+    fileBtreeDelete,
-+    fileBtreeInsert,
-+    fileBtreeFirst,
-+    fileBtreeLast,
-+    fileBtreeNext,
-+    fileBtreePrevious,
-+    fileBtreeKeySize,
-+    fileBtreeKey,
-+    fileBtreeKeyCompare,
-+    fileBtreeDataSize,
-+    fileBtreeData,
-+    fileBtreeCloseCursor,
-+#ifdef SQLITE_TEST
-+    fileBtreeCursorDump,
-+#endif
-+};
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/btree.h
-@@ -0,0 +1,156 @@
-+/*
-+** 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$
-+*/
-+#ifndef _BTREE_H_
-+#define _BTREE_H_
-+
-+/*
-+** Forward declarations of structure
-+*/
-+typedef struct Btree Btree;
-+typedef struct BtCursor BtCursor;
-+typedef struct BtOps BtOps;
-+typedef struct BtCursorOps BtCursorOps;
-+
-+
-+/*
-+** An instance of the following structure contains pointers to all
-+** methods against an open BTree.  Alternative BTree implementations
-+** (examples: file based versus in-memory) can be created by substituting
-+** different methods.  Users of the BTree cannot tell the difference.
-+**
-+** In C++ we could do this by defining a virtual base class and then
-+** creating subclasses for each different implementation.  But this is
-+** C not C++ so we have to be a little more explicit.
-+*/
-+struct BtOps {
-+    int (*Close)(Btree*);
-+    int (*SetCacheSize)(Btree*, int);
-+    int (*SetSafetyLevel)(Btree*, int);
-+    int (*BeginTrans)(Btree*);
-+    int (*Commit)(Btree*);
-+    int (*Rollback)(Btree*);
-+    int (*BeginCkpt)(Btree*);
-+    int (*CommitCkpt)(Btree*);
-+    int (*RollbackCkpt)(Btree*);
-+    int (*CreateTable)(Btree*, int*);
-+    int (*CreateIndex)(Btree*, int*);
-+    int (*DropTable)(Btree*, int);
-+    int (*ClearTable)(Btree*, int);
-+    int (*Cursor)(Btree*, int iTable, int wrFlag, BtCursor **ppCur);
-+    int (*GetMeta)(Btree*, int*);
-+    int (*UpdateMeta)(Btree*, int*);
-+    char *(*IntegrityCheck)(Btree*, int*, int);
-+    const char *(*GetFilename)(Btree*);
-+    int (*Copyfile)(Btree*,Btree*);
-+    struct Pager *(*Pager)(Btree*);
-+#ifdef SQLITE_TEST
-+    int (*PageDump)(Btree*, int, int);
-+#endif
-+};
-+
-+/*
-+** An instance of this structure defines all of the methods that can
-+** be executed against a cursor.
-+*/
-+struct BtCursorOps {
-+    int (*Moveto)(BtCursor*, const void *pKey, int nKey, int *pRes);
-+    int (*Delete)(BtCursor*);
-+    int (*Insert)(BtCursor*, const void *pKey, int nKey,
-+                             const void *pData, int nData);
-+    int (*First)(BtCursor*, int *pRes);
-+    int (*Last)(BtCursor*, int *pRes);
-+    int (*Next)(BtCursor*, int *pRes);
-+    int (*Previous)(BtCursor*, int *pRes);
-+    int (*KeySize)(BtCursor*, int *pSize);
-+    int (*Key)(BtCursor*, int offset, int amt, char *zBuf);
-+    int (*KeyCompare)(BtCursor*, const void *pKey, int nKey,
-+                                 int nIgnore, int *pRes);
-+    int (*DataSize)(BtCursor*, int *pSize);
-+    int (*Data)(BtCursor*, int offset, int amt, char *zBuf);
-+    int (*CloseCursor)(BtCursor*);
-+#ifdef SQLITE_TEST
-+    int (*CursorDump)(BtCursor*, int*);
-+#endif
-+};
-+
-+/*
-+** The number of 4-byte "meta" values contained on the first page of each
-+** database file.
-+*/
-+#define SQLITE_N_BTREE_META 10
-+
-+int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
-+int sqliteRbtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
-+
-+#define btOps(pBt) (*((BtOps **)(pBt)))
-+#define btCOps(pCur) (*((BtCursorOps **)(pCur)))
-+
-+#define sqliteBtreeClose(pBt)              (btOps(pBt)->Close(pBt))
-+#define sqliteBtreeSetCacheSize(pBt, sz)   (btOps(pBt)->SetCacheSize(pBt, sz))
-+#define sqliteBtreeSetSafetyLevel(pBt, sl) (btOps(pBt)->SetSafetyLevel(pBt, sl))
-+#define sqliteBtreeBeginTrans(pBt)         (btOps(pBt)->BeginTrans(pBt))
-+#define sqliteBtreeCommit(pBt)             (btOps(pBt)->Commit(pBt))
-+#define sqliteBtreeRollback(pBt)           (btOps(pBt)->Rollback(pBt))
-+#define sqliteBtreeBeginCkpt(pBt)          (btOps(pBt)->BeginCkpt(pBt))
-+#define sqliteBtreeCommitCkpt(pBt)         (btOps(pBt)->CommitCkpt(pBt))
-+#define sqliteBtreeRollbackCkpt(pBt)       (btOps(pBt)->RollbackCkpt(pBt))
-+#define sqliteBtreeCreateTable(pBt,piTable)\
-+                (btOps(pBt)->CreateTable(pBt,piTable))
-+#define sqliteBtreeCreateIndex(pBt, piIndex)\
-+                (btOps(pBt)->CreateIndex(pBt, piIndex))
-+#define sqliteBtreeDropTable(pBt, iTable) (btOps(pBt)->DropTable(pBt, iTable))
-+#define sqliteBtreeClearTable(pBt, iTable)\
-+                (btOps(pBt)->ClearTable(pBt, iTable))
-+#define sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)\
-+                (btOps(pBt)->Cursor(pBt, iTable, wrFlag, ppCur))
-+#define sqliteBtreeMoveto(pCur, pKey, nKey, pRes)\
-+                (btCOps(pCur)->Moveto(pCur, pKey, nKey, pRes))
-+#define sqliteBtreeDelete(pCur)           (btCOps(pCur)->Delete(pCur))
-+#define sqliteBtreeInsert(pCur, pKey, nKey, pData, nData) \
-+                (btCOps(pCur)->Insert(pCur, pKey, nKey, pData, nData))
-+#define sqliteBtreeFirst(pCur, pRes)      (btCOps(pCur)->First(pCur, pRes))
-+#define sqliteBtreeLast(pCur, pRes)       (btCOps(pCur)->Last(pCur, pRes))
-+#define sqliteBtreeNext(pCur, pRes)       (btCOps(pCur)->Next(pCur, pRes))
-+#define sqliteBtreePrevious(pCur, pRes)   (btCOps(pCur)->Previous(pCur, pRes))
-+#define sqliteBtreeKeySize(pCur, pSize)   (btCOps(pCur)->KeySize(pCur, pSize) )
-+#define sqliteBtreeKey(pCur, offset, amt, zBuf)\
-+                (btCOps(pCur)->Key(pCur, offset, amt, zBuf))
-+#define sqliteBtreeKeyCompare(pCur, pKey, nKey, nIgnore, pRes)\
-+                (btCOps(pCur)->KeyCompare(pCur, pKey, nKey, nIgnore, pRes))
-+#define sqliteBtreeDataSize(pCur, pSize)  (btCOps(pCur)->DataSize(pCur, pSize))
-+#define sqliteBtreeData(pCur, offset, amt, zBuf)\
-+                (btCOps(pCur)->Data(pCur, offset, amt, zBuf))
-+#define sqliteBtreeCloseCursor(pCur)      (btCOps(pCur)->CloseCursor(pCur))
-+#define sqliteBtreeGetMeta(pBt, aMeta)    (btOps(pBt)->GetMeta(pBt, aMeta))
-+#define sqliteBtreeUpdateMeta(pBt, aMeta) (btOps(pBt)->UpdateMeta(pBt, aMeta))
-+#define sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)\
-+                (btOps(pBt)->IntegrityCheck(pBt, aRoot, nRoot))
-+#define sqliteBtreeGetFilename(pBt)       (btOps(pBt)->GetFilename(pBt))
-+#define sqliteBtreeCopyFile(pBt1, pBt2)   (btOps(pBt1)->Copyfile(pBt1, pBt2))
-+#define sqliteBtreePager(pBt)             (btOps(pBt)->Pager(pBt))
-+
-+#ifdef SQLITE_TEST
-+#define sqliteBtreePageDump(pBt, pgno, recursive)\
-+                (btOps(pBt)->PageDump(pBt, pgno, recursive))
-+#define sqliteBtreeCursorDump(pCur, aResult)\
-+                (btCOps(pCur)->CursorDump(pCur, aResult))
-+int btree_native_byte_order;
-+#endif /* SQLITE_TEST */
-+
-+
-+#endif /* _BTREE_H_ */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/btree_rb.c
-@@ -0,0 +1,1488 @@
-+/*
-+** 2003 Feb 4
-+**
-+** 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$
-+**
-+** This file implements an in-core database using Red-Black balanced
-+** binary trees.
-+** 
-+** It was contributed to SQLite by anonymous on 2003-Feb-04 23:24:49 UTC.
-+*/
-+#include "btree.h"
-+#include "sqliteInt.h"
-+#include <assert.h>
-+
-+/*
-+** Omit this whole file if the SQLITE_OMIT_INMEMORYDB macro is
-+** defined.  This allows a lot of code to be omitted for installations
-+** that do not need it.
-+*/
-+#ifndef SQLITE_OMIT_INMEMORYDB
-+
-+
-+typedef struct BtRbTree BtRbTree;
-+typedef struct BtRbNode BtRbNode;
-+typedef struct BtRollbackOp BtRollbackOp;
-+typedef struct Rbtree Rbtree;
-+typedef struct RbtCursor RbtCursor;
-+
-+/* Forward declarations */
-+static BtOps sqliteRbtreeOps;
-+static BtCursorOps sqliteRbtreeCursorOps;
-+
-+/*
-+ * During each transaction (or checkpoint), a linked-list of
-+ * "rollback-operations" is accumulated. If the transaction is rolled back,
-+ * then the list of operations must be executed (to restore the database to
-+ * it's state before the transaction started). If the transaction is to be
-+ * committed, just delete the list.
-+ *
-+ * Each operation is represented as follows, depending on the value of eOp:
-+ *
-+ * ROLLBACK_INSERT  ->  Need to insert (pKey, pData) into table iTab.
-+ * ROLLBACK_DELETE  ->  Need to delete the record (pKey) into table iTab.
-+ * ROLLBACK_CREATE  ->  Need to create table iTab.
-+ * ROLLBACK_DROP    ->  Need to drop table iTab.
-+ */
-+struct BtRollbackOp {
-+  u8 eOp;
-+  int iTab;
-+  int nKey; 
-+  void *pKey;
-+  int nData;
-+  void *pData;
-+  BtRollbackOp *pNext;
-+};
-+
-+/*
-+** Legal values for BtRollbackOp.eOp:
-+*/
-+#define ROLLBACK_INSERT 1 /* Insert a record */
-+#define ROLLBACK_DELETE 2 /* Delete a record */
-+#define ROLLBACK_CREATE 3 /* Create a table */
-+#define ROLLBACK_DROP   4 /* Drop a table */
-+
-+struct Rbtree {
-+  BtOps *pOps;    /* Function table */
-+  int aMetaData[SQLITE_N_BTREE_META];
-+
-+  int next_idx;   /* next available table index */
-+  Hash tblHash;   /* All created tables, by index */
-+  u8 isAnonymous; /* True if this Rbtree is to be deleted when closed */
-+  u8 eTransState; /* State of this Rbtree wrt transactions */
-+
-+  BtRollbackOp *pTransRollback; 
-+  BtRollbackOp *pCheckRollback;
-+  BtRollbackOp *pCheckRollbackTail;
-+};
-+
-+/*
-+** Legal values for Rbtree.eTransState.
-+*/
-+#define TRANS_NONE           0  /* No transaction is in progress */
-+#define TRANS_INTRANSACTION  1  /* A transaction is in progress */
-+#define TRANS_INCHECKPOINT   2  /* A checkpoint is in progress  */
-+#define TRANS_ROLLBACK       3  /* We are currently rolling back a checkpoint or
-+                                 * transaction. */
-+
-+struct RbtCursor {
-+  BtCursorOps *pOps;        /* Function table */
-+  Rbtree    *pRbtree;
-+  BtRbTree *pTree;
-+  int       iTree;          /* Index of pTree in pRbtree */
-+  BtRbNode *pNode;
-+  RbtCursor *pShared;       /* List of all cursors on the same Rbtree */
-+  u8 eSkip;                 /* Determines if next step operation is a no-op */
-+  u8 wrFlag;                /* True if this cursor is open for writing */
-+};
-+
-+/*
-+** Legal values for RbtCursor.eSkip.
-+*/
-+#define SKIP_NONE     0   /* Always step the cursor */
-+#define SKIP_NEXT     1   /* The next sqliteRbtreeNext() is a no-op */
-+#define SKIP_PREV     2   /* The next sqliteRbtreePrevious() is a no-op */
-+#define SKIP_INVALID  3   /* Calls to Next() and Previous() are invalid */
-+
-+struct BtRbTree {
-+  RbtCursor *pCursors;     /* All cursors pointing to this tree */
-+  BtRbNode *pHead;         /* Head of the tree, or NULL */
-+};
-+
-+struct BtRbNode {
-+  int nKey;
-+  void *pKey;
-+  int nData;
-+  void *pData;
-+  u8 isBlack;        /* true for a black node, 0 for a red node */
-+  BtRbNode *pParent; /* Nodes parent node, NULL for the tree head */
-+  BtRbNode *pLeft;   /* Nodes left child, or NULL */
-+  BtRbNode *pRight;  /* Nodes right child, or NULL */
-+
-+  int nBlackHeight;  /* Only used during the red-black integrity check */
-+};
-+
-+/* Forward declarations */
-+static int memRbtreeMoveto(
-+  RbtCursor* pCur,
-+  const void *pKey,
-+  int nKey,
-+  int *pRes
-+);
-+static int memRbtreeClearTable(Rbtree* tree, int n);
-+static int memRbtreeNext(RbtCursor* pCur, int *pRes);
-+static int memRbtreeLast(RbtCursor* pCur, int *pRes);
-+static int memRbtreePrevious(RbtCursor* pCur, int *pRes);
-+
-+
-+/*
-+** This routine checks all cursors that point to the same table
-+** as pCur points to.  If any of those cursors were opened with
-+** wrFlag==0 then this routine returns SQLITE_LOCKED.  If all
-+** cursors point to the same table were opened with wrFlag==1
-+** then this routine returns SQLITE_OK.
-+**
-+** In addition to checking for read-locks (where a read-lock 
-+** means a cursor opened with wrFlag==0) this routine also NULLs
-+** out the pNode field of all other cursors.
-+** This is necessary because an insert 
-+** or delete might change erase the node out from under
-+** another cursor.
-+*/
-+static int checkReadLocks(RbtCursor *pCur){
-+  RbtCursor *p;
-+  assert( pCur->wrFlag );
-+  for(p=pCur->pTree->pCursors; p; p=p->pShared){
-+    if( p!=pCur ){
-+      if( p->wrFlag==0 ) return SQLITE_LOCKED;
-+      p->pNode = 0;
-+    }
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * The key-compare function for the red-black trees. Returns as follows:
-+ *
-+ * (key1 < key2)             -1
-+ * (key1 == key2)             0 
-+ * (key1 > key2)              1
-+ *
-+ * Keys are compared using memcmp(). If one key is an exact prefix of the
-+ * other, then the shorter key is less than the longer key.
-+ */
-+static int key_compare(void const*pKey1, int nKey1, void const*pKey2, int nKey2)
-+{
-+  int mcmp = memcmp(pKey1, pKey2, (nKey1 <= nKey2)?nKey1:nKey2);
-+  if( mcmp == 0){
-+    if( nKey1 == nKey2 ) return 0;
-+    return ((nKey1 < nKey2)?-1:1);
-+  }
-+  return ((mcmp>0)?1:-1);
-+}
-+
-+/*
-+ * Perform the LEFT-rotate transformation on node X of tree pTree. This
-+ * transform is part of the red-black balancing code.
-+ *
-+ *        |                   |
-+ *        X                   Y
-+ *       / \                 / \
-+ *      a   Y               X   c
-+ *         / \             / \
-+ *        b   c           a   b
-+ *
-+ *      BEFORE              AFTER
-+ */
-+static void leftRotate(BtRbTree *pTree, BtRbNode *pX)
-+{
-+  BtRbNode *pY;
-+  BtRbNode *pb;
-+  pY = pX->pRight;
-+  pb = pY->pLeft;
-+
-+  pY->pParent = pX->pParent;
-+  if( pX->pParent ){
-+    if( pX->pParent->pLeft == pX ) pX->pParent->pLeft = pY;
-+    else pX->pParent->pRight = pY;
-+  }
-+  pY->pLeft = pX;
-+  pX->pParent = pY;
-+  pX->pRight = pb;
-+  if( pb ) pb->pParent = pX;
-+  if( pTree->pHead == pX ) pTree->pHead = pY;
-+}
-+
-+/*
-+ * Perform the RIGHT-rotate transformation on node X of tree pTree. This
-+ * transform is part of the red-black balancing code.
-+ *
-+ *        |                   |
-+ *        X                   Y
-+ *       / \                 / \
-+ *      Y   c               a   X
-+ *     / \                     / \
-+ *    a   b                   b   c
-+ *
-+ *      BEFORE              AFTER
-+ */
-+static void rightRotate(BtRbTree *pTree, BtRbNode *pX)
-+{
-+  BtRbNode *pY;
-+  BtRbNode *pb;
-+  pY = pX->pLeft;
-+  pb = pY->pRight;
-+
-+  pY->pParent = pX->pParent;
-+  if( pX->pParent ){
-+    if( pX->pParent->pLeft == pX ) pX->pParent->pLeft = pY;
-+    else pX->pParent->pRight = pY;
-+  }
-+  pY->pRight = pX;
-+  pX->pParent = pY;
-+  pX->pLeft = pb;
-+  if( pb ) pb->pParent = pX;
-+  if( pTree->pHead == pX ) pTree->pHead = pY;
-+}
-+
-+/*
-+ * A string-manipulation helper function for check_redblack_tree(). If (orig ==
-+ * NULL) a copy of val is returned. If (orig != NULL) then a copy of the *
-+ * concatenation of orig and val is returned. The original orig is deleted
-+ * (using sqliteFree()).
-+ */
-+static char *append_val(char * orig, char const * val){
-+  char *z;
-+  if( !orig ){
-+    z = sqliteStrDup( val );
-+  } else{
-+    z = 0;
-+    sqliteSetString(&z, orig, val, (char*)0);
-+    sqliteFree( orig );
-+  }
-+  return z;
-+}
-+
-+/*
-+ * Append a string representation of the entire node to orig and return it.
-+ * This is used to produce debugging information if check_redblack_tree() finds
-+ * a problem with a red-black binary tree.
-+ */
-+static char *append_node(char * orig, BtRbNode *pNode, int indent)
-+{
-+  char buf[128];
-+  int i;
-+
-+  for( i=0; i<indent; i++ ){
-+      orig = append_val(orig, " ");
-+  }
-+
-+  sprintf(buf, "%p", pNode);
-+  orig = append_val(orig, buf);
-+
-+  if( pNode ){
-+    indent += 3;
-+    if( pNode->isBlack ){
-+      orig = append_val(orig, " B \n");
-+    }else{
-+      orig = append_val(orig, " R \n");
-+    }
-+    orig = append_node( orig, pNode->pLeft, indent );
-+    orig = append_node( orig, pNode->pRight, indent );
-+  }else{
-+    orig = append_val(orig, "\n");
-+  }
-+  return orig;
-+}
-+
-+/*
-+ * Print a representation of a node to stdout. This function is only included
-+ * so you can call it from within a debugger if things get really bad.  It
-+ * is not called from anyplace in the code.
-+ */
-+static void print_node(BtRbNode *pNode)
-+{
-+    char * str = append_node(0, pNode, 0);
-+    printf("%s", str);
-+
-+    /* Suppress a warning message about print_node() being unused */
-+    (void)print_node;
-+}
-+
-+/* 
-+ * Check the following properties of the red-black tree:
-+ * (1) - If a node is red, both of it's children are black
-+ * (2) - Each path from a given node to a leaf (NULL) node passes thru the
-+ *       same number of black nodes 
-+ *
-+ * If there is a problem, append a description (using append_val() ) to *msg.
-+ */
-+static void check_redblack_tree(BtRbTree * tree, char ** msg)
-+{
-+  BtRbNode *pNode;
-+
-+  /* 0 -> came from parent 
-+   * 1 -> came from left
-+   * 2 -> came from right */
-+  int prev_step = 0;
-+
-+  pNode = tree->pHead;
-+  while( pNode ){
-+    switch( prev_step ){
-+      case 0:
-+        if( pNode->pLeft ){
-+          pNode = pNode->pLeft;
-+        }else{ 
-+          prev_step = 1;
-+        }
-+        break;
-+      case 1:
-+        if( pNode->pRight ){
-+          pNode = pNode->pRight;
-+          prev_step = 0;
-+        }else{
-+          prev_step = 2;
-+        }
-+        break;
-+      case 2:
-+        /* Check red-black property (1) */
-+        if( !pNode->isBlack &&
-+            ( (pNode->pLeft && !pNode->pLeft->isBlack) ||
-+              (pNode->pRight && !pNode->pRight->isBlack) )
-+          ){
-+          char buf[128];
-+          sprintf(buf, "Red node with red child at %p\n", pNode);
-+          *msg = append_val(*msg, buf);
-+          *msg = append_node(*msg, tree->pHead, 0);
-+          *msg = append_val(*msg, "\n");
-+        }
-+
-+        /* Check red-black property (2) */
-+        { 
-+          int leftHeight = 0;
-+          int rightHeight = 0;
-+          if( pNode->pLeft ){
-+            leftHeight += pNode->pLeft->nBlackHeight;
-+            leftHeight += (pNode->pLeft->isBlack?1:0);
-+          }
-+          if( pNode->pRight ){
-+            rightHeight += pNode->pRight->nBlackHeight;
-+            rightHeight += (pNode->pRight->isBlack?1:0);
-+          }
-+          if( leftHeight != rightHeight ){
-+            char buf[128];
-+            sprintf(buf, "Different black-heights at %p\n", pNode);
-+            *msg = append_val(*msg, buf);
-+            *msg = append_node(*msg, tree->pHead, 0);
-+            *msg = append_val(*msg, "\n");
-+          }
-+          pNode->nBlackHeight = leftHeight;
-+        }
-+
-+        if( pNode->pParent ){
-+          if( pNode == pNode->pParent->pLeft ) prev_step = 1;
-+          else prev_step = 2;
-+        }
-+        pNode = pNode->pParent;
-+        break;
-+      default: assert(0);
-+    }
-+  }
-+} 
-+
-+/*
-+ * Node pX has just been inserted into pTree (by code in sqliteRbtreeInsert()).
-+ * It is possible that pX is a red node with a red parent, which is a violation
-+ * of the red-black tree properties. This function performs rotations and 
-+ * color changes to rebalance the tree
-+ */
-+static void do_insert_balancing(BtRbTree *pTree, BtRbNode *pX)
-+{
-+  /* In the first iteration of this loop, pX points to the red node just
-+   * inserted in the tree. If the parent of pX exists (pX is not the root
-+   * node) and is red, then the properties of the red-black tree are
-+   * violated.
-+   *
-+   * At the start of any subsequent iterations, pX points to a red node
-+   * with a red parent. In all other respects the tree is a legal red-black
-+   * binary tree. */
-+  while( pX != pTree->pHead && !pX->pParent->isBlack ){
-+    BtRbNode *pUncle;
-+    BtRbNode *pGrandparent;
-+
-+    /* Grandparent of pX must exist and must be black. */
-+    pGrandparent = pX->pParent->pParent;
-+    assert( pGrandparent );
-+    assert( pGrandparent->isBlack );
-+
-+    /* Uncle of pX may or may not exist. */
-+    if( pX->pParent == pGrandparent->pLeft ) 
-+      pUncle = pGrandparent->pRight;
-+    else 
-+      pUncle = pGrandparent->pLeft;
-+
-+    /* If the uncle of pX exists and is red, we do the following:
-+     *       |                 |
-+     *      G(b)              G(r)
-+     *      /  \              /  \        
-+     *   U(r)   P(r)       U(b)  P(b)
-+     *            \                \
-+     *           X(r)              X(r)
-+     *
-+     *     BEFORE             AFTER
-+     * pX is then set to G. If the parent of G is red, then the while loop
-+     * will run again.  */
-+    if( pUncle && !pUncle->isBlack ){
-+      pGrandparent->isBlack = 0;
-+      pUncle->isBlack = 1;
-+      pX->pParent->isBlack = 1;
-+      pX = pGrandparent;
-+    }else{
-+
-+      if( pX->pParent == pGrandparent->pLeft ){
-+        if( pX == pX->pParent->pRight ){
-+          /* If pX is a right-child, do the following transform, essentially
-+           * to change pX into a left-child: 
-+           *       |                  | 
-+           *      G(b)               G(b)
-+           *      /  \               /  \        
-+           *   P(r)   U(b)        X(r)  U(b)
-+           *      \                /
-+           *     X(r)            P(r) <-- new X
-+           *
-+           *     BEFORE             AFTER
-+           */
-+          pX = pX->pParent;
-+          leftRotate(pTree, pX);
-+        }
-+
-+        /* Do the following transform, which balances the tree :) 
-+         *       |                  | 
-+         *      G(b)               P(b)
-+         *      /  \               /  \        
-+         *   P(r)   U(b)        X(r)  G(r)
-+         *    /                         \
-+         *  X(r)                        U(b)
-+         *
-+         *     BEFORE             AFTER
-+         */
-+        assert( pGrandparent == pX->pParent->pParent );
-+        pGrandparent->isBlack = 0;
-+        pX->pParent->isBlack = 1;
-+        rightRotate( pTree, pGrandparent );
-+
-+      }else{
-+        /* This code is symetric to the illustrated case above. */
-+        if( pX == pX->pParent->pLeft ){
-+          pX = pX->pParent;
-+          rightRotate(pTree, pX);
-+        }
-+        assert( pGrandparent == pX->pParent->pParent );
-+        pGrandparent->isBlack = 0;
-+        pX->pParent->isBlack = 1;
-+        leftRotate( pTree, pGrandparent );
-+      }
-+    }
-+  }
-+  pTree->pHead->isBlack = 1;
-+}
-+
-+/*
-+ * A child of pParent, which in turn had child pX, has just been removed from 
-+ * pTree (the figure below depicts the operation, Z is being removed). pParent
-+ * or pX, or both may be NULL.  
-+ *                |           |
-+ *                P           P
-+ *               / \         / \
-+ *              Z           X
-+ *             / \
-+ *            X  nil
-+ *
-+ * This function is only called if Z was black. In this case the red-black tree
-+ * properties have been violated, and pX has an "extra black". This function 
-+ * performs rotations and color-changes to re-balance the tree.
-+ */
-+static 
-+void do_delete_balancing(BtRbTree *pTree, BtRbNode *pX, BtRbNode *pParent)
-+{
-+  BtRbNode *pSib; 
-+
-+  /* TODO: Comment this code! */
-+  while( pX != pTree->pHead && (!pX || pX->isBlack) ){
-+    if( pX == pParent->pLeft ){
-+      pSib = pParent->pRight;
-+      if( pSib && !(pSib->isBlack) ){
-+        pSib->isBlack = 1;
-+        pParent->isBlack = 0;
-+        leftRotate(pTree, pParent);
-+        pSib = pParent->pRight;
-+      }
-+      if( !pSib ){
-+        pX = pParent;
-+      }else if( 
-+          (!pSib->pLeft  || pSib->pLeft->isBlack) &&
-+          (!pSib->pRight || pSib->pRight->isBlack) ) {
-+        pSib->isBlack = 0;
-+        pX = pParent;
-+      }else{
-+        if( (!pSib->pRight || pSib->pRight->isBlack) ){
-+          if( pSib->pLeft ) pSib->pLeft->isBlack = 1;
-+          pSib->isBlack = 0;
-+          rightRotate( pTree, pSib );
-+          pSib = pParent->pRight;
-+        }
-+        pSib->isBlack = pParent->isBlack;
-+        pParent->isBlack = 1;
-+        if( pSib->pRight ) pSib->pRight->isBlack = 1;
-+        leftRotate(pTree, pParent);
-+        pX = pTree->pHead;
-+      }
-+    }else{
-+      pSib = pParent->pLeft;
-+      if( pSib && !(pSib->isBlack) ){
-+        pSib->isBlack = 1;
-+        pParent->isBlack = 0;
-+        rightRotate(pTree, pParent);
-+        pSib = pParent->pLeft;
-+      }
-+      if( !pSib ){
-+        pX = pParent;
-+      }else if( 
-+          (!pSib->pLeft  || pSib->pLeft->isBlack) &&
-+          (!pSib->pRight || pSib->pRight->isBlack) ){
-+        pSib->isBlack = 0;
-+        pX = pParent;
-+      }else{
-+        if( (!pSib->pLeft || pSib->pLeft->isBlack) ){
-+          if( pSib->pRight ) pSib->pRight->isBlack = 1;
-+          pSib->isBlack = 0;
-+          leftRotate( pTree, pSib );
-+          pSib = pParent->pLeft;
-+        }
-+        pSib->isBlack = pParent->isBlack;
-+        pParent->isBlack = 1;
-+        if( pSib->pLeft ) pSib->pLeft->isBlack = 1;
-+        rightRotate(pTree, pParent);
-+        pX = pTree->pHead;
-+      }
-+    }
-+    pParent = pX->pParent;
-+  }
-+  if( pX ) pX->isBlack = 1;
-+}
-+
-+/*
-+ * Create table n in tree pRbtree. Table n must not exist.
-+ */
-+static void btreeCreateTable(Rbtree* pRbtree, int n)
-+{
-+  BtRbTree *pNewTbl = sqliteMalloc(sizeof(BtRbTree));
-+  sqliteHashInsert(&pRbtree->tblHash, 0, n, pNewTbl);
-+}
-+
-+/*
-+ * Log a single "rollback-op" for the given Rbtree. See comments for struct
-+ * BtRollbackOp.
-+ */
-+static void btreeLogRollbackOp(Rbtree* pRbtree, BtRollbackOp *pRollbackOp)
-+{
-+  assert( pRbtree->eTransState == TRANS_INCHECKPOINT ||
-+      pRbtree->eTransState == TRANS_INTRANSACTION );
-+  if( pRbtree->eTransState == TRANS_INTRANSACTION ){
-+    pRollbackOp->pNext = pRbtree->pTransRollback;
-+    pRbtree->pTransRollback = pRollbackOp;
-+  }
-+  if( pRbtree->eTransState == TRANS_INCHECKPOINT ){
-+    if( !pRbtree->pCheckRollback ){
-+      pRbtree->pCheckRollbackTail = pRollbackOp;
-+    }
-+    pRollbackOp->pNext = pRbtree->pCheckRollback;
-+    pRbtree->pCheckRollback = pRollbackOp;
-+  }
-+}
-+
-+int sqliteRbtreeOpen(
-+  const char *zFilename,
-+  int mode,
-+  int nPg,
-+  Btree **ppBtree
-+){
-+  Rbtree **ppRbtree = (Rbtree**)ppBtree;
-+  *ppRbtree = (Rbtree *)sqliteMalloc(sizeof(Rbtree));
-+  if( sqlite_malloc_failed ) goto open_no_mem;
-+  sqliteHashInit(&(*ppRbtree)->tblHash, SQLITE_HASH_INT, 0);
-+
-+  /* Create a binary tree for the SQLITE_MASTER table at location 2 */
-+  btreeCreateTable(*ppRbtree, 2);
-+  if( sqlite_malloc_failed ) goto open_no_mem;
-+  (*ppRbtree)->next_idx = 3;
-+  (*ppRbtree)->pOps = &sqliteRbtreeOps;
-+  /* Set file type to 4; this is so that "attach ':memory:' as ...."  does not
-+  ** think that the database in uninitialised and refuse to attach
-+  */
-+  (*ppRbtree)->aMetaData[2] = 4;
-+  
-+  return SQLITE_OK;
-+
-+open_no_mem:
-+  *ppBtree = 0;
-+  return SQLITE_NOMEM;
-+}
-+
-+/*
-+ * Create a new table in the supplied Rbtree. Set *n to the new table number.
-+ * Return SQLITE_OK if the operation is a success.
-+ */
-+static int memRbtreeCreateTable(Rbtree* tree, int* n)
-+{
-+  assert( tree->eTransState != TRANS_NONE );
-+
-+  *n = tree->next_idx++;
-+  btreeCreateTable(tree, *n);
-+  if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+
-+  /* Set up the rollback structure (if we are not doing this as part of a
-+   * rollback) */
-+  if( tree->eTransState != TRANS_ROLLBACK ){
-+    BtRollbackOp *pRollbackOp = sqliteMalloc(sizeof(BtRollbackOp));
-+    if( pRollbackOp==0 ) return SQLITE_NOMEM;
-+    pRollbackOp->eOp = ROLLBACK_DROP;
-+    pRollbackOp->iTab = *n;
-+    btreeLogRollbackOp(tree, pRollbackOp);
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Delete table n from the supplied Rbtree. 
-+ */
-+static int memRbtreeDropTable(Rbtree* tree, int n)
-+{
-+  BtRbTree *pTree;
-+  assert( tree->eTransState != TRANS_NONE );
-+
-+  memRbtreeClearTable(tree, n);
-+  pTree = sqliteHashInsert(&tree->tblHash, 0, n, 0);
-+  assert(pTree);
-+  assert( pTree->pCursors==0 );
-+  sqliteFree(pTree);
-+
-+  if( tree->eTransState != TRANS_ROLLBACK ){
-+    BtRollbackOp *pRollbackOp = sqliteMalloc(sizeof(BtRollbackOp));
-+    if( pRollbackOp==0 ) return SQLITE_NOMEM;
-+    pRollbackOp->eOp = ROLLBACK_CREATE;
-+    pRollbackOp->iTab = n;
-+    btreeLogRollbackOp(tree, pRollbackOp);
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeKeyCompare(RbtCursor* pCur, const void *pKey, int nKey,
-+                                 int nIgnore, int *pRes)
-+{
-+  assert(pCur);
-+
-+  if( !pCur->pNode ) {
-+    *pRes = -1;
-+  } else {
-+    if( (pCur->pNode->nKey - nIgnore) < 0 ){
-+      *pRes = -1;
-+    }else{
-+      *pRes = key_compare(pCur->pNode->pKey, pCur->pNode->nKey-nIgnore, 
-+          pKey, nKey);
-+    }
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Get a new cursor for table iTable of the supplied Rbtree. The wrFlag
-+ * parameter indicates that the cursor is open for writing.
-+ *
-+ * Note that RbtCursor.eSkip and RbtCursor.pNode both initialize to 0.
-+ */
-+static int memRbtreeCursor(
-+  Rbtree* tree,
-+  int iTable,
-+  int wrFlag,
-+  RbtCursor **ppCur
-+){
-+  RbtCursor *pCur;
-+  assert(tree);
-+  pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
-+  if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+  pCur->pTree  = sqliteHashFind(&tree->tblHash, 0, iTable);
-+  assert( pCur->pTree );
-+  pCur->pRbtree = tree;
-+  pCur->iTree  = iTable;
-+  pCur->pOps = &sqliteRbtreeCursorOps;
-+  pCur->wrFlag = wrFlag;
-+  pCur->pShared = pCur->pTree->pCursors;
-+  pCur->pTree->pCursors = pCur;
-+
-+  assert( (*ppCur)->pTree );
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Insert a new record into the Rbtree.  The key is given by (pKey,nKey)
-+ * and the data is given by (pData,nData).  The cursor is used only to
-+ * define what database the record should be inserted into.  The cursor
-+ * is left pointing at the new record.
-+ *
-+ * If the key exists already in the tree, just replace the data. 
-+ */
-+static int memRbtreeInsert(
-+  RbtCursor* pCur,
-+  const void *pKey,
-+  int nKey,
-+  const void *pDataInput,
-+  int nData
-+){
-+  void * pData;
-+  int match;
-+
-+  /* It is illegal to call sqliteRbtreeInsert() if we are
-+  ** not in a transaction */
-+  assert( pCur->pRbtree->eTransState != TRANS_NONE );
-+
-+  /* Make sure some other cursor isn't trying to read this same table */
-+  if( checkReadLocks(pCur) ){
-+    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
-+  }
-+
-+  /* Take a copy of the input data now, in case we need it for the 
-+   * replace case */
-+  pData = sqliteMallocRaw(nData);
-+  if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+  memcpy(pData, pDataInput, nData);
-+
-+  /* Move the cursor to a node near the key to be inserted. If the key already
-+   * exists in the table, then (match == 0). In this case we can just replace
-+   * the data associated with the entry, we don't need to manipulate the tree.
-+   * 
-+   * If there is no exact match, then the cursor points at what would be either
-+   * the predecessor (match == -1) or successor (match == 1) of the
-+   * searched-for key, were it to be inserted. The new node becomes a child of
-+   * this node.
-+   * 
-+   * The new node is initially red.
-+   */
-+  memRbtreeMoveto( pCur, pKey, nKey, &match);
-+  if( match ){
-+    BtRbNode *pNode = sqliteMalloc(sizeof(BtRbNode));
-+    if( pNode==0 ) return SQLITE_NOMEM;
-+    pNode->nKey = nKey;
-+    pNode->pKey = sqliteMallocRaw(nKey);
-+    if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+    memcpy(pNode->pKey, pKey, nKey);
-+    pNode->nData = nData;
-+    pNode->pData = pData; 
-+    if( pCur->pNode ){
-+      switch( match ){
-+        case -1:
-+          assert( !pCur->pNode->pRight );
-+          pNode->pParent = pCur->pNode;
-+          pCur->pNode->pRight = pNode;
-+          break;
-+        case 1:
-+          assert( !pCur->pNode->pLeft );
-+          pNode->pParent = pCur->pNode;
-+          pCur->pNode->pLeft = pNode;
-+          break;
-+        default:
-+          assert(0);
-+      }
-+    }else{
-+      pCur->pTree->pHead = pNode;
-+    }
-+
-+    /* Point the cursor at the node just inserted, as per SQLite requirements */
-+    pCur->pNode = pNode;
-+
-+    /* A new node has just been inserted, so run the balancing code */
-+    do_insert_balancing(pCur->pTree, pNode);
-+
-+    /* Set up a rollback-op in case we have to roll this operation back */
-+    if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
-+      BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
-+      if( pOp==0 ) return SQLITE_NOMEM;
-+      pOp->eOp = ROLLBACK_DELETE;
-+      pOp->iTab = pCur->iTree;
-+      pOp->nKey = pNode->nKey;
-+      pOp->pKey = sqliteMallocRaw( pOp->nKey );
-+      if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+      memcpy( pOp->pKey, pNode->pKey, pOp->nKey );
-+      btreeLogRollbackOp(pCur->pRbtree, pOp);
-+    }
-+
-+  }else{ 
-+    /* No need to insert a new node in the tree, as the key already exists.
-+     * Just clobber the current nodes data. */
-+
-+    /* Set up a rollback-op in case we have to roll this operation back */
-+    if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
-+      BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
-+      if( pOp==0 ) return SQLITE_NOMEM;
-+      pOp->iTab = pCur->iTree;
-+      pOp->nKey = pCur->pNode->nKey;
-+      pOp->pKey = sqliteMallocRaw( pOp->nKey );
-+      if( sqlite_malloc_failed ) return SQLITE_NOMEM;
-+      memcpy( pOp->pKey, pCur->pNode->pKey, pOp->nKey );
-+      pOp->nData = pCur->pNode->nData;
-+      pOp->pData = pCur->pNode->pData;
-+      pOp->eOp = ROLLBACK_INSERT;
-+      btreeLogRollbackOp(pCur->pRbtree, pOp);
-+    }else{
-+      sqliteFree( pCur->pNode->pData );
-+    }
-+
-+    /* Actually clobber the nodes data */
-+    pCur->pNode->pData = pData;
-+    pCur->pNode->nData = nData;
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+/* Move the cursor so that it points to an entry near pKey.
-+** Return a success code.
-+**
-+**     *pRes<0      The cursor is left pointing at an entry that
-+**                  is smaller than pKey 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 pKey.
-+**
-+**     *pRes>0      The cursor is left pointing at an entry that
-+**                  is larger than pKey.
-+*/
-+static int memRbtreeMoveto(
-+  RbtCursor* pCur,
-+  const void *pKey,
-+  int nKey,
-+  int *pRes
-+){
-+  BtRbNode *pTmp = 0;
-+
-+  pCur->pNode = pCur->pTree->pHead;
-+  *pRes = -1;
-+  while( pCur->pNode && *pRes ) {
-+    *pRes = key_compare(pCur->pNode->pKey, pCur->pNode->nKey, pKey, nKey);
-+    pTmp = pCur->pNode;
-+    switch( *pRes ){
-+      case 1:    /* cursor > key */
-+        pCur->pNode = pCur->pNode->pLeft;
-+        break;
-+      case -1:   /* cursor < key */
-+        pCur->pNode = pCur->pNode->pRight;
-+        break;
-+    }
-+  } 
-+
-+  /* If (pCur->pNode == NULL), then we have failed to find a match. Set
-+   * pCur->pNode to pTmp, which is either NULL (if the tree is empty) or the
-+   * last node traversed in the search. In either case the relation ship
-+   * between pTmp and the searched for key is already stored in *pRes. pTmp is
-+   * either the successor or predecessor of the key we tried to move to. */
-+  if( !pCur->pNode ) pCur->pNode = pTmp;
-+  pCur->eSkip = SKIP_NONE;
-+
-+  return SQLITE_OK;
-+}
-+
-+
-+/*
-+** Delete the entry that the cursor is pointing to.
-+**
-+** The cursor is left pointing at either the next or the previous
-+** entry.  If the cursor is left pointing to the next entry, then 
-+** the pCur->eSkip flag is set to SKIP_NEXT which forces the next call to 
-+** sqliteRbtreeNext() to be a no-op.  That way, you can always call
-+** sqliteRbtreeNext() after a delete and the cursor will be left
-+** pointing to the first entry after the deleted entry.  Similarly,
-+** pCur->eSkip is set to SKIP_PREV is the cursor is left pointing to
-+** the entry prior to the deleted entry so that a subsequent call to
-+** sqliteRbtreePrevious() will always leave the cursor pointing at the
-+** entry immediately before the one that was deleted.
-+*/
-+static int memRbtreeDelete(RbtCursor* pCur)
-+{
-+  BtRbNode *pZ;      /* The one being deleted */
-+  BtRbNode *pChild;  /* The child of the spliced out node */
-+
-+  /* It is illegal to call sqliteRbtreeDelete() if we are
-+  ** not in a transaction */
-+  assert( pCur->pRbtree->eTransState != TRANS_NONE );
-+
-+  /* Make sure some other cursor isn't trying to read this same table */
-+  if( checkReadLocks(pCur) ){
-+    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
-+  }
-+
-+  pZ = pCur->pNode;
-+  if( !pZ ){
-+    return SQLITE_OK;
-+  }
-+
-+  /* If we are not currently doing a rollback, set up a rollback op for this 
-+   * deletion */
-+  if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
-+    BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
-+    if( pOp==0 ) return SQLITE_NOMEM;
-+    pOp->iTab = pCur->iTree;
-+    pOp->nKey = pZ->nKey;
-+    pOp->pKey = pZ->pKey;
-+    pOp->nData = pZ->nData;
-+    pOp->pData = pZ->pData;
-+    pOp->eOp = ROLLBACK_INSERT;
-+    btreeLogRollbackOp(pCur->pRbtree, pOp);
-+  }
-+
-+  /* First do a standard binary-tree delete (node pZ is to be deleted). How
-+   * to do this depends on how many children pZ has:
-+   *
-+   * If pZ has no children or one child, then splice out pZ.  If pZ has two
-+   * children, splice out the successor of pZ and replace the key and data of
-+   * pZ with the key and data of the spliced out successor.  */
-+  if( pZ->pLeft && pZ->pRight ){
-+    BtRbNode *pTmp;
-+    int dummy;
-+    pCur->eSkip = SKIP_NONE;
-+    memRbtreeNext(pCur, &dummy);
-+    assert( dummy == 0 );
-+    if( pCur->pRbtree->eTransState == TRANS_ROLLBACK ){
-+      sqliteFree(pZ->pKey);
-+      sqliteFree(pZ->pData);
-+    }
-+    pZ->pData = pCur->pNode->pData;
-+    pZ->nData = pCur->pNode->nData;
-+    pZ->pKey = pCur->pNode->pKey;
-+    pZ->nKey = pCur->pNode->nKey;
-+    pTmp = pZ;
-+    pZ = pCur->pNode;
-+    pCur->pNode = pTmp;
-+    pCur->eSkip = SKIP_NEXT;
-+  }else{
-+    int res;
-+    pCur->eSkip = SKIP_NONE;
-+    memRbtreeNext(pCur, &res);
-+    pCur->eSkip = SKIP_NEXT;
-+    if( res ){
-+      memRbtreeLast(pCur, &res);
-+      memRbtreePrevious(pCur, &res);
-+      pCur->eSkip = SKIP_PREV;
-+    }
-+    if( pCur->pRbtree->eTransState == TRANS_ROLLBACK ){
-+        sqliteFree(pZ->pKey);
-+        sqliteFree(pZ->pData);
-+    }
-+  }
-+
-+  /* pZ now points at the node to be spliced out. This block does the 
-+   * splicing. */
-+  {
-+    BtRbNode **ppParentSlot = 0;
-+    assert( !pZ->pLeft || !pZ->pRight ); /* pZ has at most one child */
-+    pChild = ((pZ->pLeft)?pZ->pLeft:pZ->pRight);
-+    if( pZ->pParent ){
-+      assert( pZ == pZ->pParent->pLeft || pZ == pZ->pParent->pRight );
-+      ppParentSlot = ((pZ == pZ->pParent->pLeft)
-+          ?&pZ->pParent->pLeft:&pZ->pParent->pRight);
-+      *ppParentSlot = pChild;
-+    }else{
-+      pCur->pTree->pHead = pChild;
-+    }
-+    if( pChild ) pChild->pParent = pZ->pParent;
-+  }
-+
-+  /* pZ now points at the spliced out node. pChild is the only child of pZ, or
-+   * NULL if pZ has no children. If pZ is black, and not the tree root, then we
-+   * will have violated the "same number of black nodes in every path to a
-+   * leaf" property of the red-black tree. The code in do_delete_balancing()
-+   * repairs this. */
-+  if( pZ->isBlack ){ 
-+    do_delete_balancing(pCur->pTree, pChild, pZ->pParent);
-+  }
-+
-+  sqliteFree(pZ);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Empty table n of the Rbtree.
-+ */
-+static int memRbtreeClearTable(Rbtree* tree, int n)
-+{
-+  BtRbTree *pTree;
-+  BtRbNode *pNode;
-+
-+  pTree = sqliteHashFind(&tree->tblHash, 0, n);
-+  assert(pTree);
-+
-+  pNode = pTree->pHead;
-+  while( pNode ){
-+    if( pNode->pLeft ){
-+      pNode = pNode->pLeft;
-+    }
-+    else if( pNode->pRight ){
-+      pNode = pNode->pRight;
-+    }
-+    else {
-+      BtRbNode *pTmp = pNode->pParent;
-+      if( tree->eTransState == TRANS_ROLLBACK ){
-+        sqliteFree( pNode->pKey );
-+        sqliteFree( pNode->pData );
-+      }else{
-+        BtRollbackOp *pRollbackOp = sqliteMallocRaw(sizeof(BtRollbackOp));
-+        if( pRollbackOp==0 ) return SQLITE_NOMEM;
-+        pRollbackOp->eOp = ROLLBACK_INSERT;
-+        pRollbackOp->iTab = n;
-+        pRollbackOp->nKey = pNode->nKey;
-+        pRollbackOp->pKey = pNode->pKey;
-+        pRollbackOp->nData = pNode->nData;
-+        pRollbackOp->pData = pNode->pData;
-+        btreeLogRollbackOp(tree, pRollbackOp);
-+      }
-+      sqliteFree( pNode );
-+      if( pTmp ){
-+        if( pTmp->pLeft == pNode ) pTmp->pLeft = 0;
-+        else if( pTmp->pRight == pNode ) pTmp->pRight = 0;
-+      }
-+      pNode = pTmp;
-+    }
-+  }
-+
-+  pTree->pHead = 0;
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeFirst(RbtCursor* pCur, int *pRes)
-+{
-+  if( pCur->pTree->pHead ){
-+    pCur->pNode = pCur->pTree->pHead;
-+    while( pCur->pNode->pLeft ){
-+      pCur->pNode = pCur->pNode->pLeft;
-+    }
-+  }
-+  if( pCur->pNode ){
-+    *pRes = 0;
-+  }else{
-+    *pRes = 1;
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeLast(RbtCursor* pCur, int *pRes)
-+{
-+  if( pCur->pTree->pHead ){
-+    pCur->pNode = pCur->pTree->pHead;
-+    while( pCur->pNode->pRight ){
-+      pCur->pNode = pCur->pNode->pRight;
-+    }
-+  }
-+  if( pCur->pNode ){
-+    *pRes = 0;
-+  }else{
-+    *pRes = 1;
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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.
-+*/
-+static int memRbtreeNext(RbtCursor* pCur, int *pRes)
-+{
-+  if( pCur->pNode && pCur->eSkip != SKIP_NEXT ){
-+    if( pCur->pNode->pRight ){
-+      pCur->pNode = pCur->pNode->pRight;
-+      while( pCur->pNode->pLeft )
-+        pCur->pNode = pCur->pNode->pLeft;
-+    }else{
-+      BtRbNode * pX = pCur->pNode;
-+      pCur->pNode = pX->pParent;
-+      while( pCur->pNode && (pCur->pNode->pRight == pX) ){
-+        pX = pCur->pNode;
-+        pCur->pNode = pX->pParent;
-+      }
-+    }
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+
-+  if( !pCur->pNode ){
-+    *pRes = 1;
-+  }else{
-+    *pRes = 0;
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreePrevious(RbtCursor* pCur, int *pRes)
-+{
-+  if( pCur->pNode && pCur->eSkip != SKIP_PREV ){
-+    if( pCur->pNode->pLeft ){
-+      pCur->pNode = pCur->pNode->pLeft;
-+      while( pCur->pNode->pRight )
-+        pCur->pNode = pCur->pNode->pRight;
-+    }else{
-+      BtRbNode * pX = pCur->pNode;
-+      pCur->pNode = pX->pParent;
-+      while( pCur->pNode && (pCur->pNode->pLeft == pX) ){
-+        pX = pCur->pNode;
-+        pCur->pNode = pX->pParent;
-+      }
-+    }
-+  }
-+  pCur->eSkip = SKIP_NONE;
-+
-+  if( !pCur->pNode ){
-+    *pRes = 1;
-+  }else{
-+    *pRes = 0;
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeKeySize(RbtCursor* pCur, int *pSize)
-+{
-+  if( pCur->pNode ){
-+    *pSize = pCur->pNode->nKey;
-+  }else{
-+    *pSize = 0;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeKey(RbtCursor* pCur, int offset, int amt, char *zBuf)
-+{
-+  if( !pCur->pNode ) return 0;
-+  if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
-+    memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
-+  }else{
-+    memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
-+    amt = pCur->pNode->nKey-offset;
-+  }
-+  return amt;
-+}
-+
-+static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
-+{
-+  if( pCur->pNode ){
-+    *pSize = pCur->pNode->nData;
-+  }else{
-+    *pSize = 0;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeData(RbtCursor *pCur, int offset, int amt, char *zBuf)
-+{
-+  if( !pCur->pNode ) return 0;
-+  if( (amt + offset) <= pCur->pNode->nData ){
-+    memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
-+  }else{
-+    memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
-+    amt = pCur->pNode->nData-offset;
-+  }
-+  return amt;
-+}
-+
-+static int memRbtreeCloseCursor(RbtCursor* pCur)
-+{
-+  if( pCur->pTree->pCursors==pCur ){
-+    pCur->pTree->pCursors = pCur->pShared;
-+  }else{
-+    RbtCursor *p = pCur->pTree->pCursors;
-+    while( p && p->pShared!=pCur ){ p = p->pShared; }
-+    assert( p!=0 );
-+    if( p ){
-+      p->pShared = pCur->pShared;
-+    }
-+  }
-+  sqliteFree(pCur);
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeGetMeta(Rbtree* tree, int* aMeta)
-+{
-+  memcpy( aMeta, tree->aMetaData, sizeof(int) * SQLITE_N_BTREE_META );
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeUpdateMeta(Rbtree* tree, int* aMeta)
-+{
-+  memcpy( tree->aMetaData, aMeta, sizeof(int) * SQLITE_N_BTREE_META );
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Check that each table in the Rbtree meets the requirements for a red-black
-+ * binary tree. If an error is found, return an explanation of the problem in 
-+ * memory obtained from sqliteMalloc(). Parameters aRoot and nRoot are ignored. 
-+ */
-+static char *memRbtreeIntegrityCheck(Rbtree* tree, int* aRoot, int nRoot)
-+{
-+  char * msg = 0;
-+  HashElem *p;
-+
-+  for(p=sqliteHashFirst(&tree->tblHash); p; p=sqliteHashNext(p)){
-+    BtRbTree *pTree = sqliteHashData(p);
-+    check_redblack_tree(pTree, &msg);
-+  }
-+
-+  return msg;
-+}
-+
-+static int memRbtreeSetCacheSize(Rbtree* tree, int sz)
-+{
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeSetSafetyLevel(Rbtree *pBt, int level){
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeBeginTrans(Rbtree* tree)
-+{
-+  if( tree->eTransState != TRANS_NONE ) 
-+    return SQLITE_ERROR;
-+
-+  assert( tree->pTransRollback == 0 );
-+  tree->eTransState = TRANS_INTRANSACTION;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Delete a linked list of BtRollbackOp structures.
-+*/
-+static void deleteRollbackList(BtRollbackOp *pOp){
-+  while( pOp ){
-+    BtRollbackOp *pTmp = pOp->pNext;
-+    sqliteFree(pOp->pData);
-+    sqliteFree(pOp->pKey);
-+    sqliteFree(pOp);
-+    pOp = pTmp;
-+  }
-+}
-+
-+static int memRbtreeCommit(Rbtree* tree){
-+  /* Just delete pTransRollback and pCheckRollback */
-+  deleteRollbackList(tree->pCheckRollback);
-+  deleteRollbackList(tree->pTransRollback);
-+  tree->pTransRollback = 0;
-+  tree->pCheckRollback = 0;
-+  tree->pCheckRollbackTail = 0;
-+  tree->eTransState = TRANS_NONE;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Close the supplied Rbtree. Delete everything associated with it.
-+ */
-+static int memRbtreeClose(Rbtree* tree)
-+{
-+  HashElem *p;
-+  memRbtreeCommit(tree);
-+  while( (p=sqliteHashFirst(&tree->tblHash))!=0 ){
-+    tree->eTransState = TRANS_ROLLBACK;
-+    memRbtreeDropTable(tree, sqliteHashKeysize(p));
-+  }
-+  sqliteHashClear(&tree->tblHash);
-+  sqliteFree(tree);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+ * Execute and delete the supplied rollback-list on pRbtree.
-+ */
-+static void execute_rollback_list(Rbtree *pRbtree, BtRollbackOp *pList)
-+{
-+  BtRollbackOp *pTmp;
-+  RbtCursor cur;
-+  int res;
-+
-+  cur.pRbtree = pRbtree;
-+  cur.wrFlag = 1;
-+  while( pList ){
-+    switch( pList->eOp ){
-+      case ROLLBACK_INSERT:
-+        cur.pTree  = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
-+        assert(cur.pTree);
-+        cur.iTree  = pList->iTab;
-+        cur.eSkip  = SKIP_NONE;
-+        memRbtreeInsert( &cur, pList->pKey,
-+            pList->nKey, pList->pData, pList->nData );
-+        break;
-+      case ROLLBACK_DELETE:
-+        cur.pTree  = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
-+        assert(cur.pTree);
-+        cur.iTree  = pList->iTab;
-+        cur.eSkip  = SKIP_NONE;
-+        memRbtreeMoveto(&cur, pList->pKey, pList->nKey, &res);
-+        assert(res == 0);
-+        memRbtreeDelete( &cur );
-+        break;
-+      case ROLLBACK_CREATE:
-+        btreeCreateTable(pRbtree, pList->iTab);
-+        break;
-+      case ROLLBACK_DROP:
-+        memRbtreeDropTable(pRbtree, pList->iTab);
-+        break;
-+      default:
-+        assert(0);
-+    }
-+    sqliteFree(pList->pKey);
-+    sqliteFree(pList->pData);
-+    pTmp = pList->pNext;
-+    sqliteFree(pList);
-+    pList = pTmp;
-+  }
-+}
-+
-+static int memRbtreeRollback(Rbtree* tree)
-+{
-+  tree->eTransState = TRANS_ROLLBACK;
-+  execute_rollback_list(tree, tree->pCheckRollback);
-+  execute_rollback_list(tree, tree->pTransRollback);
-+  tree->pTransRollback = 0;
-+  tree->pCheckRollback = 0;
-+  tree->pCheckRollbackTail = 0;
-+  tree->eTransState = TRANS_NONE;
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeBeginCkpt(Rbtree* tree)
-+{
-+  if( tree->eTransState != TRANS_INTRANSACTION ) 
-+    return SQLITE_ERROR;
-+
-+  assert( tree->pCheckRollback == 0 );
-+  assert( tree->pCheckRollbackTail == 0 );
-+  tree->eTransState = TRANS_INCHECKPOINT;
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeCommitCkpt(Rbtree* tree)
-+{
-+  if( tree->eTransState == TRANS_INCHECKPOINT ){ 
-+    if( tree->pCheckRollback ){
-+      tree->pCheckRollbackTail->pNext = tree->pTransRollback;
-+      tree->pTransRollback = tree->pCheckRollback;
-+      tree->pCheckRollback = 0;
-+      tree->pCheckRollbackTail = 0;
-+    }
-+    tree->eTransState = TRANS_INTRANSACTION;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeRollbackCkpt(Rbtree* tree)
-+{
-+  if( tree->eTransState != TRANS_INCHECKPOINT ) return SQLITE_OK;
-+  tree->eTransState = TRANS_ROLLBACK;
-+  execute_rollback_list(tree, tree->pCheckRollback);
-+  tree->pCheckRollback = 0;
-+  tree->pCheckRollbackTail = 0;
-+  tree->eTransState = TRANS_INTRANSACTION;
-+  return SQLITE_OK;
-+}
-+
-+#ifdef SQLITE_TEST
-+static int memRbtreePageDump(Rbtree* tree, int pgno, int rec)
-+{
-+  assert(!"Cannot call sqliteRbtreePageDump");
-+  return SQLITE_OK;
-+}
-+
-+static int memRbtreeCursorDump(RbtCursor* pCur, int* aRes)
-+{
-+  assert(!"Cannot call sqliteRbtreeCursorDump");
-+  return SQLITE_OK;
-+}
-+#endif
-+
-+static struct Pager *memRbtreePager(Rbtree* tree)
-+{
-+  return 0;
-+}
-+
-+/*
-+** Return the full pathname of the underlying database file.
-+*/
-+static const char *memRbtreeGetFilename(Rbtree *pBt){
-+  return 0;  /* A NULL return indicates there is no underlying file */
-+}
-+
-+/*
-+** The copy file function is not implemented for the in-memory database
-+*/
-+static int memRbtreeCopyFile(Rbtree *pBt, Rbtree *pBt2){
-+  return SQLITE_INTERNAL;  /* Not implemented */
-+}
-+
-+static BtOps sqliteRbtreeOps = {
-+    (int(*)(Btree*)) memRbtreeClose,
-+    (int(*)(Btree*,int)) memRbtreeSetCacheSize,
-+    (int(*)(Btree*,int)) memRbtreeSetSafetyLevel,
-+    (int(*)(Btree*)) memRbtreeBeginTrans,
-+    (int(*)(Btree*)) memRbtreeCommit,
-+    (int(*)(Btree*)) memRbtreeRollback,
-+    (int(*)(Btree*)) memRbtreeBeginCkpt,
-+    (int(*)(Btree*)) memRbtreeCommitCkpt,
-+    (int(*)(Btree*)) memRbtreeRollbackCkpt,
-+    (int(*)(Btree*,int*)) memRbtreeCreateTable,
-+    (int(*)(Btree*,int*)) memRbtreeCreateTable,
-+    (int(*)(Btree*,int)) memRbtreeDropTable,
-+    (int(*)(Btree*,int)) memRbtreeClearTable,
-+    (int(*)(Btree*,int,int,BtCursor**)) memRbtreeCursor,
-+    (int(*)(Btree*,int*)) memRbtreeGetMeta,
-+    (int(*)(Btree*,int*)) memRbtreeUpdateMeta,
-+    (char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
-+    (const char*(*)(Btree*)) memRbtreeGetFilename,
-+    (int(*)(Btree*,Btree*)) memRbtreeCopyFile,
-+    (struct Pager*(*)(Btree*)) memRbtreePager,
-+#ifdef SQLITE_TEST
-+    (int(*)(Btree*,int,int)) memRbtreePageDump,
-+#endif
-+};
-+
-+static BtCursorOps sqliteRbtreeCursorOps = {
-+    (int(*)(BtCursor*,const void*,int,int*)) memRbtreeMoveto,
-+    (int(*)(BtCursor*)) memRbtreeDelete,
-+    (int(*)(BtCursor*,const void*,int,const void*,int)) memRbtreeInsert,
-+    (int(*)(BtCursor*,int*)) memRbtreeFirst,
-+    (int(*)(BtCursor*,int*)) memRbtreeLast,
-+    (int(*)(BtCursor*,int*)) memRbtreeNext,
-+    (int(*)(BtCursor*,int*)) memRbtreePrevious,
-+    (int(*)(BtCursor*,int*)) memRbtreeKeySize,
-+    (int(*)(BtCursor*,int,int,char*)) memRbtreeKey,
-+    (int(*)(BtCursor*,const void*,int,int,int*)) memRbtreeKeyCompare,
-+    (int(*)(BtCursor*,int*)) memRbtreeDataSize,
-+    (int(*)(BtCursor*,int,int,char*)) memRbtreeData,
-+    (int(*)(BtCursor*)) memRbtreeCloseCursor,
-+#ifdef SQLITE_TEST
-+    (int(*)(BtCursor*,int*)) memRbtreeCursorDump,
-+#endif
-+
-+};
-+
-+#endif /* SQLITE_OMIT_INMEMORYDB */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/build.c
-@@ -0,0 +1,2156 @@
-+/*
-+** 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
-+**     PRAGMA
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+#include <ctype.h>
-+
-+/*
-+** This routine is called when a new SQL statement is beginning to
-+** be parsed.  Check to see if the schema for the database needs
-+** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables.
-+** If it does, then read it.
-+*/
-+void sqliteBeginParse(Parse *pParse, int explainFlag){
-+  sqlite *db = pParse->db;
-+  int i;
-+  pParse->explain = explainFlag;
-+  if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){
-+    int rc = sqliteInit(db, &pParse->zErrMsg);
-+    if( rc!=SQLITE_OK ){
-+      pParse->rc = rc;
-+      pParse->nErr++;
-+    }
-+  }
-+  for(i=0; i<db->nDb; i++){
-+    DbClearProperty(db, i, DB_Locked);
-+    if( !db->aDb[i].inTrans ){
-+      DbClearProperty(db, i, DB_Cookie);
-+    }
-+  }
-+  pParse->nVar = 0;
-+}
-+
-+/*
-+** This routine is called after a single SQL statement has been
-+** parsed and we want to execute the VDBE code to implement 
-+** that statement.  Prior action routines should have already
-+** constructed VDBE code to do the work of the SQL statement.
-+** This routine just has to execute the VDBE code.
-+**
-+** Note that if an error occurred, it might be the case that
-+** no VDBE code was generated.
-+*/
-+void sqliteExec(Parse *pParse){
-+  sqlite *db = pParse->db;
-+  Vdbe *v = pParse->pVdbe;
-+
-+  if( v==0 && (v = sqliteGetVdbe(pParse))!=0 ){
-+    sqliteVdbeAddOp(v, OP_Halt, 0, 0);
-+  }
-+  if( sqlite_malloc_failed ) return;
-+  if( v && pParse->nErr==0 ){
-+    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
-+    sqliteVdbeTrace(v, trace);
-+    sqliteVdbeMakeReady(v, pParse->nVar, pParse->explain);
-+    pParse->rc = pParse->nErr ? SQLITE_ERROR : 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->nAgg = 0;
-+  pParse->nVar = 0;
-+}
-+
-+/*
-+** 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 sqliteLocateTable().
-+*/
-+Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){
-+  Table *p = 0;
-+  int i;
-+  for(i=0; i<db->nDb; i++){
-+    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
-+    if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[j].zName) ) continue;
-+    p = sqliteHashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
-+    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 sqliteFindTable()
-+** is that this routine leaves an error message in pParse->zErrMsg
-+** where sqliteFindTable() does not.
-+*/
-+Table *sqliteLocateTable(Parse *pParse, const char *zName, const char *zDbase){
-+  Table *p;
-+
-+  p = sqliteFindTable(pParse->db, zName, zDbase);
-+  if( p==0 ){
-+    if( zDbase ){
-+      sqliteErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
-+    }else if( sqliteFindTable(pParse->db, zName, 0)!=0 ){
-+      sqliteErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
-+         zName, zDbase);
-+    }else{
-+      sqliteErrorMsg(pParse, "no such table: %s", zName);
-+    }
-+  }
-+  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.
-+*/
-+Index *sqliteFindIndex(sqlite *db, const char *zName, const char *zDb){
-+  Index *p = 0;
-+  int i;
-+  for(i=0; i<db->nDb; i++){
-+    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
-+    if( zDb && sqliteStrICmp(zDb, db->aDb[j].zName) ) continue;
-+    p = sqliteHashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
-+    if( p ) break;
-+  }
-+  return 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 sqliteDeleteIndex(sqlite *db, Index *p){
-+  Index *pOld;
-+
-+  assert( db!=0 && p->zName!=0 );
-+  pOld = sqliteHashInsert(&db->aDb[p->iDb].idxHash, p->zName,
-+                          strlen(p->zName)+1, 0);
-+  if( pOld!=0 && pOld!=p ){
-+    sqliteHashInsert(&db->aDb[p->iDb].idxHash, pOld->zName,
-+                     strlen(pOld->zName)+1, pOld);
-+  }
-+  sqliteFree(p);
-+}
-+
-+/*
-+** Unlink the given index from its table, then remove
-+** the index from the index hash table and free its memory
-+** structures.
-+*/
-+void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
-+  if( pIndex->pTable->pIndex==pIndex ){
-+    pIndex->pTable->pIndex = pIndex->pNext;
-+  }else{
-+    Index *p;
-+    for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
-+    if( p && p->pNext==pIndex ){
-+      p->pNext = pIndex->pNext;
-+    }
-+  }
-+  sqliteDeleteIndex(db, pIndex);
-+}
-+
-+/*
-+** Erase all schema information from the in-memory hash tables of
-+** database connection.  This routine is called to reclaim memory
-+** before the connection closes.  It is also called during a rollback
-+** if there were schema changes during the transaction.
-+**
-+** If iDb<=0 then reset the internal schema tables for all database
-+** files.  If iDb>=2 then reset the internal schema for only the
-+** single file indicated.
-+*/
-+void sqliteResetInternalSchema(sqlite *db, int iDb){
-+  HashElem *pElem;
-+  Hash temp1;
-+  Hash temp2;
-+  int i, j;
-+
-+  assert( iDb>=0 && iDb<db->nDb );
-+  db->flags &= ~SQLITE_Initialized;
-+  for(i=iDb; i<db->nDb; i++){
-+    Db *pDb = &db->aDb[i];
-+    temp1 = pDb->tblHash;
-+    temp2 = pDb->trigHash;
-+    sqliteHashInit(&pDb->trigHash, SQLITE_HASH_STRING, 0);
-+    sqliteHashClear(&pDb->aFKey);
-+    sqliteHashClear(&pDb->idxHash);
-+    for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
-+      Trigger *pTrigger = sqliteHashData(pElem);
-+      sqliteDeleteTrigger(pTrigger);
-+    }
-+    sqliteHashClear(&temp2);
-+    sqliteHashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0);
-+    for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
-+      Table *pTab = sqliteHashData(pElem);
-+      sqliteDeleteTable(db, pTab);
-+    }
-+    sqliteHashClear(&temp1);
-+    DbClearProperty(db, i, DB_SchemaLoaded);
-+    if( iDb>0 ) return;
-+  }
-+  assert( iDb==0 );
-+  db->flags &= ~SQLITE_InternChanges;
-+
-+  /* If one or more of the auxiliary database files has been closed,
-+  ** then remove then 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=0; i<db->nDb; i++){
-+    struct Db *pDb = &db->aDb[i];
-+    if( pDb->pBt==0 ){
-+      if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
-+      pDb->pAux = 0;
-+    }
-+  }
-+  for(i=j=2; i<db->nDb; i++){
-+    struct Db *pDb = &db->aDb[i];
-+    if( pDb->pBt==0 ){
-+      sqliteFree(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]));
-+    sqliteFree(db->aDb);
-+    db->aDb = db->aDbStatic;
-+  }
-+}
-+
-+/*
-+** This routine is called whenever a rollback occurs.  If there were
-+** schema changes during the transaction, then we have to reset the
-+** internal hash tables and reload them from disk.
-+*/
-+void sqliteRollbackInternalChanges(sqlite *db){
-+  if( db->flags & SQLITE_InternChanges ){
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+}
-+
-+/*
-+** This routine is called when a commit occurs.
-+*/
-+void sqliteCommitInternalChanges(sqlite *db){
-+  db->aDb[0].schema_cookie = db->next_cookie;
-+  db->flags &= ~SQLITE_InternChanges;
-+}
-+
-+/*
-+** 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.  Nor does it remove
-+** foreign keys from the sqlite.aFKey hash table.  But it does destroy
-+** memory structures of the indices and foreign keys associated with 
-+** the table.
-+**
-+** Indices associated with the table are unlinked from the "db"
-+** data structure if db!=NULL.  If db==NULL, indices attached to
-+** the table are deleted, but it is assumed they have already been
-+** unlinked.
-+*/
-+void sqliteDeleteTable(sqlite *db, Table *pTable){
-+  int i;
-+  Index *pIndex, *pNext;
-+  FKey *pFKey, *pNextFKey;
-+
-+  if( pTable==0 ) return;
-+
-+  /* Delete all indices associated with this table
-+  */
-+  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
-+    pNext = pIndex->pNext;
-+    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
-+    sqliteDeleteIndex(db, pIndex);
-+  }
-+
-+  /* Delete all foreign keys associated with this table.  The keys
-+  ** should have already been unlinked from the db->aFKey hash table 
-+  */
-+  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
-+    pNextFKey = pFKey->pNextFrom;
-+    assert( pTable->iDb<db->nDb );
-+    assert( sqliteHashFind(&db->aDb[pTable->iDb].aFKey,
-+                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
-+    sqliteFree(pFKey);
-+  }
-+
-+  /* Delete the Table structure itself.
-+  */
-+  for(i=0; i<pTable->nCol; i++){
-+    sqliteFree(pTable->aCol[i].zName);
-+    sqliteFree(pTable->aCol[i].zDflt);
-+    sqliteFree(pTable->aCol[i].zType);
-+  }
-+  sqliteFree(pTable->zName);
-+  sqliteFree(pTable->aCol);
-+  sqliteSelectDelete(pTable->pSelect);
-+  sqliteFree(pTable);
-+}
-+
-+/*
-+** Unlink the given table from the hash tables and the delete the
-+** table structure with all its indices and foreign keys.
-+*/
-+static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *p){
-+  Table *pOld;
-+  FKey *pF1, *pF2;
-+  int i = p->iDb;
-+  assert( db!=0 );
-+  pOld = sqliteHashInsert(&db->aDb[i].tblHash, p->zName, strlen(p->zName)+1, 0);
-+  assert( pOld==0 || pOld==p );
-+  for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
-+    int nTo = strlen(pF1->zTo) + 1;
-+    pF2 = sqliteHashFind(&db->aDb[i].aFKey, pF1->zTo, nTo);
-+    if( pF2==pF1 ){
-+      sqliteHashInsert(&db->aDb[i].aFKey, pF1->zTo, nTo, pF1->pNextTo);
-+    }else{
-+      while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
-+      if( pF2 ){
-+        pF2->pNextTo = pF1->pNextTo;
-+      }
-+    }
-+  }
-+  sqliteDeleteTable(db, p);
-+}
-+
-+/*
-+** Construct the name of a user table or index from a token.
-+**
-+** Space to hold the name is obtained from sqliteMalloc() and must
-+** be freed by the calling function.
-+*/
-+char *sqliteTableNameFromToken(Token *pName){
-+  char *zName = sqliteStrNDup(pName->z, pName->n);
-+  sqliteDequote(zName);
-+  return zName;
-+}
-+
-+/*
-+** Generate code to open the appropriate master table.  The table
-+** opened will be SQLITE_MASTER for persistent tables and 
-+** SQLITE_TEMP_MASTER for temporary tables.  The table is opened
-+** on cursor 0.
-+*/
-+void sqliteOpenMasterTable(Vdbe *v, int isTemp){
-+  sqliteVdbeAddOp(v, OP_Integer, isTemp, 0);
-+  sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
-+}
-+
-+/*
-+** 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
-+** pStart token is the CREATE and pName is 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 sqliteEndTable() routine
-+** is called to complete the construction of the new table record.
-+*/
-+void sqliteStartTable(
-+  Parse *pParse,   /* Parser context */
-+  Token *pStart,   /* The "CREATE" token */
-+  Token *pName,    /* Name of table or view to create */
-+  int isTemp,      /* True if this is a TEMP table */
-+  int isView       /* True if this is a VIEW */
-+){
-+  Table *pTable;
-+  Index *pIdx;
-+  char *zName;
-+  sqlite *db = pParse->db;
-+  Vdbe *v;
-+  int iDb;
-+
-+  pParse->sFirstToken = *pStart;
-+  zName = sqliteTableNameFromToken(pName);
-+  if( zName==0 ) return;
-+  if( db->init.iDb==1 ) isTemp = 1;
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  assert( (isTemp & 1)==isTemp );
-+  {
-+    int code;
-+    char *zDb = isTemp ? "temp" : "main";
-+    if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
-+      sqliteFree(zName);
-+      return;
-+    }
-+    if( isView ){
-+      if( isTemp ){
-+        code = SQLITE_CREATE_TEMP_VIEW;
-+      }else{
-+        code = SQLITE_CREATE_VIEW;
-+      }
-+    }else{
-+      if( isTemp ){
-+        code = SQLITE_CREATE_TEMP_TABLE;
-+      }else{
-+        code = SQLITE_CREATE_TABLE;
-+      }
-+    }
-+    if( sqliteAuthCheck(pParse, code, zName, 0, zDb) ){
-+      sqliteFree(zName);
-+      return;
-+    }
-+  }
-+#endif
-+ 
-+
-+  /* Before trying to create a temporary table, make sure the Btree for
-+  ** holding temporary tables is open.
-+  */
-+  if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
-+    int rc = sqliteBtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
-+    if( rc!=SQLITE_OK ){
-+      sqliteErrorMsg(pParse, "unable to open a temporary database "
-+        "file for storing temporary tables");
-+      pParse->nErr++;
-+      return;
-+    }
-+    if( db->flags & SQLITE_InTrans ){
-+      rc = sqliteBtreeBeginTrans(db->aDb[1].pBt);
-+      if( rc!=SQLITE_OK ){
-+        sqliteErrorMsg(pParse, "unable to get a write lock on "
-+          "the temporary database file");
-+        return;
-+      }
-+    }
-+  }
-+
-+  /* Make sure the new table name does not collide with an existing
-+  ** index or table name.  Issue an error message if it does.
-+  **
-+  ** If we are re-reading the sqlite_master table because of a schema
-+  ** change and a new permanent table is found whose name collides with
-+  ** an existing temporary table, that is not an error.
-+  */
-+  pTable = sqliteFindTable(db, zName, 0);
-+  iDb = isTemp ? 1 : db->init.iDb;
-+  if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){
-+    sqliteErrorMsg(pParse, "table %T already exists", pName);
-+    sqliteFree(zName);
-+    return;
-+  }
-+  if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 &&
-+          (pIdx->iDb==0 || !db->init.busy) ){
-+    sqliteErrorMsg(pParse, "there is already an index named %s", zName);
-+    sqliteFree(zName);
-+    return;
-+  }
-+  pTable = sqliteMalloc( sizeof(Table) );
-+  if( pTable==0 ){
-+    sqliteFree(zName);
-+    return;
-+  }
-+  pTable->zName = zName;
-+  pTable->nCol = 0;
-+  pTable->aCol = 0;
-+  pTable->iPKey = -1;
-+  pTable->pIndex = 0;
-+  pTable->iDb = iDb;
-+  if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable);
-+  pParse->pNewTable = pTable;
-+
-+  /* 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 = sqliteGetVdbe(pParse))!=0 ){
-+    sqliteBeginWriteOperation(pParse, 0, isTemp);
-+    if( !isTemp ){
-+      sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0);
-+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 1);
-+    }
-+    sqliteOpenMasterTable(v, isTemp);
-+    sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
-+    sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+    sqliteVdbeAddOp(v, OP_String, 0, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, 0, 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.  sqliteStartTable() gets called
-+** first to get things going.  Then this routine is called for each
-+** column.
-+*/
-+void sqliteAddColumn(Parse *pParse, Token *pName){
-+  Table *p;
-+  int i;
-+  char *z = 0;
-+  Column *pCol;
-+  if( (p = pParse->pNewTable)==0 ) return;
-+  sqliteSetNString(&z, pName->z, pName->n, 0);
-+  if( z==0 ) return;
-+  sqliteDequote(z);
-+  for(i=0; i<p->nCol; i++){
-+    if( sqliteStrICmp(z, p->aCol[i].zName)==0 ){
-+      sqliteErrorMsg(pParse, "duplicate column name: %s", z);
-+      sqliteFree(z);
-+      return;
-+    }
-+  }
-+  if( (p->nCol & 0x7)==0 ){
-+    Column *aNew;
-+    aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
-+    if( aNew==0 ) return;
-+    p->aCol = aNew;
-+  }
-+  pCol = &p->aCol[p->nCol];
-+  memset(pCol, 0, sizeof(p->aCol[0]));
-+  pCol->zName = z;
-+  pCol->sortOrder = SQLITE_SO_NUM;
-+  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.
-+*/
-+void sqliteAddNotNull(Parse *pParse, int onError){
-+  Table *p;
-+  int i;
-+  if( (p = pParse->pNewTable)==0 ) return;
-+  i = p->nCol-1;
-+  if( i>=0 ) p->aCol[i].notNull = onError;
-+}
-+
-+/*
-+** 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.
-+*/ 
-+void sqliteAddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
-+  Table *p;
-+  int i, j;
-+  int n;
-+  char *z, **pz;
-+  Column *pCol;
-+  if( (p = pParse->pNewTable)==0 ) return;
-+  i = p->nCol-1;
-+  if( i<0 ) return;
-+  pCol = &p->aCol[i];
-+  pz = &pCol->zType;
-+  n = pLast->n + Addr(pLast->z) - Addr(pFirst->z);
-+  sqliteSetNString(pz, pFirst->z, n, 0);
-+  z = *pz;
-+  if( z==0 ) return;
-+  for(i=j=0; z[i]; i++){
-+    int c = z[i];
-+    if( isspace(c) ) continue;
-+    z[j++] = c;
-+  }
-+  z[j] = 0;
-+  if( pParse->db->file_format>=4 ){
-+    pCol->sortOrder = sqliteCollateType(z, n);
-+  }else{
-+    pCol->sortOrder = SQLITE_SO_NUM;
-+  }
-+}
-+
-+/*
-+** The given token is the default value for the last column added to
-+** the table currently under construction.  If "minusFlag" is true, it
-+** means the value token was preceded by a minus sign.
-+**
-+** This routine is called by the parser while in the middle of
-+** parsing a CREATE TABLE statement.
-+*/
-+void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){
-+  Table *p;
-+  int i;
-+  char **pz;
-+  if( (p = pParse->pNewTable)==0 ) return;
-+  i = p->nCol-1;
-+  if( i<0 ) return;
-+  pz = &p->aCol[i].zDflt;
-+  if( minusFlag ){
-+    sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0);
-+  }else{
-+    sqliteSetNString(pz, pVal->z, pVal->n, 0);
-+  }
-+  sqliteDequote(*pz);
-+}
-+
-+/*
-+** 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 row id.  (Exception:
-+** For backwards compatibility with older databases, do not do this
-+** if the file format version number is less than 1.)  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.
-+*/
-+void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
-+  Table *pTab = pParse->pNewTable;
-+  char *zType = 0;
-+  int iCol = -1, i;
-+  if( pTab==0 ) goto primary_key_exit;
-+  if( pTab->hasPrimKey ){
-+    sqliteErrorMsg(pParse, 
-+      "table \"%s\" has more than one primary key", pTab->zName);
-+    goto primary_key_exit;
-+  }
-+  pTab->hasPrimKey = 1;
-+  if( pList==0 ){
-+    iCol = pTab->nCol - 1;
-+    pTab->aCol[iCol].isPrimKey = 1;
-+  }else{
-+    for(i=0; i<pList->nId; i++){
-+      for(iCol=0; iCol<pTab->nCol; iCol++){
-+        if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ) break;
-+      }
-+      if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;
-+    }
-+    if( pList->nId>1 ) iCol = -1;
-+  }
-+  if( iCol>=0 && iCol<pTab->nCol ){
-+    zType = pTab->aCol[iCol].zType;
-+  }
-+  if( pParse->db->file_format>=1 && 
-+           zType && sqliteStrICmp(zType, "INTEGER")==0 ){
-+    pTab->iPKey = iCol;
-+    pTab->keyConf = onError;
-+  }else{
-+    sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0);
-+    pList = 0;
-+  }
-+
-+primary_key_exit:
-+  sqliteIdListDelete(pList);
-+  return;
-+}
-+
-+/*
-+** Return the appropriate collating type given a type name.
-+**
-+** The collation type is text (SQLITE_SO_TEXT) if the type
-+** name contains the character stream "text" or "blob" or
-+** "clob".  Any other type name is collated as numeric
-+** (SQLITE_SO_NUM).
-+*/
-+int sqliteCollateType(const char *zType, int nType){
-+  int i;
-+  for(i=0; i<nType-3; i++){
-+    int c = *(zType++) | 0x60;
-+    if( (c=='b' || c=='c') && sqliteStrNICmp(zType, "lob", 3)==0 ){
-+      return SQLITE_SO_TEXT;
-+    }
-+    if( c=='c' && sqliteStrNICmp(zType, "har", 3)==0 ){
-+      return SQLITE_SO_TEXT;
-+    }
-+    if( c=='t' && sqliteStrNICmp(zType, "ext", 3)==0 ){
-+      return SQLITE_SO_TEXT;
-+    }
-+  }
-+  return SQLITE_SO_NUM;
-+}
-+
-+/*
-+** This routine is called by the parser while in the middle of
-+** parsing a CREATE TABLE statement.  A "COLLATE" clause has
-+** been seen on a column.  This routine sets the Column.sortOrder on
-+** the column currently under construction.
-+*/
-+void sqliteAddCollateType(Parse *pParse, int collType){
-+  Table *p;
-+  int i;
-+  if( (p = pParse->pNewTable)==0 ) return;
-+  i = p->nCol-1;
-+  if( i>=0 ) p->aCol[i].sortOrder = collType;
-+}
-+
-+/*
-+** Come up with a new random value for the schema cookie.  Make sure
-+** the new value is different from the old.
-+**
-+** 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.
-+*/
-+void sqliteChangeCookie(sqlite *db, Vdbe *v){
-+  if( db->next_cookie==db->aDb[0].schema_cookie ){
-+    unsigned char r;
-+    sqliteRandomness(1, &r);
-+    db->next_cookie = db->aDb[0].schema_cookie + r + 1;
-+    db->flags |= SQLITE_InternChanges;
-+    sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
-+    sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
-+  }
-+}
-+
-+/*
-+** 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.
-+*/
-+static int identLength(const char *z){
-+  int n;
-+  int needQuote = 0;
-+  for(n=0; *z; n++, z++){
-+    if( *z=='\'' ){ n++; needQuote=1; }
-+  }
-+  return n + needQuote*2;
-+}
-+
-+/*
-+** Write an identifier onto the end of the given string.  Add
-+** quote characters as needed.
-+*/
-+static void identPut(char *z, int *pIdx, char *zIdent){
-+  int i, j, needQuote;
-+  i = *pIdx;
-+  for(j=0; zIdent[j]; j++){
-+    if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
-+  }
-+  needQuote =  zIdent[j]!=0 || isdigit(zIdent[0])
-+                  || sqliteKeywordCode(zIdent, j)!=TK_ID;
-+  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(Table *p){
-+  int i, k, n;
-+  char *zStmt;
-+  char *zSep, *zSep2, *zEnd;
-+  n = 0;
-+  for(i=0; i<p->nCol; i++){
-+    n += identLength(p->aCol[i].zName);
-+  }
-+  n += identLength(p->zName);
-+  if( n<40 ){
-+    zSep = "";
-+    zSep2 = ",";
-+    zEnd = ")";
-+  }else{
-+    zSep = "\n  ";
-+    zSep2 = ",\n  ";
-+    zEnd = "\n)";
-+  }
-+  n += 35 + 6*p->nCol;
-+  zStmt = sqliteMallocRaw( n );
-+  if( zStmt==0 ) return 0;
-+  strcpy(zStmt, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE ");
-+  k = strlen(zStmt);
-+  identPut(zStmt, &k, p->zName);
-+  zStmt[k++] = '(';
-+  for(i=0; i<p->nCol; i++){
-+    strcpy(&zStmt[k], zSep);
-+    k += strlen(&zStmt[k]);
-+    zSep = zSep2;
-+    identPut(zStmt, &k, p->aCol[i].zName);
-+  }
-+  strcpy(&zStmt[k], 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 changes, 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.
-+*/
-+void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
-+  Table *p;
-+  sqlite *db = pParse->db;
-+
-+  if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite_malloc_failed ) return;
-+  p = pParse->pNewTable;
-+  if( p==0 ) return;
-+
-+  /* If the table is generated from a SELECT, then construct the
-+  ** list of columns and the text of the table.
-+  */
-+  if( pSelect ){
-+    Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect);
-+    if( pSelTab==0 ) return;
-+    assert( p->aCol==0 );
-+    p->nCol = pSelTab->nCol;
-+    p->aCol = pSelTab->aCol;
-+    pSelTab->nCol = 0;
-+    pSelTab->aCol = 0;
-+    sqliteDeleteTable(0, pSelTab);
-+  }
-+
-+  /* 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.  The record number
-+  ** for the new table entry should already be on the stack.
-+  **
-+  ** 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;
-+
-+    v = sqliteGetVdbe(pParse);
-+    if( v==0 ) return;
-+    if( p->pSelect==0 ){
-+      /* A regular table */
-+      sqliteVdbeOp3(v, OP_CreateTable, 0, p->iDb, (char*)&p->tnum, P3_POINTER);
-+    }else{
-+      /* A view */
-+      sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+    }
-+    p->tnum = 0;
-+    sqliteVdbeAddOp(v, OP_Pull, 1, 0);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, p->pSelect==0?"table":"view", P3_STATIC);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
-+    sqliteVdbeAddOp(v, OP_Dup, 4, 0);
-+    sqliteVdbeAddOp(v, OP_String, 0, 0);
-+    if( pSelect ){
-+      char *z = createTableStmt(p);
-+      n = z ? strlen(z) : 0;
-+      sqliteVdbeChangeP3(v, -1, z, n);
-+      sqliteFree(z);
-+    }else{
-+      assert( pEnd!=0 );
-+      n = Addr(pEnd->z) - Addr(pParse->sFirstToken.z) + 1;
-+      sqliteVdbeChangeP3(v, -1, pParse->sFirstToken.z, n);
-+    }
-+    sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
-+    if( !p->iDb ){
-+      sqliteChangeCookie(db, v);
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+    if( pSelect ){
-+      sqliteVdbeAddOp(v, OP_Integer, p->iDb, 0);
-+      sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0);
-+      pParse->nTab = 2;
-+      sqliteSelect(pParse, pSelect, SRT_Table, 1, 0, 0, 0);
-+    }
-+    sqliteEndWriteOperation(pParse);
-+  }
-+
-+  /* Add the table to the in-memory representation of the database.
-+  */
-+  if( pParse->explain==0 && pParse->nErr==0 ){
-+    Table *pOld;
-+    FKey *pFKey;
-+    pOld = sqliteHashInsert(&db->aDb[p->iDb].tblHash, 
-+                            p->zName, strlen(p->zName)+1, p);
-+    if( pOld ){
-+      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
-+      return;
-+    }
-+    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
-+      int nTo = strlen(pFKey->zTo) + 1;
-+      pFKey->pNextTo = sqliteHashFind(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo);
-+      sqliteHashInsert(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo, pFKey);
-+    }
-+    pParse->pNewTable = 0;
-+    db->nTable++;
-+    db->flags |= SQLITE_InternChanges;
-+  }
-+}
-+
-+/*
-+** The parser calls this routine in order to create a new VIEW
-+*/
-+void sqliteCreateView(
-+  Parse *pParse,     /* The parsing context */
-+  Token *pBegin,     /* The CREATE token that begins the statement */
-+  Token *pName,      /* 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 */
-+){
-+  Table *p;
-+  int n;
-+  const char *z;
-+  Token sEnd;
-+  DbFixer sFix;
-+
-+  sqliteStartTable(pParse, pBegin, pName, isTemp, 1);
-+  p = pParse->pNewTable;
-+  if( p==0 || pParse->nErr ){
-+    sqliteSelectDelete(pSelect);
-+    return;
-+  }
-+  if( sqliteFixInit(&sFix, pParse, p->iDb, "view", pName)
-+    && sqliteFixSelect(&sFix, pSelect)
-+  ){
-+    sqliteSelectDelete(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 sqlite_exec() call returns.
-+  */
-+  p->pSelect = sqliteSelectDup(pSelect);
-+  sqliteSelectDelete(pSelect);
-+  if( !pParse->db->init.busy ){
-+    sqliteViewGetColumnNames(pParse, p);
-+  }
-+
-+  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
-+  ** the end.
-+  */
-+  sEnd = pParse->sLastToken;
-+  if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
-+    sEnd.z += sEnd.n;
-+  }
-+  sEnd.n = 0;
-+  n = sEnd.z - pBegin->z;
-+  z = pBegin->z;
-+  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
-+  sEnd.z = &z[n-1];
-+  sEnd.n = 1;
-+
-+  /* Use sqliteEndTable() to add the view to the SQLITE_MASTER table */
-+  sqliteEndTable(pParse, &sEnd, 0);
-+  return;
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){
-+  ExprList *pEList;
-+  Select *pSel;
-+  Table *pSelTab;
-+  int nErr = 0;
-+
-+  assert( pTable );
-+
-+  /* 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, this error is caught previously and so the following test
-+  ** should always fail.  But we will leave it in place just to be safe.
-+  */
-+  if( pTable->nCol<0 ){
-+    sqliteErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
-+    return 1;
-+  }
-+
-+  /* If we get this far, it means we need to compute the table names.
-+  */
-+  assert( pTable->pSelect ); /* If nCol==0, then pTable must be a VIEW */
-+  pSel = pTable->pSelect;
-+
-+  /* Note that the call to sqliteResultSetOfSelect() will expand any
-+  ** "*" elements in this list.  But we will need to restore the list
-+  ** back to its original configuration afterwards, so we save a copy of
-+  ** the original in pEList.
-+  */
-+  pEList = pSel->pEList;
-+  pSel->pEList = sqliteExprListDup(pEList);
-+  if( pSel->pEList==0 ){
-+    pSel->pEList = pEList;
-+    return 1;  /* Malloc failed */
-+  }
-+  pTable->nCol = -1;
-+  pSelTab = sqliteResultSetOfSelect(pParse, 0, pSel);
-+  if( pSelTab ){
-+    assert( pTable->aCol==0 );
-+    pTable->nCol = pSelTab->nCol;
-+    pTable->aCol = pSelTab->aCol;
-+    pSelTab->nCol = 0;
-+    pSelTab->aCol = 0;
-+    sqliteDeleteTable(0, pSelTab);
-+    DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
-+  }else{
-+    pTable->nCol = 0;
-+    nErr++;
-+  }
-+  sqliteSelectUnbind(pSel);
-+  sqliteExprListDelete(pSel->pEList);
-+  pSel->pEList = pEList;
-+  return nErr;  
-+}
-+
-+/*
-+** Clear the column names from the VIEW pTable.
-+**
-+** This routine is called whenever any other table or view is modified.
-+** The view passed into this routine might depend directly or indirectly
-+** on the modified or deleted table so we need to clear the old column
-+** names so that they will be recomputed.
-+*/
-+static void sqliteViewResetColumnNames(Table *pTable){
-+  int i;
-+  Column *pCol;
-+  assert( pTable!=0 && pTable->pSelect!=0 );
-+  for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){
-+    sqliteFree(pCol->zName);
-+    sqliteFree(pCol->zDflt);
-+    sqliteFree(pCol->zType);
-+  }
-+  sqliteFree(pTable->aCol);
-+  pTable->aCol = 0;
-+  pTable->nCol = 0;
-+}
-+
-+/*
-+** Clear the column names from every VIEW in database idx.
-+*/
-+static void sqliteViewResetAll(sqlite *db, int idx){
-+  HashElem *i;
-+  if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
-+  for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
-+    Table *pTab = sqliteHashData(i);
-+    if( pTab->pSelect ){
-+      sqliteViewResetColumnNames(pTab);
-+    }
-+  }
-+  DbClearProperty(db, idx, DB_UnresetViews);
-+}
-+
-+/*
-+** Given a token, look up a table with that name.  If not found, leave
-+** an error for the parser to find and return NULL.
-+*/
-+Table *sqliteTableFromToken(Parse *pParse, Token *pTok){
-+  char *zName;
-+  Table *pTab;
-+  zName = sqliteTableNameFromToken(pTok);
-+  if( zName==0 ) return 0;
-+  pTab = sqliteFindTable(pParse->db, zName, 0);
-+  sqliteFree(zName);
-+  if( pTab==0 ){
-+    sqliteErrorMsg(pParse, "no such table: %T", pTok);
-+  }
-+  return pTab;
-+}
-+
-+/*
-+** This routine is called to do the work of a DROP TABLE statement.
-+** pName is the name of the table to be dropped.
-+*/
-+void sqliteDropTable(Parse *pParse, Token *pName, int isView){
-+  Table *pTable;
-+  Vdbe *v;
-+  int base;
-+  sqlite *db = pParse->db;
-+  int iDb;
-+
-+  if( pParse->nErr || sqlite_malloc_failed ) return;
-+  pTable = sqliteTableFromToken(pParse, pName);
-+  if( pTable==0 ) return;
-+  iDb = pTable->iDb;
-+  assert( iDb>=0 && iDb<db->nDb );
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  {
-+    int code;
-+    const char *zTab = SCHEMA_TABLE(pTable->iDb);
-+    const char *zDb = db->aDb[pTable->iDb].zName;
-+    if( sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
-+      return;
-+    }
-+    if( isView ){
-+      if( iDb==1 ){
-+        code = SQLITE_DROP_TEMP_VIEW;
-+      }else{
-+        code = SQLITE_DROP_VIEW;
-+      }
-+    }else{
-+      if( iDb==1 ){
-+        code = SQLITE_DROP_TEMP_TABLE;
-+      }else{
-+        code = SQLITE_DROP_TABLE;
-+      }
-+    }
-+    if( sqliteAuthCheck(pParse, code, pTable->zName, 0, zDb) ){
-+      return;
-+    }
-+    if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTable->zName, 0, zDb) ){
-+      return;
-+    }
-+  }
-+#endif
-+  if( pTable->readOnly ){
-+    sqliteErrorMsg(pParse, "table %s may not be dropped", pTable->zName);
-+    pParse->nErr++;
-+    return;
-+  }
-+  if( isView && pTable->pSelect==0 ){
-+    sqliteErrorMsg(pParse, "use DROP TABLE to delete table %s", pTable->zName);
-+    return;
-+  }
-+  if( !isView && pTable->pSelect ){
-+    sqliteErrorMsg(pParse, "use DROP VIEW to delete view %s", pTable->zName);
-+    return;
-+  }
-+
-+  /* Generate code to remove the table from the master table
-+  ** on disk.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v ){
-+    static VdbeOpList dropTable[] = {
-+      { OP_Rewind,     0, ADDR(8),  0},
-+      { OP_String,     0, 0,        0}, /* 1 */
-+      { OP_MemStore,   1, 1,        0},
-+      { OP_MemLoad,    1, 0,        0}, /* 3 */
-+      { OP_Column,     0, 2,        0},
-+      { OP_Ne,         0, ADDR(7),  0},
-+      { OP_Delete,     0, 0,        0},
-+      { OP_Next,       0, ADDR(3),  0}, /* 7 */
-+    };
-+    Index *pIdx;
-+    Trigger *pTrigger;
-+    sqliteBeginWriteOperation(pParse, 0, pTable->iDb);
-+
-+    /* Drop all triggers associated with the table being dropped */
-+    pTrigger = pTable->pTrigger;
-+    while( pTrigger ){
-+      assert( pTrigger->iDb==pTable->iDb || pTrigger->iDb==1 );
-+      sqliteDropTriggerPtr(pParse, pTrigger, 1);
-+      if( pParse->explain ){
-+        pTrigger = pTrigger->pNext;
-+      }else{
-+        pTrigger = pTable->pTrigger;
-+      }
-+    }
-+
-+    /* Drop all SQLITE_MASTER entries that refer to the table */
-+    sqliteOpenMasterTable(v, pTable->iDb);
-+    base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
-+    sqliteVdbeChangeP3(v, base+1, pTable->zName, 0);
-+
-+    /* Drop all SQLITE_TEMP_MASTER entries that refer to the table */
-+    if( pTable->iDb!=1 ){
-+      sqliteOpenMasterTable(v, 1);
-+      base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
-+      sqliteVdbeChangeP3(v, base+1, pTable->zName, 0);
-+    }
-+
-+    if( pTable->iDb==0 ){
-+      sqliteChangeCookie(db, v);
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+    if( !isView ){
-+      sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->iDb);
-+      for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
-+        sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb);
-+      }
-+    }
-+    sqliteEndWriteOperation(pParse);
-+  }
-+
-+  /* Delete the in-memory description of the table.
-+  **
-+  ** Exception: if the SQL statement began with the EXPLAIN keyword,
-+  ** then no changes should be made.
-+  */
-+  if( !pParse->explain ){
-+    sqliteUnlinkAndDeleteTable(db, pTable);
-+    db->flags |= SQLITE_InternChanges;
-+  }
-+  sqliteViewResetAll(db, iDb);
-+}
-+
-+/*
-+** This routine constructs a P3 string suitable for an OP_MakeIdxKey
-+** opcode and adds that P3 string to the most recently inserted instruction
-+** in the virtual machine.  The P3 string consists of a single character
-+** for each column in the index pIdx of table pTab.  If the column uses
-+** a numeric sort order, then the P3 string character corresponding to
-+** that column is 'n'.  If the column uses a text sort order, then the
-+** P3 string is 't'.  See the OP_MakeIdxKey opcode documentation for
-+** additional information.  See also the sqliteAddKeyType() routine.
-+*/
-+void sqliteAddIdxKeyType(Vdbe *v, Index *pIdx){
-+  char *zType;
-+  Table *pTab;
-+  int i, n;
-+  assert( pIdx!=0 && pIdx->pTable!=0 );
-+  pTab = pIdx->pTable;
-+  n = pIdx->nColumn;
-+  zType = sqliteMallocRaw( n+1 );
-+  if( zType==0 ) return;
-+  for(i=0; i<n; i++){
-+    int iCol = pIdx->aiColumn[i];
-+    assert( iCol>=0 && iCol<pTab->nCol );
-+    if( (pTab->aCol[iCol].sortOrder & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){
-+      zType[i] = 't';
-+    }else{
-+      zType[i] = 'n';
-+    }
-+  }
-+  zType[n] = 0;
-+  sqliteVdbeChangeP3(v, -1, zType, n);
-+  sqliteFree(zType);
-+}
-+
-+/*
-+** 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 new FKey
-+** is not linked into db->aFKey at this point - that does not happen
-+** until sqliteEndTable().
-+**
-+** The foreign key is set for IMMEDIATE processing.  A subsequent call
-+** to sqliteDeferForeignKey() might change this to DEFERRED.
-+*/
-+void sqliteCreateForeignKey(
-+  Parse *pParse,       /* Parsing context */
-+  IdList *pFromCol,    /* Columns in this table that point to other table */
-+  Token *pTo,          /* Name of the other table */
-+  IdList *pToCol,      /* Columns in the other table */
-+  int flags            /* Conflict resolution algorithms. */
-+){
-+  Table *p = pParse->pNewTable;
-+  int nByte;
-+  int i;
-+  int nCol;
-+  char *z;
-+  FKey *pFKey = 0;
-+
-+  assert( pTo!=0 );
-+  if( p==0 || pParse->nErr ) goto fk_end;
-+  if( pFromCol==0 ){
-+    int iCol = p->nCol-1;
-+    if( iCol<0 ) goto fk_end;
-+    if( pToCol && pToCol->nId!=1 ){
-+      sqliteErrorMsg(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->nId!=pFromCol->nId ){
-+    sqliteErrorMsg(pParse,
-+        "number of columns in foreign key does not match the number of "
-+        "columns in the referenced table");
-+    goto fk_end;
-+  }else{
-+    nCol = pFromCol->nId;
-+  }
-+  nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1;
-+  if( pToCol ){
-+    for(i=0; i<pToCol->nId; i++){
-+      nByte += strlen(pToCol->a[i].zName) + 1;
-+    }
-+  }
-+  pFKey = sqliteMalloc( nByte );
-+  if( pFKey==0 ) goto fk_end;
-+  pFKey->pFrom = p;
-+  pFKey->pNextFrom = p->pFKey;
-+  z = (char*)&pFKey[1];
-+  pFKey->aCol = (struct sColMap*)z;
-+  z += sizeof(struct sColMap)*nCol;
-+  pFKey->zTo = z;
-+  memcpy(z, pTo->z, pTo->n);
-+  z[pTo->n] = 0;
-+  z += pTo->n+1;
-+  pFKey->pNextTo = 0;
-+  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( sqliteStrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
-+          pFKey->aCol[i].iFrom = j;
-+          break;
-+        }
-+      }
-+      if( j>=p->nCol ){
-+        sqliteErrorMsg(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 = strlen(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 = flags & 0xff;
-+  pFKey->updateConf = (flags >> 8 ) & 0xff;
-+  pFKey->insertConf = (flags >> 16 ) & 0xff;
-+
-+  /* Link the foreign key to the table as the last step.
-+  */
-+  p->pFKey = pFKey;
-+  pFKey = 0;
-+
-+fk_end:
-+  sqliteFree(pFKey);
-+  sqliteIdListDelete(pFromCol);
-+  sqliteIdListDelete(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.
-+*/
-+void sqliteDeferForeignKey(Parse *pParse, int isDeferred){
-+  Table *pTab;
-+  FKey *pFKey;
-+  if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
-+  pFKey->isDeferred = isDeferred;
-+}
-+
-+/*
-+** Create a new index for an SQL table.  pIndex is the name of the index 
-+** and pTable 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.  
-+*/
-+void sqliteCreateIndex(
-+  Parse *pParse,   /* All information about this parse */
-+  Token *pName,    /* Name of the index.  May be NULL */
-+  SrcList *pTable, /* Name of the table to index.  Use pParse->pNewTable if 0 */
-+  IdList *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 a CREATE TABLE statement */
-+  Token *pEnd      /* The ")" that closes the CREATE INDEX statement */
-+){
-+  Table *pTab;     /* Table to be indexed */
-+  Index *pIndex;   /* The index to be created */
-+  char *zName = 0;
-+  int i, j;
-+  Token nullId;    /* Fake token for an empty ID list */
-+  DbFixer sFix;    /* For assigning database names to pTable */
-+  int isTemp;      /* True for a temporary index */
-+  sqlite *db = pParse->db;
-+
-+  if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index;
-+  if( db->init.busy 
-+     && sqliteFixInit(&sFix, pParse, db->init.iDb, "index", pName)
-+     && sqliteFixSrcList(&sFix, pTable)
-+  ){
-+    goto exit_create_index;
-+  }
-+
-+  /*
-+  ** Find the table that is to be indexed.  Return early if not found.
-+  */
-+  if( pTable!=0 ){
-+    assert( pName!=0 );
-+    assert( pTable->nSrc==1 );
-+    pTab =  sqliteSrcListLookup(pParse, pTable);
-+  }else{
-+    assert( pName==0 );
-+    pTab =  pParse->pNewTable;
-+  }
-+  if( pTab==0 || pParse->nErr ) goto exit_create_index;
-+  if( pTab->readOnly ){
-+    sqliteErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
-+    goto exit_create_index;
-+  }
-+  if( pTab->iDb>=2 && db->init.busy==0 ){
-+    sqliteErrorMsg(pParse, "table %s may not have indices added", pTab->zName);
-+    goto exit_create_index;
-+  }
-+  if( pTab->pSelect ){
-+    sqliteErrorMsg(pParse, "views may not be indexed");
-+    goto exit_create_index;
-+  }
-+  isTemp = pTab->iDb==1;
-+
-+  /*
-+  ** 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 && !db->init.busy ){
-+    Index *pISameName;    /* Another index with the same name */
-+    Table *pTSameName;    /* A table with same name as the index */
-+    zName = sqliteTableNameFromToken(pName);
-+    if( zName==0 ) goto exit_create_index;
-+    if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
-+      sqliteErrorMsg(pParse, "index %s already exists", zName);
-+      goto exit_create_index;
-+    }
-+    if( (pTSameName = sqliteFindTable(db, zName, 0))!=0 ){
-+      sqliteErrorMsg(pParse, "there is already a table named %s", zName);
-+      goto exit_create_index;
-+    }
-+  }else if( pName==0 ){
-+    char zBuf[30];
-+    int n;
-+    Index *pLoop;
-+    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
-+    sprintf(zBuf,"%d)",n);
-+    zName = 0;
-+    sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
-+    if( zName==0 ) goto exit_create_index;
-+  }else{
-+    zName = sqliteTableNameFromToken(pName);
-+  }
-+
-+  /* Check for authorization to create an index.
-+  */
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  {
-+    const char *zDb = db->aDb[pTab->iDb].zName;
-+
-+    assert( pTab->iDb==db->init.iDb || isTemp );
-+    if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
-+      goto exit_create_index;
-+    }
-+    i = SQLITE_CREATE_INDEX;
-+    if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
-+    if( sqliteAuthCheck(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 = strlen(nullId.z);
-+    pList = sqliteIdListAppend(0, &nullId);
-+    if( pList==0 ) goto exit_create_index;
-+  }
-+
-+  /* 
-+  ** Allocate the index structure. 
-+  */
-+  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
-+                        sizeof(int)*pList->nId );
-+  if( pIndex==0 ) goto exit_create_index;
-+  pIndex->aiColumn = (int*)&pIndex[1];
-+  pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
-+  strcpy(pIndex->zName, zName);
-+  pIndex->pTable = pTab;
-+  pIndex->nColumn = pList->nId;
-+  pIndex->onError = onError;
-+  pIndex->autoIndex = pName==0;
-+  pIndex->iDb = isTemp ? 1 : db->init.iDb;
-+
-+  /* 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.
-+  */
-+  for(i=0; i<pList->nId; i++){
-+    for(j=0; j<pTab->nCol; j++){
-+      if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
-+    }
-+    if( j>=pTab->nCol ){
-+      sqliteErrorMsg(pParse, "table %s has no column named %s",
-+        pTab->zName, pList->a[i].zName);
-+      sqliteFree(pIndex);
-+      goto exit_create_index;
-+    }
-+    pIndex->aiColumn[i] = j;
-+  }
-+
-+  /* Link the new Index structure to its table and to the other
-+  ** in-memory database structures. 
-+  */
-+  if( !pParse->explain ){
-+    Index *p;
-+    p = sqliteHashInsert(&db->aDb[pIndex->iDb].idxHash, 
-+                         pIndex->zName, strlen(pIndex->zName)+1, pIndex);
-+    if( p ){
-+      assert( p==pIndex );  /* Malloc must have failed */
-+      sqliteFree(pIndex);
-+      goto exit_create_index;
-+    }
-+    db->flags |= SQLITE_InternChanges;
-+  }
-+
-+  /* 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 operation of UPDATE
-+  ** and INSERT.
-+  */
-+  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;
-+  }
-+
-+  /* If the db->init.busy is 1 it means we are reading the SQL off the
-+  ** "sqlite_master" table on the disk.  So do not write to the disk
-+  ** again.  Extract the table number from the db->init.newTnum field.
-+  */
-+  if( db->init.busy && pTable!=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 pTable==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 ){
-+    int n;
-+    Vdbe *v;
-+    int lbl1, lbl2;
-+    int i;
-+    int addr;
-+
-+    v = sqliteGetVdbe(pParse);
-+    if( v==0 ) goto exit_create_index;
-+    if( pTable!=0 ){
-+      sqliteBeginWriteOperation(pParse, 0, isTemp);
-+      sqliteOpenMasterTable(v, isTemp);
-+    }
-+    sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, "index", P3_STATIC);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, pIndex->zName, 0);
-+    sqliteVdbeOp3(v, OP_String, 0, 0, pTab->zName, 0);
-+    sqliteVdbeOp3(v, OP_CreateIndex, 0, isTemp,(char*)&pIndex->tnum,P3_POINTER);
-+    pIndex->tnum = 0;
-+    if( pTable ){
-+      sqliteVdbeCode(v,
-+          OP_Dup,       0,      0,
-+          OP_Integer,   isTemp, 0,
-+          OP_OpenWrite, 1,      0,
-+      0);
-+    }
-+    addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
-+    if( pStart && pEnd ){
-+      n = Addr(pEnd->z) - Addr(pStart->z) + 1;
-+      sqliteVdbeChangeP3(v, addr, pStart->z, n);
-+    }
-+    sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
-+    if( pTable ){
-+      sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+      sqliteVdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0);
-+      lbl2 = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2);
-+      lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0);
-+      for(i=0; i<pIndex->nColumn; i++){
-+        int iCol = pIndex->aiColumn[i];
-+        if( pTab->iPKey==iCol ){
-+          sqliteVdbeAddOp(v, OP_Dup, i, 0);
-+        }else{
-+          sqliteVdbeAddOp(v, OP_Column, 2, iCol);
-+        }
-+      }
-+      sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
-+      if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIndex);
-+      sqliteVdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
-+                      "indexed columns are not unique", P3_STATIC);
-+      sqliteVdbeAddOp(v, OP_Next, 2, lbl1);
-+      sqliteVdbeResolveLabel(v, lbl2);
-+      sqliteVdbeAddOp(v, OP_Close, 2, 0);
-+      sqliteVdbeAddOp(v, OP_Close, 1, 0);
-+    }
-+    if( pTable!=0 ){
-+      if( !isTemp ){
-+        sqliteChangeCookie(db, v);
-+      }
-+      sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+      sqliteEndWriteOperation(pParse);
-+    }
-+  }
-+
-+  /* Clean up before exiting */
-+exit_create_index:
-+  sqliteIdListDelete(pList);
-+  sqliteSrcListDelete(pTable);
-+  sqliteFree(zName);
-+  return;
-+}
-+
-+/*
-+** This routine will drop an existing named index.  This routine
-+** implements the DROP INDEX statement.
-+*/
-+void sqliteDropIndex(Parse *pParse, SrcList *pName){
-+  Index *pIndex;
-+  Vdbe *v;
-+  sqlite *db = pParse->db;
-+
-+  if( pParse->nErr || sqlite_malloc_failed ) return;
-+  assert( pName->nSrc==1 );
-+  pIndex = sqliteFindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
-+  if( pIndex==0 ){
-+    sqliteErrorMsg(pParse, "no such index: %S", pName, 0);
-+    goto exit_drop_index;
-+  }
-+  if( pIndex->autoIndex ){
-+    sqliteErrorMsg(pParse, "index associated with UNIQUE "
-+      "or PRIMARY KEY constraint cannot be dropped", 0);
-+    goto exit_drop_index;
-+  }
-+  if( pIndex->iDb>1 ){
-+    sqliteErrorMsg(pParse, "cannot alter schema of attached "
-+       "databases", 0);
-+    goto exit_drop_index;
-+  }
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  {
-+    int code = SQLITE_DROP_INDEX;
-+    Table *pTab = pIndex->pTable;
-+    const char *zDb = db->aDb[pIndex->iDb].zName;
-+    const char *zTab = SCHEMA_TABLE(pIndex->iDb);
-+    if( sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
-+      goto exit_drop_index;
-+    }
-+    if( pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
-+    if( sqliteAuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
-+      goto exit_drop_index;
-+    }
-+  }
-+#endif
-+
-+  /* Generate code to remove the index and from the master table */
-+  v = sqliteGetVdbe(pParse);
-+  if( v ){
-+    static VdbeOpList dropIndex[] = {
-+      { OP_Rewind,     0, ADDR(9), 0}, 
-+      { OP_String,     0, 0,       0}, /* 1 */
-+      { OP_MemStore,   1, 1,       0},
-+      { OP_MemLoad,    1, 0,       0}, /* 3 */
-+      { OP_Column,     0, 1,       0},
-+      { OP_Eq,         0, ADDR(8), 0},
-+      { OP_Next,       0, ADDR(3), 0},
-+      { OP_Goto,       0, ADDR(9), 0},
-+      { OP_Delete,     0, 0,       0}, /* 8 */
-+    };
-+    int base;
-+
-+    sqliteBeginWriteOperation(pParse, 0, pIndex->iDb);
-+    sqliteOpenMasterTable(v, pIndex->iDb);
-+    base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
-+    sqliteVdbeChangeP3(v, base+1, pIndex->zName, 0);
-+    if( pIndex->iDb==0 ){
-+      sqliteChangeCookie(db, v);
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+    sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb);
-+    sqliteEndWriteOperation(pParse);
-+  }
-+
-+  /* Delete the in-memory description of this index.
-+  */
-+  if( !pParse->explain ){
-+    sqliteUnlinkAndDeleteIndex(db, pIndex);
-+    db->flags |= SQLITE_InternChanges;
-+  }
-+
-+exit_drop_index:
-+  sqliteSrcListDelete(pName);
-+}
-+
-+/*
-+** 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.
-+*/
-+IdList *sqliteIdListAppend(IdList *pList, Token *pToken){
-+  if( pList==0 ){
-+    pList = sqliteMalloc( sizeof(IdList) );
-+    if( pList==0 ) return 0;
-+    pList->nAlloc = 0;
-+  }
-+  if( pList->nId>=pList->nAlloc ){
-+    struct IdList_item *a;
-+    pList->nAlloc = pList->nAlloc*2 + 5;
-+    a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
-+    if( a==0 ){
-+      sqliteIdListDelete(pList);
-+      return 0;
-+    }
-+    pList->a = a;
-+  }
-+  memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
-+  if( pToken ){
-+    char **pz = &pList->a[pList->nId].zName;
-+    sqliteSetNString(pz, pToken->z, pToken->n, 0);
-+    if( *pz==0 ){
-+      sqliteIdListDelete(pList);
-+      return 0;
-+    }else{
-+      sqliteDequote(*pz);
-+    }
-+  }
-+  pList->nId++;
-+  return pList;
-+}
-+
-+/*
-+** 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 pToken is NULL.
-+**
-+** A new SrcList is returned, or NULL if malloc() fails.
-+**
-+** 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:
-+**
-+**         sqliteSrcListAppend(A,B,0);
-+**
-+** Then B is a table name and the database name is unspecified.  If called
-+** like this:
-+**
-+**         sqliteSrcListAppend(A,B,C);
-+**
-+** Then C is the table name and B is the database name.
-+*/
-+SrcList *sqliteSrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
-+  if( pList==0 ){
-+    pList = sqliteMalloc( sizeof(SrcList) );
-+    if( pList==0 ) return 0;
-+    pList->nAlloc = 1;
-+  }
-+  if( pList->nSrc>=pList->nAlloc ){
-+    SrcList *pNew;
-+    pList->nAlloc *= 2;
-+    pNew = sqliteRealloc(pList,
-+               sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
-+    if( pNew==0 ){
-+      sqliteSrcListDelete(pList);
-+      return 0;
-+    }
-+    pList = pNew;
-+  }
-+  memset(&pList->a[pList->nSrc], 0, sizeof(pList->a[0]));
-+  if( pDatabase && pDatabase->z==0 ){
-+    pDatabase = 0;
-+  }
-+  if( pDatabase && pTable ){
-+    Token *pTemp = pDatabase;
-+    pDatabase = pTable;
-+    pTable = pTemp;
-+  }
-+  if( pTable ){
-+    char **pz = &pList->a[pList->nSrc].zName;
-+    sqliteSetNString(pz, pTable->z, pTable->n, 0);
-+    if( *pz==0 ){
-+      sqliteSrcListDelete(pList);
-+      return 0;
-+    }else{
-+      sqliteDequote(*pz);
-+    }
-+  }
-+  if( pDatabase ){
-+    char **pz = &pList->a[pList->nSrc].zDatabase;
-+    sqliteSetNString(pz, pDatabase->z, pDatabase->n, 0);
-+    if( *pz==0 ){
-+      sqliteSrcListDelete(pList);
-+      return 0;
-+    }else{
-+      sqliteDequote(*pz);
-+    }
-+  }
-+  pList->a[pList->nSrc].iCursor = -1;
-+  pList->nSrc++;
-+  return pList;
-+}
-+
-+/*
-+** Assign cursors to all tables in a SrcList
-+*/
-+void sqliteSrcListAssignCursors(Parse *pParse, SrcList *pList){
-+  int i;
-+  for(i=0; i<pList->nSrc; i++){
-+    if( pList->a[i].iCursor<0 ){
-+      pList->a[i].iCursor = pParse->nTab++;
-+    }
-+  }
-+}
-+
-+/*
-+** Add an alias to the last identifier on the given identifier list.
-+*/
-+void sqliteSrcListAddAlias(SrcList *pList, Token *pToken){
-+  if( pList && pList->nSrc>0 ){
-+    int i = pList->nSrc - 1;
-+    sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
-+    sqliteDequote(pList->a[i].zAlias);
-+  }
-+}
-+
-+/*
-+** Delete an IdList.
-+*/
-+void sqliteIdListDelete(IdList *pList){
-+  int i;
-+  if( pList==0 ) return;
-+  for(i=0; i<pList->nId; i++){
-+    sqliteFree(pList->a[i].zName);
-+  }
-+  sqliteFree(pList->a);
-+  sqliteFree(pList);
-+}
-+
-+/*
-+** Return the index in pList of the identifier named zId.  Return -1
-+** if not found.
-+*/
-+int sqliteIdListIndex(IdList *pList, const char *zName){
-+  int i;
-+  if( pList==0 ) return -1;
-+  for(i=0; i<pList->nId; i++){
-+    if( sqliteStrICmp(pList->a[i].zName, zName)==0 ) return i;
-+  }
-+  return -1;
-+}
-+
-+/*
-+** Delete an entire SrcList including all its substructure.
-+*/
-+void sqliteSrcListDelete(SrcList *pList){
-+  int i;
-+  if( pList==0 ) return;
-+  for(i=0; i<pList->nSrc; i++){
-+    sqliteFree(pList->a[i].zDatabase);
-+    sqliteFree(pList->a[i].zName);
-+    sqliteFree(pList->a[i].zAlias);
-+    if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){
-+      sqliteDeleteTable(0, pList->a[i].pTab);
-+    }
-+    sqliteSelectDelete(pList->a[i].pSelect);
-+    sqliteExprDelete(pList->a[i].pOn);
-+    sqliteIdListDelete(pList->a[i].pUsing);
-+  }
-+  sqliteFree(pList);
-+}
-+
-+/*
-+** Begin a transaction
-+*/
-+void sqliteBeginTransaction(Parse *pParse, int onError){
-+  sqlite *db;
-+
-+  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-+  if( pParse->nErr || sqlite_malloc_failed ) return;
-+  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
-+  if( db->flags & SQLITE_InTrans ){
-+    sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");
-+    return;
-+  }
-+  sqliteBeginWriteOperation(pParse, 0, 0);
-+  if( !pParse->explain ){
-+    db->flags |= SQLITE_InTrans;
-+    db->onError = onError;
-+  }
-+}
-+
-+/*
-+** Commit a transaction
-+*/
-+void sqliteCommitTransaction(Parse *pParse){
-+  sqlite *db;
-+
-+  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-+  if( pParse->nErr || sqlite_malloc_failed ) return;
-+  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
-+  if( (db->flags & SQLITE_InTrans)==0 ){
-+    sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
-+    return;
-+  }
-+  if( !pParse->explain ){
-+    db->flags &= ~SQLITE_InTrans;
-+  }
-+  sqliteEndWriteOperation(pParse);
-+  if( !pParse->explain ){
-+    db->onError = OE_Default;
-+  }
-+}
-+
-+/*
-+** Rollback a transaction
-+*/
-+void sqliteRollbackTransaction(Parse *pParse){
-+  sqlite *db;
-+  Vdbe *v;
-+
-+  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
-+  if( pParse->nErr || sqlite_malloc_failed ) return;
-+  if( sqliteAuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
-+  if( (db->flags & SQLITE_InTrans)==0 ){
-+    sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
-+    return; 
-+  }
-+  v = sqliteGetVdbe(pParse);
-+  if( v ){
-+    sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
-+  }
-+  if( !pParse->explain ){
-+    db->flags &= ~SQLITE_InTrans;
-+    db->onError = OE_Default;
-+  }
-+}
-+
-+/*
-+** Generate VDBE code that will verify the schema cookie for all
-+** named database files.
-+*/
-+void sqliteCodeVerifySchema(Parse *pParse, int iDb){
-+  sqlite *db = pParse->db;
-+  Vdbe *v = sqliteGetVdbe(pParse);
-+  assert( iDb>=0 && iDb<db->nDb );
-+  assert( db->aDb[iDb].pBt!=0 );
-+  if( iDb!=1 && !DbHasProperty(db, iDb, DB_Cookie) ){
-+    sqliteVdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie);
-+    DbSetProperty(db, iDb, DB_Cookie);
-+  }
-+}
-+
-+/*
-+** 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 setCheckpoint 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.
-+**
-+** Only database iDb and the temp database are made writable by this call.
-+** If iDb==0, then the main and temp databases are made writable.   If
-+** iDb==1 then only the temp database is made writable.  If iDb>1 then the
-+** specified auxiliary database and the temp database are made writable.
-+*/
-+void sqliteBeginWriteOperation(Parse *pParse, int setCheckpoint, int iDb){
-+  Vdbe *v;
-+  sqlite *db = pParse->db;
-+  if( DbHasProperty(db, iDb, DB_Locked) ) return;
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) return;
-+  if( !db->aDb[iDb].inTrans ){
-+    sqliteVdbeAddOp(v, OP_Transaction, iDb, 0);
-+    DbSetProperty(db, iDb, DB_Locked);
-+    sqliteCodeVerifySchema(pParse, iDb);
-+    if( iDb!=1 ){
-+      sqliteBeginWriteOperation(pParse, setCheckpoint, 1);
-+    }
-+  }else if( setCheckpoint ){
-+    sqliteVdbeAddOp(v, OP_Checkpoint, iDb, 0);
-+    DbSetProperty(db, iDb, DB_Locked);
-+  }
-+}
-+
-+/*
-+** Generate code that concludes an operation that may have changed
-+** the database.  If a statement transaction was started, then emit
-+** an OP_Commit that will cause the changes to be committed to disk.
-+**
-+** Note that checkpoints are automatically committed at the end of
-+** a statement.  Note also that there can be multiple calls to 
-+** sqliteBeginWriteOperation() but there should only be a single
-+** call to sqliteEndWriteOperation() at the conclusion of the statement.
-+*/
-+void sqliteEndWriteOperation(Parse *pParse){
-+  Vdbe *v;
-+  sqlite *db = pParse->db;
-+  if( pParse->trigStack ) return; /* if this is in a trigger */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) return;
-+  if( db->flags & SQLITE_InTrans ){
-+    /* A BEGIN has executed.  Do not commit until we see an explicit
-+    ** COMMIT statement. */
-+  }else{
-+    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
-+  }
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/config_static.w32.h
-@@ -0,0 +1 @@
-+#define SQLITE_PTR_SZ 4
-\ No newline at end of file
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/copy.c
-@@ -0,0 +1,110 @@
-+/*
-+** 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 COPY command.
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** The COPY command is for compatibility with PostgreSQL and specificially
-+** for the ability to read the output of pg_dump.  The format is as
-+** follows:
-+**
-+**    COPY table FROM file [USING DELIMITERS string]
-+**
-+** "table" is an existing table name.  We will read lines of code from
-+** file to fill this table with data.  File might be "stdin".  The optional
-+** delimiter string identifies the field separators.  The default is a tab.
-+*/
-+void sqliteCopy(
-+  Parse *pParse,       /* The parser context */
-+  SrcList *pTableName, /* The name of the table into which we will insert */
-+  Token *pFilename,    /* The file from which to obtain information */
-+  Token *pDelimiter,   /* Use this as the field delimiter */
-+  int onError          /* What to do if a constraint fails */
-+){
-+  Table *pTab;
-+  int i;
-+  Vdbe *v;
-+  int addr, end;
-+  char *zFile = 0;
-+  const char *zDb;
-+  sqlite *db = pParse->db;
-+
-+
-+  if( sqlite_malloc_failed  ) goto copy_cleanup;
-+  assert( pTableName->nSrc==1 );
-+  pTab = sqliteSrcListLookup(pParse, pTableName);
-+  if( pTab==0 || sqliteIsReadOnly(pParse, pTab, 0) ) goto copy_cleanup;
-+  zFile = sqliteStrNDup(pFilename->z, pFilename->n);
-+  sqliteDequote(zFile);
-+  assert( pTab->iDb<db->nDb );
-+  zDb = db->aDb[pTab->iDb].zName;
-+  if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb)
-+      || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){
-+    goto copy_cleanup;
-+  }
-+  v = sqliteGetVdbe(pParse);
-+  if( v ){
-+    sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
-+    addr = sqliteVdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n);
-+    sqliteVdbeDequoteP3(v, addr);
-+    sqliteOpenTableAndIndices(pParse, pTab, 0);
-+    if( db->flags & SQLITE_CountRows ){
-+      sqliteVdbeAddOp(v, OP_Integer, 0, 0);  /* Initialize the row count */
-+    }
-+    end = sqliteVdbeMakeLabel(v);
-+    addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
-+    if( pDelimiter ){
-+      sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
-+      sqliteVdbeDequoteP3(v, addr);
-+    }else{
-+      sqliteVdbeChangeP3(v, addr, "\t", 1);
-+    }
-+    if( pTab->iPKey>=0 ){
-+      sqliteVdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0);
-+      sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
-+    }else{
-+      sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
-+    }
-+    for(i=0; i<pTab->nCol; i++){
-+      if( i==pTab->iPKey ){
-+        /* The integer primary key column is filled with NULL since its
-+        ** value is always pulled from the record number */
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_FileColumn, i, 0);
-+      }
-+    }
-+    sqliteGenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0, 
-+                                   0, onError, addr);
-+    sqliteCompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1);
-+    if( (db->flags & SQLITE_CountRows)!=0 ){
-+      sqliteVdbeAddOp(v, OP_AddImm, 1, 0);  /* Increment row count */
-+    }
-+    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
-+    sqliteVdbeResolveLabel(v, end);
-+    sqliteVdbeAddOp(v, OP_Noop, 0, 0);
-+    sqliteEndWriteOperation(pParse);
-+    if( db->flags & SQLITE_CountRows ){
-+      sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
-+      sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
-+      sqliteVdbeAddOp(v, OP_Callback, 1, 0);
-+    }
-+  }
-+  
-+copy_cleanup:
-+  sqliteSrcListDelete(pTableName);
-+  sqliteFree(zFile);
-+  return;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/date.c
-@@ -0,0 +1,881 @@
-+/*
-+** 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
-+** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
-+** All other code has file scope.
-+**
-+** $Id$
-+**
-+** NOTES:
-+**
-+** 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 "os.h"
-+#include "sqliteInt.h"
-+#include <ctype.h>
-+#include <stdlib.h>
-+#include <assert.h>
-+#include <time.h>
-+#ifndef PHP_WIN32
-+#include "main/php_reentrancy.h"
-+#endif
-+
-+#ifndef SQLITE_OMIT_DATETIME_FUNCS
-+
-+/*
-+** A structure for holding a single date and time.
-+*/
-+typedef struct DateTime DateTime;
-+struct DateTime {
-+  double rJD;      /* The julian day number */
-+  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 if Y,M,D are valid */
-+  char validHMS;   /* True if h,m,s are valid */
-+  char validJD;    /* True if rJD is valid */
-+  char validTZ;    /* True 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( !isdigit(*zDate) ){
-+        return cnt;
-+      }
-+      val = val*10 + *zDate - '0';
-+      zDate++;
-+    }
-+    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
-+      return cnt;
-+    }
-+    *pVal = val;
-+    zDate++;
-+    cnt++;
-+  }while( nextC );
-+  return cnt;
-+}
-+
-+/*
-+** Read text from z[] and convert into a floating point number.  Return
-+** the number of digits converted.
-+*/
-+static int getValue(const char *z, double *pR){
-+  const char *zEnd;
-+  *pR = sqliteAtoF(z, &zEnd);
-+  return zEnd - z;
-+}
-+
-+/*
-+** Parse a timezone extension on the end of a date-time.
-+** The extension is of the form:
-+**
-+**        (+/-)HH:MM
-+**
-+** If the parse is successful, write the number of minutes
-+** of change in *pnMin and return 0.  If a parser error occurs,
-+** return 0.
-+**
-+** A missing specifier is not considered an error.
-+*/
-+static int parseTimezone(const char *zDate, DateTime *p){
-+  int sgn = 0;
-+  int nHr, nMn;
-+  while( isspace(*zDate) ){ zDate++; }
-+  p->tz = 0;
-+  if( *zDate=='-' ){
-+    sgn = -1;
-+  }else if( *zDate=='+' ){
-+    sgn = +1;
-+  }else{
-+    return *zDate!=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);
-+  while( isspace(*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=='.' && isdigit(zDate[1]) ){
-+      double rScale = 1.0;
-+      zDate++;
-+      while( isdigit(*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;
-+  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 = 365.25*(Y+4716);
-+  X2 = 30.6001*(M+1);
-+  p->rJD = X1 + X2 + D + B - 1524.5;
-+  p->validJD = 1;
-+  p->validYMD = 0;
-+  if( p->validHMS ){
-+    p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
-+    if( p->validTZ ){
-+      p->rJD += p->tz*60/86400.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( isspace(*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;
-+}
-+
-+/*
-+** 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(const char *zDate, DateTime *p){
-+  memset(p, 0, sizeof(*p));
-+  if( parseYyyyMmDd(zDate,p)==0 ){
-+    return 0;
-+  }else if( parseHhMmSs(zDate, p)==0 ){
-+    return 0;
-+  }else if( sqliteStrICmp(zDate,"now")==0){
-+    double r;
-+    if( sqliteOsCurrentTime(&r)==0 ){
-+      p->rJD = r;
-+      p->validJD = 1;
-+      return 0;
-+    }
-+    return 1;
-+  }else if( sqliteIsNumber(zDate) ){
-+    p->rJD = sqliteAtoF(zDate, 0);
-+    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 = p->rJD + 0.5;
-+    A = (Z - 1867216.25)/36524.25;
-+    A = Z + 1 + A - (A/4);
-+    B = A + 1524;
-+    C = (B - 122.1)/365.25;
-+    D = 365.25*C;
-+    E = (B-D)/30.6001;
-+    X1 = 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 Z, s;
-+  if( p->validHMS ) return;
-+  Z = p->rJD + 0.5;
-+  s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
-+  p->s = 0.001*s;
-+  s = 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;
-+}
-+
-+/*
-+** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
-+** for the time value p where p is in UTC.
-+*/
-+static double localtimeOffset(DateTime *p){
-+  DateTime x, y;
-+  time_t t;
-+  struct tm *pTm, tmbuf;
-+  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 = x.s + 0.5;
-+    x.s = s;
-+  }
-+  x.tz = 0;
-+  x.validJD = 0;
-+  computeJD(&x);
-+  t = (x.rJD-2440587.5)*86400.0 + 0.5;
-+  sqliteOsEnterMutex();
-+  pTm = php_localtime_r(&t, &tmbuf);
-+  if (!pTm) {
-+        return 0;
-+  }
-+  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;
-+  sqliteOsLeaveMutex();
-+  y.validYMD = 1;
-+  y.validHMS = 1;
-+  y.validJD = 0;
-+  y.validTZ = 0;
-+  computeJD(&y);
-+  return y.rJD - x.rJD;
-+}
-+
-+/*
-+** 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<sizeof(zBuf)-1 && zMod[n]; n++){
-+    z[n] = tolower(zMod[n]);
-+  }
-+  z[n] = 0;
-+  switch( z[0] ){
-+    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->rJD += localtimeOffset(p);
-+        clearYMD_HMS_TZ(p);
-+        rc = 0;
-+      }
-+      break;
-+    }
-+    case 'u': {
-+      /*
-+      **    unixepoch
-+      **
-+      ** Treat the current value of p->rJD as the number of
-+      ** seconds since 1970.  Convert to a real julian day number.
-+      */
-+      if( strcmp(z, "unixepoch")==0 && p->validJD ){
-+        p->rJD = p->rJD/86400.0 + 2440587.5;
-+        clearYMD_HMS_TZ(p);
-+        rc = 0;
-+      }else if( strcmp(z, "utc")==0 ){
-+        double c1;
-+        computeJD(p);
-+        c1 = localtimeOffset(p);
-+        p->rJD -= c1;
-+        clearYMD_HMS_TZ(p);
-+        p->rJD += c1 - localtimeOffset(p);
-+        rc = 0;
-+      }
-+      break;
-+    }
-+    case 'w': {
-+      /*
-+      **    weekday N
-+      **
-+      ** Move the date to the same time on the next occurrance 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=r)==r && n>=0 && r<7 ){
-+        int Z;
-+        computeYMD_HMS(p);
-+        p->validTZ = 0;
-+        p->validJD = 0;
-+        computeJD(p);
-+        Z = p->rJD + 1.5;
-+        Z %= 7;
-+        if( Z>n ) Z -= 7;
-+        p->rJD += n - Z;
-+        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': {
-+      n = getValue(z, &r);
-+      if( n<=0 ) break;
-+      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;
-+        int day;
-+        if( !isdigit(*z2) ) z2++;
-+        memset(&tx, 0, sizeof(tx));
-+        if( parseHhMmSs(z2, &tx) ) break;
-+        computeJD(&tx);
-+        tx.rJD -= 0.5;
-+        day = (int)tx.rJD;
-+        tx.rJD -= day;
-+        if( z[0]=='-' ) tx.rJD = -tx.rJD;
-+        computeJD(p);
-+        clearYMD_HMS_TZ(p);
-+       p->rJD += tx.rJD;
-+        rc = 0;
-+        break;
-+      }
-+      z += n;
-+      while( isspace(z[0]) ) z++;
-+      n = strlen(z);
-+      if( n>10 || n<3 ) break;
-+      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
-+      computeJD(p);
-+      rc = 0;
-+      if( n==3 && strcmp(z,"day")==0 ){
-+        p->rJD += r;
-+      }else if( n==4 && strcmp(z,"hour")==0 ){
-+        p->rJD += r/24.0;
-+      }else if( n==6 && strcmp(z,"minute")==0 ){
-+        p->rJD += r/(24.0*60.0);
-+      }else if( n==6 && strcmp(z,"second")==0 ){
-+        p->rJD += r/(24.0*60.0*60.0);
-+      }else if( n==5 && strcmp(z,"month")==0 ){
-+        int x, y;
-+        computeYMD_HMS(p);
-+        p->M += 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 = r;
-+        if( y!=r ){
-+          p->rJD += (r - y)*30.0;
-+        }
-+      }else if( n==4 && strcmp(z,"year")==0 ){
-+        computeYMD_HMS(p);
-+        p->Y += r;
-+        p->validJD = 0;
-+        computeJD(p);
-+      }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.
-+*/
-+static int isDate(int argc, const char **argv, DateTime *p){
-+  int i;
-+  if( argc==0 ) return 1;
-+  if( argv[0]==0 || parseDateOrTime(argv[0], p) ) return 1;
-+  for(i=1; i<argc; i++){
-+    if( argv[i]==0 || parseModifier(argv[i], 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(sqlite_func *context, int argc, const char **argv){
-+  DateTime x;
-+  if( isDate(argc, argv, &x)==0 ){
-+    computeJD(&x);
-+    sqlite_set_result_double(context, x.rJD);
-+  }
-+}
-+
-+/*
-+**    datetime( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD HH:MM:SS
-+*/
-+static void datetimeFunc(sqlite_func *context, int argc, const char **argv){
-+  DateTime x;
-+  if( isDate(argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeYMD_HMS(&x);
-+    sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
-+           (int)(x.s));
-+    sqlite_set_result_string(context, zBuf, -1);
-+  }
-+}
-+
-+/*
-+**    time( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return HH:MM:SS
-+*/
-+static void timeFunc(sqlite_func *context, int argc, const char **argv){
-+  DateTime x;
-+  if( isDate(argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeHMS(&x);
-+    sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
-+    sqlite_set_result_string(context, zBuf, -1);
-+  }
-+}
-+
-+/*
-+**    date( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD
-+*/
-+static void dateFunc(sqlite_func *context, int argc, const char **argv){
-+  DateTime x;
-+  if( isDate(argc, argv, &x)==0 ){
-+    char zBuf[100];
-+    computeYMD(&x);
-+    sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
-+    sqlite_set_result_string(context, zBuf, -1);
-+  }
-+}
-+
-+/*
-+**    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(sqlite_func *context, int argc, const char **argv){
-+  DateTime x;
-+  int n, i, j;
-+  char *z;
-+  const char *zFmt = argv[0];
-+  char zBuf[100];
-+  if( argv[0]==0 || isDate(argc-1, argv+1, &x) ) return;
-+  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++;
-+    }
-+  }
-+  if( n<sizeof(zBuf) ){
-+    z = zBuf;
-+  }else{
-+    z = sqliteMalloc( n );
-+    if( z==0 ) 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':  sprintf(&z[j],"%02d",x.D); j+=2; break;
-+        case 'f': {
-+          int s = x.s;
-+          int ms = (x.s - s)*1000.0;
-+          sprintf(&z[j],"%02d.%03d",s,ms);
-+          j += strlen(&z[j]);
-+          break;
-+        }
-+        case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
-+        case 'W': /* Fall thru */
-+        case 'j': {
-+          int n;             /* Number of days since 1st day of year */
-+          DateTime y = x;
-+          y.validJD = 0;
-+          y.M = 1;
-+          y.D = 1;
-+          computeJD(&y);
-+          n = x.rJD - y.rJD;
-+          if( zFmt[i]=='W' ){
-+            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
-+            wd = ((int)(x.rJD+0.5)) % 7;
-+            sprintf(&z[j],"%02d",(n+7-wd)/7);
-+            j += 2;
-+          }else{
-+            sprintf(&z[j],"%03d",n+1);
-+            j += 3;
-+          }
-+          break;
-+        }
-+        case 'J':  sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
-+        case 'm':  sprintf(&z[j],"%02d",x.M); j+=2; break;
-+        case 'M':  sprintf(&z[j],"%02d",x.m); j+=2; break;
-+        case 's': {
-+          sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
-+          j += strlen(&z[j]);
-+          break;
-+        }
-+        case 'S':  sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
-+        case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
-+        case 'Y':  sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
-+        case '%':  z[j++] = '%'; break;
-+      }
-+    }
-+  }
-+  z[j] = 0;
-+  sqlite_set_result_string(context, z, -1);
-+  if( z!=zBuf ){
-+    sqliteFree(z);
-+  }
-+}
-+
-+
-+#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
-+
-+/*
-+** This function registered all of the above C functions as SQL
-+** functions.  This should be the only routine in this file with
-+** external linkage.
-+*/
-+void sqliteRegisterDateTimeFunctions(sqlite *db){
-+#ifndef SQLITE_OMIT_DATETIME_FUNCS
-+  static struct {
-+     char *zName;
-+     int nArg;
-+     int dataType;
-+     void (*xFunc)(sqlite_func*,int,const char**);
-+  } aFuncs[] = {
-+    { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
-+    { "date",      -1, SQLITE_TEXT,    dateFunc        },
-+    { "time",      -1, SQLITE_TEXT,    timeFunc        },
-+    { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
-+    { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
-+  };
-+  int i;
-+
-+  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-+    sqlite_create_function(db, aFuncs[i].zName,
-+           aFuncs[i].nArg, aFuncs[i].xFunc, 0);
-+    if( aFuncs[i].xFunc ){
-+      sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
-+    }
-+  }
-+#endif
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/delete.c
-@@ -0,0 +1,393 @@
-+/*
-+** 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 DELETE FROM statements.
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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.
-+*/
-+Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
-+  Table *pTab = 0;
-+  int i;
-+  for(i=0; i<pSrc->nSrc; i++){
-+    const char *zTab = pSrc->a[i].zName;
-+    const char *zDb = pSrc->a[i].zDatabase;
-+    pTab = sqliteLocateTable(pParse, zTab, zDb);
-+    pSrc->a[i].pTab = pTab;
-+  }
-+  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;
-+*/
-+int sqliteIsReadOnly(Parse *pParse, Table *pTab, int viewOk){
-+  if( pTab->readOnly ){
-+    sqliteErrorMsg(pParse, "table %s may not be modified", pTab->zName);
-+    return 1;
-+  }
-+  if( !viewOk && pTab->pSelect ){
-+    sqliteErrorMsg(pParse, "cannot modify %s because it is a view",pTab->zName);
-+    return 1;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Process a DELETE FROM statement.
-+*/
-+void sqliteDeleteFrom(
-+  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;         /* 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 */
-+  sqlite *db;            /* Main database structure */
-+  int isView;            /* True if attempting to delete from a view */
-+  AuthContext sContext;  /* Authorization context */
-+
-+  int row_triggers_exist = 0;  /* True if any triggers exist */
-+  int before_triggers;         /* True if there are BEFORE triggers */
-+  int after_triggers;          /* True if there are AFTER triggers */
-+  int oldIdx = -1;             /* Cursor for the OLD table of AFTER triggers */
-+
-+  sContext.pParse = 0;
-+  if( pParse->nErr || sqlite_malloc_failed ){
-+    pTabList = 0;
-+    goto delete_from_cleanup;
-+  }
-+  db = pParse->db;
-+  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 = sqliteSrcListLookup(pParse, pTabList);
-+  if( pTab==0 )  goto delete_from_cleanup;
-+  before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, 
-+                         TK_DELETE, TK_BEFORE, TK_ROW, 0);
-+  after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, 
-+                         TK_DELETE, TK_AFTER, TK_ROW, 0);
-+  row_triggers_exist = before_triggers || after_triggers;
-+  isView = pTab->pSelect!=0;
-+  if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
-+    goto delete_from_cleanup;
-+  }
-+  assert( pTab->iDb<db->nDb );
-+  zDb = db->aDb[pTab->iDb].zName;
-+  if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
-+    goto delete_from_cleanup;
-+  }
-+
-+  /* If pTab is really a view, make sure it has been initialized.
-+  */
-+  if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
-+    goto delete_from_cleanup;
-+  }
-+
-+  /* Allocate a cursor used to store the old.* data for a trigger.
-+  */
-+  if( row_triggers_exist ){ 
-+    oldIdx = pParse->nTab++;
-+  }
-+
-+  /* Resolve the column names in all the expressions.
-+  */
-+  assert( pTabList->nSrc==1 );
-+  iCur = pTabList->a[0].iCursor = pParse->nTab++;
-+  if( pWhere ){
-+    if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
-+      goto delete_from_cleanup;
-+    }
-+    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
-+      goto delete_from_cleanup;
-+    }
-+  }
-+
-+  /* Start the view context
-+  */
-+  if( isView ){
-+    sqliteAuthContextPush(pParse, &sContext, pTab->zName);
-+  }
-+
-+  /* Begin generating code.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ){
-+    goto delete_from_cleanup;
-+  }
-+  sqliteBeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
-+
-+  /* If we are trying to delete from a view, construct that view into
-+  ** a temporary table.
-+  */
-+  if( isView ){
-+    Select *pView = sqliteSelectDup(pTab->pSelect);
-+    sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
-+    sqliteSelectDelete(pView);
-+  }
-+
-+  /* Initialize the counter of the number of rows deleted, if
-+  ** we are counting rows.
-+  */
-+  if( db->flags & SQLITE_CountRows ){
-+    sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+  }
-+
-+  /* Special case: A DELETE without a WHERE clause deletes everything.
-+  ** It is easier just to erase the whole table.  Note, however, that
-+  ** this means that the row change count will be incorrect.
-+  */
-+  if( pWhere==0 && !row_triggers_exist ){
-+    if( db->flags & SQLITE_CountRows ){
-+      /* If counting rows deleted, just count the total number of
-+      ** entries in the table. */
-+      int endOfLoop = sqliteVdbeMakeLabel(v);
-+      int addr;
-+      if( !isView ){
-+        sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+        sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
-+      }
-+      sqliteVdbeAddOp(v, OP_Rewind, iCur, sqliteVdbeCurrentAddr(v)+2);
-+      addr = sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Next, iCur, addr);
-+      sqliteVdbeResolveLabel(v, endOfLoop);
-+      sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+    }
-+    if( !isView ){
-+      sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
-+      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-+        sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
-+      }
-+    }
-+  }
-+
-+  /* The usual case: There is a WHERE clause so we have to scan through
-+  ** the table and pick which records to delete.
-+  */
-+  else{
-+    /* Begin the database scan
-+    */
-+    pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
-+    if( pWInfo==0 ) goto delete_from_cleanup;
-+
-+    /* Remember the key of every item to be deleted.
-+    */
-+    sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
-+    if( db->flags & SQLITE_CountRows ){
-+      sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
-+    }
-+
-+    /* End the database scan loop.
-+    */
-+    sqliteWhereEnd(pWInfo);
-+
-+    /* Open the pseudo-table used to store OLD if there are triggers.
-+    */
-+    if( row_triggers_exist ){
-+      sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
-+    }
-+
-+    /* 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.
-+    */
-+    sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
-+    end = sqliteVdbeMakeLabel(v);
-+
-+    /* This is the beginning of the delete loop when there are
-+    ** row triggers.
-+    */
-+    if( row_triggers_exist ){
-+      addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+      if( !isView ){
-+        sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+        sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
-+      }
-+      sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+
-+      sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
-+      sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
-+      sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
-+      if( !isView ){
-+        sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+      }
-+
-+      sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, 
-+          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
-+        addr);
-+    }
-+
-+    if( !isView ){
-+      /* Open cursors for the table we are deleting from and all its
-+      ** indices.  If there are row triggers, this happens inside the
-+      ** OP_ListRead loop because the cursor have to all be closed
-+      ** before the trigger fires.  If there are no row triggers, the
-+      ** cursors are opened only once on the outside the loop.
-+      */
-+      pParse->nTab = iCur + 1;
-+      sqliteOpenTableAndIndices(pParse, pTab, iCur);
-+
-+      /* This is the beginning of the delete loop when there are no
-+      ** row triggers */
-+      if( !row_triggers_exist ){ 
-+        addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
-+      }
-+
-+      /* Delete the row */
-+      sqliteGenerateRowDelete(db, v, pTab, iCur, pParse->trigStack==0);
-+    }
-+
-+    /* If there are row triggers, close all cursors then invoke
-+    ** the AFTER triggers
-+    */
-+    if( row_triggers_exist ){
-+      if( !isView ){
-+        for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
-+          sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
-+        }
-+        sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+      }
-+      sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, 
-+          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
-+        addr);
-+    }
-+
-+    /* End of the delete loop */
-+    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
-+    sqliteVdbeResolveLabel(v, end);
-+    sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
-+
-+    /* Close the cursors after the loop if there are no row triggers */
-+    if( !row_triggers_exist ){
-+      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
-+        sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
-+      }
-+      sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+      pParse->nTab = iCur;
-+    }
-+  }
-+  sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
-+  sqliteEndWriteOperation(pParse);
-+
-+  /*
-+  ** Return the number of rows that were deleted.
-+  */
-+  if( db->flags & SQLITE_CountRows ){
-+    sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
-+    sqliteVdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
-+    sqliteVdbeAddOp(v, OP_Callback, 1, 0);
-+  }
-+
-+delete_from_cleanup:
-+  sqliteAuthContextPop(&sContext);
-+  sqliteSrcListDelete(pTabList);
-+  sqliteExprDelete(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 on the top
-+**       of the stack.
-+**
-+** This routine pops the top of the stack to remove the record number
-+** and then generates code to remove both the table record and all index
-+** entries that point to that record.
-+*/
-+void sqliteGenerateRowDelete(
-+  sqlite *db,        /* The database containing the index */
-+  Vdbe *v,           /* Generate code into this VDBE */
-+  Table *pTab,       /* Table containing the row to be deleted */
-+  int iCur,          /* Cursor number for the table */
-+  int count          /* Increment the row change counter */
-+){
-+  int addr;
-+  addr = sqliteVdbeAddOp(v, OP_NotExists, iCur, 0);
-+  sqliteGenerateRowIndexDelete(db, v, pTab, iCur, 0);
-+  sqliteVdbeAddOp(v, OP_Delete, iCur,
-+    (count?OPFLAG_NCHANGE:0) | OPFLAG_CSCHANGE);
-+  sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
-+}
-+
-+/*
-+** 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.
-+*/
-+void sqliteGenerateRowIndexDelete(
-+  sqlite *db,        /* The database containing the index */
-+  Vdbe *v,           /* Generate code into this VDBE */
-+  Table *pTab,       /* Table containing the row to be deleted */
-+  int iCur,          /* Cursor number for the table */
-+  char *aIdxUsed     /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
-+){
-+  int i;
-+  Index *pIdx;
-+
-+  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
-+    int j;
-+    if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
-+    sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
-+    for(j=0; j<pIdx->nColumn; j++){
-+      int idx = pIdx->aiColumn[j];
-+      if( idx==pTab->iPKey ){
-+        sqliteVdbeAddOp(v, OP_Dup, j, 0);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Column, iCur, idx);
-+      }
-+    }
-+    sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
-+    if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
-+    sqliteVdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
-+  }
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/encode.c
-@@ -0,0 +1,257 @@
-+/*
-+** 2002 April 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 helper routines used to translate binary data into
-+** a null-terminated string (suitable for use in SQLite) and back again.
-+** These are convenience routines for use by people who want to store binary
-+** data in an SQLite database.  The code in this file is not used by any other
-+** part of the SQLite library.
-+**
-+** $Id$
-+*/
-+#include <string.h>
-+#include <assert.h>
-+
-+/*
-+** How This Encoder Works
-+**
-+** The output is allowed to contain any character except 0x27 (') and
-+** 0x00.  This is accomplished by using an escape character to encode
-+** 0x27 and 0x00 as a two-byte sequence.  The escape character is always
-+** 0x01.  An 0x00 is encoded as the two byte sequence 0x01 0x01.  The
-+** 0x27 character is encoded as the two byte sequence 0x01 0x28.  Finally,
-+** the escape character itself is encoded as the two-character sequence
-+** 0x01 0x02.
-+**
-+** To summarize, the encoder works by using an escape sequences as follows:
-+**
-+**       0x00  ->  0x01 0x01
-+**       0x01  ->  0x01 0x02
-+**       0x27  ->  0x01 0x28
-+**
-+** If that were all the encoder did, it would work, but in certain cases
-+** it could double the size of the encoded string.  For example, to
-+** encode a string of 100 0x27 characters would require 100 instances of
-+** the 0x01 0x03 escape sequence resulting in a 200-character output.
-+** We would prefer to keep the size of the encoded string smaller than
-+** this.
-+**
-+** To minimize the encoding size, we first add a fixed offset value to each 
-+** byte in the sequence.  The addition is modulo 256.  (That is to say, if
-+** the sum of the original character value and the offset exceeds 256, then
-+** the higher order bits are truncated.)  The offset is chosen to minimize
-+** the number of characters in the string that need to be escaped.  For
-+** example, in the case above where the string was composed of 100 0x27
-+** characters, the offset might be 0x01.  Each of the 0x27 characters would
-+** then be converted into an 0x28 character which would not need to be
-+** escaped at all and so the 100 character input string would be converted
-+** into just 100 characters of output.  Actually 101 characters of output - 
-+** we have to record the offset used as the first byte in the sequence so
-+** that the string can be decoded.  Since the offset value is stored as
-+** part of the output string and the output string is not allowed to contain
-+** characters 0x00 or 0x27, the offset cannot be 0x00 or 0x27.
-+**
-+** Here, then, are the encoding steps:
-+**
-+**     (1)   Choose an offset value and make it the first character of
-+**           output.
-+**
-+**     (2)   Copy each input character into the output buffer, one by
-+**           one, adding the offset value as you copy.
-+**
-+**     (3)   If the value of an input character plus offset is 0x00, replace
-+**           that one character by the two-character sequence 0x01 0x01.
-+**           If the sum is 0x01, replace it with 0x01 0x02.  If the sum
-+**           is 0x27, replace it with 0x01 0x03.
-+**
-+**     (4)   Put a 0x00 terminator at the end of the output.
-+**
-+** Decoding is obvious:
-+**
-+**     (5)   Copy encoded characters except the first into the decode 
-+**           buffer.  Set the first encoded character aside for use as
-+**           the offset in step 7 below.
-+**
-+**     (6)   Convert each 0x01 0x01 sequence into a single character 0x00.
-+**           Convert 0x01 0x02 into 0x01.  Convert 0x01 0x28 into 0x27.
-+**
-+**     (7)   Subtract the offset value that was the first character of
-+**           the encoded buffer from all characters in the output buffer.
-+**
-+** The only tricky part is step (1) - how to compute an offset value to
-+** minimize the size of the output buffer.  This is accomplished by testing
-+** all offset values and picking the one that results in the fewest number
-+** of escapes.  To do that, we first scan the entire input and count the
-+** number of occurances of each character value in the input.  Suppose
-+** the number of 0x00 characters is N(0), the number of occurances of 0x01
-+** is N(1), and so forth up to the number of occurances of 0xff is N(255).
-+** An offset of 0 is not allowed so we don't have to test it.  The number
-+** of escapes required for an offset of 1 is N(1)+N(2)+N(40).  The number
-+** of escapes required for an offset of 2 is N(2)+N(3)+N(41).  And so forth.
-+** In this way we find the offset that gives the minimum number of escapes,
-+** and thus minimizes the length of the output string.
-+*/
-+
-+/*
-+** Encode a binary buffer "in" of size n bytes so that it contains
-+** no instances of characters '\'' or '\000'.  The output is 
-+** null-terminated and can be used as a string value in an INSERT
-+** or UPDATE statement.  Use sqlite_decode_binary() to convert the
-+** string back into its original binary.
-+**
-+** The result is written into a preallocated output buffer "out".
-+** "out" must be able to hold at least 2 +(257*n)/254 bytes.
-+** In other words, the output will be expanded by as much as 3
-+** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
-+** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
-+**
-+** The return value is the number of characters in the encoded
-+** string, excluding the "\000" terminator.
-+**
-+** If out==NULL then no output is generated but the routine still returns
-+** the number of characters that would have been generated if out had
-+** not been NULL.
-+*/
-+int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out){
-+  int i, j, e, m;
-+  unsigned char x;
-+  int cnt[256];
-+  if( n<=0 ){
-+    if( out ){
-+      out[0] = 'x';
-+      out[1] = 0;
-+    }
-+    return 1;
-+  }
-+  memset(cnt, 0, sizeof(cnt));
-+  for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
-+  m = n;
-+  for(i=1; i<256; i++){
-+    int sum;
-+    if( i=='\'' ) continue;
-+    sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
-+    if( sum<m ){
-+      m = sum;
-+      e = i;
-+      if( m==0 ) break;
-+    }
-+  }
-+  if( out==0 ){
-+    return n+m+1;
-+  }
-+  out[0] = e;
-+  j = 1;
-+  for(i=0; i<n; i++){
-+    x = in[i] - e;
-+    if( x==0 || x==1 || x=='\''){
-+      out[j++] = 1;
-+      x++;
-+    }
-+    out[j++] = x;
-+  }
-+  out[j] = 0;
-+  assert( j==n+m+1 );
-+  return j;
-+}
-+
-+/*
-+** Decode the string "in" into binary data and write it into "out".
-+** This routine reverses the encoding created by sqlite_encode_binary().
-+** The output will always be a few bytes less than the input.  The number
-+** of bytes of output is returned.  If the input is not a well-formed
-+** encoding, -1 is returned.
-+**
-+** The "in" and "out" parameters may point to the same buffer in order
-+** to decode a string in place.
-+*/
-+int sqlite_decode_binary(const unsigned char *in, unsigned char *out){
-+  int i, e;
-+  unsigned char c;
-+  e = *(in++);
-+  if (e == 0) {
-+    return 0;
-+  }
-+  i = 0;
-+  while( (c = *(in++))!=0 ){
-+    if (c == 1) {
-+      c = *(in++) - 1;
-+    }
-+    out[i++] = c + e;
-+  }
-+  return i;
-+}
-+
-+#ifdef ENCODER_TEST
-+#include <stdio.h>
-+/*
-+** The subroutines above are not tested by the usual test suite.  To test
-+** these routines, compile just this one file with a -DENCODER_TEST=1 option
-+** and run the result.
-+*/
-+int main(int argc, char **argv){
-+  int i, j, n, m, nOut, nByteIn, nByteOut;
-+  unsigned char in[30000];
-+  unsigned char out[33000];
-+
-+  nByteIn = nByteOut = 0;
-+  for(i=0; i<sizeof(in); i++){
-+    printf("Test %d: ", i+1);
-+    n = rand() % (i+1);
-+    if( i%100==0 ){
-+      int k;
-+      for(j=k=0; j<n; j++){
-+        /* if( k==0 || k=='\'' ) k++; */
-+        in[j] = k;
-+        k = (k+1)&0xff;
-+      }
-+    }else{
-+      for(j=0; j<n; j++) in[j] = rand() & 0xff;
-+    }
-+    nByteIn += n;
-+    nOut = sqlite_encode_binary(in, n, out);
-+    nByteOut += nOut;
-+    if( nOut!=strlen(out) ){
-+      printf(" ERROR return value is %d instead of %d\n", nOut, strlen(out));
-+      exit(1);
-+    }
-+    if( nOut!=sqlite_encode_binary(in, n, 0) ){
-+      printf(" ERROR actual output size disagrees with predicted size\n");
-+      exit(1);
-+    }
-+    m = (256*n + 1262)/253;
-+    printf("size %d->%d (max %d)", n, strlen(out)+1, m);
-+    if( strlen(out)+1>m ){
-+      printf(" ERROR output too big\n");
-+      exit(1);
-+    }
-+    for(j=0; out[j]; j++){
-+      if( out[j]=='\'' ){
-+        printf(" ERROR contains (')\n");
-+        exit(1);
-+      }
-+    }
-+    j = sqlite_decode_binary(out, out);
-+    if( j!=n ){
-+      printf(" ERROR decode size %d\n", j);
-+      exit(1);
-+    }
-+    if( memcmp(in, out, n)!=0 ){
-+      printf(" ERROR decode mismatch\n");
-+      exit(1);
-+    }
-+    printf(" OK\n");
-+  }
-+  fprintf(stderr,"Finished.  Total encoding: %d->%d bytes\n",
-+          nByteIn, nByteOut);
-+  fprintf(stderr,"Avg size increase: %.3f%%\n",
-+    (nByteOut-nByteIn)*100.0/(double)nByteIn);
-+}
-+#endif /* ENCODER_TEST */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/expr.c
-@@ -0,0 +1,1662 @@
-+/*
-+** 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.
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+#include <ctype.h>
-+
-+/*
-+** Construct a new expression node and return a pointer to it.  Memory
-+** for this node is obtained from sqliteMalloc().  The calling function
-+** is responsible for making sure the node eventually gets freed.
-+*/
-+Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
-+  Expr *pNew;
-+  pNew = sqliteMalloc( sizeof(Expr) );
-+  if( pNew==0 ){
-+    /* When malloc fails, we leak memory from pLeft and pRight */
-+    return 0;
-+  }
-+  pNew->op = op;
-+  pNew->pLeft = pLeft;
-+  pNew->pRight = pRight;
-+  if( pToken ){
-+    assert( pToken->dyn==0 );
-+    pNew->token = *pToken;
-+    pNew->span = *pToken;
-+  }else{
-+    assert( pNew->token.dyn==0 );
-+    assert( pNew->token.z==0 );
-+    assert( pNew->token.n==0 );
-+    if( pLeft && pRight ){
-+      sqliteExprSpan(pNew, &pLeft->span, &pRight->span);
-+    }else{
-+      pNew->span = pNew->token;
-+    }
-+  }
-+  return pNew;
-+}
-+
-+/*
-+** Set the Expr.span field of the given expression to span all
-+** text between the two given tokens.
-+*/
-+void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
-+  assert( pRight!=0 );
-+  assert( pLeft!=0 );
-+  /* Note: pExpr might be NULL due to a prior malloc failure */
-+  if( pExpr && pRight->z && pLeft->z ){
-+    if( pLeft->dyn==0 && pRight->dyn==0 ){
-+      pExpr->span.z = pLeft->z;
-+      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
-+    }else{
-+      pExpr->span.z = 0;
-+    }
-+  }
-+}
-+
-+/*
-+** Construct a new expression node for a function with multiple
-+** arguments.
-+*/
-+Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
-+  Expr *pNew;
-+  pNew = sqliteMalloc( sizeof(Expr) );
-+  if( pNew==0 ){
-+    /* sqliteExprListDelete(pList); // Leak pList when malloc fails */
-+    return 0;
-+  }
-+  pNew->op = TK_FUNCTION;
-+  pNew->pList = pList;
-+  if( pToken ){
-+    assert( pToken->dyn==0 );
-+    pNew->token = *pToken;
-+  }else{
-+    pNew->token.z = 0;
-+  }
-+  pNew->span = pNew->token;
-+  return pNew;
-+}
-+
-+/*
-+** Recursively delete an expression tree.
-+*/
-+void sqliteExprDelete(Expr *p){
-+  if( p==0 ) return;
-+  if( p->span.dyn ) sqliteFree((char*)p->span.z);
-+  if( p->token.dyn ) sqliteFree((char*)p->token.z);
-+  sqliteExprDelete(p->pLeft);
-+  sqliteExprDelete(p->pRight);
-+  sqliteExprListDelete(p->pList);
-+  sqliteSelectDelete(p->pSelect);
-+  sqliteFree(p);
-+}
-+
-+
-+/*
-+** 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 sqliteExprListDup(),
-+** sqliteIdListDup(), and sqliteSrcListDup() can not be further expanded 
-+** by subsequent calls to sqlite*ListAppend() routines.
-+**
-+** Any tables that the SrcList might point to are not duplicated.
-+*/
-+Expr *sqliteExprDup(Expr *p){
-+  Expr *pNew;
-+  if( p==0 ) return 0;
-+  pNew = sqliteMallocRaw( sizeof(*p) );
-+  if( pNew==0 ) return 0;
-+  memcpy(pNew, p, sizeof(*pNew));
-+  if( p->token.z!=0 ){
-+    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
-+    pNew->token.dyn = 1;
-+  }else{
-+    assert( pNew->token.z==0 );
-+  }
-+  pNew->span.z = 0;
-+  pNew->pLeft = sqliteExprDup(p->pLeft);
-+  pNew->pRight = sqliteExprDup(p->pRight);
-+  pNew->pList = sqliteExprListDup(p->pList);
-+  pNew->pSelect = sqliteSelectDup(p->pSelect);
-+  return pNew;
-+}
-+void sqliteTokenCopy(Token *pTo, Token *pFrom){
-+  if( pTo->dyn ) sqliteFree((char*)pTo->z);
-+  if( pFrom->z ){
-+    pTo->n = pFrom->n;
-+    pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
-+    pTo->dyn = 1;
-+  }else{
-+    pTo->z = 0;
-+  }
-+}
-+ExprList *sqliteExprListDup(ExprList *p){
-+  ExprList *pNew;
-+  struct ExprList_item *pItem;
-+  int i;
-+  if( p==0 ) return 0;
-+  pNew = sqliteMalloc( sizeof(*pNew) );
-+  if( pNew==0 ) return 0;
-+  pNew->nExpr = pNew->nAlloc = p->nExpr;
-+  pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
-+  if( pItem==0 ){
-+    sqliteFree(pNew);
-+    return 0;
-+  }
-+  for(i=0; i<p->nExpr; i++, pItem++){
-+    Expr *pNewExpr, *pOldExpr;
-+    pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
-+    if( pOldExpr->span.z!=0 && pNewExpr ){
-+      /* Always make a copy of the span for top-level expressions in the
-+      ** expression list.  The logic in SELECT processing that determines
-+      ** the names of columns in the result set needs this information */
-+      sqliteTokenCopy(&pNewExpr->span, &pOldExpr->span);
-+    }
-+    assert( pNewExpr==0 || pNewExpr->span.z!=0 
-+            || pOldExpr->span.z==0 || sqlite_malloc_failed );
-+    pItem->zName = sqliteStrDup(p->a[i].zName);
-+    pItem->sortOrder = p->a[i].sortOrder;
-+    pItem->isAgg = p->a[i].isAgg;
-+    pItem->done = 0;
-+  }
-+  return pNew;
-+}
-+SrcList *sqliteSrcListDup(SrcList *p){
-+  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 = sqliteMallocRaw( 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];
-+    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
-+    pNewItem->zName = sqliteStrDup(pOldItem->zName);
-+    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
-+    pNewItem->jointype = pOldItem->jointype;
-+    pNewItem->iCursor = pOldItem->iCursor;
-+    pNewItem->pTab = 0;
-+    pNewItem->pSelect = sqliteSelectDup(pOldItem->pSelect);
-+    pNewItem->pOn = sqliteExprDup(pOldItem->pOn);
-+    pNewItem->pUsing = sqliteIdListDup(pOldItem->pUsing);
-+  }
-+  return pNew;
-+}
-+IdList *sqliteIdListDup(IdList *p){
-+  IdList *pNew;
-+  int i;
-+  if( p==0 ) return 0;
-+  pNew = sqliteMallocRaw( sizeof(*pNew) );
-+  if( pNew==0 ) return 0;
-+  pNew->nId = pNew->nAlloc = p->nId;
-+  pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
-+  if( pNew->a==0 ) 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 = sqliteStrDup(pOldItem->zName);
-+    pNewItem->idx = pOldItem->idx;
-+  }
-+  return pNew;
-+}
-+Select *sqliteSelectDup(Select *p){
-+  Select *pNew;
-+  if( p==0 ) return 0;
-+  pNew = sqliteMallocRaw( sizeof(*p) );
-+  if( pNew==0 ) return 0;
-+  pNew->isDistinct = p->isDistinct;
-+  pNew->pEList = sqliteExprListDup(p->pEList);
-+  pNew->pSrc = sqliteSrcListDup(p->pSrc);
-+  pNew->pWhere = sqliteExprDup(p->pWhere);
-+  pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
-+  pNew->pHaving = sqliteExprDup(p->pHaving);
-+  pNew->pOrderBy = sqliteExprListDup(p->pOrderBy);
-+  pNew->op = p->op;
-+  pNew->pPrior = sqliteSelectDup(p->pPrior);
-+  pNew->nLimit = p->nLimit;
-+  pNew->nOffset = p->nOffset;
-+  pNew->zSelect = 0;
-+  pNew->iLimit = -1;
-+  pNew->iOffset = -1;
-+  return pNew;
-+}
-+
-+
-+/*
-+** Add a new element to the end of an expression list.  If pList is
-+** initially NULL, then create a new expression list.
-+*/
-+ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
-+  if( pList==0 ){
-+    pList = sqliteMalloc( sizeof(ExprList) );
-+    if( pList==0 ){
-+      /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
-+      return 0;
-+    }
-+    assert( pList->nAlloc==0 );
-+  }
-+  if( pList->nAlloc<=pList->nExpr ){
-+    pList->nAlloc = pList->nAlloc*2 + 4;
-+    pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
-+    if( pList->a==0 ){
-+      /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
-+      pList->nExpr = pList->nAlloc = 0;
-+      return pList;
-+    }
-+  }
-+  assert( pList->a!=0 );
-+  if( pExpr || pName ){
-+    struct ExprList_item *pItem = &pList->a[pList->nExpr++];
-+    memset(pItem, 0, sizeof(*pItem));
-+    pItem->pExpr = pExpr;
-+    if( pName ){
-+      sqliteSetNString(&pItem->zName, pName->z, pName->n, 0);
-+      sqliteDequote(pItem->zName);
-+    }
-+  }
-+  return pList;
-+}
-+
-+/*
-+** Delete an entire expression list.
-+*/
-+void sqliteExprListDelete(ExprList *pList){
-+  int i;
-+  if( pList==0 ) return;
-+  assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
-+  assert( pList->nExpr<=pList->nAlloc );
-+  for(i=0; i<pList->nExpr; i++){
-+    sqliteExprDelete(pList->a[i].pExpr);
-+    sqliteFree(pList->a[i].zName);
-+  }
-+  sqliteFree(pList->a);
-+  sqliteFree(pList);
-+}
-+
-+/*
-+** Walk an expression tree.  Return 1 if the expression is constant
-+** and 0 if it involves 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.
-+*/
-+int sqliteExprIsConstant(Expr *p){
-+  switch( p->op ){
-+    case TK_ID:
-+    case TK_COLUMN:
-+    case TK_DOT:
-+    case TK_FUNCTION:
-+      return 0;
-+    case TK_NULL:
-+    case TK_STRING:
-+    case TK_INTEGER:
-+    case TK_FLOAT:
-+    case TK_VARIABLE:
-+      return 1;
-+    default: {
-+      if( p->pLeft && !sqliteExprIsConstant(p->pLeft) ) return 0;
-+      if( p->pRight && !sqliteExprIsConstant(p->pRight) ) return 0;
-+      if( p->pList ){
-+        int i;
-+        for(i=0; i<p->pList->nExpr; i++){
-+          if( !sqliteExprIsConstant(p->pList->a[i].pExpr) ) return 0;
-+        }
-+      }
-+      return p->pLeft!=0 || p->pRight!=0 || (p->pList && p->pList->nExpr>0);
-+    }
-+  }
-+  return 0;
-+}
-+
-+/*
-+** If the given expression 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.
-+*/
-+int sqliteExprIsInteger(Expr *p, int *pValue){
-+  switch( p->op ){
-+    case TK_INTEGER: {
-+      if( sqliteFitsIn32Bits(p->token.z) ){
-+        *pValue = atoi(p->token.z);
-+        return 1;
-+      }
-+      break;
-+    }
-+    case TK_STRING: {
-+      const char *z = p->token.z;
-+      int n = p->token.n;
-+      if( n>0 && z[0]=='-' ){ z++; n--; }
-+      while( n>0 && *z && isdigit(*z) ){ z++; n--; }
-+      if( n==0 && sqliteFitsIn32Bits(p->token.z) ){
-+        *pValue = atoi(p->token.z);
-+        return 1;
-+      }
-+      break;
-+    }
-+    case TK_UPLUS: {
-+      return sqliteExprIsInteger(p->pLeft, pValue);
-+    }
-+    case TK_UMINUS: {
-+      int v;
-+      if( sqliteExprIsInteger(p->pLeft, &v) ){
-+        *pValue = -v;
-+        return 1;
-+      }
-+      break;
-+    }
-+    default: break;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Return TRUE if the given string is a row-id column name.
-+*/
-+int sqliteIsRowid(const char *z){
-+  if( sqliteStrICmp(z, "_ROWID_")==0 ) return 1;
-+  if( sqliteStrICmp(z, "ROWID")==0 ) return 1;
-+  if( sqliteStrICmp(z, "OID")==0 ) return 1;
-+  return 0;
-+}
-+
-+/*
-+** 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 holding
-+**                         the table.
-+**    pExpr->iTable        Set to the cursor number for the table obtained
-+**                         from pSrcList.
-+**    pExpr->iColumn       Set to the column number within the table.
-+**    pExpr->dataType      Set to the appropriate data type for the column.
-+**    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 pDbToken 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 pTableToken is the name of the table (the "Y").  This
-+** value can be NULL if pDbToken is also NULL.  If pTableToken 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 non-zero.  Return zero on success.
-+*/
-+static int lookupName(
-+  Parse *pParse,      /* The parsing context */
-+  Token *pDbToken,     /* Name of the database containing table, or NULL */
-+  Token *pTableToken,  /* Name of table containing column, or NULL */
-+  Token *pColumnToken, /* Name of the column. */
-+  SrcList *pSrcList,   /* List of tables used to resolve column names */
-+  ExprList *pEList,    /* List of expressions used to resolve "AS" */
-+  Expr *pExpr          /* Make this EXPR node point to the selected column */
-+){
-+  char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */
-+  char *zTab = 0;      /* Name of the table.  The "Y" in X.Y.Z or Y.Z */
-+  char *zCol = 0;      /* Name of the column.  The "Z" */
-+  int i, j;            /* Loop counters */
-+  int cnt = 0;         /* Number of matching column names */
-+  int cntTab = 0;      /* Number of matching table names */
-+  sqlite *db = pParse->db;  /* The database */
-+
-+  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
-+  if( pDbToken && pDbToken->z ){
-+    zDb = sqliteStrNDup(pDbToken->z, pDbToken->n);
-+    sqliteDequote(zDb);
-+  }else{
-+    zDb = 0;
-+  }
-+  if( pTableToken && pTableToken->z ){
-+    zTab = sqliteStrNDup(pTableToken->z, pTableToken->n);
-+    sqliteDequote(zTab);
-+  }else{
-+    assert( zDb==0 );
-+    zTab = 0;
-+  }
-+  zCol = sqliteStrNDup(pColumnToken->z, pColumnToken->n);
-+  sqliteDequote(zCol);
-+  if( sqlite_malloc_failed ){
-+    return 1;  /* Leak memory (zDb and zTab) if malloc fails */
-+  }
-+  assert( zTab==0 || pEList==0 );
-+
-+  pExpr->iTable = -1;
-+  for(i=0; i<pSrcList->nSrc; i++){
-+    struct SrcList_item *pItem = &pSrcList->a[i];
-+    Table *pTab = pItem->pTab;
-+    Column *pCol;
-+
-+    if( pTab==0 ) continue;
-+    assert( pTab->nCol>0 );
-+    if( zTab ){
-+      if( pItem->zAlias ){
-+        char *zTabName = pItem->zAlias;
-+        if( sqliteStrICmp(zTabName, zTab)!=0 ) continue;
-+      }else{
-+        char *zTabName = pTab->zName;
-+        if( zTabName==0 || sqliteStrICmp(zTabName, zTab)!=0 ) continue;
-+        if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
-+          continue;
-+        }
-+      }
-+    }
-+    if( 0==(cntTab++) ){
-+      pExpr->iTable = pItem->iCursor;
-+      pExpr->iDb = pTab->iDb;
-+    }
-+    for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
-+      if( sqliteStrICmp(pCol->zName, zCol)==0 ){
-+        cnt++;
-+        pExpr->iTable = pItem->iCursor;
-+        pExpr->iDb = pTab->iDb;
-+        /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
-+        pExpr->iColumn = j==pTab->iPKey ? -1 : j;
-+        pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK;
-+        break;
-+      }
-+    }
-+  }
-+
-+  /* 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->trigStack!=0 ){
-+    TriggerStack *pTriggerStack = pParse->trigStack;
-+    Table *pTab = 0;
-+    if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zTab) == 0 ){
-+      pExpr->iTable = pTriggerStack->newIdx;
-+      assert( pTriggerStack->pTab );
-+      pTab = pTriggerStack->pTab;
-+    }else if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zTab) == 0 ){
-+      pExpr->iTable = pTriggerStack->oldIdx;
-+      assert( pTriggerStack->pTab );
-+      pTab = pTriggerStack->pTab;
-+    }
-+
-+    if( pTab ){ 
-+      int j;
-+      Column *pCol = pTab->aCol;
-+      
-+      pExpr->iDb = pTab->iDb;
-+      cntTab++;
-+      for(j=0; j < pTab->nCol; j++, pCol++) {
-+        if( sqliteStrICmp(pCol->zName, zCol)==0 ){
-+          cnt++;
-+          pExpr->iColumn = j==pTab->iPKey ? -1 : j;
-+          pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK;
-+          break;
-+        }
-+      }
-+    }
-+  }
-+
-+  /*
-+  ** Perhaps the name is a reference to the ROWID
-+  */
-+  if( cnt==0 && cntTab==1 && sqliteIsRowid(zCol) ){
-+    cnt = 1;
-+    pExpr->iColumn = -1;
-+    pExpr->dataType = SQLITE_SO_NUM;
-+  }
-+
-+  /*
-+  ** 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!=0 ){
-+    for(j=0; j<pEList->nExpr; j++){
-+      char *zAs = pEList->a[j].zName;
-+      if( zAs!=0 && sqliteStrICmp(zAs, zCol)==0 ){
-+        assert( pExpr->pLeft==0 && pExpr->pRight==0 );
-+        pExpr->op = TK_AS;
-+        pExpr->iColumn = j;
-+        pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr);
-+        sqliteFree(zCol);
-+        assert( zTab==0 && zDb==0 );
-+        return 0;
-+      }
-+    } 
-+  }
-+
-+  /*
-+  ** 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.
-+  */
-+  if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
-+    sqliteFree(zCol);
-+    return 0;
-+  }
-+
-+  /*
-+  ** 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 ){
-+    char *z = 0;
-+    char *zErr;
-+    zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
-+    if( zDb ){
-+      sqliteSetString(&z, zDb, ".", zTab, ".", zCol, 0);
-+    }else if( zTab ){
-+      sqliteSetString(&z, zTab, ".", zCol, 0);
-+    }else{
-+      z = sqliteStrDup(zCol);
-+    }
-+    sqliteErrorMsg(pParse, zErr, z);
-+    sqliteFree(z);
-+  }
-+
-+  /* Clean up and return
-+  */
-+  sqliteFree(zDb);
-+  sqliteFree(zTab);
-+  sqliteFree(zCol);
-+  sqliteExprDelete(pExpr->pLeft);
-+  pExpr->pLeft = 0;
-+  sqliteExprDelete(pExpr->pRight);
-+  pExpr->pRight = 0;
-+  pExpr->op = TK_COLUMN;
-+  sqliteAuthRead(pParse, pExpr, pSrcList);
-+  return cnt!=1;
-+}
-+
-+/*
-+** This routine walks an expression tree and resolves references to
-+** table columns.  Nodes of the form ID.ID or ID resolve into an
-+** index to the table in the table list and a column offset.  The 
-+** Expr.opcode for such nodes is changed to TK_COLUMN.  The Expr.iTable
-+** value is changed to the index of the referenced table in pTabList
-+** plus the "base" value.  The base value will ultimately become the
-+** VDBE cursor number for a cursor that is pointing into the referenced
-+** table.  The Expr.iColumn value is changed to the index of the column 
-+** of the referenced table.  The Expr.iColumn value for the special
-+** ROWID column is -1.  Any INTEGER PRIMARY KEY column is tried as an
-+** alias for ROWID.
-+**
-+** We also check for instances of the IN operator.  IN comes in two
-+** forms:
-+**
-+**           expr IN (exprlist)
-+** and
-+**           expr IN (SELECT ...)
-+**
-+** The first form is handled by creating a set holding the list
-+** of allowed values.  The second form causes the SELECT to generate 
-+** a temporary table.
-+**
-+** This routine also looks for scalar SELECTs that are part of an expression.
-+** If it finds any, it generates code to write the value of that select
-+** into a memory cell.
-+**
-+** Unknown columns or tables provoke an error.  The function returns
-+** the number of errors seen and leaves an error message on pParse->zErrMsg.
-+*/
-+int sqliteExprResolveIds(
-+  Parse *pParse,     /* The parser context */
-+  SrcList *pSrcList, /* List of tables used to resolve column names */
-+  ExprList *pEList,  /* List of expressions used to resolve "AS" */
-+  Expr *pExpr        /* The expression to be analyzed. */
-+){
-+  int i;
-+
-+  if( pExpr==0 || pSrcList==0 ) return 0;
-+  for(i=0; i<pSrcList->nSrc; i++){
-+    assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab );
-+  }
-+  switch( pExpr->op ){
-+    /* Double-quoted strings (ex: "abc") are used as identifiers if
-+    ** possible.  Otherwise they remain as strings.  Single-quoted
-+    ** strings (ex: 'abc') are always string literals.
-+    */
-+    case TK_STRING: {
-+      if( pExpr->token.z[0]=='\'' ) break;
-+      /* Fall thru into the TK_ID case if this is a double-quoted string */
-+    }
-+    /* A lone identifier is the name of a columnd.
-+    */
-+    case TK_ID: {
-+      if( lookupName(pParse, 0, 0, &pExpr->token, pSrcList, pEList, pExpr) ){
-+        return 1;
-+      }
-+      break; 
-+    }
-+  
-+    /* A table name and column name:     ID.ID
-+    ** Or a database, table and column:  ID.ID.ID
-+    */
-+    case TK_DOT: {
-+      Token *pColumn;
-+      Token *pTable;
-+      Token *pDb;
-+      Expr *pRight;
-+
-+      pRight = pExpr->pRight;
-+      if( pRight->op==TK_ID ){
-+        pDb = 0;
-+        pTable = &pExpr->pLeft->token;
-+        pColumn = &pRight->token;
-+      }else{
-+        assert( pRight->op==TK_DOT );
-+        pDb = &pExpr->pLeft->token;
-+        pTable = &pRight->pLeft->token;
-+        pColumn = &pRight->pRight->token;
-+      }
-+      if( lookupName(pParse, pDb, pTable, pColumn, pSrcList, 0, pExpr) ){
-+        return 1;
-+      }
-+      break;
-+    }
-+
-+    case TK_IN: {
-+      Vdbe *v = sqliteGetVdbe(pParse);
-+      if( v==0 ) return 1;
-+      if( sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
-+        return 1;
-+      }
-+      if( pExpr->pSelect ){
-+        /* Case 1:     expr IN (SELECT ...)
-+        **
-+        ** Generate code to write the results of the select into a temporary
-+        ** table.  The cursor number of the temporary table has already
-+        ** been put in iTable by sqliteExprResolveInSelect().
-+        */
-+        pExpr->iTable = pParse->nTab++;
-+        sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 1);
-+        sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable, 0,0,0);
-+      }else if( pExpr->pList ){
-+        /* Case 2:     expr IN (exprlist)
-+        **
-+        ** Create a set to put the exprlist values in.  The Set id is stored
-+        ** in iTable.
-+        */
-+        int i, iSet;
-+        for(i=0; i<pExpr->pList->nExpr; i++){
-+          Expr *pE2 = pExpr->pList->a[i].pExpr;
-+          if( !sqliteExprIsConstant(pE2) ){
-+            sqliteErrorMsg(pParse,
-+              "right-hand side of IN operator must be constant");
-+            return 1;
-+          }
-+          if( sqliteExprCheck(pParse, pE2, 0, 0) ){
-+            return 1;
-+          }
-+        }
-+        iSet = pExpr->iTable = pParse->nSet++;
-+        for(i=0; i<pExpr->pList->nExpr; i++){
-+          Expr *pE2 = pExpr->pList->a[i].pExpr;
-+          switch( pE2->op ){
-+            case TK_FLOAT:
-+            case TK_INTEGER:
-+            case TK_STRING: {
-+              int addr;
-+              assert( pE2->token.z );
-+              addr = sqliteVdbeOp3(v, OP_SetInsert, iSet, 0,
-+                                  pE2->token.z, pE2->token.n);
-+              sqliteVdbeDequoteP3(v, addr);
-+              break;
-+            }
-+            default: {
-+              sqliteExprCode(pParse, pE2);
-+              sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
-+              break;
-+            }
-+          }
-+        }
-+      }
-+      break;
-+    }
-+
-+    case TK_SELECT: {
-+      /* 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.
-+      */
-+      pExpr->iColumn = pParse->nMem++;
-+      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn,0,0,0) ){
-+        return 1;
-+      }
-+      break;
-+    }
-+
-+    /* For all else, just recursively walk the tree */
-+    default: {
-+      if( pExpr->pLeft
-+      && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
-+        return 1;
-+      }
-+      if( pExpr->pRight 
-+      && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pRight) ){
-+        return 1;
-+      }
-+      if( pExpr->pList ){
-+        int i;
-+        ExprList *pList = pExpr->pList;
-+        for(i=0; i<pList->nExpr; i++){
-+          Expr *pArg = pList->a[i].pExpr;
-+          if( sqliteExprResolveIds(pParse, pSrcList, pEList, pArg) ){
-+            return 1;
-+          }
-+        }
-+      }
-+    }
-+  }
-+  return 0;
-+}
-+
-+/*
-+** pExpr is a node that defines a function of some kind.  It might
-+** be a syntactic function like "count(x)" or it might be a function
-+** that implements an operator, like "a LIKE b".  
-+**
-+** This routine makes *pzName point to the name of the function and 
-+** *pnName hold the number of characters in the function name.
-+*/
-+static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
-+  switch( pExpr->op ){
-+    case TK_FUNCTION: {
-+      *pzName = pExpr->token.z;
-+      *pnName = pExpr->token.n;
-+      break;
-+    }
-+    case TK_LIKE: {
-+      *pzName = "like";
-+      *pnName = 4;
-+      break;
-+    }
-+    case TK_GLOB: {
-+      *pzName = "glob";
-+      *pnName = 4;
-+      break;
-+    }
-+    default: {
-+      *pzName = "can't happen";
-+      *pnName = 12;
-+      break;
-+    }
-+  }
-+}
-+
-+/*
-+** Error check the functions in an expression.  Make sure all
-+** function names are recognized and all functions have the correct
-+** number of arguments.  Leave an error message in pParse->zErrMsg
-+** if anything is amiss.  Return the number of errors.
-+**
-+** if pIsAgg is not null and this expression is an aggregate function
-+** (like count(*) or max(value)) then write a 1 into *pIsAgg.
-+*/
-+int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
-+  int nErr = 0;
-+  if( pExpr==0 ) return 0;
-+  switch( pExpr->op ){
-+    case TK_GLOB:
-+    case TK_LIKE:
-+    case TK_FUNCTION: {
-+      int n = pExpr->pList ? pExpr->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 i;
-+      int nId;                    /* Number of characters in function name */
-+      const char *zId;            /* The function name. */
-+      FuncDef *pDef;
-+
-+      getFunctionName(pExpr, &zId, &nId);
-+      pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0);
-+      if( pDef==0 ){
-+        pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0);
-+        if( pDef==0 ){
-+          no_such_func = 1;
-+        }else{
-+          wrong_num_args = 1;
-+        }
-+      }else{
-+        is_agg = pDef->xFunc==0;
-+      }
-+      if( is_agg && !allowAgg ){
-+        sqliteErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId);
-+        nErr++;
-+        is_agg = 0;
-+      }else if( no_such_func ){
-+        sqliteErrorMsg(pParse, "no such function: %.*s", nId, zId);
-+        nErr++;
-+      }else if( wrong_num_args ){
-+        sqliteErrorMsg(pParse,"wrong number of arguments to function %.*s()",
-+             nId, zId);
-+        nErr++;
-+      }
-+      if( is_agg ){
-+        pExpr->op = TK_AGG_FUNCTION;
-+        if( pIsAgg ) *pIsAgg = 1;
-+      }
-+      for(i=0; nErr==0 && i<n; i++){
-+        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
-+                               allowAgg && !is_agg, pIsAgg);
-+      }
-+      if( pDef==0 ){
-+        /* Already reported an error */
-+      }else if( pDef->dataType>=0 ){
-+        if( pDef->dataType<n ){
-+          pExpr->dataType = 
-+             sqliteExprType(pExpr->pList->a[pDef->dataType].pExpr);
-+        }else{
-+          pExpr->dataType = SQLITE_SO_NUM;
-+        }
-+      }else if( pDef->dataType==SQLITE_ARGS ){
-+        pDef->dataType = SQLITE_SO_TEXT;
-+        for(i=0; i<n; i++){
-+          if( sqliteExprType(pExpr->pList->a[i].pExpr)==SQLITE_SO_NUM ){
-+            pExpr->dataType = SQLITE_SO_NUM;
-+            break;
-+          }
-+        }
-+      }else if( pDef->dataType==SQLITE_NUMERIC ){
-+        pExpr->dataType = SQLITE_SO_NUM;
-+      }else{
-+        pExpr->dataType = SQLITE_SO_TEXT;
-+      }
-+    }
-+    default: {
-+      if( pExpr->pLeft ){
-+        nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);
-+      }
-+      if( nErr==0 && pExpr->pRight ){
-+        nErr = sqliteExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg);
-+      }
-+      if( nErr==0 && pExpr->pList ){
-+        int n = pExpr->pList->nExpr;
-+        int i;
-+        for(i=0; nErr==0 && i<n; i++){
-+          Expr *pE2 = pExpr->pList->a[i].pExpr;
-+          nErr = sqliteExprCheck(pParse, pE2, allowAgg, pIsAgg);
-+        }
-+      }
-+      break;
-+    }
-+  }
-+  return nErr;
-+}
-+
-+/*
-+** Return either SQLITE_SO_NUM or SQLITE_SO_TEXT to indicate whether the
-+** given expression should sort as numeric values or as text.
-+**
-+** The sqliteExprResolveIds() and sqliteExprCheck() routines must have
-+** both been called on the expression before it is passed to this routine.
-+*/
-+int sqliteExprType(Expr *p){
-+  if( p==0 ) return SQLITE_SO_NUM;
-+  while( p ) switch( p->op ){
-+    case TK_PLUS:
-+    case TK_MINUS:
-+    case TK_STAR:
-+    case TK_SLASH:
-+    case TK_AND:
-+    case TK_OR:
-+    case TK_ISNULL:
-+    case TK_NOTNULL:
-+    case TK_NOT:
-+    case TK_UMINUS:
-+    case TK_UPLUS:
-+    case TK_BITAND:
-+    case TK_BITOR:
-+    case TK_BITNOT:
-+    case TK_LSHIFT:
-+    case TK_RSHIFT:
-+    case TK_REM:
-+    case TK_INTEGER:
-+    case TK_FLOAT:
-+    case TK_IN:
-+    case TK_BETWEEN:
-+    case TK_GLOB:
-+    case TK_LIKE:
-+      return SQLITE_SO_NUM;
-+
-+    case TK_STRING:
-+    case TK_NULL:
-+    case TK_CONCAT:
-+    case TK_VARIABLE:
-+      return SQLITE_SO_TEXT;
-+
-+    case TK_LT:
-+    case TK_LE:
-+    case TK_GT:
-+    case TK_GE:
-+    case TK_NE:
-+    case TK_EQ:
-+      if( sqliteExprType(p->pLeft)==SQLITE_SO_NUM ){
-+        return SQLITE_SO_NUM;
-+      }
-+      p = p->pRight;
-+      break;
-+
-+    case TK_AS:
-+      p = p->pLeft;
-+      break;
-+
-+    case TK_COLUMN:
-+    case TK_FUNCTION:
-+    case TK_AGG_FUNCTION:
-+      return p->dataType;
-+
-+    case TK_SELECT:
-+      assert( p->pSelect );
-+      assert( p->pSelect->pEList );
-+      assert( p->pSelect->pEList->nExpr>0 );
-+      p = p->pSelect->pEList->a[0].pExpr;
-+      break;
-+
-+    case TK_CASE: {
-+      if( p->pRight && sqliteExprType(p->pRight)==SQLITE_SO_NUM ){
-+        return SQLITE_SO_NUM;
-+      }
-+      if( p->pList ){
-+        int i;
-+        ExprList *pList = p->pList;
-+        for(i=1; i<pList->nExpr; i+=2){
-+          if( sqliteExprType(pList->a[i].pExpr)==SQLITE_SO_NUM ){
-+            return SQLITE_SO_NUM;
-+          }
-+        }
-+      }
-+      return SQLITE_SO_TEXT;
-+    }
-+
-+    default:
-+      assert( p->op==TK_ABORT );  /* Can't Happen */
-+      break;
-+  }
-+  return SQLITE_SO_NUM;
-+}
-+
-+/*
-+** Generate code into the current Vdbe to evaluate the given
-+** expression and leave the result on the top of stack.
-+*/
-+void sqliteExprCode(Parse *pParse, Expr *pExpr){
-+  Vdbe *v = pParse->pVdbe;
-+  int op;
-+  if( v==0 || pExpr==0 ) return;
-+  switch( pExpr->op ){
-+    case TK_PLUS:     op = OP_Add;      break;
-+    case TK_MINUS:    op = OP_Subtract; break;
-+    case TK_STAR:     op = OP_Multiply; break;
-+    case TK_SLASH:    op = OP_Divide;   break;
-+    case TK_AND:      op = OP_And;      break;
-+    case TK_OR:       op = OP_Or;       break;
-+    case TK_LT:       op = OP_Lt;       break;
-+    case TK_LE:       op = OP_Le;       break;
-+    case TK_GT:       op = OP_Gt;       break;
-+    case TK_GE:       op = OP_Ge;       break;
-+    case TK_NE:       op = OP_Ne;       break;
-+    case TK_EQ:       op = OP_Eq;       break;
-+    case TK_ISNULL:   op = OP_IsNull;   break;
-+    case TK_NOTNULL:  op = OP_NotNull;  break;
-+    case TK_NOT:      op = OP_Not;      break;
-+    case TK_UMINUS:   op = OP_Negative; break;
-+    case TK_BITAND:   op = OP_BitAnd;   break;
-+    case TK_BITOR:    op = OP_BitOr;    break;
-+    case TK_BITNOT:   op = OP_BitNot;   break;
-+    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
-+    case TK_RSHIFT:   op = OP_ShiftRight; break;
-+    case TK_REM:      op = OP_Remainder;  break;
-+    default: break;
-+  }
-+  switch( pExpr->op ){
-+    case TK_COLUMN: {
-+      if( pParse->useAgg ){
-+        sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
-+      }else if( pExpr->iColumn>=0 ){
-+        sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
-+      }
-+      break;
-+    }
-+    case TK_STRING:
-+    case TK_FLOAT:
-+    case TK_INTEGER: {
-+      if( pExpr->op==TK_INTEGER && sqliteFitsIn32Bits(pExpr->token.z) ){
-+        sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      }
-+      assert( pExpr->token.z );
-+      sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
-+      sqliteVdbeDequoteP3(v, -1);
-+      break;
-+    }
-+    case TK_NULL: {
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      break;
-+    }
-+    case TK_VARIABLE: {
-+      sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
-+      break;
-+    }
-+    case TK_LT:
-+    case TK_LE:
-+    case TK_GT:
-+    case TK_GE:
-+    case TK_NE:
-+    case TK_EQ: {
-+      if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
-+        op += 6;  /* Convert numeric opcodes to text opcodes */
-+      }
-+      /* Fall through into the next case */
-+    }
-+    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: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteExprCode(pParse, pExpr->pRight);
-+      sqliteVdbeAddOp(v, op, 0, 0);
-+      break;
-+    }
-+    case TK_LSHIFT:
-+    case TK_RSHIFT: {
-+      sqliteExprCode(pParse, pExpr->pRight);
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, op, 0, 0);
-+      break;
-+    }
-+    case TK_CONCAT: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteExprCode(pParse, pExpr->pRight);
-+      sqliteVdbeAddOp(v, OP_Concat, 2, 0);
-+      break;
-+    }
-+    case TK_UMINUS: {
-+      assert( pExpr->pLeft );
-+      if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){
-+        Token *p = &pExpr->pLeft->token;
-+        char *z = sqliteMalloc( p->n + 2 );
-+        sprintf(z, "-%.*s", p->n, p->z);
-+        if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){
-+          sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0);
-+        }else{
-+          sqliteVdbeAddOp(v, OP_String, 0, 0);
-+        }
-+        sqliteVdbeChangeP3(v, -1, z, p->n+1);
-+        sqliteFree(z);
-+        break;
-+      }
-+      /* Fall through into TK_NOT */
-+    }
-+    case TK_BITNOT:
-+    case TK_NOT: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, op, 0, 0);
-+      break;
-+    }
-+    case TK_ISNULL:
-+    case TK_NOTNULL: {
-+      int dest;
-+      sqliteVdbeAddOp(v, OP_Integer, 1, 0);
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      dest = sqliteVdbeCurrentAddr(v) + 2;
-+      sqliteVdbeAddOp(v, op, 1, dest);
-+      sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
-+      break;
-+    }
-+    case TK_AGG_FUNCTION: {
-+      sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
-+      break;
-+    }
-+    case TK_GLOB:
-+    case TK_LIKE:
-+    case TK_FUNCTION: {
-+      ExprList *pList = pExpr->pList;
-+      int nExpr = pList ? pList->nExpr : 0;
-+      FuncDef *pDef;
-+      int nId;
-+      const char *zId;
-+      getFunctionName(pExpr, &zId, &nId);
-+      pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0);
-+      assert( pDef!=0 );
-+      nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes);
-+      sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
-+      break;
-+    }
-+    case TK_SELECT: {
-+      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
-+      break;
-+    }
-+    case TK_IN: {
-+      int addr;
-+      sqliteVdbeAddOp(v, OP_Integer, 1, 0);
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      addr = sqliteVdbeCurrentAddr(v);
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, addr+4);
-+      sqliteVdbeAddOp(v, OP_Pop, 2, 0);
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, addr+6);
-+      if( pExpr->pSelect ){
-+        sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+6);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+6);
-+      }
-+      sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
-+      break;
-+    }
-+    case TK_BETWEEN: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+      sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
-+      sqliteVdbeAddOp(v, OP_Ge, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Pull, 1, 0);
-+      sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
-+      sqliteVdbeAddOp(v, OP_Le, 0, 0);
-+      sqliteVdbeAddOp(v, OP_And, 0, 0);
-+      break;
-+    }
-+    case TK_UPLUS:
-+    case TK_AS: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      break;
-+    }
-+    case TK_CASE: {
-+      int expr_end_label;
-+      int jumpInst;
-+      int addr;
-+      int nExpr;
-+      int i;
-+
-+      assert(pExpr->pList);
-+      assert((pExpr->pList->nExpr % 2) == 0);
-+      assert(pExpr->pList->nExpr > 0);
-+      nExpr = pExpr->pList->nExpr;
-+      expr_end_label = sqliteVdbeMakeLabel(v);
-+      if( pExpr->pLeft ){
-+        sqliteExprCode(pParse, pExpr->pLeft);
-+      }
-+      for(i=0; i<nExpr; i=i+2){
-+        sqliteExprCode(pParse, pExpr->pList->a[i].pExpr);
-+        if( pExpr->pLeft ){
-+          sqliteVdbeAddOp(v, OP_Dup, 1, 1);
-+          jumpInst = sqliteVdbeAddOp(v, OP_Ne, 1, 0);
-+          sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+        }else{
-+          jumpInst = sqliteVdbeAddOp(v, OP_IfNot, 1, 0);
-+        }
-+        sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, expr_end_label);
-+        addr = sqliteVdbeCurrentAddr(v);
-+        sqliteVdbeChangeP2(v, jumpInst, addr);
-+      }
-+      if( pExpr->pLeft ){
-+        sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      }
-+      if( pExpr->pRight ){
-+        sqliteExprCode(pParse, pExpr->pRight);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      }
-+      sqliteVdbeResolveLabel(v, expr_end_label);
-+      break;
-+    }
-+    case TK_RAISE: {
-+      if( !pParse->trigStack ){
-+        sqliteErrorMsg(pParse,
-+                       "RAISE() may only be used within a trigger-program");
-+        pParse->nErr++;
-+      return;
-+      }
-+      if( pExpr->iColumn == OE_Rollback ||
-+        pExpr->iColumn == OE_Abort ||
-+        pExpr->iColumn == OE_Fail ){
-+        sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
-+                           pExpr->token.z, pExpr->token.n);
-+        sqliteVdbeDequoteP3(v, -1);
-+      } else {
-+        assert( pExpr->iColumn == OE_Ignore );
-+        sqliteVdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump,
-+                           "(IGNORE jump)", 0);
-+      }
-+    }
-+    break;
-+  }
-+}
-+
-+/*
-+** Generate code that pushes the value of every element of the given
-+** expression list onto the stack.  If the includeTypes flag is true,
-+** then also push a string that is the datatype of each element onto
-+** the stack after the value.
-+**
-+** Return the number of elements pushed onto the stack.
-+*/
-+int sqliteExprCodeExprList(
-+  Parse *pParse,     /* Parsing context */
-+  ExprList *pList,   /* The expression list to be coded */
-+  int includeTypes   /* TRUE to put datatypes on the stack too */
-+){
-+  struct ExprList_item *pItem;
-+  int i, n;
-+  Vdbe *v;
-+  if( pList==0 ) return 0;
-+  v = sqliteGetVdbe(pParse);
-+  n = pList->nExpr;
-+  for(pItem=pList->a, i=0; i<n; i++, pItem++){
-+    sqliteExprCode(pParse, pItem->pExpr);
-+    if( includeTypes ){
-+      sqliteVdbeOp3(v, OP_String, 0, 0, 
-+         sqliteExprType(pItem->pExpr)==SQLITE_SO_NUM ? "numeric" : "text",
-+         P3_STATIC);
-+    }
-+  }
-+  return includeTypes ? n*2 : 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 true.
-+*/
-+void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
-+  Vdbe *v = pParse->pVdbe;
-+  int op = 0;
-+  if( v==0 || pExpr==0 ) return;
-+  switch( pExpr->op ){
-+    case TK_LT:       op = OP_Lt;       break;
-+    case TK_LE:       op = OP_Le;       break;
-+    case TK_GT:       op = OP_Gt;       break;
-+    case TK_GE:       op = OP_Ge;       break;
-+    case TK_NE:       op = OP_Ne;       break;
-+    case TK_EQ:       op = OP_Eq;       break;
-+    case TK_ISNULL:   op = OP_IsNull;   break;
-+    case TK_NOTNULL:  op = OP_NotNull;  break;
-+    default:  break;
-+  }
-+  switch( pExpr->op ){
-+    case TK_AND: {
-+      int d2 = sqliteVdbeMakeLabel(v);
-+      sqliteExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
-+      sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
-+      sqliteVdbeResolveLabel(v, d2);
-+      break;
-+    }
-+    case TK_OR: {
-+      sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
-+      sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
-+      break;
-+    }
-+    case TK_NOT: {
-+      sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
-+      break;
-+    }
-+    case TK_LT:
-+    case TK_LE:
-+    case TK_GT:
-+    case TK_GE:
-+    case TK_NE:
-+    case TK_EQ: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteExprCode(pParse, pExpr->pRight);
-+      if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
-+        op += 6;  /* Convert numeric opcodes to text opcodes */
-+      }
-+      sqliteVdbeAddOp(v, op, jumpIfNull, dest);
-+      break;
-+    }
-+    case TK_ISNULL:
-+    case TK_NOTNULL: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, op, 1, dest);
-+      break;
-+    }
-+    case TK_IN: {
-+      int addr;
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      addr = sqliteVdbeCurrentAddr(v);
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
-+      if( pExpr->pSelect ){
-+        sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest);
-+      }
-+      break;
-+    }
-+    case TK_BETWEEN: {
-+      int addr;
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+      sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
-+      addr = sqliteVdbeAddOp(v, OP_Lt, !jumpIfNull, 0);
-+      sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
-+      sqliteVdbeAddOp(v, OP_Le, jumpIfNull, dest);
-+      sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+      sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      break;
-+    }
-+    default: {
-+      sqliteExprCode(pParse, pExpr);
-+      sqliteVdbeAddOp(v, OP_If, jumpIfNull, dest);
-+      break;
-+    }
-+  }
-+}
-+
-+/*
-+** 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 true or fall through if jumpIfNull is false.
-+*/
-+void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
-+  Vdbe *v = pParse->pVdbe;
-+  int op = 0;
-+  if( v==0 || pExpr==0 ) return;
-+  switch( pExpr->op ){
-+    case TK_LT:       op = OP_Ge;       break;
-+    case TK_LE:       op = OP_Gt;       break;
-+    case TK_GT:       op = OP_Le;       break;
-+    case TK_GE:       op = OP_Lt;       break;
-+    case TK_NE:       op = OP_Eq;       break;
-+    case TK_EQ:       op = OP_Ne;       break;
-+    case TK_ISNULL:   op = OP_NotNull;  break;
-+    case TK_NOTNULL:  op = OP_IsNull;   break;
-+    default:  break;
-+  }
-+  switch( pExpr->op ){
-+    case TK_AND: {
-+      sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
-+      sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
-+      break;
-+    }
-+    case TK_OR: {
-+      int d2 = sqliteVdbeMakeLabel(v);
-+      sqliteExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
-+      sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
-+      sqliteVdbeResolveLabel(v, d2);
-+      break;
-+    }
-+    case TK_NOT: {
-+      sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
-+      break;
-+    }
-+    case TK_LT:
-+    case TK_LE:
-+    case TK_GT:
-+    case TK_GE:
-+    case TK_NE:
-+    case TK_EQ: {
-+      if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
-+        /* Convert numeric comparison opcodes into text comparison opcodes.
-+        ** This step depends on the fact that the text comparision opcodes are
-+        ** always 6 greater than their corresponding numeric comparison
-+        ** opcodes.
-+        */
-+        assert( OP_Eq+6 == OP_StrEq );
-+        op += 6;
-+      }
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteExprCode(pParse, pExpr->pRight);
-+      sqliteVdbeAddOp(v, op, jumpIfNull, dest);
-+      break;
-+    }
-+    case TK_ISNULL:
-+    case TK_NOTNULL: {
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, op, 1, dest);
-+      break;
-+    }
-+    case TK_IN: {
-+      int addr;
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      addr = sqliteVdbeCurrentAddr(v);
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
-+      if( pExpr->pSelect ){
-+        sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest);
-+      }
-+      break;
-+    }
-+    case TK_BETWEEN: {
-+      int addr;
-+      sqliteExprCode(pParse, pExpr->pLeft);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+      sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
-+      addr = sqliteVdbeCurrentAddr(v);
-+      sqliteVdbeAddOp(v, OP_Ge, !jumpIfNull, addr+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, dest);
-+      sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
-+      sqliteVdbeAddOp(v, OP_Gt, jumpIfNull, dest);
-+      break;
-+    }
-+    default: {
-+      sqliteExprCode(pParse, pExpr);
-+      sqliteVdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
-+      break;
-+    }
-+  }
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteExprCompare(Expr *pA, Expr *pB){
-+  int i;
-+  if( pA==0 ){
-+    return pB==0;
-+  }else if( pB==0 ){
-+    return 0;
-+  }
-+  if( pA->op!=pB->op ) return 0;
-+  if( !sqliteExprCompare(pA->pLeft, pB->pLeft) ) return 0;
-+  if( !sqliteExprCompare(pA->pRight, pB->pRight) ) return 0;
-+  if( pA->pList ){
-+    if( pB->pList==0 ) return 0;
-+    if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
-+    for(i=0; i<pA->pList->nExpr; i++){
-+      if( !sqliteExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
-+        return 0;
-+      }
-+    }
-+  }else if( pB->pList ){
-+    return 0;
-+  }
-+  if( pA->pSelect || pB->pSelect ) return 0;
-+  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
-+  if( pA->token.z ){
-+    if( pB->token.z==0 ) return 0;
-+    if( pB->token.n!=pA->token.n ) return 0;
-+    if( sqliteStrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
-+  }
-+  return 1;
-+}
-+
-+/*
-+** Add a new element to the pParse->aAgg[] array and return its index.
-+*/
-+static int appendAggInfo(Parse *pParse){
-+  if( (pParse->nAgg & 0x7)==0 ){
-+    int amt = pParse->nAgg + 8;
-+    AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
-+    if( aAgg==0 ){
-+      return -1;
-+    }
-+    pParse->aAgg = aAgg;
-+  }
-+  memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
-+  return pParse->nAgg++;
-+}
-+
-+/*
-+** 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 sqliteExprResolveIds() and sqliteExprCheck().
-+**
-+** If errors are seen, leave an error message in zErrMsg and return
-+** the number of errors.
-+*/
-+int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
-+  int i;
-+  AggExpr *aAgg;
-+  int nErr = 0;
-+
-+  if( pExpr==0 ) return 0;
-+  switch( pExpr->op ){
-+    case TK_COLUMN: {
-+      aAgg = pParse->aAgg;
-+      for(i=0; i<pParse->nAgg; i++){
-+        if( aAgg[i].isAgg ) continue;
-+        if( aAgg[i].pExpr->iTable==pExpr->iTable
-+         && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
-+          break;
-+        }
-+      }
-+      if( i>=pParse->nAgg ){
-+        i = appendAggInfo(pParse);
-+        if( i<0 ) return 1;
-+        pParse->aAgg[i].isAgg = 0;
-+        pParse->aAgg[i].pExpr = pExpr;
-+      }
-+      pExpr->iAgg = i;
-+      break;
-+    }
-+    case TK_AGG_FUNCTION: {
-+      aAgg = pParse->aAgg;
-+      for(i=0; i<pParse->nAgg; i++){
-+        if( !aAgg[i].isAgg ) continue;
-+        if( sqliteExprCompare(aAgg[i].pExpr, pExpr) ){
-+          break;
-+        }
-+      }
-+      if( i>=pParse->nAgg ){
-+        i = appendAggInfo(pParse);
-+        if( i<0 ) return 1;
-+        pParse->aAgg[i].isAgg = 1;
-+        pParse->aAgg[i].pExpr = pExpr;
-+        pParse->aAgg[i].pFunc = sqliteFindFunction(pParse->db,
-+             pExpr->token.z, pExpr->token.n,
-+             pExpr->pList ? pExpr->pList->nExpr : 0, 0);
-+      }
-+      pExpr->iAgg = i;
-+      break;
-+    }
-+    default: {
-+      if( pExpr->pLeft ){
-+        nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pLeft);
-+      }
-+      if( nErr==0 && pExpr->pRight ){
-+        nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pRight);
-+      }
-+      if( nErr==0 && pExpr->pList ){
-+        int n = pExpr->pList->nExpr;
-+        int i;
-+        for(i=0; nErr==0 && i<n; i++){
-+          nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pList->a[i].pExpr);
-+        }
-+      }
-+      break;
-+    }
-+  }
-+  return nErr;
-+}
-+
-+/*
-+** Locate a user function given a name and a number of arguments.
-+** 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.
-+*/
-+FuncDef *sqliteFindFunction(
-+  sqlite *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 */
-+  int createFlag     /* Create new entry if true and does not otherwise exist */
-+){
-+  FuncDef *pFirst, *p, *pMaybe;
-+  pFirst = p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, nName);
-+  if( p && !createFlag && nArg<0 ){
-+    while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
-+    return p;
-+  }
-+  pMaybe = 0;
-+  while( p && p->nArg!=nArg ){
-+    if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
-+    p = p->pNext;
-+  }
-+  if( p && !createFlag && p->xFunc==0 && p->xStep==0 ){
-+    return 0;
-+  }
-+  if( p==0 && pMaybe ){
-+    assert( createFlag==0 );
-+    return pMaybe;
-+  }
-+  if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)))!=0 ){
-+    p->nArg = nArg;
-+    p->pNext = pFirst;
-+    p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC;
-+    sqliteHashInsert(&db->aFunc, zName, nName, (void*)p);
-+  }
-+  return p;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/func.c
-@@ -0,0 +1,658 @@
-+/*
-+** 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.
-+**
-+** $Id$
-+*/
-+#include <ctype.h>
-+#include <math.h>
-+#include <stdlib.h>
-+#include <assert.h>
-+#include "sqliteInt.h"
-+#include "os.h"
-+
-+/*
-+** Implementation of the non-aggregate min() and max() functions
-+*/
-+static void minmaxFunc(sqlite_func *context, int argc, const char **argv){
-+  const char *zBest; 
-+  int i;
-+  int (*xCompare)(const char*, const char*);
-+  int mask;    /* 0 for min() or 0xffffffff for max() */
-+
-+  if( argc==0 ) return;
-+  mask = (int)sqlite_user_data(context);
-+  zBest = argv[0];
-+  if( zBest==0 ) return;
-+  if( argv[1][0]=='n' ){
-+    xCompare = sqliteCompare;
-+  }else{
-+    xCompare = strcmp;
-+  }
-+  for(i=2; i<argc; i+=2){
-+    if( argv[i]==0 ) return;
-+    if( (xCompare(argv[i], zBest)^mask)<0 ){
-+      zBest = argv[i];
-+    }
-+  }
-+  sqlite_set_result_string(context, zBest, -1);
-+}
-+
-+/*
-+** Return the type of the argument.
-+*/
-+static void typeofFunc(sqlite_func *context, int argc, const char **argv){
-+  assert( argc==2 );
-+  sqlite_set_result_string(context, argv[1], -1);
-+}
-+
-+/*
-+** Implementation of the length() function
-+*/
-+static void lengthFunc(sqlite_func *context, int argc, const char **argv){
-+  const char *z;
-+  int len;
-+
-+  assert( argc==1 );
-+  z = argv[0];
-+  if( z==0 ) return;
-+#ifdef SQLITE_UTF8
-+  for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
-+#else
-+  len = strlen(z);
-+#endif
-+  sqlite_set_result_int(context, len);
-+}
-+
-+/*
-+** Implementation of the abs() function
-+*/
-+static void absFunc(sqlite_func *context, int argc, const char **argv){
-+  const char *z;
-+  assert( argc==1 );
-+  z = argv[0];
-+  if( z==0 ) return;
-+  if( z[0]=='-' && isdigit(z[1]) ) z++;
-+  sqlite_set_result_string(context, z, -1);
-+}
-+
-+/*
-+** Implementation of the substr() function
-+*/
-+static void substrFunc(sqlite_func *context, int argc, const char **argv){
-+  const char *z;
-+#ifdef SQLITE_UTF8
-+  const char *z2;
-+  int i;
-+#endif
-+  int p1, p2, len;
-+  assert( argc==3 );
-+  z = argv[0];
-+  if( z==0 ) return;
-+  p1 = atoi(argv[1]?argv[1]:0);
-+  p2 = atoi(argv[2]?argv[2]:0);
-+#ifdef SQLITE_UTF8
-+  for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
-+#else
-+  len = strlen(z);
-+#endif
-+  if( p1<0 ){
-+    p1 += len;
-+    if( p1<0 ){
-+      p2 += p1;
-+      p1 = 0;
-+    }
-+  }else if( p1>0 ){
-+    p1--;
-+  }
-+  if( p1+p2>len ){
-+    p2 = len-p1;
-+  }
-+#ifdef SQLITE_UTF8
-+  for(i=0; i<p1 && z[i]; i++){
-+    if( (z[i]&0xc0)==0x80 ) p1++;
-+  }
-+  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
-+  for(; i<p1+p2 && z[i]; i++){
-+    if( (z[i]&0xc0)==0x80 ) p2++;
-+  }
-+  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
-+#endif
-+  if( p2<0 ) p2 = 0;
-+  sqlite_set_result_string(context, &z[p1], p2);
-+}
-+
-+/*
-+** Implementation of the round() function
-+*/
-+static void roundFunc(sqlite_func *context, int argc, const char **argv){
-+  int n;
-+  double r;
-+  char zBuf[100];
-+  assert( argc==1 || argc==2 );
-+  if( argv[0]==0 || (argc==2 && argv[1]==0) ) return;
-+  n = argc==2 ? atoi(argv[1]) : 0;
-+  if( n>30 ) n = 30;
-+  if( n<0 ) n = 0;
-+  r = sqliteAtoF(argv[0], 0);
-+  sprintf(zBuf,"%.*f",n,r);
-+  sqlite_set_result_string(context, zBuf, -1);
-+}
-+
-+/*
-+** Implementation of the upper() and lower() SQL functions.
-+*/
-+static void upperFunc(sqlite_func *context, int argc, const char **argv){
-+  unsigned char *z;
-+  int i;
-+  if( argc<1 || argv[0]==0 ) return;
-+  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
-+  if( z==0 ) return;
-+  for(i=0; z[i]; i++){
-+    if( islower(z[i]) ) z[i] = toupper(z[i]);
-+  }
-+}
-+static void lowerFunc(sqlite_func *context, int argc, const char **argv){
-+  unsigned char *z;
-+  int i;
-+  if( argc<1 || argv[0]==0 ) return;
-+  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
-+  if( z==0 ) return;
-+  for(i=0; z[i]; i++){
-+    if( isupper(z[i]) ) z[i] = tolower(z[i]);
-+  }
-+}
-+
-+/*
-+** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
-+** All three do the same thing.  They return the first non-NULL
-+** argument.
-+*/
-+static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
-+  int i;
-+  for(i=0; i<argc; i++){
-+    if( argv[i] ){
-+      sqlite_set_result_string(context, argv[i], -1);
-+      break;
-+    }
-+  }
-+}
-+
-+/*
-+** Implementation of random().  Return a random integer.  
-+*/
-+static void randomFunc(sqlite_func *context, int argc, const char **argv){
-+  int r;
-+  sqliteRandomness(sizeof(r), &r);
-+  sqlite_set_result_int(context, r);
-+}
-+
-+/*
-+** Implementation of the last_insert_rowid() SQL function.  The return
-+** value is the same as the sqlite_last_insert_rowid() API function.
-+*/
-+static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){
-+  sqlite *db = sqlite_user_data(context);
-+  sqlite_set_result_int(context, sqlite_last_insert_rowid(db));
-+}
-+
-+/*
-+** Implementation of the change_count() SQL function.  The return
-+** value is the same as the sqlite_changes() API function.
-+*/
-+static void change_count(sqlite_func *context, int arg, const char **argv){
-+  sqlite *db = sqlite_user_data(context);
-+  sqlite_set_result_int(context, sqlite_changes(db));
-+}
-+
-+/*
-+** Implementation of the last_statement_change_count() SQL function.  The
-+** return value is the same as the sqlite_last_statement_changes() API function.
-+*/
-+static void last_statement_change_count(sqlite_func *context, int arg,
-+                                        const char **argv){
-+  sqlite *db = sqlite_user_data(context);
-+  sqlite_set_result_int(context, sqlite_last_statement_changes(db));
-+}
-+
-+/*
-+** Implementation of the like() SQL function.  This function implements
-+** the build-in LIKE operator.  The first argument to the function is the
-+** string and the second argument is the pattern.  So, the SQL statements:
-+**
-+**       A LIKE B
-+**
-+** is implemented as like(A,B).
-+*/
-+static void likeFunc(sqlite_func *context, int arg, const char **argv){
-+  if( argv[0]==0 || argv[1]==0 ) return;
-+  sqlite_set_result_int(context, 
-+    sqliteLikeCompare((const unsigned char*)argv[0],
-+                      (const unsigned char*)argv[1]));
-+}
-+
-+/*
-+** Implementation of the glob() SQL function.  This function implements
-+** the build-in GLOB operator.  The first argument to the function is the
-+** string and the second argument is the pattern.  So, the SQL statements:
-+**
-+**       A GLOB B
-+**
-+** is implemented as glob(A,B).
-+*/
-+static void globFunc(sqlite_func *context, int arg, const char **argv){
-+  if( argv[0]==0 || argv[1]==0 ) return;
-+  sqlite_set_result_int(context,
-+    sqliteGlobCompare((const unsigned char*)argv[0],
-+                      (const unsigned char*)argv[1]));
-+}
-+
-+/*
-+** 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(sqlite_func *context, int argc, const char **argv){
-+  if( argv[0]!=0 && sqliteCompare(argv[0],argv[1])!=0 ){
-+    sqlite_set_result_string(context, argv[0], -1);
-+  }
-+}
-+
-+/*
-+** Implementation of the VERSION(*) function.  The result is the version
-+** of the SQLite library that is running.
-+*/
-+static void versionFunc(sqlite_func *context, int argc, const char **argv){
-+  sqlite_set_result_string(context, sqlite_version, -1);
-+}
-+
-+/*
-+** 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(sqlite_func *context, int argc, const char **argv){
-+  if( argc<1 ) return;
-+  if( argv[0]==0 ){
-+    sqlite_set_result_string(context, "NULL", 4);
-+  }else if( sqliteIsNumber(argv[0]) ){
-+    sqlite_set_result_string(context, argv[0], -1);
-+  }else{
-+    int i,j,n;
-+    char *z;
-+    for(i=n=0; argv[0][i]; i++){ if( argv[0][i]=='\'' ) n++; }
-+    z = sqliteMalloc( i+n+3 );
-+    if( z==0 ) return;
-+    z[0] = '\'';
-+    for(i=0, j=1; argv[0][i]; i++){
-+      z[j++] = argv[0][i];
-+      if( argv[0][i]=='\'' ){
-+        z[j++] = '\'';
-+      }
-+    }
-+    z[j++] = '\'';
-+    z[j] = 0;
-+    sqlite_set_result_string(context, z, j);
-+    sqliteFree(z);
-+  }
-+}
-+
-+#ifdef SQLITE_SOUNDEX
-+/*
-+** Compute the soundex encoding of a word.
-+*/
-+static void soundexFunc(sqlite_func *context, int argc, const char **argv){
-+  char zResult[8];
-+  const char *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 = argv[0];
-+  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
-+  if( zIn[i] ){
-+    zResult[0] = toupper(zIn[i]);
-+    for(j=1; j<4 && zIn[i]; i++){
-+      int code = iCode[zIn[i]&0x7f];
-+      if( code>0 ){
-+        zResult[j++] = code + '0';
-+      }
-+    }
-+    while( j<4 ){
-+      zResult[j++] = '0';
-+    }
-+    zResult[j] = 0;
-+    sqlite_set_result_string(context, zResult, 4);
-+  }else{
-+    sqlite_set_result_string(context, "?000", 4);
-+  }
-+}
-+#endif
-+
-+#ifdef SQLITE_TEST
-+/*
-+** This function generates a string of random characters.  Used for
-+** generating test data.
-+*/
-+static void randStr(sqlite_func *context, int argc, const char **argv){
-+  static const unsigned char zSrc[] = 
-+     "abcdefghijklmnopqrstuvwxyz"
-+     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+     "0123456789"
-+     ".-!,:*^+=_|?/<> ";
-+  int iMin, iMax, n, r, i;
-+  unsigned char zBuf[1000];
-+  if( argc>=1 ){
-+    iMin = atoi(argv[0]);
-+    if( iMin<0 ) iMin = 0;
-+    if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
-+  }else{
-+    iMin = 1;
-+  }
-+  if( argc>=2 ){
-+    iMax = atoi(argv[1]);
-+    if( iMax<iMin ) iMax = iMin;
-+    if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
-+  }else{
-+    iMax = 50;
-+  }
-+  n = iMin;
-+  if( iMax>iMin ){
-+    sqliteRandomness(sizeof(r), &r);
-+    r &= 0x7fffffff;
-+    n += r%(iMax + 1 - iMin);
-+  }
-+  assert( n<sizeof(zBuf) );
-+  sqliteRandomness(n, zBuf);
-+  for(i=0; i<n; i++){
-+    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
-+  }
-+  zBuf[n] = 0;
-+  sqlite_set_result_string(context, zBuf, n);
-+}
-+#endif
-+
-+/*
-+** An instance of the following structure holds the context of a
-+** sum() or avg() aggregate computation.
-+*/
-+typedef struct SumCtx SumCtx;
-+struct SumCtx {
-+  double sum;     /* Sum of terms */
-+  int cnt;        /* Number of elements summed */
-+};
-+
-+/*
-+** Routines used to compute the sum or average.
-+*/
-+static void sumStep(sqlite_func *context, int argc, const char **argv){
-+  SumCtx *p;
-+  if( argc<1 ) return;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p && argv[0] ){
-+    p->sum += sqliteAtoF(argv[0], 0);
-+    p->cnt++;
-+  }
-+}
-+static void sumFinalize(sqlite_func *context){
-+  SumCtx *p;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  sqlite_set_result_double(context, p ? p->sum : 0.0);
-+}
-+static void avgFinalize(sqlite_func *context){
-+  SumCtx *p;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p && p->cnt>0 ){
-+    sqlite_set_result_double(context, p->sum/(double)p->cnt);
-+  }
-+}
-+
-+/*
-+** An instance of the following structure holds the context of a
-+** variance or standard deviation computation.
-+*/
-+typedef struct StdDevCtx StdDevCtx;
-+struct StdDevCtx {
-+  double sum;     /* Sum of terms */
-+  double sum2;    /* Sum of the squares of terms */
-+  int cnt;        /* Number of terms counted */
-+};
-+
-+#if 0   /* Omit because math library is required */
-+/*
-+** Routines used to compute the standard deviation as an aggregate.
-+*/
-+static void stdDevStep(sqlite_func *context, int argc, const char **argv){
-+  StdDevCtx *p;
-+  double x;
-+  if( argc<1 ) return;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p && argv[0] ){
-+    x = sqliteAtoF(argv[0], 0);
-+    p->sum += x;
-+    p->sum2 += x*x;
-+    p->cnt++;
-+  }
-+}
-+static void stdDevFinalize(sqlite_func *context){
-+  double rN = sqlite_aggregate_count(context);
-+  StdDevCtx *p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p && p->cnt>1 ){
-+    double rCnt = cnt;
-+    sqlite_set_result_double(context, 
-+       sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0)));
-+  }
-+}
-+#endif
-+
-+/*
-+** The following structure keeps track of state information for the
-+** count() aggregate function.
-+*/
-+typedef struct CountCtx CountCtx;
-+struct CountCtx {
-+  int n;
-+};
-+
-+/*
-+** Routines to implement the count() aggregate function.
-+*/
-+static void countStep(sqlite_func *context, int argc, const char **argv){
-+  CountCtx *p;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( (argc==0 || argv[0]) && p ){
-+    p->n++;
-+  }
-+}   
-+static void countFinalize(sqlite_func *context){
-+  CountCtx *p;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  sqlite_set_result_int(context, p ? p->n : 0);
-+}
-+
-+/*
-+** This function tracks state information for the min() and max()
-+** aggregate functions.
-+*/
-+typedef struct MinMaxCtx MinMaxCtx;
-+struct MinMaxCtx {
-+  char *z;         /* The best so far */
-+  char zBuf[28];   /* Space that can be used for storage */
-+};
-+
-+/*
-+** Routines to implement min() and max() aggregate functions.
-+*/
-+static void minmaxStep(sqlite_func *context, int argc, const char **argv){
-+  MinMaxCtx *p;
-+  int (*xCompare)(const char*, const char*);
-+  int mask;    /* 0 for min() or 0xffffffff for max() */
-+
-+  assert( argc==2 );
-+  if( argv[0]==0 ) return;  /* Ignore NULL values */
-+  if( argv[1][0]=='n' ){
-+    xCompare = sqliteCompare;
-+  }else{
-+    xCompare = strcmp;
-+  }
-+  mask = (int)sqlite_user_data(context);
-+  assert( mask==0 || mask==-1 );
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p==0 || argc<1 ) return;
-+  if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
-+    int len;
-+    if( p->zBuf[0] ){
-+      sqliteFree(p->z);
-+    }
-+    len = strlen(argv[0]);
-+    if( len < sizeof(p->zBuf)-1 ){
-+      p->z = &p->zBuf[1];
-+      p->zBuf[0] = 0;
-+    }else{
-+      p->z = sqliteMalloc( len+1 );
-+      p->zBuf[0] = 1;
-+      if( p->z==0 ) return;
-+    }
-+    strcpy(p->z, argv[0]);
-+  }
-+}
-+static void minMaxFinalize(sqlite_func *context){
-+  MinMaxCtx *p;
-+  p = sqlite_aggregate_context(context, sizeof(*p));
-+  if( p && p->z && p->zBuf[0]<2 ){
-+    sqlite_set_result_string(context, p->z, strlen(p->z));
-+  }
-+  if( p && p->zBuf[0] ){
-+    sqliteFree(p->z);
-+  }
-+}
-+
-+/*
-+** This function registered all of the above C functions as SQL
-+** functions.  This should be the only routine in this file with
-+** external linkage.
-+*/
-+void sqliteRegisterBuiltinFunctions(sqlite *db){
-+  static struct {
-+     char *zName;
-+     signed char nArg;
-+     signed char dataType;
-+     u8 argType;               /* 0: none.  1: db  2: (-1) */
-+     void (*xFunc)(sqlite_func*,int,const char**);
-+  } aFuncs[] = {
-+    { "min",       -1, SQLITE_ARGS,    0, minmaxFunc },
-+    { "min",        0, 0,              0, 0          },
-+    { "max",       -1, SQLITE_ARGS,    2, minmaxFunc },
-+    { "max",        0, 0,              2, 0          },
-+    { "typeof",     1, SQLITE_TEXT,    0, typeofFunc },
-+    { "length",     1, SQLITE_NUMERIC, 0, lengthFunc },
-+    { "substr",     3, SQLITE_TEXT,    0, substrFunc },
-+    { "abs",        1, SQLITE_NUMERIC, 0, absFunc    },
-+    { "round",      1, SQLITE_NUMERIC, 0, roundFunc  },
-+    { "round",      2, SQLITE_NUMERIC, 0, roundFunc  },
-+    { "upper",      1, SQLITE_TEXT,    0, upperFunc  },
-+    { "lower",      1, SQLITE_TEXT,    0, lowerFunc  },
-+    { "coalesce",  -1, SQLITE_ARGS,    0, ifnullFunc },
-+    { "coalesce",   0, 0,              0, 0          },
-+    { "coalesce",   1, 0,              0, 0          },
-+    { "ifnull",     2, SQLITE_ARGS,    0, ifnullFunc },
-+    { "random",    -1, SQLITE_NUMERIC, 0, randomFunc },
-+    { "like",       2, SQLITE_NUMERIC, 0, likeFunc   },
-+    { "glob",       2, SQLITE_NUMERIC, 0, globFunc   },
-+    { "nullif",     2, SQLITE_ARGS,    0, nullifFunc },
-+    { "sqlite_version",0,SQLITE_TEXT,  0, versionFunc},
-+    { "quote",      1, SQLITE_ARGS,    0, quoteFunc  },
-+    { "last_insert_rowid", 0, SQLITE_NUMERIC, 1, last_insert_rowid },
-+    { "change_count",      0, SQLITE_NUMERIC, 1, change_count      },
-+    { "last_statement_change_count",
-+                           0, SQLITE_NUMERIC, 1, last_statement_change_count },
-+#ifdef SQLITE_SOUNDEX
-+    { "soundex",    1, SQLITE_TEXT,    0, soundexFunc},
-+#endif
-+#ifdef SQLITE_TEST
-+    { "randstr",    2, SQLITE_TEXT,    0, randStr    },
-+#endif
-+  };
-+  static struct {
-+    char *zName;
-+    signed char nArg;
-+    signed char dataType;
-+    u8 argType;
-+    void (*xStep)(sqlite_func*,int,const char**);
-+    void (*xFinalize)(sqlite_func*);
-+  } aAggs[] = {
-+    { "min",    1, 0,              0, minmaxStep,   minMaxFinalize },
-+    { "max",    1, 0,              2, minmaxStep,   minMaxFinalize },
-+    { "sum",    1, SQLITE_NUMERIC, 0, sumStep,      sumFinalize    },
-+    { "avg",    1, SQLITE_NUMERIC, 0, sumStep,      avgFinalize    },
-+    { "count",  0, SQLITE_NUMERIC, 0, countStep,    countFinalize  },
-+    { "count",  1, SQLITE_NUMERIC, 0, countStep,    countFinalize  },
-+#if 0
-+    { "stddev", 1, SQLITE_NUMERIC, 0, stdDevStep,   stdDevFinalize },
-+#endif
-+  };
-+  static const char *azTypeFuncs[] = { "min", "max", "typeof" };
-+  int i;
-+
-+  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-+    void *pArg;
-+    switch( aFuncs[i].argType ){
-+      case 0:  pArg = 0;           break;
-+      case 1:  pArg = db;          break;
-+      case 2:  pArg = (void*)(-1); break;
-+    }
-+    sqlite_create_function(db, aFuncs[i].zName,
-+           aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
-+    if( aFuncs[i].xFunc ){
-+      sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
-+    }
-+  }
-+  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
-+    void *pArg;
-+    switch( aAggs[i].argType ){
-+      case 0:  pArg = 0;           break;
-+      case 1:  pArg = db;          break;
-+      case 2:  pArg = (void*)(-1); break;
-+    }
-+    sqlite_create_aggregate(db, aAggs[i].zName,
-+           aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
-+    sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
-+  }
-+  for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){
-+    int n = strlen(azTypeFuncs[i]);
-+    FuncDef *p = sqliteHashFind(&db->aFunc, azTypeFuncs[i], n);
-+    while( p ){
-+      p->includeTypes = 1;
-+      p = p->pNext;
-+    }
-+  }
-+  sqliteRegisterDateTimeFunctions(db);
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/hash.c
-@@ -0,0 +1,356 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include <assert.h>
-+
-+/* Turn bulk memory into a hash table object by initializing the
-+** fields of the Hash structure.
-+**
-+** "new" is a pointer to the hash table that is to be initialized.
-+** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
-+** SQLITE_HASH_BINARY, or SQLITE_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.  CopyKey only makes
-+** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
-+** for other key classes.
-+*/
-+void sqliteHashInit(Hash *new, int keyClass, int copyKey){
-+  assert( new!=0 );
-+  assert( keyClass>=SQLITE_HASH_INT && keyClass<=SQLITE_HASH_BINARY );
-+  new->keyClass = keyClass;
-+  new->copyKey = copyKey &&
-+                (keyClass==SQLITE_HASH_STRING || keyClass==SQLITE_HASH_BINARY);
-+  new->first = 0;
-+  new->count = 0;
-+  new->htsize = 0;
-+  new->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.
-+*/
-+void sqliteHashClear(Hash *pH){
-+  HashElem *elem;         /* For looping over all elements of the table */
-+
-+  assert( pH!=0 );
-+  elem = pH->first;
-+  pH->first = 0;
-+  if( pH->ht ) sqliteFree(pH->ht);
-+  pH->ht = 0;
-+  pH->htsize = 0;
-+  while( elem ){
-+    HashElem *next_elem = elem->next;
-+    if( pH->copyKey && elem->pKey ){
-+      sqliteFree(elem->pKey);
-+    }
-+    sqliteFree(elem);
-+    elem = next_elem;
-+  }
-+  pH->count = 0;
-+}
-+
-+/*
-+** Hash and comparison functions when the mode is SQLITE_HASH_INT
-+*/
-+static int intHash(const void *pKey, int nKey){
-+  return nKey ^ (nKey<<8) ^ (nKey>>8);
-+}
-+static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
-+  return n2 - n1;
-+}
-+
-+#if 0 /* NOT USED */
-+/*
-+** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
-+*/
-+static int ptrHash(const void *pKey, int nKey){
-+  uptr x = Addr(pKey);
-+  return x ^ (x<<8) ^ (x>>8);
-+}
-+static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
-+  if( pKey1==pKey2 ) return 0;
-+  if( pKey1<pKey2 ) return -1;
-+  return 1;
-+}
-+#endif
-+
-+/*
-+** Hash and comparison functions when the mode is SQLITE_HASH_STRING
-+*/
-+static int strHash(const void *pKey, int nKey){
-+  return sqliteHashNoCase((const char*)pKey, nKey); 
-+}
-+static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
-+  if( n1!=n2 ) return n2-n1;
-+  return sqliteStrNICmp((const char*)pKey1,(const char*)pKey2,n1);
-+}
-+
-+/*
-+** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
-+*/
-+static int binHash(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 binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
-+  if( n1!=n2 ) return n2-n1;
-+  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 "hashFunction".  The function takes a
-+** single parameter "keyClass".  The return value of hashFunction()
-+** is a pointer to another function.  Specifically, the return value
-+** of hashFunction() is a pointer to a function that takes two parameters
-+** with types "const void*" and "int" and returns an "int".
-+*/
-+static int (*hashFunction(int keyClass))(const void*,int){
-+  switch( keyClass ){
-+    case SQLITE_HASH_INT:     return &intHash;
-+    /* case SQLITE_HASH_POINTER: return &ptrHash; // NOT USED */
-+    case SQLITE_HASH_STRING:  return &strHash;
-+    case SQLITE_HASH_BINARY:  return &binHash;;
-+    default: break;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** 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 (*compareFunction(int keyClass))(const void*,int,const void*,int){
-+  switch( keyClass ){
-+    case SQLITE_HASH_INT:     return &intCompare;
-+    /* case SQLITE_HASH_POINTER: return &ptrCompare; // NOT USED */
-+    case SQLITE_HASH_STRING:  return &strCompare;
-+    case SQLITE_HASH_BINARY:  return &binCompare;
-+    default: break;
-+  }
-+  return 0;
-+}
-+
-+
-+/* 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 rehash(Hash *pH, int new_size){
-+  struct _ht *new_ht;            /* The new hash table */
-+  HashElem *elem, *next_elem;    /* For looping over existing elements */
-+  HashElem *x;                   /* Element being copied to new hash table */
-+  int (*xHash)(const void*,int); /* The hash function */
-+
-+  assert( (new_size & (new_size-1))==0 );
-+  new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
-+  if( new_ht==0 ) return;
-+  if( pH->ht ) sqliteFree(pH->ht);
-+  pH->ht = new_ht;
-+  pH->htsize = new_size;
-+  xHash = hashFunction(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;
-+    x = new_ht[h].chain;
-+    if( x ){
-+      elem->next = x;
-+      elem->prev = x->prev;
-+      if( x->prev ) x->prev->next = elem;
-+      else          pH->first = elem;
-+      x->prev = elem;
-+    }else{
-+      elem->next = pH->first;
-+      if( pH->first ) pH->first->prev = elem;
-+      elem->prev = 0;
-+      pH->first = elem;
-+    }
-+    new_ht[h].chain = elem;
-+    new_ht[h].count++;
-+  }
-+}
-+
-+/* 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 void *pKey,   /* The key we are searching for */
-+  int nKey,
-+  int h               /* The hash for this key. */
-+){
-+  HashElem *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 ){
-+    elem = pH->ht[h].chain;
-+    count = pH->ht[h].count;
-+    xCompare = compareFunction(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 removeElementGivenHash(
-+  Hash *pH,         /* The pH containing "elem" */
-+  HashElem* elem,   /* The element to be removed from the pH */
-+  int h             /* Hash value for the element */
-+){
-+  if( elem->prev ){
-+    elem->prev->next = elem->next; 
-+  }else{
-+    pH->first = elem->next;
-+  }
-+  if( elem->next ){
-+    elem->next->prev = elem->prev;
-+  }
-+  if( pH->ht[h].chain==elem ){
-+    pH->ht[h].chain = elem->next;
-+  }
-+  pH->ht[h].count--;
-+  if( pH->ht[h].count<=0 ){
-+    pH->ht[h].chain = 0;
-+  }
-+  if( pH->copyKey && elem->pKey ){
-+    sqliteFree(elem->pKey);
-+  }
-+  sqliteFree( elem );
-+  pH->count--;
-+}
-+
-+/* 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.
-+*/
-+void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
-+  int h;             /* A hash on key */
-+  HashElem *elem;    /* The element that matches key */
-+  int (*xHash)(const void*,int);  /* The hash function */
-+
-+  if( pH==0 || pH->ht==0 ) return 0;
-+  xHash = hashFunction(pH->keyClass);
-+  assert( xHash!=0 );
-+  h = (*xHash)(pKey,nKey);
-+  assert( (pH->htsize & (pH->htsize-1))==0 );
-+  elem = findElementGivenHash(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.
-+*/
-+void *sqliteHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
-+  int hraw;             /* Raw hash value of the key */
-+  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 */
-+  int (*xHash)(const void*,int);  /* The hash function */
-+
-+  assert( pH!=0 );
-+  xHash = hashFunction(pH->keyClass);
-+  assert( xHash!=0 );
-+  hraw = (*xHash)(pKey, nKey);
-+  assert( (pH->htsize & (pH->htsize-1))==0 );
-+  h = hraw & (pH->htsize-1);
-+  elem = findElementGivenHash(pH,pKey,nKey,h);
-+  if( elem ){
-+    void *old_data = elem->data;
-+    if( data==0 ){
-+      removeElementGivenHash(pH,elem,h);
-+    }else{
-+      elem->data = data;
-+    }
-+    return old_data;
-+  }
-+  if( data==0 ) return 0;
-+  new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
-+  if( new_elem==0 ) return data;
-+  if( pH->copyKey && pKey!=0 ){
-+    new_elem->pKey = sqliteMallocRaw( nKey );
-+    if( new_elem->pKey==0 ){
-+      sqliteFree(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->htsize==0 ) rehash(pH,8);
-+  if( pH->htsize==0 ){
-+    pH->count = 0;
-+    sqliteFree(new_elem);
-+    return data;
-+  }
-+  if( pH->count > pH->htsize ){
-+    rehash(pH,pH->htsize*2);
-+  }
-+  assert( (pH->htsize & (pH->htsize-1))==0 );
-+  h = hraw & (pH->htsize-1);
-+  elem = pH->ht[h].chain;
-+  if( elem ){
-+    new_elem->next = elem;
-+    new_elem->prev = elem->prev;
-+    if( elem->prev ){ elem->prev->next = new_elem; }
-+    else            { pH->first = new_elem; }
-+    elem->prev = new_elem;
-+  }else{
-+    new_elem->next = pH->first;
-+    new_elem->prev = 0;
-+    if( pH->first ){ pH->first->prev = new_elem; }
-+    pH->first = new_elem;
-+  }
-+  pH->ht[h].count++;
-+  pH->ht[h].chain = new_elem;
-+  new_elem->data = data;
-+  return 0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/hash.h
-@@ -0,0 +1,109 @@
-+/*
-+** 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$
-+*/
-+#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, 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 Hash {
-+  char keyClass;          /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
-+  char copyKey;           /* True if copy of key made on insert */
-+  int count;              /* Number of entries in this table */
-+  HashElem *first;        /* The first element of the array */
-+  int htsize;             /* Number of buckets in the hash table */
-+  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 */
-+  void *pKey; int nKey;    /* Key associated with this element */
-+};
-+
-+/*
-+** There are 4 different modes of operation for a hash table:
-+**
-+**   SQLITE_HASH_INT         nKey is used as the key and pKey is ignored.
-+**
-+**   SQLITE_HASH_POINTER     pKey is used as the key and nKey is ignored.
-+**
-+**   SQLITE_HASH_STRING      pKey points to a string that is nKey bytes long
-+**                           (including the null-terminator, if any).  Case
-+**                           is ignored in comparisons.
-+**
-+**   SQLITE_HASH_BINARY      pKey points to binary data nKey bytes long. 
-+**                           memcmp() is used to compare keys.
-+**
-+** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
-+** if the copyKey parameter to HashInit is 1.  
-+*/
-+#define SQLITE_HASH_INT       1
-+/* #define SQLITE_HASH_POINTER   2 // NOT USED */
-+#define SQLITE_HASH_STRING    3
-+#define SQLITE_HASH_BINARY    4
-+
-+/*
-+** Access routines.  To delete, insert a NULL pointer.
-+*/
-+void sqliteHashInit(Hash*, int keytype, int copyKey);
-+void *sqliteHashInsert(Hash*, const void *pKey, int nKey, void *pData);
-+void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
-+void sqliteHashClear(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)
-+#define sqliteHashKeysize(E) ((E)->nKey)
-+
-+/*
-+** Number of entries in a hash table
-+*/
-+#define sqliteHashCount(H)  ((H)->count)
-+
-+#endif /* _SQLITE_HASH_H_ */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/insert.c
-@@ -0,0 +1,919 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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 three templates.  For a simple
-+** select with data coming from a VALUES clause, the code executes
-+** once straight down through.  The template looks like this:
-+**
-+**         open write cursor to <table> and its indices
-+**         puts VALUES clause expressions onto the stack
-+**         write the resulting record into <table>
-+**         cleanup
-+**
-+** If the statement is of the form
-+**
-+**   INSERT INTO <table> SELECT ...
-+**
-+** And the SELECT clause does not read from <table> at any time, then
-+** the generated code follows this template:
-+**
-+**         goto B
-+**      A: setup for the SELECT
-+**         loop over the tables in the SELECT
-+**           gosub C
-+**         end loop
-+**         cleanup after the SELECT
-+**         goto D
-+**      B: open write cursor to <table> and its indices
-+**         goto A
-+**      C: insert the select result into <table>
-+**         return
-+**      D: cleanup
-+**
-+** The third 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:
-+**
-+**         goto B
-+**      A: setup for the SELECT
-+**         loop over the tables in the SELECT
-+**           gosub C
-+**         end loop
-+**         cleanup after the SELECT
-+**         goto D
-+**      C: insert the select result into the intermediate table
-+**         return
-+**      B: open a cursor to an intermediate table
-+**         goto A
-+**      D: open write cursor to <table> and its indices
-+**         loop over the intermediate table
-+**           transfer values form intermediate table into <table>
-+**         end the loop
-+**         cleanup
-+*/
-+void sqliteInsert(
-+  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 */
-+){
-+  Table *pTab;          /* The table to insert into */
-+  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 base;             /* VDBE Cursor number for pTab */
-+  int iCont, iBreak;    /* Beginning and end of the loop over srcTab */
-+  sqlite *db;           /* The main database structure */
-+  int keyColumn = -1;   /* Column that is the INTEGER PRIMARY KEY */
-+  int endOfLoop;        /* Label for the end of the insertion loop */
-+  int useTempTable;     /* Store SELECT results in intermediate table */
-+  int srcTab;           /* Data comes from this temporary cursor if >=0 */
-+  int iSelectLoop;      /* Address of code that implements the SELECT */
-+  int iCleanup;         /* Address of the cleanup code */
-+  int iInsertBlock;     /* Address of the subroutine used to insert data */
-+  int iCntMem;          /* Memory cell used for the row counter */
-+  int isView;           /* True if attempting to insert into a view */
-+
-+  int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */
-+  int before_triggers;        /* True if there are BEFORE triggers */
-+  int after_triggers;         /* True if there are AFTER triggers */
-+  int newIdx = -1;            /* Cursor for the NEW table */
-+
-+  if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
-+  db = pParse->db;
-+
-+  /* Locate the table into which we will be inserting new information.
-+  */
-+  assert( pTabList->nSrc==1 );
-+  zTab = pTabList->a[0].zName;
-+  if( zTab==0 ) goto insert_cleanup;
-+  pTab = sqliteSrcListLookup(pParse, pTabList);
-+  if( pTab==0 ){
-+    goto insert_cleanup;
-+  }
-+  assert( pTab->iDb<db->nDb );
-+  zDb = db->aDb[pTab->iDb].zName;
-+  if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
-+    goto insert_cleanup;
-+  }
-+
-+  /* Ensure that:
-+  *  (a) the table is not read-only, 
-+  *  (b) that if it is a view then ON INSERT triggers exist
-+  */
-+  before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT, 
-+                                       TK_BEFORE, TK_ROW, 0);
-+  after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
-+                                       TK_AFTER, TK_ROW, 0);
-+  row_triggers_exist = before_triggers || after_triggers;
-+  isView = pTab->pSelect!=0;
-+  if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
-+    goto insert_cleanup;
-+  }
-+  if( pTab==0 ) goto insert_cleanup;
-+
-+  /* If pTab is really a view, make sure it has been initialized.
-+  */
-+  if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
-+    goto insert_cleanup;
-+  }
-+
-+  /* Allocate a VDBE
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) goto insert_cleanup;
-+  sqliteBeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
-+
-+  /* if there are row triggers, allocate a temp table for new.* references. */
-+  if( row_triggers_exist ){
-+    newIdx = pParse->nTab++;
-+  }
-+
-+  /* Figure out how many columns of data are supplied.  If the data
-+  ** is coming from a SELECT statement, then this step also generates
-+  ** all the code to implement the SELECT statement and invoke a subroutine
-+  ** to process each row of the result. (Template 2.) If the SELECT
-+  ** statement uses the the table that is being inserted into, then the
-+  ** subroutine is also coded here.  That subroutine stores the SELECT
-+  ** results in a temporary table. (Template 3.)
-+  */
-+  if( pSelect ){
-+    /* Data is coming from a SELECT.  Generate code to implement that SELECT
-+    */
-+    int rc, iInitCode;
-+    iInitCode = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
-+    iSelectLoop = sqliteVdbeCurrentAddr(v);
-+    iInsertBlock = sqliteVdbeMakeLabel(v);
-+    rc = sqliteSelect(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0);
-+    if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
-+    iCleanup = sqliteVdbeMakeLabel(v);
-+    sqliteVdbeAddOp(v, OP_Goto, 0, iCleanup);
-+    assert( pSelect->pEList );
-+    nColumn = pSelect->pEList->nExpr;
-+
-+    /* Set useTempTable to TRUE if the result of the SELECT statement
-+    ** should be written into a temporary table.  Set to FALSE if each
-+    ** row of the SELECT can be written directly into the result table.
-+    **
-+    ** 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( row_triggers_exist ){
-+      useTempTable = 1;
-+    }else{
-+      int addr = sqliteVdbeFindOp(v, OP_OpenRead, pTab->tnum);
-+      useTempTable = 0;
-+      if( addr>0 ){
-+        VdbeOp *pOp = sqliteVdbeGetOp(v, addr-2);
-+        if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){
-+          useTempTable = 1;
-+        }
-+      }
-+    }
-+
-+    if( useTempTable ){
-+      /* Generate the subroutine that SELECT calls to process each row of
-+      ** the result.  Store the result in a temporary table
-+      */
-+      srcTab = pParse->nTab++;
-+      sqliteVdbeResolveLabel(v, iInsertBlock);
-+      sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
-+      sqliteVdbeAddOp(v, OP_NewRecno, srcTab, 0);
-+      sqliteVdbeAddOp(v, OP_Pull, 1, 0);
-+      sqliteVdbeAddOp(v, OP_PutIntKey, srcTab, 0);
-+      sqliteVdbeAddOp(v, OP_Return, 0, 0);
-+
-+      /* The following code runs first because the GOTO at the very top
-+      ** of the program jumps to it.  Create the temporary table, then jump
-+      ** back up and execute the SELECT code above.
-+      */
-+      sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
-+      sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
-+      sqliteVdbeResolveLabel(v, iCleanup);
-+    }else{
-+      sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
-+    }
-+  }else{
-+    /* This is the case if the data for the INSERT is coming from a VALUES
-+    ** clause
-+    */
-+    SrcList dummy;
-+    assert( pList!=0 );
-+    srcTab = -1;
-+    useTempTable = 0;
-+    assert( pList );
-+    nColumn = pList->nExpr;
-+    dummy.nSrc = 0;
-+    for(i=0; i<nColumn; i++){
-+      if( sqliteExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
-+        goto insert_cleanup;
-+      }
-+      if( sqliteExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
-+        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( pColumn==0 && nColumn!=pTab->nCol ){
-+    sqliteErrorMsg(pParse, 
-+       "table %S has %d columns but %d values were supplied",
-+       pTabList, 0, pTab->nCol, nColumn);
-+    goto insert_cleanup;
-+  }
-+  if( pColumn!=0 && nColumn!=pColumn->nId ){
-+    sqliteErrorMsg(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( sqliteStrICmp(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( sqliteIsRowid(pColumn->a[i].zName) ){
-+          keyColumn = i;
-+        }else{
-+          sqliteErrorMsg(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 ){
-+    keyColumn = pTab->iPKey;
-+  }
-+
-+  /* Open the temp table for FOR EACH ROW triggers
-+  */
-+  if( row_triggers_exist ){
-+    sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
-+  }
-+    
-+  /* Initialize the count of rows to be inserted
-+  */
-+  if( db->flags & SQLITE_CountRows ){
-+    iCntMem = pParse->nMem++;
-+    sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+    sqliteVdbeAddOp(v, OP_MemStore, iCntMem, 1);
-+  }
-+
-+  /* Open tables and indices if there are no row triggers */
-+  if( !row_triggers_exist ){
-+    base = pParse->nTab;
-+    idx = sqliteOpenTableAndIndices(pParse, pTab, base);
-+    pParse->nTab += idx;
-+  }
-+
-+  /* If the data source is a temporary table, then we have to create
-+  ** a loop because there might be multiple rows of data.  If the data
-+  ** source is a subroutine call from the SELECT statement, then we need
-+  ** to launch the SELECT statement processing.
-+  */
-+  if( useTempTable ){
-+    iBreak = sqliteVdbeMakeLabel(v);
-+    sqliteVdbeAddOp(v, OP_Rewind, srcTab, iBreak);
-+    iCont = sqliteVdbeCurrentAddr(v);
-+  }else if( pSelect ){
-+    sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
-+    sqliteVdbeResolveLabel(v, iInsertBlock);
-+  }
-+
-+  /* Run the BEFORE and INSTEAD OF triggers, if there are any
-+  */
-+  endOfLoop = sqliteVdbeMakeLabel(v);
-+  if( before_triggers ){
-+
-+    /* 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 ){
-+      sqliteVdbeAddOp(v, OP_Integer, -1, 0);
-+    }else if( useTempTable ){
-+      sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
-+    }else if( pSelect ){
-+      sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
-+    }else{
-+      sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Integer, -1, 0);
-+      sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
-+    }
-+
-+    /* 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 ){
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
-+      }else if( useTempTable ){
-+        sqliteVdbeAddOp(v, OP_Column, srcTab, j); 
-+      }else if( pSelect ){
-+        sqliteVdbeAddOp(v, OP_Dup, nColumn-j-1, 1);
-+      }else{
-+        sqliteExprCode(pParse, pList->a[j].pExpr);
-+      }
-+    }
-+    sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
-+
-+    /* Fire BEFORE or INSTEAD OF triggers */
-+    if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, 
-+        newIdx, -1, onError, endOfLoop) ){
-+      goto insert_cleanup;
-+    }
-+  }
-+
-+  /* If any triggers exists, the opening of tables and indices is deferred
-+  ** until now.
-+  */
-+  if( row_triggers_exist && !isView ){
-+    base = pParse->nTab;
-+    idx = sqliteOpenTableAndIndices(pParse, pTab, base);
-+    pParse->nTab += idx;
-+  }
-+
-+  /* Push the record number for the new entry onto the stack.  The
-+  ** record number is a randomly generate integer created by NewRecno
-+  ** 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( keyColumn>=0 ){
-+      if( useTempTable ){
-+        sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
-+      }else if( pSelect ){
-+        sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
-+      }else{
-+        sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
-+      }
-+      /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
-+      ** to generate a unique primary key value.
-+      */
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
-+      sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
-+    }else{
-+      sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
-+    }
-+
-+    /* Push onto the stack, data for all columns of the new entry, beginning
-+    ** with the first column.
-+    */
-+    for(i=0; i<pTab->nCol; 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. */
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+        continue;
-+      }
-+      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 ){
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
-+      }else if( useTempTable ){
-+        sqliteVdbeAddOp(v, OP_Column, srcTab, j); 
-+      }else if( pSelect ){
-+        sqliteVdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
-+      }else{
-+        sqliteExprCode(pParse, pList->a[j].pExpr);
-+      }
-+    }
-+
-+    /* Generate code to check constraints and generate index keys and
-+    ** do the insertion.
-+    */
-+    sqliteGenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
-+                                   0, onError, endOfLoop);
-+    sqliteCompleteInsertion(pParse, pTab, base, 0,0,0,
-+                            after_triggers ? newIdx : -1);
-+  }
-+
-+  /* Update the count of rows that are inserted
-+  */
-+  if( (db->flags & SQLITE_CountRows)!=0 ){
-+    sqliteVdbeAddOp(v, OP_MemIncr, iCntMem, 0);
-+  }
-+
-+  if( row_triggers_exist ){
-+    /* Close all tables opened */
-+    if( !isView ){
-+      sqliteVdbeAddOp(v, OP_Close, base, 0);
-+      for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
-+        sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
-+      }
-+    }
-+
-+    /* Code AFTER triggers */
-+    if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1, 
-+          onError, endOfLoop) ){
-+      goto insert_cleanup;
-+    }
-+  }
-+
-+  /* The bottom of the loop, if the data source is a SELECT statement
-+  */
-+  sqliteVdbeResolveLabel(v, endOfLoop);
-+  if( useTempTable ){
-+    sqliteVdbeAddOp(v, OP_Next, srcTab, iCont);
-+    sqliteVdbeResolveLabel(v, iBreak);
-+    sqliteVdbeAddOp(v, OP_Close, srcTab, 0);
-+  }else if( pSelect ){
-+    sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
-+    sqliteVdbeAddOp(v, OP_Return, 0, 0);
-+    sqliteVdbeResolveLabel(v, iCleanup);
-+  }
-+
-+  if( !row_triggers_exist ){
-+    /* Close all tables opened */
-+    sqliteVdbeAddOp(v, OP_Close, base, 0);
-+    for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
-+      sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
-+    }
-+  }
-+
-+  sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
-+  sqliteEndWriteOperation(pParse);
-+
-+  /*
-+  ** Return the number of rows inserted.
-+  */
-+  if( db->flags & SQLITE_CountRows ){
-+    sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
-+    sqliteVdbeAddOp(v, OP_MemLoad, iCntMem, 0);
-+    sqliteVdbeAddOp(v, OP_Callback, 1, 0);
-+  }
-+
-+insert_cleanup:
-+  sqliteSrcListDelete(pTabList);
-+  if( pList ) sqliteExprListDelete(pList);
-+  if( pSelect ) sqliteSelectDelete(pSelect);
-+  sqliteIdListDelete(pColumn);
-+}
-+
-+/*
-+** Generate code to do a constraint check prior to an INSERT or an UPDATE.
-+**
-+** When this routine is called, the stack contains (from bottom to top)
-+** the following values:
-+**
-+**    1.  The recno of the row to be updated before the update.  This
-+**        value is omitted unless we are doing an UPDATE that involves a
-+**        change to the record number.
-+**
-+**    2.  The recno of the row after the update.
-+**
-+**    3.  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 old recno shown as entry (1) above is omitted unless both isUpdate
-+** and recnoChng are 1.  isUpdate is true for UPDATEs and false for
-+** INSERTs and recnoChng is true if the record number is being changed.
-+**
-+** The code generated by this routine pushes additional entries onto
-+** the stack which are the keys for new index entries for the new record.
-+** The order of index keys is the same as the order of the indices on
-+** the pTable->pIndex list.  A key is only created for index i if 
-+** aIdxUsed!=0 and aIdxUsed[i]!=0.
-+**
-+** 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
-+**                                sqlite_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 sqlite_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 "base".  All indices of pTab must also have open
-+** read/write cursors with cursor number base+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 aIdxUsed[i]==0.
-+**
-+** If the isUpdate flag is true, it means that the "base" cursor is
-+** initially pointing to an entry that is being updated.  The isUpdate
-+** flag causes extra code to be generated so that the "base" cursor
-+** is still pointing at the same entry after the routine returns.
-+** Without the isUpdate flag, the "base" cursor might be moved.
-+*/
-+void sqliteGenerateConstraintChecks(
-+  Parse *pParse,      /* The parser context */
-+  Table *pTab,        /* the table into which we are inserting */
-+  int base,           /* Index of a read/write cursor pointing at pTab */
-+  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
-+  int recnoChng,      /* True if the record number will change */
-+  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 i;
-+  Vdbe *v;
-+  int nCol;
-+  int onError;
-+  int addr;
-+  int extra;
-+  int iCur;
-+  Index *pIdx;
-+  int seenReplace = 0;
-+  int jumpInst1, jumpInst2;
-+  int contAddr;
-+  int hasTwoRecnos = (isUpdate && recnoChng);
-+
-+  v = sqliteGetVdbe(pParse);
-+  assert( v!=0 );
-+  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
-+  nCol = pTab->nCol;
-+
-+  /* 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( pParse->db->onError!=OE_Default ){
-+      onError = pParse->db->onError;
-+    }else if( onError==OE_Default ){
-+      onError = OE_Abort;
-+    }
-+    if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){
-+      onError = OE_Abort;
-+    }
-+    sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1);
-+    addr = sqliteVdbeAddOp(v, OP_NotNull, 1, 0);
-+    switch( onError ){
-+      case OE_Rollback:
-+      case OE_Abort:
-+      case OE_Fail: {
-+        char *zMsg = 0;
-+        sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
-+        sqliteSetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
-+                        " may not be NULL", (char*)0);
-+        sqliteVdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
-+        break;
-+      }
-+      case OE_Ignore: {
-+        sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
-+        break;
-+      }
-+      case OE_Replace: {
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
-+        sqliteVdbeAddOp(v, OP_Push, nCol-i, 0);
-+        break;
-+      }
-+      default: assert(0);
-+    }
-+    sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
-+  }
-+
-+  /* Test all CHECK constraints
-+  */
-+  /**** TBD ****/
-+
-+  /* 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( recnoChng ){
-+    onError = pTab->keyConf;
-+    if( overrideError!=OE_Default ){
-+      onError = overrideError;
-+    }else if( pParse->db->onError!=OE_Default ){
-+      onError = pParse->db->onError;
-+    }else if( onError==OE_Default ){
-+      onError = OE_Abort;
-+    }
-+    
-+    if( isUpdate ){
-+      sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
-+      sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
-+      jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
-+    }
-+    sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
-+    jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
-+    switch( onError ){
-+      default: {
-+        onError = OE_Abort;
-+        /* Fall thru into the next case */
-+      }
-+      case OE_Rollback:
-+      case OE_Abort:
-+      case OE_Fail: {
-+        sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
-+                         "PRIMARY KEY must be unique", P3_STATIC);
-+        break;
-+      }
-+      case OE_Replace: {
-+        sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
-+        if( isUpdate ){
-+          sqliteVdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
-+          sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
-+        }
-+        seenReplace = 1;
-+        break;
-+      }
-+      case OE_Ignore: {
-+        assert( seenReplace==0 );
-+        sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
-+        break;
-+      }
-+    }
-+    contAddr = sqliteVdbeCurrentAddr(v);
-+    sqliteVdbeChangeP2(v, jumpInst2, contAddr);
-+    if( isUpdate ){
-+      sqliteVdbeChangeP2(v, jumpInst1, contAddr);
-+      sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
-+      sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
-+    }
-+  }
-+
-+  /* 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.
-+  */
-+  extra = -1;
-+  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
-+    if( aIdxUsed && aIdxUsed[iCur]==0 ) continue;  /* Skip unused indices */
-+    extra++;
-+
-+    /* Create a key for accessing the index entry */
-+    sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1);
-+    for(i=0; i<pIdx->nColumn; i++){
-+      int idx = pIdx->aiColumn[i];
-+      if( idx==pTab->iPKey ){
-+        sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
-+      }
-+    }
-+    jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
-+    if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
-+
-+    /* Find out what action to take in case there is an indexing conflict */
-+    onError = pIdx->onError;
-+    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
-+    if( overrideError!=OE_Default ){
-+      onError = overrideError;
-+    }else if( pParse->db->onError!=OE_Default ){
-+      onError = pParse->db->onError;
-+    }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 */
-+    sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
-+    jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
-+
-+    /* Generate code that executes if the new index entry is not unique */
-+    switch( onError ){
-+      case OE_Rollback:
-+      case OE_Abort:
-+      case OE_Fail: {
-+        int j, n1, n2;
-+        char zErrMsg[200];
-+        strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
-+        n1 = strlen(zErrMsg);
-+        for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
-+          char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
-+          n2 = strlen(zCol);
-+          if( j>0 ){
-+            strcpy(&zErrMsg[n1], ", ");
-+            n1 += 2;
-+          }
-+          if( n1+n2>sizeof(zErrMsg)-30 ){
-+            strcpy(&zErrMsg[n1], "...");
-+            n1 += 3;
-+            break;
-+          }else{
-+            strcpy(&zErrMsg[n1], zCol);
-+            n1 += n2;
-+          }
-+        }
-+        strcpy(&zErrMsg[n1], 
-+            pIdx->nColumn>1 ? " are not unique" : " is not unique");
-+        sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
-+        break;
-+      }
-+      case OE_Ignore: {
-+        assert( seenReplace==0 );
-+        sqliteVdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
-+        break;
-+      }
-+      case OE_Replace: {
-+        sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0);
-+        if( isUpdate ){
-+          sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
-+          sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
-+        }
-+        seenReplace = 1;
-+        break;
-+      }
-+      default: assert(0);
-+    }
-+    contAddr = sqliteVdbeCurrentAddr(v);
-+#if NULL_DISTINCT_FOR_UNIQUE
-+    sqliteVdbeChangeP2(v, jumpInst1, contAddr);
-+#endif
-+    sqliteVdbeChangeP2(v, jumpInst2, contAddr);
-+  }
-+}
-+
-+/*
-+** This routine generates code to finish the INSERT or UPDATE operation
-+** that was started by a prior call to sqliteGenerateConstraintChecks.
-+** The stack must contain keys for all active indices followed by data
-+** and the recno for the new entry.  This routine creates the new
-+** entries in all indices and in the main table.
-+**
-+** The arguments to this routine should be the same as the first six
-+** arguments to sqliteGenerateConstraintChecks.
-+*/
-+void sqliteCompleteInsertion(
-+  Parse *pParse,      /* The parser context */
-+  Table *pTab,        /* the table into which we are inserting */
-+  int base,           /* Index of a read/write cursor pointing at pTab */
-+  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
-+  int recnoChng,      /* True if the record number will change */
-+  int isUpdate,       /* True for UPDATE, False for INSERT */
-+  int newIdx          /* Index of NEW table for triggers.  -1 if none */
-+){
-+  int i;
-+  Vdbe *v;
-+  int nIdx;
-+  Index *pIdx;
-+
-+  v = sqliteGetVdbe(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( aIdxUsed && aIdxUsed[i]==0 ) continue;
-+    sqliteVdbeAddOp(v, OP_IdxPut, base+i+1, 0);
-+  }
-+  sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
-+  if( newIdx>=0 ){
-+    sqliteVdbeAddOp(v, OP_Dup, 1, 0);
-+    sqliteVdbeAddOp(v, OP_Dup, 1, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
-+  }
-+  sqliteVdbeAddOp(v, OP_PutIntKey, base,
-+    (pParse->trigStack?0:OPFLAG_NCHANGE) |
-+    (isUpdate?0:OPFLAG_LASTROWID) | OPFLAG_CSCHANGE);
-+  if( isUpdate && recnoChng ){
-+    sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+  }
-+}
-+
-+/*
-+** Generate code that will open write cursors for a table and for all
-+** indices of that table.  The "base" parameter is the cursor number used
-+** for the table.  Indices are opened on subsequent cursors.
-+**
-+** Return the total number of cursors opened.  This is always at least
-+** 1 (for the main table) plus more for each cursor.
-+*/
-+int sqliteOpenTableAndIndices(Parse *pParse, Table *pTab, int base){
-+  int i;
-+  Index *pIdx;
-+  Vdbe *v = sqliteGetVdbe(pParse);
-+  assert( v!=0 );
-+  sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+  sqliteVdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
-+  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
-+    sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
-+    sqliteVdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
-+  }
-+  return i;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/libsqlite.dsp
-@@ -0,0 +1,353 @@
-+# Microsoft Developer Studio Project File - Name="libsqlite" - Package Owner=<4>\r
-+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
-+# ** DO NOT EDIT **\r
-+\r
-+# TARGTYPE "Win32 (x86) Static Library" 0x0104\r
-+\r
-+CFG=libsqlite - Win32 Debug_TS\r
-+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-+!MESSAGE use the Export Makefile command and run\r
-+!MESSAGE \r
-+!MESSAGE NMAKE /f "libsqlite.mak".\r
-+!MESSAGE \r
-+!MESSAGE You can specify a configuration when running NMAKE\r
-+!MESSAGE by defining the macro CFG on the command line. For example:\r
-+!MESSAGE \r
-+!MESSAGE NMAKE /f "libsqlite.mak" CFG="libsqlite - Win32 Debug_TS"\r
-+!MESSAGE \r
-+!MESSAGE Possible choices for configuration are:\r
-+!MESSAGE \r
-+!MESSAGE "libsqlite - Win32 Debug_TS" (based on "Win32 (x86) Static Library")\r
-+!MESSAGE "libsqlite - Win32 Release_TS" (based on "Win32 (x86) Static Library")\r
-+!MESSAGE "libsqlite - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")\r
-+!MESSAGE \r
-+\r
-+# Begin Project\r
-+# PROP AllowPerConfigDependencies 0\r
-+# PROP Scc_ProjName ""\r
-+# PROP Scc_LocalPath ""\r
-+CPP=cl.exe\r
-+RSC=rc.exe\r
-+\r
-+!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"\r
-+\r
-+# PROP BASE Use_MFC 0\r
-+# PROP BASE Use_Debug_Libraries 1\r
-+# PROP BASE Output_Dir "Debug_TS"\r
-+# PROP BASE Intermediate_Dir "Debug_TS"\r
-+# PROP BASE Target_Dir ""\r
-+# PROP Use_MFC 0\r
-+# PROP Use_Debug_Libraries 1\r
-+# PROP Output_Dir "..\..\Debug_TS"\r
-+# PROP Intermediate_Dir "..\..\Debug_TS"\r
-+# PROP Target_Dir ""\r
-+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c\r
-+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /GZ /c\r
-+# ADD BASE RSC /l 0x406 /d "_DEBUG"\r
-+# ADD RSC /l 0x406 /d "_DEBUG"\r
-+BSC32=bscmake.exe\r
-+# ADD BASE BSC32 /nologo\r
-+# ADD BSC32 /nologo\r
-+LIB32=link.exe -lib\r
-+# ADD BASE LIB32 /nologo\r
-+# ADD LIB32 /nologo\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"\r
-+\r
-+# PROP BASE Use_MFC 0\r
-+# PROP BASE Use_Debug_Libraries 0\r
-+# PROP BASE Output_Dir "Release_TS"\r
-+# PROP BASE Intermediate_Dir "Release_TS"\r
-+# PROP BASE Target_Dir ""\r
-+# PROP Use_MFC 0\r
-+# PROP Use_Debug_Libraries 0\r
-+# PROP Output_Dir "..\..\Release_TS"\r
-+# PROP Intermediate_Dir "..\..\Release_TS"\r
-+# PROP Target_Dir ""\r
-+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c\r
-+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c\r
-+# ADD BASE RSC /l 0x406 /d "NDEBUG"\r
-+# ADD RSC /l 0x406 /d "NDEBUG"\r
-+BSC32=bscmake.exe\r
-+# ADD BASE BSC32 /nologo\r
-+# ADD BSC32 /nologo\r
-+LIB32=link.exe -lib\r
-+# ADD BASE LIB32 /nologo\r
-+# ADD LIB32 /nologo\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"\r
-+\r
-+# PROP BASE Use_MFC 0\r
-+# PROP BASE Use_Debug_Libraries 0\r
-+# PROP BASE Output_Dir "libsqlite___Win32_Release_TSDbg"\r
-+# PROP BASE Intermediate_Dir "libsqlite___Win32_Release_TSDbg"\r
-+# PROP BASE Target_Dir ""\r
-+# PROP Use_MFC 0\r
-+# PROP Use_Debug_Libraries 0\r
-+# PROP Output_Dir "..\..\Release_TSDbg"\r
-+# PROP Intermediate_Dir "..\..\Release_TSDbg"\r
-+# PROP Target_Dir ""\r
-+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c\r
-+# ADD CPP /nologo /MD /W3 /GX /Zi /Od /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D THREADSAFE=1 /YX /FD /c\r
-+# ADD BASE RSC /l 0x406 /d "NDEBUG"\r
-+# ADD RSC /l 0x406 /d "NDEBUG"\r
-+BSC32=bscmake.exe\r
-+# ADD BASE BSC32 /nologo\r
-+# ADD BSC32 /nologo\r
-+LIB32=link.exe -lib\r
-+# ADD BASE LIB32 /nologo /out:"Release_TS\libsqlite.lib"\r
-+# ADD LIB32 /nologo\r
-+\r
-+!ENDIF \r
-+\r
-+# Begin Target\r
-+\r
-+# Name "libsqlite - Win32 Debug_TS"\r
-+# Name "libsqlite - Win32 Release_TS"\r
-+# Name "libsqlite - Win32 Release_TSDbg"\r
-+# Begin Group "Source Files"\r
-+\r
-+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
-+# Begin Source File\r
-+\r
-+SOURCE=attach.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=auth.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=btree.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=btree_rb.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=build.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=copy.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\date.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=delete.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=encode.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=expr.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=func.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=hash.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=insert.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=main.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=opcodes.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=os.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=pager.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=parse.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=pragma.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=printf.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=random.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=select.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=table.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=tokenize.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=trigger.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=update.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=util.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=vacuum.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=vdbe.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\vdbeaux.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=where.c\r
-+# End Source File\r
-+# End Group\r
-+# Begin Group "Header Files"\r
-+\r
-+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
-+# Begin Source File\r
-+\r
-+SOURCE=btree.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=config_static.w32.h\r
-+\r
-+!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=config_static.w32.h\r
-+\r
-+"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\config.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=config_static.w32.h\r
-+\r
-+"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\config.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=config_static.w32.h\r
-+\r
-+"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\config.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ENDIF \r
-+\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=hash.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=opcodes.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=os.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=pager.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=parse.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=sqlite.w32.h\r
-+\r
-+!IF  "$(CFG)" == "libsqlite - Win32 Debug_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=sqlite.w32.h\r
-+\r
-+"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\sqlite.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=sqlite.w32.h\r
-+\r
-+"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\sqlite.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "libsqlite - Win32 Release_TSDbg"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\r
-+InputPath=sqlite.w32.h\r
-+\r
-+"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\sqlite.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ENDIF \r
-+\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=sqliteInt.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=vdbe.h\r
-+# End Source File\r
-+# End Group\r
-+# End Target\r
-+# End Project\r
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/main.c
-@@ -0,0 +1,1143 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+#include <ctype.h>
-+
-+/*
-+** A pointer to this structure is used to communicate information
-+** from sqliteInit into the sqliteInitCallback.
-+*/
-+typedef struct {
-+  sqlite *db;         /* The database being initialized */
-+  char **pzErrMsg;    /* Error message stored here */
-+} InitData;
-+
-+/*
-+** Fill the InitData structure with an error message that indicates
-+** that the database is corrupt.
-+*/
-+static void corruptSchema(InitData *pData, const char *zExtra){
-+  sqliteSetString(pData->pzErrMsg, "malformed database schema",
-+     zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
-+}
-+
-+/*
-+** This is the callback routine for the code that initializes the
-+** database.  See sqliteInit() below for additional information.
-+**
-+** Each callback contains the following information:
-+**
-+**     argv[0] = "file-format" or "schema-cookie" or "table" or "index"
-+**     argv[1] = table or index name or meta statement type.
-+**     argv[2] = root page number for table or index.  NULL for meta.
-+**     argv[3] = SQL text for a CREATE TABLE or CREATE INDEX statement.
-+**     argv[4] = "1" for temporary files, "0" for main database, "2" or more
-+**               for auxiliary database files.
-+**
-+*/
-+static
-+int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
-+  InitData *pData = (InitData*)pInit;
-+  int nErr = 0;
-+
-+  assert( argc==5 );
-+  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
-+  if( argv[0]==0 ){
-+    corruptSchema(pData, 0);
-+    return 1;
-+  }
-+  switch( argv[0][0] ){
-+    case 'v':
-+    case 'i':
-+    case 't': {  /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
-+      sqlite *db = pData->db;
-+      if( argv[2]==0 || argv[4]==0 ){
-+        corruptSchema(pData, 0);
-+        return 1;
-+      }
-+      if( argv[3] && argv[3][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;
-+        assert( db->init.busy );
-+        db->init.iDb = atoi(argv[4]);
-+        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
-+        db->init.newTnum = atoi(argv[2]);
-+        if( sqlite_exec(db, argv[3], 0, 0, &zErr) ){
-+          corruptSchema(pData, zErr);
-+          sqlite_freemem(zErr);
-+        }
-+        db->init.iDb = 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.
-+        */
-+        int iDb;
-+        Index *pIndex;
-+
-+        iDb = atoi(argv[4]);
-+        assert( iDb>=0 && iDb<db->nDb );
-+        pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName);
-+        if( pIndex==0 || pIndex->tnum!=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{
-+          pIndex->tnum = atoi(argv[2]);
-+        }
-+      }
-+      break;
-+    }
-+    default: {
-+      /* This can not happen! */
-+      nErr = 1;
-+      assert( nErr==0 );
-+    }
-+  }
-+  return nErr;
-+}
-+
-+/*
-+** This is a callback procedure used to reconstruct a table.  The
-+** name of the table to be reconstructed is passed in as argv[0].
-+**
-+** This routine is used to automatically upgrade a database from
-+** format version 1 or 2 to version 3.  The correct operation of
-+** this routine relys on the fact that no indices are used when
-+** copying a table out to a temporary file.
-+**
-+** The change from version 2 to version 3 occurred between SQLite
-+** version 2.5.6 and 2.6.0 on 2002-July-18.  
-+*/
-+static
-+int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
-+  InitData *pData = (InitData*)pInit;
-+  int rc;
-+  Table *pTab;
-+  Trigger *pTrig;
-+  char *zErr = 0;
-+
-+  pTab = sqliteFindTable(pData->db, argv[0], 0);
-+  assert( pTab!=0 );
-+  assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
-+  if( pTab ){
-+    pTrig = pTab->pTrigger;
-+    pTab->pTrigger = 0;  /* Disable all triggers before rebuilding the table */
-+  }
-+  rc = sqlite_exec_printf(pData->db,
-+    "CREATE TEMP TABLE sqlite_x AS SELECT * FROM '%q'; "
-+    "DELETE FROM '%q'; "
-+    "INSERT INTO '%q' SELECT * FROM sqlite_x; "
-+    "DROP TABLE sqlite_x;",
-+    0, 0, &zErr, argv[0], argv[0], argv[0]);
-+  if( zErr ){
-+    if( *pData->pzErrMsg ) sqlite_freemem(*pData->pzErrMsg);
-+    *pData->pzErrMsg = zErr;
-+  }
-+
-+  /* If an error occurred in the SQL above, then the transaction will
-+  ** rollback which will delete the internal symbol tables.  This will
-+  ** cause the structure that pTab points to be deleted.  In case that
-+  ** happened, we need to refetch pTab.
-+  */
-+  pTab = sqliteFindTable(pData->db, argv[0], 0);
-+  if( pTab ){
-+    assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
-+    pTab->pTrigger = pTrig;  /* Re-enable triggers */
-+  }
-+  return rc!=SQLITE_OK;
-+}
-+
-+
-+
-+/*
-+** 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 sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
-+  int rc;
-+  BtCursor *curMain;
-+  int size;
-+  Table *pTab;
-+  char const *azArg[6];
-+  char zDbNum[30];
-+  int meta[SQLITE_N_BTREE_META];
-+  InitData initData;
-+  char const *zMasterSchema;
-+  char const *zMasterName;
-+  char *zSql = 0;
-+
-+  /*
-+  ** The master database table has a structure like this
-+  */
-+  static char master_schema[] = 
-+     "CREATE TABLE sqlite_master(\n"
-+     "  type text,\n"
-+     "  name text,\n"
-+     "  tbl_name text,\n"
-+     "  rootpage integer,\n"
-+     "  sql text\n"
-+     ")"
-+  ;
-+  static 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"
-+     ")"
-+  ;
-+
-+  assert( iDb>=0 && iDb<db->nDb );
-+
-+  /* 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( iDb==1 ){
-+    zMasterSchema = temp_master_schema;
-+    zMasterName = TEMP_MASTER_NAME;
-+  }else{
-+    zMasterSchema = master_schema;
-+    zMasterName = MASTER_NAME;
-+  }
-+
-+  /* Construct the schema table.
-+  */
-+  sqliteSafetyOff(db);
-+  azArg[0] = "table";
-+  azArg[1] = zMasterName;
-+  azArg[2] = "2";
-+  azArg[3] = zMasterSchema;
-+  sprintf(zDbNum, "%d", iDb);
-+  azArg[4] = zDbNum;
-+  azArg[5] = 0;
-+  initData.db = db;
-+  initData.pzErrMsg = pzErrMsg;
-+  sqliteInitCallback(&initData, 5, (char **)azArg, 0);
-+  pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
-+  if( pTab ){
-+    pTab->readOnly = 1;
-+  }else{
-+    return SQLITE_NOMEM;
-+  }
-+  sqliteSafetyOn(db);
-+
-+  /* Create a cursor to hold the database open
-+  */
-+  if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
-+  rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
-+  if( rc ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
-+    return rc;
-+  }
-+
-+  /* Get the database meta information
-+  */
-+  rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta);
-+  if( rc ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
-+    sqliteBtreeCloseCursor(curMain);
-+    return rc;
-+  }
-+  db->aDb[iDb].schema_cookie = meta[1];
-+  if( iDb==0 ){
-+    db->next_cookie = meta[1];
-+    db->file_format = meta[2];
-+    size = meta[3];
-+    if( size==0 ){ size = MAX_PAGES; }
-+    db->cache_size = size;
-+    db->safety_level = meta[4];
-+    if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){
-+      db->temp_store = meta[6];
-+    }
-+    if( db->safety_level==0 ) db->safety_level = 2;
-+
-+    /*
-+    **  file_format==1    Version 2.1.0.
-+    **  file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.
-+    **  file_format==3    Version 2.6.0. Fix empty-string index bug.
-+    **  file_format==4    Version 2.7.0. Add support for separate numeric and
-+    **                    text datatypes.
-+    */
-+    if( db->file_format==0 ){
-+      /* This happens if the database was initially empty */
-+      db->file_format = 4;
-+    }else if( db->file_format>4 ){
-+      sqliteBtreeCloseCursor(curMain);
-+      sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
-+      return SQLITE_ERROR;
-+    }
-+  }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
-+    assert( db->file_format>=4 );
-+    if( meta[2]==0 ){
-+      sqliteSetString(pzErrMsg, "cannot attach empty database: ",
-+         db->aDb[iDb].zName, (char*)0);
-+    }else{
-+      sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "
-+         "database: ", db->aDb[iDb].zName, (char*)0);
-+    }
-+    sqliteBtreeClose(db->aDb[iDb].pBt);
-+    db->aDb[iDb].pBt = 0;
-+    return SQLITE_FORMAT;
-+  }
-+  sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
-+  sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
-+
-+  /* Read the schema information out of the schema tables
-+  */
-+  assert( db->init.busy );
-+  sqliteSafetyOff(db);
-+
-+  /* The following SQL will read the schema from the master tables.
-+  ** The first version works with SQLite file formats 2 or greater.
-+  ** The second version is for format 1 files.
-+  **
-+  ** Beginning with file format 2, the rowid for new table entries
-+  ** (including entries in sqlite_master) is an increasing integer.
-+  ** So for file format 2 and later, we can play back sqlite_master
-+  ** and all the CREATE statements will appear in the right order.
-+  ** But with file format 1, table entries were random and so we
-+  ** have to make sure the CREATE TABLEs occur before their corresponding
-+  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
-+  ** CREATE TRIGGER in file format 1 because those constructs did
-+  ** not exist then.) 
-+  */
-+  if( db->file_format>=2 ){
-+    sqliteSetString(&zSql, 
-+        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
-+       db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
-+  }else{
-+    sqliteSetString(&zSql, 
-+        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
-+       db->aDb[iDb].zName, "\".", zMasterName, 
-+       " WHERE type IN ('table', 'index')"
-+       " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
-+  }
-+  rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
-+
-+  sqliteFree(zSql);
-+  sqliteSafetyOn(db);
-+  sqliteBtreeCloseCursor(curMain);
-+  if( sqlite_malloc_failed ){
-+    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
-+    rc = SQLITE_NOMEM;
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+  if( rc==SQLITE_OK ){
-+    DbSetProperty(db, iDb, DB_SchemaLoaded);
-+  }else{
-+    sqliteResetInternalSchema(db, iDb);
-+  }
-+  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 the database is initialized, the SQLITE_Initialized
-+** bit is set in the flags field of the sqlite structure.  An
-+** attempt is made to initialize the database as soon as it
-+** is opened.  If that fails (perhaps because another process
-+** has the sqlite_master table locked) than another attempt
-+** is made the first time the database is accessed.
-+*/
-+int sqliteInit(sqlite *db, char **pzErrMsg){
-+  int i, rc;
-+  
-+  if( db->init.busy ) return SQLITE_OK;
-+  assert( (db->flags & SQLITE_Initialized)==0 );
-+  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 = sqliteInitOne(db, i, pzErrMsg);
-+    if( rc ){
-+      sqliteResetInternalSchema(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.
-+  */
-+  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
-+    rc = sqliteInitOne(db, 1, pzErrMsg);
-+    if( rc ){
-+      sqliteResetInternalSchema(db, 1);
-+    }
-+  }
-+
-+  db->init.busy = 0;
-+  if( rc==SQLITE_OK ){
-+    db->flags |= SQLITE_Initialized;
-+    sqliteCommitInternalChanges(db);
-+  }
-+
-+  /* If the database is in formats 1 or 2, then upgrade it to
-+  ** version 3.  This will reconstruct all indices.  If the
-+  ** upgrade fails for any reason (ex: out of disk space, database
-+  ** is read only, interrupt received, etc.) then fail the init.
-+  */
-+  if( rc==SQLITE_OK && db->file_format<3 ){
-+    char *zErr = 0;
-+    InitData initData;
-+    int meta[SQLITE_N_BTREE_META];
-+
-+    db->magic = SQLITE_MAGIC_OPEN;
-+    initData.db = db;
-+    initData.pzErrMsg = &zErr;
-+    db->file_format = 3;
-+    rc = sqlite_exec(db,
-+      "BEGIN; SELECT name FROM sqlite_master WHERE type='table';",
-+      upgrade_3_callback,
-+      &initData,
-+      &zErr);
-+    if( rc==SQLITE_OK ){
-+      sqliteBtreeGetMeta(db->aDb[0].pBt, meta);
-+      meta[2] = 4;
-+      sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta);
-+      sqlite_exec(db, "COMMIT", 0, 0, 0);
-+    }
-+    if( rc!=SQLITE_OK ){
-+      sqliteSetString(pzErrMsg, 
-+        "unable to upgrade database to the version 2.6 format",
-+        zErr ? ": " : 0, zErr, (char*)0);
-+    }
-+    sqlite_freemem(zErr);
-+  }
-+
-+  if( rc!=SQLITE_OK ){
-+    db->flags &= ~SQLITE_Initialized;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** The version of the library
-+*/
-+const char rcsid[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
-+const char sqlite_version[] = SQLITE_VERSION;
-+
-+/*
-+** Does the library expect data to be encoded as UTF-8 or iso8859?  The
-+** following global constant always lets us know.
-+*/
-+#ifdef SQLITE_UTF8
-+const char sqlite_encoding[] = "UTF-8";
-+#else
-+const char sqlite_encoding[] = "iso8859";
-+#endif
-+
-+/*
-+** Open a new SQLite database.  Construct an "sqlite" structure to define
-+** the state of this database and return a pointer to that structure.
-+**
-+** An attempt is made to initialize the in-memory data structures that
-+** hold the database schema.  But if this fails (because the schema file
-+** is locked) then that step is deferred until the first call to
-+** sqlite_exec().
-+*/
-+sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
-+  sqlite *db;
-+  int rc, i;
-+
-+  /* Allocate the sqlite data structure */
-+  db = sqliteMalloc( sizeof(sqlite) );
-+  if( pzErrMsg ) *pzErrMsg = 0;
-+  if( db==0 ) goto no_mem_on_open;
-+  db->onError = OE_Default;
-+  db->priorNewRowid = 0;
-+  db->magic = SQLITE_MAGIC_BUSY;
-+  db->nDb = 2;
-+  db->aDb = db->aDbStatic;
-+  /* db->flags |= SQLITE_ShortColNames; */
-+  sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
-+  for(i=0; i<db->nDb; i++){
-+    sqliteHashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
-+    sqliteHashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
-+    sqliteHashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
-+    sqliteHashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
-+  }
-+  
-+  /* Open the backend database driver */
-+  if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
-+    db->temp_store = 2;
-+  }
-+  rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
-+  if( rc!=SQLITE_OK ){
-+    switch( rc ){
-+      default: {
-+        sqliteSetString(pzErrMsg, "unable to open database: ",
-+           zFilename, (char*)0);
-+      }
-+    }
-+    sqliteFree(db);
-+    sqliteStrRealloc(pzErrMsg);
-+    return 0;
-+  }
-+  db->aDb[0].zName = "main";
-+  db->aDb[1].zName = "temp";
-+
-+  /* Attempt to read the schema */
-+  sqliteRegisterBuiltinFunctions(db);
-+  rc = sqliteInit(db, pzErrMsg);
-+  db->magic = SQLITE_MAGIC_OPEN;
-+  if( sqlite_malloc_failed ){
-+    sqlite_close(db);
-+    goto no_mem_on_open;
-+  }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
-+    sqlite_close(db);
-+    sqliteStrRealloc(pzErrMsg);
-+    return 0;
-+  }else if( pzErrMsg ){
-+    sqliteFree(*pzErrMsg);
-+    *pzErrMsg = 0;
-+  }
-+
-+  /* Return a pointer to the newly opened database structure */
-+  return db;
-+
-+no_mem_on_open:
-+  sqliteSetString(pzErrMsg, "out of memory", (char*)0);
-+  sqliteStrRealloc(pzErrMsg);
-+  return 0;
-+}
-+
-+/*
-+** Return the ROWID of the most recent insert
-+*/
-+int sqlite_last_insert_rowid(sqlite *db){
-+  return db->lastRowid;
-+}
-+
-+/*
-+** Return the number of changes in the most recent call to sqlite_exec().
-+*/
-+int sqlite_changes(sqlite *db){
-+  return db->nChange;
-+}
-+
-+/*
-+** Return the number of changes produced by the last INSERT, UPDATE, or
-+** DELETE statement to complete execution. The count does not include
-+** changes due to SQL statements executed in trigger programs that were
-+** triggered by that statement
-+*/
-+int sqlite_last_statement_changes(sqlite *db){
-+  return db->lsChange;
-+}
-+
-+/*
-+** Close an existing SQLite database
-+*/
-+void sqlite_close(sqlite *db){
-+  HashElem *i;
-+  int j;
-+  db->want_to_close = 1;
-+  if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){
-+    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
-+    return;
-+  }
-+  db->magic = SQLITE_MAGIC_CLOSED;
-+  for(j=0; j<db->nDb; j++){
-+    struct Db *pDb = &db->aDb[j];
-+    if( pDb->pBt ){
-+      sqliteBtreeClose(pDb->pBt);
-+      pDb->pBt = 0;
-+    }
-+  }
-+  sqliteResetInternalSchema(db, 0);
-+  assert( db->nDb<=2 );
-+  assert( db->aDb==db->aDbStatic );
-+  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
-+    FuncDef *pFunc, *pNext;
-+    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
-+      pNext = pFunc->pNext;
-+      sqliteFree(pFunc);
-+    }
-+  }
-+  sqliteHashClear(&db->aFunc);
-+  sqliteFree(db);
-+}
-+
-+/*
-+** Rollback all database files.
-+*/
-+void sqliteRollbackAll(sqlite *db){
-+  int i;
-+  for(i=0; i<db->nDb; i++){
-+    if( db->aDb[i].pBt ){
-+      sqliteBtreeRollback(db->aDb[i].pBt);
-+      db->aDb[i].inTrans = 0;
-+    }
-+  }
-+  sqliteResetInternalSchema(db, 0);
-+  /* sqliteRollbackInternalChanges(db); */
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqlite_exec(
-+  sqlite *db,                 /* The database on which the SQL executes */
-+  const char *zSql,           /* The SQL to be executed */
-+  sqlite_callback xCallback,  /* Invoke this callback routine */
-+  void *pArg,                 /* First argument to xCallback() */
-+  char **pzErrMsg             /* Write error messages here */
-+){
-+  int rc = SQLITE_OK;
-+  const char *zLeftover;
-+  sqlite_vm *pVm;
-+  int nRetry = 0;
-+  int nChange = 0;
-+  int nCallback;
-+
-+  if( zSql==0 ) return SQLITE_OK;
-+  while( rc==SQLITE_OK && zSql[0] ){
-+    pVm = 0;
-+    rc = sqlite_compile(db, zSql, &zLeftover, &pVm, pzErrMsg);
-+    if( rc!=SQLITE_OK ){
-+      assert( pVm==0 || sqlite_malloc_failed );
-+      return rc;
-+    }
-+    if( pVm==0 ){
-+      /* This happens if the zSql input contained only whitespace */
-+      break;
-+    }
-+    db->nChange += nChange;
-+    nCallback = 0;
-+    while(1){
-+      int nArg;
-+      char **azArg, **azCol;
-+      rc = sqlite_step(pVm, &nArg, (const char***)&azArg,(const char***)&azCol);
-+      if( rc==SQLITE_ROW ){
-+        if( xCallback!=0 && xCallback(pArg, nArg, azArg, azCol) ){
-+          sqlite_finalize(pVm, 0);
-+          return SQLITE_ABORT;
-+        }
-+        nCallback++;
-+      }else{
-+        if( rc==SQLITE_DONE && nCallback==0
-+          && (db->flags & SQLITE_NullCallback)!=0 && xCallback!=0 ){
-+          xCallback(pArg, nArg, azArg, azCol);
-+        }
-+        rc = sqlite_finalize(pVm, pzErrMsg);
-+        if( rc==SQLITE_SCHEMA && nRetry<2 ){
-+          nRetry++;
-+          rc = SQLITE_OK;
-+          break;
-+        }
-+        if( db->pVdbe==0 ){
-+          nChange = db->nChange;
-+        }
-+        nRetry = 0;
-+        zSql = zLeftover;
-+        while( isspace(zSql[0]) ) zSql++;
-+        break;
-+      }
-+    }
-+  }
-+  return rc;
-+}
-+
-+
-+/*
-+** Compile a single statement of SQL into a virtual machine.  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.
-+*/
-+int sqlite_compile(
-+  sqlite *db,                 /* The database on which the SQL executes */
-+  const char *zSql,           /* The SQL to be executed */
-+  const char **pzTail,        /* OUT: Next statement after the first */
-+  sqlite_vm **ppVm,           /* OUT: The virtual machine */
-+  char **pzErrMsg             /* OUT: Write error messages here */
-+){
-+  Parse sParse;
-+
-+  if( pzErrMsg ) *pzErrMsg = 0;
-+  if( sqliteSafetyOn(db) ) goto exec_misuse;
-+  if( !db->init.busy ){
-+    if( (db->flags & SQLITE_Initialized)==0 ){
-+      int rc, cnt = 1;
-+      while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY
-+         && db->xBusyCallback
-+         && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
-+      if( rc!=SQLITE_OK ){
-+        sqliteStrRealloc(pzErrMsg);
-+        sqliteSafetyOff(db);
-+        return rc;
-+      }
-+      if( pzErrMsg ){
-+        sqliteFree(*pzErrMsg);
-+        *pzErrMsg = 0;
-+      }
-+    }
-+    if( db->file_format<3 ){
-+      sqliteSafetyOff(db);
-+      sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
-+      return SQLITE_ERROR;
-+    }
-+  }
-+  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
-+  if( db->pVdbe==0 ){ db->nChange = 0; }
-+  memset(&sParse, 0, sizeof(sParse));
-+  sParse.db = db;
-+  sqliteRunParser(&sParse, zSql, pzErrMsg);
-+  if( db->xTrace && !db->init.busy ){
-+    /* Trace only the statment that was compiled.
-+    ** Make a copy of that part of the SQL string since zSQL is const
-+    ** and we must pass a zero terminated string to the trace function
-+    ** The copy is unnecessary if the tail pointer is pointing at the
-+    ** beginnig or end of the SQL string.
-+    */
-+    if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
-+      char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
-+      if( tmpSql ){
-+        db->xTrace(db->pTraceArg, tmpSql);
-+        free(tmpSql);
-+      }else{
-+        /* If a memory error occurred during the copy,
-+        ** trace entire SQL string and fall through to the
-+        ** sqlite_malloc_failed test to report the error.
-+        */
-+        db->xTrace(db->pTraceArg, zSql); 
-+      }
-+    }else{
-+      db->xTrace(db->pTraceArg, zSql); 
-+    }
-+  }
-+  if( sqlite_malloc_failed ){
-+    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
-+    sParse.rc = SQLITE_NOMEM;
-+    sqliteRollbackAll(db);
-+    sqliteResetInternalSchema(db, 0);
-+    db->flags &= ~SQLITE_InTrans;
-+  }
-+  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
-+  if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0);
-+  }
-+  sqliteStrRealloc(pzErrMsg);
-+  if( sParse.rc==SQLITE_SCHEMA ){
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+  assert( ppVm );
-+  *ppVm = (sqlite_vm*)sParse.pVdbe;
-+  if( pzTail ) *pzTail = sParse.zTail;
-+  if( sqliteSafetyOff(db) ) goto exec_misuse;
-+  return sParse.rc;
-+
-+exec_misuse:
-+  if( pzErrMsg ){
-+    *pzErrMsg = 0;
-+    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
-+    sqliteStrRealloc(pzErrMsg);
-+  }
-+  return SQLITE_MISUSE;
-+}
-+
-+
-+/*
-+** The following routine destroys a virtual machine that is created by
-+** the sqlite_compile() routine.
-+**
-+** The integer returned is an SQLITE_ success/failure code that describes
-+** the result of executing the virtual machine.  An error message is
-+** written into memory obtained from malloc and *pzErrMsg is made to
-+** point to that error if pzErrMsg is not NULL.  The calling routine
-+** should use sqlite_freemem() to delete the message when it has finished
-+** with it.
-+*/
-+int sqlite_finalize(
-+  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
-+  char **pzErrMsg            /* OUT: Write error messages here */
-+){
-+  int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
-+  sqliteStrRealloc(pzErrMsg);
-+  return rc;
-+}
-+
-+/*
-+** Terminate the current execution of a virtual machine then
-+** reset the virtual machine back to its starting state so that it
-+** can be reused.  Any error message resulting from the prior execution
-+** is written into *pzErrMsg.  A success code from the prior execution
-+** is returned.
-+*/
-+int sqlite_reset(
-+  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
-+  char **pzErrMsg            /* OUT: Write error messages here */
-+){
-+  int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
-+  sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0);
-+  sqliteStrRealloc(pzErrMsg);
-+  return rc;
-+}
-+
-+/*
-+** Return a static string that describes the kind of error specified in the
-+** argument.
-+*/
-+const char *sqlite_error_string(int rc){
-+  const char *z;
-+  switch( rc ){
-+    case SQLITE_OK:         z = "not an error";                          break;
-+    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;
-+    case SQLITE_INTERNAL:   z = "internal SQLite implementation flaw";   break;
-+    case SQLITE_PERM:       z = "access permission denied";              break;
-+    case SQLITE_ABORT:      z = "callback requested query abort";        break;
-+    case SQLITE_BUSY:       z = "database is locked";                    break;
-+    case SQLITE_LOCKED:     z = "database table is locked";              break;
-+    case SQLITE_NOMEM:      z = "out of memory";                         break;
-+    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;
-+    case SQLITE_INTERRUPT:  z = "interrupted";                           break;
-+    case SQLITE_IOERR:      z = "disk I/O error";                        break;
-+    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;
-+    case SQLITE_NOTFOUND:   z = "table or record not found";             break;
-+    case SQLITE_FULL:       z = "database is full";                      break;
-+    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
-+    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
-+    case SQLITE_EMPTY:      z = "table contains no data";                break;
-+    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
-+    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
-+    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
-+    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
-+    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
-+    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
-+    case SQLITE_AUTH:       z = "authorization denied";                  break;
-+    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;
-+    case SQLITE_RANGE:      z = "bind index out of range";               break;
-+    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;
-+    default:                z = "unknown error";                         break;
-+  }
-+  return z;
-+}
-+
-+/*
-+** 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 *Timeout,           /* Maximum amount of time to wait */
-+ const char *NotUsed,     /* The name of the table that is busy */
-+ int count                /* Number of times table has been busy */
-+){
-+#if SQLITE_MIN_SLEEP_MS==1
-+  static const char delays[] =
-+     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50,  50, 100};
-+  static const short int totals[] =
-+     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
-+# define NDELAY (sizeof(delays)/sizeof(delays[0]))
-+  int timeout = (int)(long)Timeout;
-+  int delay, prior;
-+
-+  if( count <= NDELAY ){
-+    delay = delays[count-1];
-+    prior = totals[count-1];
-+  }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;
-+  }
-+  sqliteOsSleep(delay);
-+  return 1;
-+#else
-+  int timeout = (int)(long)Timeout;
-+  if( (count+1)*1000 > timeout ){
-+    return 0;
-+  }
-+  sqliteOsSleep(1000);
-+  return 1;
-+#endif
-+}
-+
-+/*
-+** This routine sets the busy callback for an Sqlite database to the
-+** given callback function with the given argument.
-+*/
-+void sqlite_busy_handler(
-+  sqlite *db,
-+  int (*xBusy)(void*,const char*,int),
-+  void *pArg
-+){
-+  db->xBusyCallback = xBusy;
-+  db->pBusyArg = pArg;
-+}
-+
-+#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.
-+*/
-+void sqlite_progress_handler(
-+  sqlite *db, 
-+  int nOps,
-+  int (*xProgress)(void*), 
-+  void *pArg
-+){
-+  if( nOps>0 ){
-+    db->xProgress = xProgress;
-+    db->nProgressOps = nOps;
-+    db->pProgressArg = pArg;
-+  }else{
-+    db->xProgress = 0;
-+    db->nProgressOps = 0;
-+    db->pProgressArg = 0;
-+  }
-+}
-+#endif
-+
-+
-+/*
-+** This routine installs a default busy handler that waits for the
-+** specified number of milliseconds before returning 0.
-+*/
-+void sqlite_busy_timeout(sqlite *db, int ms){
-+  if( ms>0 ){
-+    sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)(long)ms);
-+  }else{
-+    sqlite_busy_handler(db, 0, 0);
-+  }
-+}
-+
-+/*
-+** Cause any pending operation to stop at its earliest opportunity.
-+*/
-+void sqlite_interrupt(sqlite *db){
-+  db->flags |= SQLITE_Interrupt;
-+}
-+
-+/*
-+** Windows systems should call this routine to free memory that
-+** is returned in the in the errmsg parameter of sqlite_open() when
-+** SQLite is a DLL.  For some reason, it does not work to call free()
-+** directly.
-+**
-+** Note that we need to call free() not sqliteFree() here, since every
-+** string that is exported from SQLite should have already passed through
-+** sqliteStrRealloc().
-+*/
-+void sqlite_freemem(void *p){ free(p); }
-+
-+/*
-+** Windows systems need functions to call to return the sqlite_version
-+** and sqlite_encoding strings since they are unable to access constants
-+** within DLLs.
-+*/
-+const char *sqlite_libversion(void){ return sqlite_version; }
-+const char *sqlite_libencoding(void){ return sqlite_encoding; }
-+
-+/*
-+** Create new user-defined functions.  The sqlite_create_function()
-+** routine creates a regular function and sqlite_create_aggregate()
-+** creates an aggregate function.
-+**
-+** Passing a NULL xFunc argument or NULL xStep and xFinalize arguments
-+** disables the function.  Calling sqlite_create_function() with the
-+** same name and number of arguments as a prior call to
-+** sqlite_create_aggregate() disables the prior call to
-+** sqlite_create_aggregate(), and vice versa.
-+**
-+** If nArg is -1 it means that this function will accept any number
-+** of arguments, including 0.  The maximum allowed value of nArg is 127.
-+*/
-+int sqlite_create_function(
-+  sqlite *db,          /* Add the function to this database connection */
-+  const char *zName,   /* Name of the function to add */
-+  int nArg,            /* Number of arguments */
-+  void (*xFunc)(sqlite_func*,int,const char**),  /* The implementation */
-+  void *pUserData      /* User data */
-+){
-+  FuncDef *p;
-+  int nName;
-+  if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
-+  if( nArg<-1 || nArg>127 ) return 1;
-+  nName = strlen(zName);
-+  if( nName>255 ) return 1;
-+  p = sqliteFindFunction(db, zName, nName, nArg, 1);
-+  if( p==0 ) return 1;
-+  p->xFunc = xFunc;
-+  p->xStep = 0;
-+  p->xFinalize = 0;
-+  p->pUserData = pUserData;
-+  return 0;
-+}
-+int sqlite_create_aggregate(
-+  sqlite *db,          /* Add the function to this database connection */
-+  const char *zName,   /* Name of the function to add */
-+  int nArg,            /* Number of arguments */
-+  void (*xStep)(sqlite_func*,int,const char**), /* The step function */
-+  void (*xFinalize)(sqlite_func*),              /* The finalizer */
-+  void *pUserData      /* User data */
-+){
-+  FuncDef *p;
-+  int nName;
-+  if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
-+  if( nArg<-1 || nArg>127 ) return 1;
-+  nName = strlen(zName);
-+  if( nName>255 ) return 1;
-+  p = sqliteFindFunction(db, zName, nName, nArg, 1);
-+  if( p==0 ) return 1;
-+  p->xFunc = 0;
-+  p->xStep = xStep;
-+  p->xFinalize = xFinalize;
-+  p->pUserData = pUserData;
-+  return 0;
-+}
-+
-+/*
-+** Change the datatype for all functions with a given name.  See the
-+** header comment for the prototype of this function in sqlite.h for
-+** additional information.
-+*/
-+int sqlite_function_type(sqlite *db, const char *zName, int dataType){
-+  FuncDef *p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, strlen(zName));
-+  while( p ){
-+    p->dataType = dataType; 
-+    p = p->pNext;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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
-+** sqlite_exec().
-+*/
-+void *sqlite_trace(sqlite *db, void (*xTrace)(void*,const char*), void *pArg){
-+  void *pOld = db->pTraceArg;
-+  db->xTrace = xTrace;
-+  db->pTraceArg = pArg;
-+  return pOld;
-+}
-+
-+/*** EXPERIMENTAL ***
-+**
-+** Register a function to be invoked when a transaction comments.
-+** If either function returns non-zero, then the commit becomes a
-+** rollback.
-+*/
-+void *sqlite_commit_hook(
-+  sqlite *db,               /* Attach the hook to this database */
-+  int (*xCallback)(void*),  /* Function to invoke on each commit */
-+  void *pArg                /* Argument to the function */
-+){
-+  void *pOld = db->pCommitArg;
-+  db->xCommitCallback = xCallback;
-+  db->pCommitArg = pArg;
-+  return pOld;
-+}
-+
-+
-+/*
-+** 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 for temporary use only and is deleted as soon as the connection
-+** is closed.
-+**
-+** A temporary database can be either a disk file (that is automatically
-+** deleted when the file is closed) or a set of red-black trees held in memory,
-+** depending on the values of the TEMP_STORE compile-time macro and the
-+** db->temp_store variable, according to the following chart:
-+**
-+**       TEMP_STORE     db->temp_store     Location of temporary database
-+**       ----------     --------------     ------------------------------
-+**           0               any             file
-+**           1                1              file
-+**           1                2              memory
-+**           1                0              file
-+**           2                1              file
-+**           2                2              memory
-+**           2                0              memory
-+**           3               any             memory
-+*/
-+int sqliteBtreeFactory(
-+  const sqlite *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 */
-+  Btree **ppBtree){         /* Pointer to new Btree object written here */
-+
-+  assert( ppBtree != 0);
-+
-+#ifndef SQLITE_OMIT_INMEMORYDB
-+  if( zFilename==0 ){
-+    if (TEMP_STORE == 0) {
-+      /* Always use file based temporary DB */
-+      return sqliteBtreeOpen(0, omitJournal, nCache, ppBtree);
-+    } else if (TEMP_STORE == 1 || TEMP_STORE == 2) {
-+      /* Switch depending on compile-time and/or runtime settings. */
-+      int location = db->temp_store==0 ? TEMP_STORE : db->temp_store;
-+
-+      if (location == 1) {
-+        return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
-+      } else {
-+        return sqliteRbtreeOpen(0, 0, 0, ppBtree);
-+      }
-+    } else {
-+      /* Always use in-core DB */
-+      return sqliteRbtreeOpen(0, 0, 0, ppBtree);
-+    }
-+  }else if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
-+    return sqliteRbtreeOpen(0, 0, 0, ppBtree);
-+  }else
-+#endif
-+  {
-+    return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
-+  }
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/opcodes.c
-@@ -0,0 +1,140 @@
-+/* Automatically generated file.  Do not edit */
-+char *sqliteOpcodeNames[] = { "???", 
-+  "Goto", 
-+  "Gosub", 
-+  "Return", 
-+  "Halt", 
-+  "Integer", 
-+  "String", 
-+  "Variable", 
-+  "Pop", 
-+  "Dup", 
-+  "Pull", 
-+  "Push", 
-+  "ColumnName", 
-+  "Callback", 
-+  "Concat", 
-+  "Add", 
-+  "Subtract", 
-+  "Multiply", 
-+  "Divide", 
-+  "Remainder", 
-+  "Function", 
-+  "BitAnd", 
-+  "BitOr", 
-+  "ShiftLeft", 
-+  "ShiftRight", 
-+  "AddImm", 
-+  "ForceInt", 
-+  "MustBeInt", 
-+  "Eq", 
-+  "Ne", 
-+  "Lt", 
-+  "Le", 
-+  "Gt", 
-+  "Ge", 
-+  "StrEq", 
-+  "StrNe", 
-+  "StrLt", 
-+  "StrLe", 
-+  "StrGt", 
-+  "StrGe", 
-+  "And", 
-+  "Or", 
-+  "Negative", 
-+  "AbsValue", 
-+  "Not", 
-+  "BitNot", 
-+  "Noop", 
-+  "If", 
-+  "IfNot", 
-+  "IsNull", 
-+  "NotNull", 
-+  "MakeRecord", 
-+  "MakeIdxKey", 
-+  "MakeKey", 
-+  "IncrKey", 
-+  "Checkpoint", 
-+  "Transaction", 
-+  "Commit", 
-+  "Rollback", 
-+  "ReadCookie", 
-+  "SetCookie", 
-+  "VerifyCookie", 
-+  "OpenRead", 
-+  "OpenWrite", 
-+  "OpenTemp", 
-+  "OpenPseudo", 
-+  "Close", 
-+  "MoveLt", 
-+  "MoveTo", 
-+  "Distinct", 
-+  "NotFound", 
-+  "Found", 
-+  "IsUnique", 
-+  "NotExists", 
-+  "NewRecno", 
-+  "PutIntKey", 
-+  "PutStrKey", 
-+  "Delete", 
-+  "SetCounts", 
-+  "KeyAsData", 
-+  "RowKey", 
-+  "RowData", 
-+  "Column", 
-+  "Recno", 
-+  "FullKey", 
-+  "NullRow", 
-+  "Last", 
-+  "Rewind", 
-+  "Prev", 
-+  "Next", 
-+  "IdxPut", 
-+  "IdxDelete", 
-+  "IdxRecno", 
-+  "IdxLT", 
-+  "IdxGT", 
-+  "IdxGE", 
-+  "IdxIsNull", 
-+  "Destroy", 
-+  "Clear", 
-+  "CreateIndex", 
-+  "CreateTable", 
-+  "IntegrityCk", 
-+  "ListWrite", 
-+  "ListRewind", 
-+  "ListRead", 
-+  "ListReset", 
-+  "ListPush", 
-+  "ListPop", 
-+  "ContextPush", 
-+  "ContextPop", 
-+  "SortPut", 
-+  "SortMakeRec", 
-+  "SortMakeKey", 
-+  "Sort", 
-+  "SortNext", 
-+  "SortCallback", 
-+  "SortReset", 
-+  "FileOpen", 
-+  "FileRead", 
-+  "FileColumn", 
-+  "MemStore", 
-+  "MemLoad", 
-+  "MemIncr", 
-+  "AggReset", 
-+  "AggInit", 
-+  "AggFunc", 
-+  "AggFocus", 
-+  "AggSet", 
-+  "AggGet", 
-+  "AggNext", 
-+  "SetInsert", 
-+  "SetFound", 
-+  "SetNotFound", 
-+  "SetFirst", 
-+  "SetNext", 
-+  "Vacuum", 
-+  "StackDepth", 
-+  "StackReset", 
-+};
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/opcodes.h
-@@ -0,0 +1,138 @@
-+/* Automatically generated file.  Do not edit */
-+#define OP_Goto                          1
-+#define OP_Gosub                         2
-+#define OP_Return                        3
-+#define OP_Halt                          4
-+#define OP_Integer                       5
-+#define OP_String                        6
-+#define OP_Variable                      7
-+#define OP_Pop                           8
-+#define OP_Dup                           9
-+#define OP_Pull                         10
-+#define OP_Push                         11
-+#define OP_ColumnName                   12
-+#define OP_Callback                     13
-+#define OP_Concat                       14
-+#define OP_Add                          15
-+#define OP_Subtract                     16
-+#define OP_Multiply                     17
-+#define OP_Divide                       18
-+#define OP_Remainder                    19
-+#define OP_Function                     20
-+#define OP_BitAnd                       21
-+#define OP_BitOr                        22
-+#define OP_ShiftLeft                    23
-+#define OP_ShiftRight                   24
-+#define OP_AddImm                       25
-+#define OP_ForceInt                     26
-+#define OP_MustBeInt                    27
-+#define OP_Eq                           28
-+#define OP_Ne                           29
-+#define OP_Lt                           30
-+#define OP_Le                           31
-+#define OP_Gt                           32
-+#define OP_Ge                           33
-+#define OP_StrEq                        34
-+#define OP_StrNe                        35
-+#define OP_StrLt                        36
-+#define OP_StrLe                        37
-+#define OP_StrGt                        38
-+#define OP_StrGe                        39
-+#define OP_And                          40
-+#define OP_Or                           41
-+#define OP_Negative                     42
-+#define OP_AbsValue                     43
-+#define OP_Not                          44
-+#define OP_BitNot                       45
-+#define OP_Noop                         46
-+#define OP_If                           47
-+#define OP_IfNot                        48
-+#define OP_IsNull                       49
-+#define OP_NotNull                      50
-+#define OP_MakeRecord                   51
-+#define OP_MakeIdxKey                   52
-+#define OP_MakeKey                      53
-+#define OP_IncrKey                      54
-+#define OP_Checkpoint                   55
-+#define OP_Transaction                  56
-+#define OP_Commit                       57
-+#define OP_Rollback                     58
-+#define OP_ReadCookie                   59
-+#define OP_SetCookie                    60
-+#define OP_VerifyCookie                 61
-+#define OP_OpenRead                     62
-+#define OP_OpenWrite                    63
-+#define OP_OpenTemp                     64
-+#define OP_OpenPseudo                   65
-+#define OP_Close                        66
-+#define OP_MoveLt                       67
-+#define OP_MoveTo                       68
-+#define OP_Distinct                     69
-+#define OP_NotFound                     70
-+#define OP_Found                        71
-+#define OP_IsUnique                     72
-+#define OP_NotExists                    73
-+#define OP_NewRecno                     74
-+#define OP_PutIntKey                    75
-+#define OP_PutStrKey                    76
-+#define OP_Delete                       77
-+#define OP_SetCounts                    78
-+#define OP_KeyAsData                    79
-+#define OP_RowKey                       80
-+#define OP_RowData                      81
-+#define OP_Column                       82
-+#define OP_Recno                        83
-+#define OP_FullKey                      84
-+#define OP_NullRow                      85
-+#define OP_Last                         86
-+#define OP_Rewind                       87
-+#define OP_Prev                         88
-+#define OP_Next                         89
-+#define OP_IdxPut                       90
-+#define OP_IdxDelete                    91
-+#define OP_IdxRecno                     92
-+#define OP_IdxLT                        93
-+#define OP_IdxGT                        94
-+#define OP_IdxGE                        95
-+#define OP_IdxIsNull                    96
-+#define OP_Destroy                      97
-+#define OP_Clear                        98
-+#define OP_CreateIndex                  99
-+#define OP_CreateTable                 100
-+#define OP_IntegrityCk                 101
-+#define OP_ListWrite                   102
-+#define OP_ListRewind                  103
-+#define OP_ListRead                    104
-+#define OP_ListReset                   105
-+#define OP_ListPush                    106
-+#define OP_ListPop                     107
-+#define OP_ContextPush                 108
-+#define OP_ContextPop                  109
-+#define OP_SortPut                     110
-+#define OP_SortMakeRec                 111
-+#define OP_SortMakeKey                 112
-+#define OP_Sort                        113
-+#define OP_SortNext                    114
-+#define OP_SortCallback                115
-+#define OP_SortReset                   116
-+#define OP_FileOpen                    117
-+#define OP_FileRead                    118
-+#define OP_FileColumn                  119
-+#define OP_MemStore                    120
-+#define OP_MemLoad                     121
-+#define OP_MemIncr                     122
-+#define OP_AggReset                    123
-+#define OP_AggInit                     124
-+#define OP_AggFunc                     125
-+#define OP_AggFocus                    126
-+#define OP_AggSet                      127
-+#define OP_AggGet                      128
-+#define OP_AggNext                     129
-+#define OP_SetInsert                   130
-+#define OP_SetFound                    131
-+#define OP_SetNotFound                 132
-+#define OP_SetFirst                    133
-+#define OP_SetNext                     134
-+#define OP_Vacuum                      135
-+#define OP_StackDepth                  136
-+#define OP_StackReset                  137
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/os.c
-@@ -0,0 +1,1850 @@
-+/*
-+** 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 file contains code that is specific to particular operating
-+** systems.  The purpose of this file is to provide a uniform abstraction
-+** on which the rest of SQLite can operate.
-+*/
-+#include "os.h"          /* Must be first to enable large file support */
-+#include "sqliteInt.h"
-+
-+#if OS_UNIX
-+# include <time.h>
-+# include <errno.h>
-+# include <unistd.h>
-+# 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
-+#endif
-+
-+
-+#if OS_WIN
-+# include <winbase.h>
-+#endif
-+
-+#if OS_MAC
-+# include <extras.h>
-+# include <path2fss.h>
-+# include <TextUtils.h>
-+# include <FinderRegistry.h>
-+# include <Folders.h>
-+# include <Timer.h>
-+# include <OSUtils.h>
-+#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 its DOS - what did you expect?
-+*/
-+#ifdef __DJGPP__
-+# define fcntl(A,B,C) 0
-+#endif
-+
-+/*
-+** Macros used to determine whether or not to use threads.  The
-+** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
-+** Posix threads and SQLITE_W32_THREADS is defined if we are
-+** synchronizing using Win32 threads.
-+*/
-+#if OS_UNIX && defined(THREADSAFE) && THREADSAFE
-+# include <pthread.h>
-+# define SQLITE_UNIX_THREADS 1
-+#endif
-+#if OS_WIN && defined(THREADSAFE) && THREADSAFE
-+# define SQLITE_W32_THREADS 1
-+#endif
-+#if OS_MAC && defined(THREADSAFE) && THREADSAFE
-+# include <Multiprocessing.h>
-+# define SQLITE_MACOS_MULTITASKING 1
-+#endif
-+
-+/*
-+** Macros for performance tracing.  Normally turned off
-+*/
-+#if 0
-+static int last_page = 0;
-+__inline__ unsigned long long int hwtime(void){
-+  unsigned long long int x;
-+  __asm__("rdtsc\n\t"
-+          "mov %%edx, %%ecx\n\t"
-+          :"=A" (x));
-+  return x;
-+}
-+static unsigned long long int g_start;
-+static unsigned int elapse;
-+#define TIMER_START       g_start=hwtime()
-+#define TIMER_END         elapse=hwtime()-g_start
-+#define SEEK(X)           last_page=(X)
-+#define TRACE1(X)         fprintf(stderr,X)
-+#define TRACE2(X,Y)       fprintf(stderr,X,Y)
-+#define TRACE3(X,Y,Z)     fprintf(stderr,X,Y,Z)
-+#define TRACE4(X,Y,Z,A)   fprintf(stderr,X,Y,Z,A)
-+#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
-+#else
-+#define TIMER_START
-+#define TIMER_END
-+#define SEEK(X)
-+#define TRACE1(X)
-+#define TRACE2(X,Y)
-+#define TRACE3(X,Y,Z)
-+#define TRACE4(X,Y,Z,A)
-+#define TRACE5(X,Y,Z,A,B)
-+#endif
-+
-+
-+#if OS_UNIX
-+/*
-+** Here is the dirt on POSIX advisory locks:  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.
-+**
-+** Bummer.  If you ask me, this is broken.  Badly broken.  It 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.
-+**
-+** The OsFile 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 OsFile 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.
-+**
-+** 2004-Jan-11:
-+** More recent discoveries about POSIX advisory locks.  (The more
-+** I discover, the more I realize the a POSIX advisory locks are
-+** an abomination.)
-+**
-+** 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 OsFile structure contains
-+** a pointer to an openCnt structure.  There is one openCnt structure
-+** per open inode, which means that multiple OsFiles can point to a single
-+** openCnt.  When an attempt is made to close an OsFile, if there are
-+** other OsFiles 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 openCnt structure keeps a list of file descriptors that need to
-+** be closed and that list is walked (and cleared) when the last lock
-+** clears.
-+**
-+** First, under Linux threads, because each thread has a separate
-+** process ID, lock operations in one thread do not override locks
-+** to the same file in other threads.  Linux threads behave like
-+** separate processes in this respect.  But, if you close a file
-+** descriptor in linux threads, all locks are cleared, even locks
-+** on other threads and even though the other threads have different
-+** process IDs.  Linux threads is inconsistent in this respect.
-+** (I'm beginning to think that linux threads is an abomination too.)
-+** The consequence of this all is that the hash table for the lockInfo
-+** structure has to include the process id as part of its key because
-+** locks in different threads are treated as distinct.  But the 
-+** openCnt structure should not include the process id in its
-+** key because close() clears lock on all threads, not just the current
-+** thread.  Were it not for this goofiness in linux threads, we could
-+** combine the lockInfo and openCnt structures into a single structure.
-+*/
-+
-+/*
-+** An instance of the following structure serves as the key used
-+** to locate a particular lockInfo structure given its inode.  Note
-+** that we have to include the process ID as part of the key.  On some
-+** threading implementations (ex: linux), each thread has a separate
-+** process ID.
-+*/
-+struct lockKey {
-+  dev_t dev;   /* Device number */
-+  ino_t ino;   /* Inode number */
-+  pid_t pid;   /* Process ID */
-+};
-+
-+/*
-+** An instance of the following structure is allocated for each open
-+** inode on each thread with a different process ID.  (Threads have
-+** different process IDs on linux, but not on most other unixes.)
-+**
-+** A single inode can have multiple file descriptors, so each OsFile
-+** structure contains a pointer to an instance of this object and this
-+** object keeps a count of the number of OsFiles pointing to it.
-+*/
-+struct lockInfo {
-+  struct lockKey key;  /* The lookup key */
-+  int cnt;             /* 0: unlocked.  -1: write lock.  1...: read lock. */
-+  int nRef;            /* Number of pointers to this structure */
-+};
-+
-+/*
-+** An instance of the following structure serves as the key used
-+** to locate a particular openCnt structure given its inode.  This
-+** is the same as the lockKey except that the process ID is omitted.
-+*/
-+struct openKey {
-+  dev_t dev;   /* Device number */
-+  ino_t ino;   /* Inode number */
-+};
-+
-+/*
-+** 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.
-+*/
-+struct openCnt {
-+  struct openKey key;   /* The lookup key */
-+  int nRef;             /* Number of pointers to this structure */
-+  int nLock;            /* Number of outstanding locks */
-+  int nPending;         /* Number of pending close() operations */
-+  int *aPending;        /* Malloced space holding fd's awaiting a close() */
-+};
-+
-+/* 
-+** These hash table maps inodes and process IDs into lockInfo and openCnt
-+** structures.  Access to these hash tables must be protected by a mutex.
-+*/
-+static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
-+static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
-+
-+/*
-+** Release a lockInfo structure previously allocated by findLockInfo().
-+*/
-+static void releaseLockInfo(struct lockInfo *pLock){
-+  pLock->nRef--;
-+  if( pLock->nRef==0 ){
-+    sqliteHashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
-+    sqliteFree(pLock);
-+  }
-+}
-+
-+/*
-+** Release a openCnt structure previously allocated by findLockInfo().
-+*/
-+static void releaseOpenCnt(struct openCnt *pOpen){
-+  pOpen->nRef--;
-+  if( pOpen->nRef==0 ){
-+    sqliteHashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
-+    sqliteFree(pOpen->aPending);
-+    sqliteFree(pOpen);
-+  }
-+}
-+
-+/*
-+** Given a file descriptor, locate lockInfo and openCnt structures that
-+** describes that file descriptor.  Create a new ones if necessary.  The
-+** return values might be unset if an error occurs.
-+**
-+** Return the number of errors.
-+*/
-+int findLockInfo(
-+  int fd,                      /* The file descriptor used in the key */
-+  struct lockInfo **ppLock,    /* Return the lockInfo structure here */
-+  struct openCnt **ppOpen   /* Return the openCnt structure here */
-+){
-+  int rc;
-+  struct lockKey key1;
-+  struct openKey key2;
-+  struct stat statbuf;
-+  struct lockInfo *pLock;
-+  struct openCnt *pOpen;
-+  rc = fstat(fd, &statbuf);
-+  if( rc!=0 ) return 1;
-+  memset(&key1, 0, sizeof(key1));
-+  key1.dev = statbuf.st_dev;
-+  key1.ino = statbuf.st_ino;
-+  key1.pid = getpid();
-+  memset(&key2, 0, sizeof(key2));
-+  key2.dev = statbuf.st_dev;
-+  key2.ino = statbuf.st_ino;
-+  pLock = (struct lockInfo*)sqliteHashFind(&lockHash, &key1, sizeof(key1));
-+  if( pLock==0 ){
-+    struct lockInfo *pOld;
-+    pLock = sqliteMallocRaw( sizeof(*pLock) );
-+    if( pLock==0 ) return 1;
-+    pLock->key = key1;
-+    pLock->nRef = 1;
-+    pLock->cnt = 0;
-+    pOld = sqliteHashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
-+    if( pOld!=0 ){
-+      assert( pOld==pLock );
-+      sqliteFree(pLock);
-+      return 1;
-+    }
-+  }else{
-+    pLock->nRef++;
-+  }
-+  *ppLock = pLock;
-+  pOpen = (struct openCnt*)sqliteHashFind(&openHash, &key2, sizeof(key2));
-+  if( pOpen==0 ){
-+    struct openCnt *pOld;
-+    pOpen = sqliteMallocRaw( sizeof(*pOpen) );
-+    if( pOpen==0 ){
-+      releaseLockInfo(pLock);
-+      return 1;
-+    }
-+    pOpen->key = key2;
-+    pOpen->nRef = 1;
-+    pOpen->nLock = 0;
-+    pOpen->nPending = 0;
-+    pOpen->aPending = 0;
-+    pOld = sqliteHashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
-+    if( pOld!=0 ){
-+      assert( pOld==pOpen );
-+      sqliteFree(pOpen);
-+      releaseLockInfo(pLock);
-+      return 1;
-+    }
-+  }else{
-+    pOpen->nRef++;
-+  }
-+  *ppOpen = pOpen;
-+  return 0;
-+}
-+
-+#endif  /** POSIX advisory lock work-around **/
-+
-+/*
-+** 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
-+int sqlite_io_error_pending = 0;
-+#define SimulateIOError(A)  \
-+   if( sqlite_io_error_pending ) \
-+     if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; }
-+static void local_ioerr(){
-+  sqlite_io_error_pending = 0;  /* Really just a place to set a breakpoint */
-+}
-+#else
-+#define SimulateIOError(A)
-+#endif
-+
-+/*
-+** When testing, keep a count of the number of open files.
-+*/
-+#ifdef SQLITE_TEST
-+int sqlite_open_file_count = 0;
-+#define OpenCounter(X)  sqlite_open_file_count+=(X)
-+#else
-+#define OpenCounter(X)
-+#endif
-+
-+
-+/*
-+** Delete the named file
-+*/
-+int sqliteOsDelete(const char *zFilename){
-+#if OS_UNIX
-+  unlink(zFilename);
-+#endif
-+#if OS_WIN
-+  DeleteFile(zFilename);
-+#endif
-+#if OS_MAC
-+  unlink(zFilename);
-+#endif
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Return TRUE if the named file exists.
-+*/
-+int sqliteOsFileExists(const char *zFilename){
-+#if OS_UNIX
-+  return access(zFilename, 0)==0;
-+#endif
-+#if OS_WIN
-+  return GetFileAttributes(zFilename) != 0xffffffff;
-+#endif
-+#if OS_MAC
-+  return access(zFilename, 0)==0;
-+#endif
-+}
-+
-+
-+#if 0 /* NOT USED */
-+/*
-+** Change the name of an existing file.
-+*/
-+int sqliteOsFileRename(const char *zOldName, const char *zNewName){
-+#if OS_UNIX
-+  if( link(zOldName, zNewName) ){
-+    return SQLITE_ERROR;
-+  }
-+  unlink(zOldName);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  if( !MoveFile(zOldName, zNewName) ){
-+    return SQLITE_ERROR;
-+  }
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  /**** FIX ME ***/
-+  return SQLITE_ERROR;
-+#endif
-+}
-+#endif /* NOT USED */
-+
-+/*
-+** Attempt to open a file for both reading and writing.  If that
-+** fails, try opening it read-only.  If the file does not exist,
-+** try to create it.
-+**
-+** On success, a handle for the open file is written to *id
-+** and *pReadonly is set to 0 if the file was opened for reading and
-+** writing or 1 if the file was opened read-only.  The function returns
-+** SQLITE_OK.
-+**
-+** On failure, the function returns SQLITE_CANTOPEN and leaves
-+** *id and *pReadonly unchanged.
-+*/
-+int sqliteOsOpenReadWrite(
-+  const char *zFilename,
-+  OsFile *id,
-+  int *pReadonly
-+){
-+#if OS_UNIX
-+  int rc;
-+  id->dirfd = -1;
-+  id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
-+  if( id->fd<0 ){
-+#ifdef EISDIR
-+    if( errno==EISDIR ){
-+      return SQLITE_CANTOPEN;
-+    }
-+#endif
-+    id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-+    if( id->fd<0 ){
-+      return SQLITE_CANTOPEN; 
-+    }
-+    *pReadonly = 1;
-+  }else{
-+    *pReadonly = 0;
-+  }
-+  sqliteOsEnterMutex();
-+  rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
-+  sqliteOsLeaveMutex();
-+  if( rc ){
-+    close(id->fd);
-+    return SQLITE_NOMEM;
-+  }
-+  id->locked = 0;
-+  TRACE3("OPEN    %-3d %s\n", id->fd, zFilename);
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  HANDLE h = CreateFile(zFilename,
-+     GENERIC_READ | GENERIC_WRITE,
-+     FILE_SHARE_READ | FILE_SHARE_WRITE,
-+     NULL,
-+     OPEN_ALWAYS,
-+     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-+     NULL
-+  );
-+  if( h==INVALID_HANDLE_VALUE ){
-+    h = CreateFile(zFilename,
-+       GENERIC_READ,
-+       FILE_SHARE_READ,
-+       NULL,
-+       OPEN_ALWAYS,
-+       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-+       NULL
-+    );
-+    if( h==INVALID_HANDLE_VALUE ){
-+      return SQLITE_CANTOPEN;
-+    }
-+    *pReadonly = 1;
-+  }else{
-+    *pReadonly = 0;
-+  }
-+  id->h = h;
-+  id->locked = 0;
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  FSSpec fsSpec;
-+# ifdef _LARGE_FILE
-+  HFSUniStr255 dfName;
-+  FSRef fsRef;
-+  if( __path2fss(zFilename, &fsSpec) != noErr ){
-+    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-+      return SQLITE_CANTOPEN;
-+  }
-+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-+    return SQLITE_CANTOPEN;
-+  FSGetDataForkName(&dfName);
-+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-+                 fsRdWrShPerm, &(id->refNum)) != noErr ){
-+    if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-+                   fsRdWrPerm, &(id->refNum)) != noErr ){
-+      if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-+                   fsRdPerm, &(id->refNum)) != noErr )
-+        return SQLITE_CANTOPEN;
-+      else
-+        *pReadonly = 1;
-+    } else
-+      *pReadonly = 0;
-+  } else
-+    *pReadonly = 0;
-+# else
-+  __path2fss(zFilename, &fsSpec);
-+  if( !sqliteOsFileExists(zFilename) ){
-+    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-+      return SQLITE_CANTOPEN;
-+  }
-+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
-+    if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
-+      if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
-+        return SQLITE_CANTOPEN;
-+      else
-+        *pReadonly = 1;
-+    } else
-+      *pReadonly = 0;
-+  } else
-+    *pReadonly = 0;
-+# endif
-+  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
-+    id->refNumRF = -1;
-+  }
-+  id->locked = 0;
-+  id->delOnClose = 0;
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+}
-+
-+
-+/*
-+** Attempt to open a new file for exclusive access by this process.
-+** The file will be opened for both reading and writing.  To avoid
-+** a potential security problem, we do not allow the file to have
-+** previously existed.  Nor do we allow the file to be a symbolic
-+** link.
-+**
-+** If delFlag is true, then make arrangements to automatically delete
-+** the file when it is closed.
-+**
-+** On success, write the file handle into *id and return SQLITE_OK.
-+**
-+** On failure, return SQLITE_CANTOPEN.
-+*/
-+int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
-+#if OS_UNIX
-+  int rc;
-+  if( access(zFilename, 0)==0 ){
-+    return SQLITE_CANTOPEN;
-+  }
-+  id->dirfd = -1;
-+  id->fd = open(zFilename,
-+                O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
-+  if( id->fd<0 ){
-+    return SQLITE_CANTOPEN;
-+  }
-+  sqliteOsEnterMutex();
-+  rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
-+  sqliteOsLeaveMutex();
-+  if( rc ){
-+    close(id->fd);
-+    unlink(zFilename);
-+    return SQLITE_NOMEM;
-+  }
-+  id->locked = 0;
-+  if( delFlag ){
-+    unlink(zFilename);
-+  }
-+  TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  HANDLE h;
-+  int fileflags;
-+  if( delFlag ){
-+    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
-+                     | FILE_FLAG_DELETE_ON_CLOSE;
-+  }else{
-+    fileflags = FILE_FLAG_RANDOM_ACCESS;
-+  }
-+  h = CreateFile(zFilename,
-+     GENERIC_READ | GENERIC_WRITE,
-+     0,
-+     NULL,
-+     CREATE_ALWAYS,
-+     fileflags,
-+     NULL
-+  );
-+  if( h==INVALID_HANDLE_VALUE ){
-+    return SQLITE_CANTOPEN;
-+  }
-+  id->h = h;
-+  id->locked = 0;
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  FSSpec fsSpec;
-+# ifdef _LARGE_FILE
-+  HFSUniStr255 dfName;
-+  FSRef fsRef;
-+  __path2fss(zFilename, &fsSpec);
-+  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-+    return SQLITE_CANTOPEN;
-+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-+    return SQLITE_CANTOPEN;
-+  FSGetDataForkName(&dfName);
-+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-+                 fsRdWrPerm, &(id->refNum)) != noErr )
-+    return SQLITE_CANTOPEN;
-+# else
-+  __path2fss(zFilename, &fsSpec);
-+  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-+    return SQLITE_CANTOPEN;
-+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
-+    return SQLITE_CANTOPEN;
-+# endif
-+  id->refNumRF = -1;
-+  id->locked = 0;
-+  id->delOnClose = delFlag;
-+  if (delFlag)
-+    id->pathToDel = sqliteOsFullPathname(zFilename);
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+}
-+
-+/*
-+** Attempt to open a new file for read-only access.
-+**
-+** On success, write the file handle into *id and return SQLITE_OK.
-+**
-+** On failure, return SQLITE_CANTOPEN.
-+*/
-+int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
-+#if OS_UNIX
-+  int rc;
-+  id->dirfd = -1;
-+  id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
-+  if( id->fd<0 ){
-+    return SQLITE_CANTOPEN;
-+  }
-+  sqliteOsEnterMutex();
-+  rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
-+  sqliteOsLeaveMutex();
-+  if( rc ){
-+    close(id->fd);
-+    return SQLITE_NOMEM;
-+  }
-+  id->locked = 0;
-+  TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  HANDLE h = CreateFile(zFilename,
-+     GENERIC_READ,
-+     0,
-+     NULL,
-+     OPEN_EXISTING,
-+     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-+     NULL
-+  );
-+  if( h==INVALID_HANDLE_VALUE ){
-+    return SQLITE_CANTOPEN;
-+  }
-+  id->h = h;
-+  id->locked = 0;
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  FSSpec fsSpec;
-+# ifdef _LARGE_FILE
-+  HFSUniStr255 dfName;
-+  FSRef fsRef;
-+  if( __path2fss(zFilename, &fsSpec) != noErr )
-+    return SQLITE_CANTOPEN;
-+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-+    return SQLITE_CANTOPEN;
-+  FSGetDataForkName(&dfName);
-+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-+                 fsRdPerm, &(id->refNum)) != noErr )
-+    return SQLITE_CANTOPEN;
-+# else
-+  __path2fss(zFilename, &fsSpec);
-+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
-+    return SQLITE_CANTOPEN;
-+# endif
-+  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
-+    id->refNumRF = -1;
-+  }
-+  id->locked = 0;
-+  id->delOnClose = 0;
-+  OpenCounter(+1);
-+  return SQLITE_OK;
-+#endif
-+}
-+
-+/*
-+** Attempt to open a file descriptor for the directory that contains a
-+** file.  This file descriptor can be used to fsync() the directory
-+** in order to make sure the creation of a new file is actually written
-+** to disk.
-+**
-+** This routine is only meaningful for Unix.  It is a no-op under
-+** windows since windows does not support hard links.
-+**
-+** On success, a handle for a previously open file is at *id is
-+** updated with the new directory file descriptor and SQLITE_OK is
-+** returned.
-+**
-+** On failure, the function returns SQLITE_CANTOPEN and leaves
-+** *id unchanged.
-+*/
-+int sqliteOsOpenDirectory(
-+  const char *zDirname,
-+  OsFile *id
-+){
-+#if OS_UNIX
-+  if( id->fd<0 ){
-+    /* Do not open the directory if the corresponding file is not already
-+    ** open. */
-+    return SQLITE_CANTOPEN;
-+  }
-+  assert( id->dirfd<0 );
-+  id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
-+  if( id->dirfd<0 ){
-+    return SQLITE_CANTOPEN; 
-+  }
-+  TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
-+#endif
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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.
-+*/
-+const char *sqlite_temp_directory = 0;
-+
-+/*
-+** Create a temporary file name in zBuf.  zBuf must be big enough to
-+** hold at least SQLITE_TEMPNAME_SIZE characters.
-+*/
-+int sqliteOsTempFileName(char *zBuf){
-+#if OS_UNIX
-+  static const char *azDirs[] = {
-+     0,
-+     "/var/tmp",
-+     "/usr/tmp",
-+     "/tmp",
-+     ".",
-+  };
-+  static unsigned char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  int i, j;
-+  struct stat buf;
-+  const char *zDir = ".";
-+  azDirs[0] = sqlite_temp_directory;
-+  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;
-+  }
-+  do{
-+    sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
-+    j = strlen(zBuf);
-+    sqliteRandomness(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 );
-+#endif
-+#if OS_WIN
-+  static char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  int i, j;
-+  const char *zDir;
-+  char zTempPath[SQLITE_TEMPNAME_SIZE];
-+  if( sqlite_temp_directory==0 ){
-+    GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
-+    for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
-+    zTempPath[i] = 0;
-+    zDir = zTempPath;
-+  }else{
-+    zDir = sqlite_temp_directory;
-+  }
-+  for(;;){
-+    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zDir);
-+    j = strlen(zBuf);
-+    sqliteRandomness(15, &zBuf[j]);
-+    for(i=0; i<15; i++, j++){
-+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-+    }
-+    zBuf[j] = 0;
-+    if( !sqliteOsFileExists(zBuf) ) break;
-+  }
-+#endif
-+#if OS_MAC
-+  static char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  int i, j;
-+  char *zDir;
-+  char zTempPath[SQLITE_TEMPNAME_SIZE];
-+  char zdirName[32];
-+  CInfoPBRec infoRec;
-+  Str31 dirName;
-+  memset(&infoRec, 0, sizeof(infoRec));
-+  memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
-+  if( sqlite_temp_directory!=0 ){
-+    zDir = sqlite_temp_directory;
-+  }else if( FindFolder(kOnSystemDisk, kTemporaryFolderType,  kCreateFolder,
-+       &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
-+    infoRec.dirInfo.ioNamePtr = dirName;
-+    do{
-+      infoRec.dirInfo.ioFDirIndex = -1;
-+      infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
-+      if( PBGetCatInfoSync(&infoRec) == noErr ){
-+        CopyPascalStringToC(dirName, zdirName);
-+        i = strlen(zdirName);
-+        memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
-+        strcpy(zTempPath, zdirName);
-+        zTempPath[i] = ':';
-+      }else{
-+        *zTempPath = 0;
-+        break;
-+      }
-+    } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
-+    zDir = zTempPath;
-+  }
-+  if( zDir[0]==0 ){
-+    getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
-+    zDir = zTempPath;
-+  }
-+  for(;;){
-+    sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zDir);
-+    j = strlen(zBuf);
-+    sqliteRandomness(15, &zBuf[j]);
-+    for(i=0; i<15; i++, j++){
-+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-+    }
-+    zBuf[j] = 0;
-+    if( !sqliteOsFileExists(zBuf) ) break;
-+  }
-+#endif
-+  return SQLITE_OK; 
-+}
-+
-+/*
-+** Close a file.
-+*/
-+int sqliteOsClose(OsFile *id){
-+#if OS_UNIX
-+  sqliteOsUnlock(id);
-+  if( id->dirfd>=0 ) close(id->dirfd);
-+  id->dirfd = -1;
-+  sqliteOsEnterMutex();
-+  if( id->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.
-+    */
-+    int *aNew;
-+    struct openCnt *pOpen = id->pOpen;
-+    pOpen->nPending++;
-+    aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
-+    if( aNew==0 ){
-+      /* If a malloc fails, just leak the file descriptor */
-+    }else{
-+      pOpen->aPending = aNew;
-+      pOpen->aPending[pOpen->nPending-1] = id->fd;
-+    }
-+  }else{
-+    /* There are no outstanding locks so we can close the file immediately */
-+    close(id->fd);
-+  }
-+  releaseLockInfo(id->pLock);
-+  releaseOpenCnt(id->pOpen);
-+  sqliteOsLeaveMutex();
-+  TRACE2("CLOSE   %-3d\n", id->fd);
-+  OpenCounter(-1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  CloseHandle(id->h);
-+  OpenCounter(-1);
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  if( id->refNumRF!=-1 )
-+    FSClose(id->refNumRF);
-+# ifdef _LARGE_FILE
-+  FSCloseFork(id->refNum);
-+# else
-+  FSClose(id->refNum);
-+# endif
-+  if( id->delOnClose ){
-+    unlink(id->pathToDel);
-+    sqliteFree(id->pathToDel);
-+  }
-+  OpenCounter(-1);
-+  return SQLITE_OK;
-+#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.
-+*/
-+int sqliteOsRead(OsFile *id, void *pBuf, int amt){
-+#if OS_UNIX
-+  int got;
-+  SimulateIOError(SQLITE_IOERR);
-+  TIMER_START;
-+  got = read(id->fd, pBuf, amt);
-+  TIMER_END;
-+  TRACE4("READ    %-3d %7d %d\n", id->fd, last_page, elapse);
-+  SEEK(0);
-+  /* if( got<0 ) got = 0; */
-+  if( got==amt ){
-+    return SQLITE_OK;
-+  }else{
-+    return SQLITE_IOERR;
-+  }
-+#endif
-+#if OS_WIN
-+  DWORD got;
-+  SimulateIOError(SQLITE_IOERR);
-+  TRACE2("READ %d\n", last_page);
-+  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
-+    got = 0;
-+  }
-+  if( got==(DWORD)amt ){
-+    return SQLITE_OK;
-+  }else{
-+    return SQLITE_IOERR;
-+  }
-+#endif
-+#if OS_MAC
-+  int got;
-+  SimulateIOError(SQLITE_IOERR);
-+  TRACE2("READ %d\n", last_page);
-+# ifdef _LARGE_FILE
-+  FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
-+# else
-+  got = amt;
-+  FSRead(id->refNum, &got, pBuf);
-+# endif
-+  if( got==amt ){
-+    return SQLITE_OK;
-+  }else{
-+    return SQLITE_IOERR;
-+  }
-+#endif
-+}
-+
-+/*
-+** Write data from a buffer into a file.  Return SQLITE_OK on success
-+** or some other error code on failure.
-+*/
-+int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
-+#if OS_UNIX
-+  int wrote = 0;
-+  SimulateIOError(SQLITE_IOERR);
-+  TIMER_START;
-+  while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
-+    amt -= wrote;
-+    pBuf = &((char*)pBuf)[wrote];
-+  }
-+  TIMER_END;
-+  TRACE4("WRITE   %-3d %7d %d\n", id->fd, last_page, elapse);
-+  SEEK(0);
-+  if( amt>0 ){
-+    return SQLITE_FULL;
-+  }
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  int rc;
-+  DWORD wrote;
-+  SimulateIOError(SQLITE_IOERR);
-+  TRACE2("WRITE %d\n", last_page);
-+  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
-+    amt -= wrote;
-+    pBuf = &((char*)pBuf)[wrote];
-+  }
-+  if( !rc || amt>(int)wrote ){
-+    return SQLITE_FULL;
-+  }
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  OSErr oserr;
-+  int wrote = 0;
-+  SimulateIOError(SQLITE_IOERR);
-+  TRACE2("WRITE %d\n", last_page);
-+  while( amt>0 ){
-+# ifdef _LARGE_FILE
-+    oserr = FSWriteFork(id->refNum, fsAtMark, 0,
-+                        (ByteCount)amt, pBuf, (ByteCount*)&wrote);
-+# else
-+    wrote = amt;
-+    oserr = FSWrite(id->refNum, &wrote, pBuf);
-+# endif
-+    if( wrote == 0 || oserr != noErr)
-+      break;
-+    amt -= wrote;
-+    pBuf = &((char*)pBuf)[wrote];
-+  }
-+  if( oserr != noErr || amt>wrote ){
-+    return SQLITE_FULL;
-+  }
-+  return SQLITE_OK;
-+#endif
-+}
-+
-+/*
-+** Move the read/write pointer in a file.
-+*/
-+int sqliteOsSeek(OsFile *id, off_t offset){
-+  SEEK(offset/1024 + 1);
-+#if OS_UNIX
-+  lseek(id->fd, offset, SEEK_SET);
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  {
-+    LONG upperBits = offset>>32;
-+    LONG lowerBits = offset & 0xffffffff;
-+    DWORD rc;
-+    rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
-+    /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
-+  }
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+  {
-+    off_t curSize;
-+    if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){
-+      return SQLITE_IOERR;
-+    }
-+    if( offset >= curSize ){
-+      if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){
-+        return SQLITE_IOERR;
-+      }
-+    }
-+# ifdef _LARGE_FILE
-+    if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
-+# else
-+    if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
-+# endif
-+      return SQLITE_IOERR;
-+    }else{
-+      return SQLITE_OK;
-+    }
-+  }
-+#endif
-+}
-+
-+#ifdef SQLITE_NOSYNC
-+# define fsync(X) 0
-+#endif
-+
-+/*
-+** Make sure all writes to a particular file are committed to disk.
-+**
-+** 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.
-+*/
-+int sqliteOsSync(OsFile *id){
-+#if OS_UNIX
-+  SimulateIOError(SQLITE_IOERR);
-+  TRACE2("SYNC    %-3d\n", id->fd);
-+  if( fsync(id->fd) ){
-+    return SQLITE_IOERR;
-+  }else{
-+    if( id->dirfd>=0 ){
-+      TRACE2("DIRSYNC %-3d\n", id->dirfd);
-+      fsync(id->dirfd);
-+      close(id->dirfd);  /* Only need to sync once, so close the directory */
-+      id->dirfd = -1;    /* when we are done. */
-+    }
-+    return SQLITE_OK;
-+  }
-+#endif
-+#if OS_WIN
-+  if( FlushFileBuffers(id->h) ){
-+    return SQLITE_OK;
-+  }else{
-+    return SQLITE_IOERR;
-+  }
-+#endif
-+#if OS_MAC
-+# ifdef _LARGE_FILE
-+  if( FSFlushFork(id->refNum) != noErr ){
-+# else
-+  ParamBlockRec params;
-+  memset(&params, 0, sizeof(ParamBlockRec));
-+  params.ioParam.ioRefNum = id->refNum;
-+  if( PBFlushFileSync(&params) != noErr ){
-+# endif
-+    return SQLITE_IOERR;
-+  }else{
-+    return SQLITE_OK;
-+  }
-+#endif
-+}
-+
-+/*
-+** Truncate an open file to a specified size
-+*/
-+int sqliteOsTruncate(OsFile *id, off_t nByte){
-+  SimulateIOError(SQLITE_IOERR);
-+#if OS_UNIX
-+  return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
-+#endif
-+#if OS_WIN
-+  {
-+    LONG upperBits = nByte>>32;
-+    SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
-+    SetEndOfFile(id->h);
-+  }
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+# ifdef _LARGE_FILE
-+  if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
-+# else
-+  if( SetEOF(id->refNum, nByte) != noErr ){
-+# endif
-+    return SQLITE_IOERR;
-+  }else{
-+    return SQLITE_OK;
-+  }
-+#endif
-+}
-+
-+/*
-+** Determine the current size of a file in bytes
-+*/
-+int sqliteOsFileSize(OsFile *id, off_t *pSize){
-+#if OS_UNIX
-+  struct stat buf;
-+  SimulateIOError(SQLITE_IOERR);
-+  if( fstat(id->fd, &buf)!=0 ){
-+    return SQLITE_IOERR;
-+  }
-+  *pSize = buf.st_size;
-+  return SQLITE_OK;
-+#endif
-+#if OS_WIN
-+  DWORD upperBits, lowerBits;
-+  SimulateIOError(SQLITE_IOERR);
-+  lowerBits = GetFileSize(id->h, &upperBits);
-+  *pSize = (((off_t)upperBits)<<32) + lowerBits;
-+  return SQLITE_OK;
-+#endif
-+#if OS_MAC
-+# ifdef _LARGE_FILE
-+  if( FSGetForkSize(id->refNum, pSize) != noErr){
-+# else
-+  if( GetEOF(id->refNum, pSize) != noErr ){
-+# endif
-+    return SQLITE_IOERR;
-+  }else{
-+    return SQLITE_OK;
-+  }
-+#endif
-+}
-+
-+#if OS_WIN
-+/*
-+** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
-+** 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.
-+*/
-+int isNT(void){
-+  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
-+  if( osType==0 ){
-+    OSVERSIONINFO sInfo;
-+    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-+    GetVersionEx(&sInfo);
-+    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
-+  }
-+  return osType==2;
-+}
-+#endif
-+
-+/*
-+** Windows file locking notes:  [similar issues apply to MacOS]
-+**
-+** 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.
-+** (This is a design error on the part of Windows, but there is nothing
-+** we can do about that.)  So the region used for locking is at the
-+** end of the file where it is unlikely to ever interfere with an
-+** actual read attempt.
-+**
-+** A database read 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.
-+** A database write lock is obtained by locking all bytes in the range.
-+** There can only be one writer.
-+**
-+** A lock is obtained on the first byte of the lock range before acquiring
-+** either a read lock or a write lock.  This prevents two processes from
-+** attempting to get a lock at a same time.  The semantics of 
-+** sqliteOsReadLock() require that if there is already a write lock, that
-+** lock is converted into a read lock atomically.  The lock on the first
-+** byte allows us to drop the old write lock and get the read lock without
-+** another process jumping into the middle and messing us up.  The same
-+** argument applies to sqliteOsWriteLock().
-+**
-+** 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.
-+**
-+** Note: On MacOS we use the resource fork for locking.
-+**
-+** The following #defines specify the range of bytes used for locking.
-+** N_LOCKBYTE is the number of bytes available for doing the locking.
-+** The first byte used to hold the lock while the lock is changing does
-+** not count toward this number.  FIRST_LOCKBYTE is the address of
-+** the first byte in the range of bytes used for locking.
-+*/
-+#define N_LOCKBYTE       10239
-+#if OS_MAC
-+# define FIRST_LOCKBYTE   (0x000fffff - N_LOCKBYTE)
-+#else
-+# define FIRST_LOCKBYTE   (0xffffffff - N_LOCKBYTE)
-+#endif
-+
-+/*
-+** Change the status of the lock on the file "id" to be a readlock.
-+** If the file was write locked, then this reduces the lock to a read.
-+** If the file was read locked, then this acquires a new read lock.
-+**
-+** Return SQLITE_OK on success and SQLITE_BUSY on failure.  If this
-+** library was compiled with large file support (LFS) but LFS is not
-+** available on the host, then an SQLITE_NOLFS is returned.
-+*/
-+int sqliteOsReadLock(OsFile *id){
-+#if OS_UNIX
-+  int rc;
-+  sqliteOsEnterMutex();
-+  if( id->pLock->cnt>0 ){
-+    if( !id->locked ){
-+      id->pLock->cnt++;
-+      id->locked = 1;
-+      id->pOpen->nLock++;
-+    }
-+    rc = SQLITE_OK;
-+  }else if( id->locked || id->pLock->cnt==0 ){
-+    struct flock lock;
-+    int s;
-+    lock.l_type = F_RDLCK;
-+    lock.l_whence = SEEK_SET;
-+    lock.l_start = lock.l_len = 0L;
-+    s = fcntl(id->fd, F_SETLK, &lock);
-+    if( s!=0 ){
-+      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
-+    }else{
-+      rc = SQLITE_OK;
-+      if( !id->locked ){
-+        id->pOpen->nLock++;
-+        id->locked = 1;
-+      }
-+      id->pLock->cnt = 1;
-+    }
-+  }else{
-+    rc = SQLITE_BUSY;
-+  }
-+  sqliteOsLeaveMutex();
-+  return rc;
-+#endif
-+#if OS_WIN
-+  int rc;
-+  if( id->locked>0 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    int lk;
-+    int res;
-+    int cnt = 100;
-+    sqliteRandomness(sizeof(lk), &lk);
-+    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
-+    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
-+      Sleep(1);
-+    }
-+    if( res ){
-+      UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-+      if( isNT() ){
-+        OVERLAPPED ovlp;
-+        ovlp.Offset = FIRST_LOCKBYTE+1;
-+        ovlp.OffsetHigh = 0;
-+        ovlp.hEvent = 0;
-+        res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 
-+                          0, N_LOCKBYTE, 0, &ovlp);
-+      }else{
-+        res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
-+      }
-+      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
-+    }
-+    if( res ){
-+      id->locked = lk;
-+      rc = SQLITE_OK;
-+    }else{
-+      rc = SQLITE_BUSY;
-+    }
-+  }
-+  return rc;
-+#endif
-+#if OS_MAC
-+  int rc;
-+  if( id->locked>0 || id->refNumRF == -1 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    int lk;
-+    OSErr res;
-+    int cnt = 5;
-+    ParamBlockRec params;
-+    sqliteRandomness(sizeof(lk), &lk);
-+    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
-+    memset(&params, 0, sizeof(params));
-+    params.ioParam.ioRefNum = id->refNumRF;
-+    params.ioParam.ioPosMode = fsFromStart;
-+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-+    params.ioParam.ioReqCount = 1;
-+    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
-+      UInt32 finalTicks;
-+      Delay(1, &finalTicks); /* 1/60 sec */
-+    }
-+    if( res == noErr ){
-+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-+      params.ioParam.ioReqCount = N_LOCKBYTE;
-+      PBUnlockRangeSync(&params);
-+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
-+      params.ioParam.ioReqCount = 1;
-+      res = PBLockRangeSync(&params);
-+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-+      params.ioParam.ioReqCount = 1;
-+      PBUnlockRangeSync(&params);
-+    }
-+    if( res == noErr ){
-+      id->locked = lk;
-+      rc = SQLITE_OK;
-+    }else{
-+      rc = SQLITE_BUSY;
-+    }
-+  }
-+  return rc;
-+#endif
-+}
-+
-+/*
-+** Change the lock status to be an exclusive or write lock.  Return
-+** SQLITE_OK on success and SQLITE_BUSY on a failure.  If this
-+** library was compiled with large file support (LFS) but LFS is not
-+** available on the host, then an SQLITE_NOLFS is returned.
-+*/
-+int sqliteOsWriteLock(OsFile *id){
-+#if OS_UNIX
-+  int rc;
-+  sqliteOsEnterMutex();
-+  if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
-+    struct flock lock;
-+    int s;
-+    lock.l_type = F_WRLCK;
-+    lock.l_whence = SEEK_SET;
-+    lock.l_start = lock.l_len = 0L;
-+    s = fcntl(id->fd, F_SETLK, &lock);
-+    if( s!=0 ){
-+      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
-+    }else{
-+      rc = SQLITE_OK;
-+      if( !id->locked ){
-+        id->pOpen->nLock++;
-+        id->locked = 1;
-+      }
-+      id->pLock->cnt = -1;
-+    }
-+  }else{
-+    rc = SQLITE_BUSY;
-+  }
-+  sqliteOsLeaveMutex();
-+  return rc;
-+#endif
-+#if OS_WIN
-+  int rc;
-+  if( id->locked<0 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    int res;
-+    int cnt = 100;
-+    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
-+      Sleep(1);
-+    }
-+    if( res ){
-+      if( id->locked>0 ){
-+        if( isNT() ){
-+          UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-+        }else{
-+          res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
-+        }
-+      }
-+      if( res ){
-+        res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-+      }else{
-+        res = 0;
-+      }
-+      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
-+    }
-+    if( res ){
-+      id->locked = -1;
-+      rc = SQLITE_OK;
-+    }else{
-+      rc = SQLITE_BUSY;
-+    }
-+  }
-+  return rc;
-+#endif
-+#if OS_MAC
-+  int rc;
-+  if( id->locked<0 || id->refNumRF == -1 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    OSErr res;
-+    int cnt = 5;
-+    ParamBlockRec params;
-+    memset(&params, 0, sizeof(params));
-+    params.ioParam.ioRefNum = id->refNumRF;
-+    params.ioParam.ioPosMode = fsFromStart;
-+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-+    params.ioParam.ioReqCount = 1;
-+    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
-+      UInt32 finalTicks;
-+      Delay(1, &finalTicks); /* 1/60 sec */
-+    }
-+    if( res == noErr ){
-+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
-+      params.ioParam.ioReqCount = 1;
-+      if( id->locked==0 
-+            || PBUnlockRangeSync(&params)==noErr ){
-+        params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-+        params.ioParam.ioReqCount = N_LOCKBYTE;
-+        res = PBLockRangeSync(&params);
-+      }else{
-+        res = afpRangeNotLocked;
-+      }
-+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-+      params.ioParam.ioReqCount = 1;
-+      PBUnlockRangeSync(&params);
-+    }
-+    if( res == noErr ){
-+      id->locked = -1;
-+      rc = SQLITE_OK;
-+    }else{
-+      rc = SQLITE_BUSY;
-+    }
-+  }
-+  return rc;
-+#endif
-+}
-+
-+/*
-+** Unlock the given file descriptor.  If the file descriptor was
-+** not previously locked, then this routine is a no-op.  If this
-+** library was compiled with large file support (LFS) but LFS is not
-+** available on the host, then an SQLITE_NOLFS is returned.
-+*/
-+int sqliteOsUnlock(OsFile *id){
-+#if OS_UNIX
-+  int rc;
-+  if( !id->locked ) return SQLITE_OK;
-+  sqliteOsEnterMutex();
-+  assert( id->pLock->cnt!=0 );
-+  if( id->pLock->cnt>1 ){
-+    id->pLock->cnt--;
-+    rc = SQLITE_OK;
-+  }else{
-+    struct flock lock;
-+    int s;
-+    lock.l_type = F_UNLCK;
-+    lock.l_whence = SEEK_SET;
-+    lock.l_start = lock.l_len = 0L;
-+    s = fcntl(id->fd, F_SETLK, &lock);
-+    if( s!=0 ){
-+      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
-+    }else{
-+      rc = SQLITE_OK;
-+      id->pLock->cnt = 0;
-+    }
-+  }
-+  if( rc==SQLITE_OK ){
-+    /* 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.
-+    */
-+    struct openCnt *pOpen = id->pOpen;
-+    pOpen->nLock--;
-+    assert( pOpen->nLock>=0 );
-+    if( pOpen->nLock==0 && pOpen->nPending>0 ){
-+      int i;
-+      for(i=0; i<pOpen->nPending; i++){
-+        close(pOpen->aPending[i]);
-+      }
-+      sqliteFree(pOpen->aPending);
-+      pOpen->nPending = 0;
-+      pOpen->aPending = 0;
-+    }
-+  }
-+  sqliteOsLeaveMutex();
-+  id->locked = 0;
-+  return rc;
-+#endif
-+#if OS_WIN
-+  int rc;
-+  if( id->locked==0 ){
-+    rc = SQLITE_OK;
-+  }else if( isNT() || id->locked<0 ){
-+    UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-+    rc = SQLITE_OK;
-+    id->locked = 0;
-+  }else{
-+    UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
-+    rc = SQLITE_OK;
-+    id->locked = 0;
-+  }
-+  return rc;
-+#endif
-+#if OS_MAC
-+  int rc;
-+  ParamBlockRec params;
-+  memset(&params, 0, sizeof(params));
-+  params.ioParam.ioRefNum = id->refNumRF;
-+  params.ioParam.ioPosMode = fsFromStart;
-+  if( id->locked==0 || id->refNumRF == -1 ){
-+    rc = SQLITE_OK;
-+  }else if( id->locked<0 ){
-+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-+    params.ioParam.ioReqCount = N_LOCKBYTE;
-+    PBUnlockRangeSync(&params);
-+    rc = SQLITE_OK;
-+    id->locked = 0;
-+  }else{
-+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
-+    params.ioParam.ioReqCount = 1;
-+    PBUnlockRangeSync(&params);
-+    rc = SQLITE_OK;
-+    id->locked = 0;
-+  }
-+  return rc;
-+#endif
-+}
-+
-+/*
-+** Get information to seed the random number generator.  The seed
-+** is written into the buffer zBuf[256].  The calling function must
-+** supply a sufficiently large buffer.
-+*/
-+int sqliteOsRandomSeed(char *zBuf){
-+  /* 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, 256);
-+#if OS_UNIX && !defined(SQLITE_TEST)
-+  {
-+    int pid;
-+    time((time_t*)zBuf);
-+    pid = getpid();
-+    memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
-+  }
-+#endif
-+#if OS_WIN && !defined(SQLITE_TEST)
-+  GetSystemTime((LPSYSTEMTIME)zBuf);
-+#endif
-+#if OS_MAC
-+  {
-+    int pid;
-+    Microseconds((UnsignedWide*)zBuf);
-+    pid = getpid();
-+    memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
-+  }
-+#endif
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Sleep for a little while.  Return the amount of time slept.
-+*/
-+int sqliteOsSleep(int ms){
-+#if OS_UNIX
-+#if defined(HAVE_USLEEP) && HAVE_USLEEP
-+  usleep(ms*1000);
-+  return ms;
-+#else
-+  sleep((ms+999)/1000);
-+  return 1000*((ms+999)/1000);
-+#endif
-+#endif
-+#if OS_WIN
-+  Sleep(ms);
-+  return ms;
-+#endif
-+#if OS_MAC
-+  UInt32 finalTicks;
-+  UInt32 ticks = (((UInt32)ms+16)*3)/50;  /* 1/60 sec per tick */
-+  Delay(ticks, &finalTicks);
-+  return (int)((ticks*50)/3);
-+#endif
-+}
-+
-+/*
-+** Static variables used for thread synchronization
-+*/
-+static int inMutex = 0;
-+#ifdef SQLITE_UNIX_THREADS
-+  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-+#endif
-+#ifdef SQLITE_W32_THREADS
-+  static CRITICAL_SECTION cs;
-+#endif
-+#ifdef SQLITE_MACOS_MULTITASKING
-+  static MPCriticalRegionID criticalRegion;
-+#endif
-+
-+/*
-+** The following pair of routine implement mutual exclusion for
-+** multi-threaded processes.  Only a single thread is allowed to
-+** executed code that is surrounded by EnterMutex() and LeaveMutex().
-+**
-+** SQLite uses only a single Mutex.  There is not much critical
-+** code and what little there is executes quickly and without blocking.
-+*/
-+void sqliteOsEnterMutex(){
-+#ifdef SQLITE_UNIX_THREADS
-+  pthread_mutex_lock(&mutex);
-+#endif
-+#ifdef SQLITE_W32_THREADS
-+  static int isInit = 0;
-+  while( !isInit ){
-+    static long lock = 0;
-+    if( InterlockedIncrement(&lock)==1 ){
-+      InitializeCriticalSection(&cs);
-+      isInit = 1;
-+    }else{
-+      Sleep(1);
-+    }
-+  }
-+  EnterCriticalSection(&cs);
-+#endif
-+#ifdef SQLITE_MACOS_MULTITASKING
-+  static volatile int notInit = 1;
-+  if( notInit ){
-+    if( notInit == 2 ) /* as close as you can get to thread safe init */
-+      MPYield();
-+    else{
-+      notInit = 2;
-+      MPCreateCriticalRegion(&criticalRegion);
-+      notInit = 0;
-+    }
-+  }
-+  MPEnterCriticalRegion(criticalRegion, kDurationForever);
-+#endif
-+  assert( !inMutex );
-+  inMutex = 1;
-+}
-+void sqliteOsLeaveMutex(){
-+  assert( inMutex );
-+  inMutex = 0;
-+#ifdef SQLITE_UNIX_THREADS
-+  pthread_mutex_unlock(&mutex);
-+#endif
-+#ifdef SQLITE_W32_THREADS
-+  LeaveCriticalSection(&cs);
-+#endif
-+#ifdef SQLITE_MACOS_MULTITASKING
-+  MPExitCriticalRegion(criticalRegion);
-+#endif
-+}
-+
-+/*
-+** Turn a relative pathname into a full pathname.  Return a pointer
-+** to the full pathname stored in space obtained from sqliteMalloc().
-+** The calling function is responsible for freeing this space once it
-+** is no longer needed.
-+*/
-+char *sqliteOsFullPathname(const char *zRelative){
-+#if OS_UNIX
-+  char *zFull = 0;
-+  if( zRelative[0]=='/' ){
-+    sqliteSetString(&zFull, zRelative, (char*)0);
-+  }else{
-+    char zBuf[5000];
-+    zBuf[0] = 0;
-+    sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
-+                    (char*)0);
-+  }
-+  return zFull;
-+#endif
-+#if OS_WIN
-+  char *zNotUsed;
-+  char *zFull;
-+  int nByte;
-+  nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
-+  zFull = sqliteMalloc( nByte );
-+  if( zFull==0 ) return 0;
-+  GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
-+  return zFull;
-+#endif
-+#if OS_MAC
-+  char *zFull = 0;
-+  if( zRelative[0]==':' ){
-+    char zBuf[_MAX_PATH+1];
-+    sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
-+                    (char*)0);
-+  }else{
-+    if( strchr(zRelative, ':') ){
-+      sqliteSetString(&zFull, zRelative, (char*)0);
-+    }else{
-+    char zBuf[_MAX_PATH+1];
-+      sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
-+    }
-+  }
-+  return zFull;
-+#endif
-+}
-+
-+/*
-+** The following variable, if set to a non-zero value, becomes the result
-+** returned from sqliteOsCurrentTime().  This is used for testing.
-+*/
-+#ifdef SQLITE_TEST
-+int sqlite_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 sqliteOsCurrentTime(double *prNow){
-+#if OS_UNIX
-+  time_t t;
-+  time(&t);
-+  *prNow = t/86400.0 + 2440587.5;
-+#endif
-+#if OS_WIN
-+  FILETIME ft;
-+  /* FILETIME structure is a 64-bit value representing the number of 
-+     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
-+  */
-+  double now;
-+  GetSystemTimeAsFileTime( &ft );
-+  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
-+  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
-+#endif
-+#ifdef SQLITE_TEST
-+  if( sqlite_current_time ){
-+    *prNow = sqlite_current_time/86400.0 + 2440587.5;
-+  }
-+#endif
-+  return 0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/os.h
-@@ -0,0 +1,191 @@
-+/*
-+** 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.
-+*/
-+#ifndef _SQLITE_OS_H_
-+#define _SQLITE_OS_H_
-+
-+/*
-+** Helpful hint:  To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
-+** to the compiler command line.
-+*/
-+
-+/*
-+** 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.
-+**
-+** 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.
-+**
-+** Similar is true for MacOS.  LFS is only supported on MacOS 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
-+
-+/*
-+** 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 -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
-+*/
-+#ifndef TEMP_FILE_PREFIX
-+# define TEMP_FILE_PREFIX "sqlite_"
-+#endif
-+
-+/*
-+** Figure out if we are dealing with Unix, Windows or MacOS.
-+**
-+** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
-+**      The MacOS build is designed to use CodeWarrior (tested with v8)
-+*/
-+#ifndef OS_UNIX
-+# ifndef OS_WIN
-+#  ifndef OS_MAC
-+#    if defined(__MACOS__)
-+#      define OS_MAC 1
-+#      define OS_WIN 0
-+#      define OS_UNIX 0
-+#    elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
-+#      define OS_MAC 0
-+#      define OS_WIN 1
-+#      define OS_UNIX 0
-+#    else
-+#      define OS_MAC 0
-+#      define OS_WIN 0
-+#      define OS_UNIX 1
-+#    endif
-+#  else
-+#    define OS_WIN 0
-+#    define OS_UNIX 0
-+#  endif
-+# else
-+#  define OS_MAC 0
-+#  define OS_UNIX 0
-+# endif
-+#else
-+# define OS_MAC 0
-+# ifndef OS_WIN
-+#  define OS_WIN 0
-+# endif
-+#endif
-+
-+/*
-+** A handle for an open file is stored in an OsFile object.
-+*/
-+#if OS_UNIX
-+# include <sys/types.h>
-+# include <sys/stat.h>
-+# include <fcntl.h>
-+# include <unistd.h>
-+  typedef struct OsFile OsFile;
-+  struct OsFile {
-+    struct openCnt *pOpen;    /* Info about all open fd's on this inode */
-+    struct lockInfo *pLock;   /* Info about locks on this inode */
-+    int fd;                   /* The file descriptor */
-+    int locked;               /* True if this instance holds the lock */
-+    int dirfd;                /* File descriptor for the directory */
-+  };
-+# define SQLITE_TEMPNAME_SIZE 200
-+# if defined(HAVE_USLEEP) && HAVE_USLEEP
-+#  define SQLITE_MIN_SLEEP_MS 1
-+# else
-+#  define SQLITE_MIN_SLEEP_MS 1000
-+# endif
-+#endif
-+
-+#if OS_WIN
-+#include <windows.h>
-+#include <winbase.h>
-+  typedef struct OsFile OsFile;
-+  struct OsFile {
-+    HANDLE h;               /* Handle for accessing the file */
-+    int locked;             /* 0: unlocked, <0: write lock, >0: read lock */
-+  };
-+# if defined(_MSC_VER) || defined(__BORLANDC__)
-+    typedef __int64 off_t;
-+# else
-+#  if !defined(_CYGWIN_TYPES_H)
-+     typedef long long off_t;
-+#    if defined(__MINGW32__)
-+#      define _OFF_T_
-+#    endif
-+#  endif
-+# endif
-+# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
-+# define SQLITE_MIN_SLEEP_MS 1
-+#endif
-+
-+#if OS_MAC
-+# include <unistd.h>
-+# include <Files.h>
-+  typedef struct OsFile OsFile;
-+  struct OsFile {
-+    SInt16 refNum;           /* Data fork/file reference number */
-+    SInt16 refNumRF;         /* Resource fork reference number (for locking) */
-+    int locked;              /* 0: unlocked, <0: write lock, >0: read lock */
-+    int delOnClose;          /* True if file is to be deleted on close */
-+    char *pathToDel;         /* Name of file to delete on close */
-+  };
-+# ifdef _LARGE_FILE
-+    typedef SInt64 off_t;
-+# else
-+    typedef SInt32 off_t;
-+# endif
-+# define SQLITE_TEMPNAME_SIZE _MAX_PATH
-+# define SQLITE_MIN_SLEEP_MS 17
-+#endif
-+
-+int sqliteOsDelete(const char*);
-+int sqliteOsFileExists(const char*);
-+int sqliteOsFileRename(const char*, const char*);
-+int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
-+int sqliteOsOpenExclusive(const char*, OsFile*, int);
-+int sqliteOsOpenReadOnly(const char*, OsFile*);
-+int sqliteOsOpenDirectory(const char*, OsFile*);
-+int sqliteOsTempFileName(char*);
-+int sqliteOsClose(OsFile*);
-+int sqliteOsRead(OsFile*, void*, int amt);
-+int sqliteOsWrite(OsFile*, const void*, int amt);
-+int sqliteOsSeek(OsFile*, off_t offset);
-+int sqliteOsSync(OsFile*);
-+int sqliteOsTruncate(OsFile*, off_t size);
-+int sqliteOsFileSize(OsFile*, off_t *pSize);
-+int sqliteOsReadLock(OsFile*);
-+int sqliteOsWriteLock(OsFile*);
-+int sqliteOsUnlock(OsFile*);
-+int sqliteOsRandomSeed(char*);
-+int sqliteOsSleep(int ms);
-+int sqliteOsCurrentTime(double*);
-+void sqliteOsEnterMutex(void);
-+void sqliteOsLeaveMutex(void);
-+char *sqliteOsFullPathname(const char*);
-+
-+
-+
-+#endif /* _SQLITE_OS_H_ */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/pager.c
-@@ -0,0 +1,2220 @@
-+/*
-+** 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$
-+*/
-+#include "os.h"         /* Must be first to enable large file support */
-+#include "sqliteInt.h"
-+#include "pager.h"
-+#include <assert.h>
-+#include <string.h>
-+
-+/*
-+** Macros for troubleshooting.  Normally turned off
-+*/
-+#if 0
-+static Pager *mainPager = 0;
-+#define SET_PAGER(X)  if( mainPager==0 ) mainPager = (X)
-+#define CLR_PAGER(X)  if( mainPager==(X) ) mainPager = 0
-+#define TRACE1(X)     if( pPager==mainPager ) fprintf(stderr,X)
-+#define TRACE2(X,Y)   if( pPager==mainPager ) fprintf(stderr,X,Y)
-+#define TRACE3(X,Y,Z) if( pPager==mainPager ) fprintf(stderr,X,Y,Z)
-+#else
-+#define SET_PAGER(X)
-+#define CLR_PAGER(X)
-+#define TRACE1(X)
-+#define TRACE2(X,Y)
-+#define TRACE3(X,Y,Z)
-+#endif
-+
-+
-+/*
-+** The page cache as a whole is always in one of the following
-+** states:
-+**
-+**   SQLITE_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.
-+**
-+**   SQLITE_READLOCK     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.
-+**
-+**   SQLITE_WRITELOCK    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.
-+**
-+** The page cache comes up in SQLITE_UNLOCK.  The first time a
-+** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
-+** After all pages have been released using sqlite_page_unref(),
-+** the state transitions back to SQLITE_UNLOCK.  The first time
-+** that sqlite_page_write() is called, the state transitions to
-+** SQLITE_WRITELOCK.  (Note that sqlite_page_write() can only be
-+** called on an outstanding page which means that the pager must
-+** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
-+** The sqlite_page_rollback() and sqlite_page_commit() functions 
-+** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
-+*/
-+#define SQLITE_UNLOCK      0
-+#define SQLITE_READLOCK    1
-+#define SQLITE_WRITELOCK   2
-+
-+
-+/*
-+** Each in-memory image of a page begins with the following header.
-+** This header is only visible to this pager module.  The client
-+** code that calls pager sees only the data that follows the header.
-+**
-+** Client code should call sqlitepager_write() on a page prior to making
-+** any modifications to that page.  The first time sqlitepager_write()
-+** is called, the original page contents are written into the rollback
-+** journal and PgHdr.inJournal and PgHdr.needSync are set.  Later, once
-+** the journal page has made it onto the disk surface, PgHdr.needSync
-+** is cleared.  The modified page cannot be written back into the original
-+** database file until the journal pages has been synced to disk and the
-+** PgHdr.needSync has been cleared.
-+**
-+** The PgHdr.dirty flag is set when sqlitepager_write() is called and
-+** is cleared again when the page content is written back to the original
-+** database file.
-+*/
-+typedef struct PgHdr PgHdr;
-+struct PgHdr {
-+  Pager *pPager;                 /* The pager to which this page belongs */
-+  Pgno pgno;                     /* The page number for this page */
-+  PgHdr *pNextHash, *pPrevHash;  /* Hash collision chain for PgHdr.pgno */
-+  int nRef;                      /* Number of users of this page */
-+  PgHdr *pNextFree, *pPrevFree;  /* Freelist of pages where nRef==0 */
-+  PgHdr *pNextAll, *pPrevAll;    /* A list of all pages */
-+  PgHdr *pNextCkpt, *pPrevCkpt;  /* List of pages in the checkpoint journal */
-+  u8 inJournal;                  /* TRUE if has been written to journal */
-+  u8 inCkpt;                     /* TRUE if written to the checkpoint journal */
-+  u8 dirty;                      /* TRUE if we need to write back changes */
-+  u8 needSync;                   /* Sync journal before writing this page */
-+  u8 alwaysRollback;             /* Disable dont_rollback() for this page */
-+  PgHdr *pDirty;                 /* Dirty pages sorted by PgHdr.pgno */
-+  /* SQLITE_PAGE_SIZE bytes of page data follow this header */
-+  /* Pager.nExtra bytes of local data follow the page data */
-+};
-+
-+
-+/*
-+** A macro used for invoking the codec if there is one
-+*/
-+#ifdef SQLITE_HAS_CODEC
-+# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
-+#else
-+# define CODEC(P,D,N,X)
-+#endif
-+
-+/*
-+** Convert a pointer to a PgHdr into a pointer to its data
-+** and back again.
-+*/
-+#define PGHDR_TO_DATA(P)  ((void*)(&(P)[1]))
-+#define DATA_TO_PGHDR(D)  (&((PgHdr*)(D))[-1])
-+#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
-+
-+/*
-+** How big to make the hash table used for locating in-memory pages
-+** by page number.
-+*/
-+#define N_PG_HASH 2048
-+
-+/*
-+** Hash a page number
-+*/
-+#define pager_hash(PN)  ((PN)&(N_PG_HASH-1))
-+
-+/*
-+** A open page cache is an instance of the following structure.
-+*/
-+struct Pager {
-+  char *zFilename;            /* Name of the database file */
-+  char *zJournal;             /* Name of the journal file */
-+  char *zDirectory;           /* Directory hold database and journal files */
-+  OsFile fd, jfd;             /* File descriptors for database and journal */
-+  OsFile cpfd;                /* File descriptor for the checkpoint journal */
-+  int dbSize;                 /* Number of pages in the file */
-+  int origDbSize;             /* dbSize before the current change */
-+  int ckptSize;               /* Size of database (in pages) at ckpt_begin() */
-+  off_t ckptJSize;            /* Size of journal at ckpt_begin() */
-+  int nRec;                   /* Number of pages written to the journal */
-+  u32 cksumInit;              /* Quasi-random value added to every checksum */
-+  int ckptNRec;               /* Number of records in the checkpoint journal */
-+  int nExtra;                 /* Add this many bytes to each in-memory page */
-+  void (*xDestructor)(void*); /* Call this routine when freeing pages */
-+  int nPage;                  /* Total number of in-memory pages */
-+  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
-+  int mxPage;                 /* Maximum number of pages to hold in cache */
-+  int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
-+  void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
-+  void *pCodecArg;            /* First argument to xCodec() */
-+  u8 journalOpen;             /* True if journal file descriptors is valid */
-+  u8 journalStarted;          /* True if header of journal is synced */
-+  u8 useJournal;              /* Use a rollback journal on this file */
-+  u8 ckptOpen;                /* True if the checkpoint journal is open */
-+  u8 ckptInUse;               /* True we are in a checkpoint */
-+  u8 ckptAutoopen;            /* Open ckpt journal when main journal is opened*/
-+  u8 noSync;                  /* Do not sync the journal if true */
-+  u8 fullSync;                /* Do extra syncs of the journal for robustness */
-+  u8 state;                   /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
-+  u8 errMask;                 /* One of several kinds of errors */
-+  u8 tempFile;                /* zFilename is a temporary file */
-+  u8 readOnly;                /* True for a read-only database */
-+  u8 needSync;                /* True if an fsync() is needed on the journal */
-+  u8 dirtyFile;               /* True if database file has changed in any way */
-+  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
-+  u8 *aInJournal;             /* One bit for each page in the database file */
-+  u8 *aInCkpt;                /* One bit for each page in the database */
-+  PgHdr *pFirst, *pLast;      /* List of free pages */
-+  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
-+  PgHdr *pAll;                /* List of all pages */
-+  PgHdr *pCkpt;               /* List of pages in the checkpoint journal */
-+  PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number of PgHdr */
-+};
-+
-+/*
-+** These are bits that can be set in Pager.errMask.
-+*/
-+#define PAGER_ERR_FULL     0x01  /* a write() failed */
-+#define PAGER_ERR_MEM      0x02  /* malloc() failed */
-+#define PAGER_ERR_LOCK     0x04  /* error in the locking protocol */
-+#define PAGER_ERR_CORRUPT  0x08  /* database or journal corruption */
-+#define PAGER_ERR_DISK     0x10  /* general disk I/O error - bad hard drive? */
-+
-+/*
-+** The journal file contains page records in the following
-+** format.
-+**
-+** Actually, this structure is the complete page record for pager
-+** formats less than 3.  Beginning with format 3, this record is surrounded
-+** by two checksums.
-+*/
-+typedef struct PageRecord PageRecord;
-+struct PageRecord {
-+  Pgno pgno;                      /* The page number */
-+  char aData[SQLITE_PAGE_SIZE];   /* Original data for page pgno */
-+};
-+
-+/*
-+** Journal files begin with the following magic string.  The data
-+** was obtained from /dev/random.  It is used only as a sanity check.
-+**
-+** There are three journal formats (so far). The 1st journal format writes
-+** 32-bit integers in the byte-order of the host machine.  New
-+** formats writes integers as big-endian.  All new journals use the
-+** new format, but we have to be able to read an older journal in order
-+** to rollback journals created by older versions of the library.
-+**
-+** The 3rd journal format (added for 2.8.0) adds additional sanity
-+** checking information to the journal.  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 3rd journal format consists
-+** of a 32-bit checksum on each page of data.  The checksum covers both
-+** the page number and the SQLITE_PAGE_SIZE 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 aJournalMagic1[] = {
-+  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
-+};
-+static const unsigned char aJournalMagic2[] = {
-+  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd5,
-+};
-+static const unsigned char aJournalMagic3[] = {
-+  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd6,
-+};
-+#define JOURNAL_FORMAT_1 1
-+#define JOURNAL_FORMAT_2 2
-+#define JOURNAL_FORMAT_3 3
-+
-+/*
-+** The following integer determines what format to use when creating
-+** new primary journal files.  By default we always use format 3.
-+** When testing, we can set this value to older journal formats in order to
-+** make sure that newer versions of the library are able to rollback older
-+** journal files.
-+**
-+** Note that checkpoint journals always use format 2 and omit the header.
-+*/
-+#ifdef SQLITE_TEST
-+int journal_format = 3;
-+#else
-+# define journal_format 3
-+#endif
-+
-+/*
-+** The size of the header and of each page in the journal varies according
-+** to which journal format is being used.  The following macros figure out
-+** the sizes based on format numbers.
-+*/
-+#define JOURNAL_HDR_SZ(X) \
-+   (sizeof(aJournalMagic1) + sizeof(Pgno) + ((X)>=3)*2*sizeof(u32))
-+#define JOURNAL_PG_SZ(X) \
-+   (SQLITE_PAGE_SIZE + sizeof(Pgno) + ((X)>=3)*sizeof(u32))
-+
-+/*
-+** Enable reference count tracking here:
-+*/
-+#ifdef SQLITE_TEST
-+  int pager_refinfo_enable = 0;
-+  static void pager_refinfo(PgHdr *p){
-+    static int cnt = 0;
-+    if( !pager_refinfo_enable ) return;
-+    printf(
-+       "REFCNT: %4d addr=0x%08x nRef=%d\n",
-+       p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
-+    );
-+    cnt++;   /* Something to set a breakpoint on */
-+  }
-+# define REFINFO(X)  pager_refinfo(X)
-+#else
-+# define REFINFO(X)
-+#endif
-+
-+/*
-+** 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.
-+**
-+** If the journal format is 2 or 3, read a big-endian integer.  If the
-+** journal format is 1, read an integer in the native byte-order of the
-+** host machine.
-+*/
-+static int read32bits(int format, OsFile *fd, u32 *pRes){
-+  u32 res;
-+  int rc;
-+  rc = sqliteOsRead(fd, &res, sizeof(res));
-+  if( rc==SQLITE_OK && format>JOURNAL_FORMAT_1 ){
-+    unsigned char ac[4];
-+    memcpy(ac, &res, 4);
-+    res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
-+  }
-+  *pRes = res;
-+  return rc;
-+}
-+
-+/*
-+** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
-+** on success or an error code is something goes wrong.
-+**
-+** If the journal format is 2 or 3, write the integer as 4 big-endian
-+** bytes.  If the journal format is 1, write the integer in the native
-+** byte order.  In normal operation, only formats 2 and 3 are used.
-+** Journal format 1 is only used for testing.
-+*/
-+static int write32bits(OsFile *fd, u32 val){
-+  unsigned char ac[4];
-+  if( journal_format<=1 ){
-+    return sqliteOsWrite(fd, &val, 4);
-+  }
-+  ac[0] = (val>>24) & 0xff;
-+  ac[1] = (val>>16) & 0xff;
-+  ac[2] = (val>>8) & 0xff;
-+  ac[3] = val & 0xff;
-+  return sqliteOsWrite(fd, ac, 4);
-+}
-+
-+/*
-+** Write a 32-bit integer into a page header right before the
-+** page data.  This will overwrite the PgHdr.pDirty pointer.
-+**
-+** The integer is big-endian for formats 2 and 3 and native byte order
-+** for journal format 1.
-+*/
-+static void store32bits(u32 val, PgHdr *p, int offset){
-+  unsigned char *ac;
-+  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
-+  if( journal_format<=1 ){
-+    memcpy(ac, &val, 4);
-+  }else{
-+    ac[0] = (val>>24) & 0xff;
-+    ac[1] = (val>>16) & 0xff;
-+    ac[2] = (val>>8) & 0xff;
-+    ac[3] = val & 0xff;
-+  }
-+}
-+
-+
-+/*
-+** Convert the bits in the pPager->errMask into an approprate
-+** return code.
-+*/
-+static int pager_errcode(Pager *pPager){
-+  int rc = SQLITE_OK;
-+  if( pPager->errMask & PAGER_ERR_LOCK )    rc = SQLITE_PROTOCOL;
-+  if( pPager->errMask & PAGER_ERR_DISK )    rc = SQLITE_IOERR;
-+  if( pPager->errMask & PAGER_ERR_FULL )    rc = SQLITE_FULL;
-+  if( pPager->errMask & PAGER_ERR_MEM )     rc = SQLITE_NOMEM;
-+  if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
-+  return rc;
-+}
-+
-+/*
-+** Add or remove a page from the list of all pages that are in the
-+** checkpoint journal.
-+**
-+** The Pager keeps a separate list of pages that are currently in
-+** the checkpoint journal.  This helps the sqlitepager_ckpt_commit()
-+** routine run MUCH faster for the common case where there are many
-+** pages in memory but only a few are in the checkpoint journal.
-+*/
-+static void page_add_to_ckpt_list(PgHdr *pPg){
-+  Pager *pPager = pPg->pPager;
-+  if( pPg->inCkpt ) return;
-+  assert( pPg->pPrevCkpt==0 && pPg->pNextCkpt==0 );
-+  pPg->pPrevCkpt = 0;
-+  if( pPager->pCkpt ){
-+    pPager->pCkpt->pPrevCkpt = pPg;
-+  }
-+  pPg->pNextCkpt = pPager->pCkpt;
-+  pPager->pCkpt = pPg;
-+  pPg->inCkpt = 1;
-+}
-+static void page_remove_from_ckpt_list(PgHdr *pPg){
-+  if( !pPg->inCkpt ) return;
-+  if( pPg->pPrevCkpt ){
-+    assert( pPg->pPrevCkpt->pNextCkpt==pPg );
-+    pPg->pPrevCkpt->pNextCkpt = pPg->pNextCkpt;
-+  }else{
-+    assert( pPg->pPager->pCkpt==pPg );
-+    pPg->pPager->pCkpt = pPg->pNextCkpt;
-+  }
-+  if( pPg->pNextCkpt ){
-+    assert( pPg->pNextCkpt->pPrevCkpt==pPg );
-+    pPg->pNextCkpt->pPrevCkpt = pPg->pPrevCkpt;
-+  }
-+  pPg->pNextCkpt = 0;
-+  pPg->pPrevCkpt = 0;
-+  pPg->inCkpt = 0;
-+}
-+
-+/*
-+** Find a page in the hash table given its page number.  Return
-+** a pointer to the page or NULL if not found.
-+*/
-+static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
-+  PgHdr *p = pPager->aHash[pager_hash(pgno)];
-+  while( p && p->pgno!=pgno ){
-+    p = p->pNextHash;
-+  }
-+  return p;
-+}
-+
-+/*
-+** Unlock the database and clear the in-memory cache.  This routine
-+** sets the state of the pager back to what it was when it was first
-+** opened.  Any outstanding pages are invalidated and subsequent attempts
-+** to access those pages will likely result in a coredump.
-+*/
-+static void pager_reset(Pager *pPager){
-+  PgHdr *pPg, *pNext;
-+  for(pPg=pPager->pAll; pPg; pPg=pNext){
-+    pNext = pPg->pNextAll;
-+    sqliteFree(pPg);
-+  }
-+  pPager->pFirst = 0;
-+  pPager->pFirstSynced = 0;
-+  pPager->pLast = 0;
-+  pPager->pAll = 0;
-+  memset(pPager->aHash, 0, sizeof(pPager->aHash));
-+  pPager->nPage = 0;
-+  if( pPager->state>=SQLITE_WRITELOCK ){
-+    sqlitepager_rollback(pPager);
-+  }
-+  sqliteOsUnlock(&pPager->fd);
-+  pPager->state = SQLITE_UNLOCK;
-+  pPager->dbSize = -1;
-+  pPager->nRef = 0;
-+  assert( pPager->journalOpen==0 );
-+}
-+
-+/*
-+** When this routine is called, the pager has the journal file open and
-+** a write lock on the database.  This routine releases the database
-+** write lock and acquires a read lock in its place.  The journal file
-+** is deleted and closed.
-+**
-+** TODO: Consider keeping the journal file open for temporary databases.
-+** This might give a performance improvement on windows where opening
-+** a file is an expensive operation.
-+*/
-+static int pager_unwritelock(Pager *pPager){
-+  int rc;
-+  PgHdr *pPg;
-+  if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
-+  sqlitepager_ckpt_commit(pPager);
-+  if( pPager->ckptOpen ){
-+    sqliteOsClose(&pPager->cpfd);
-+    pPager->ckptOpen = 0;
-+  }
-+  if( pPager->journalOpen ){
-+    sqliteOsClose(&pPager->jfd);
-+    pPager->journalOpen = 0;
-+    sqliteOsDelete(pPager->zJournal);
-+    sqliteFree( pPager->aInJournal );
-+    pPager->aInJournal = 0;
-+    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-+      pPg->inJournal = 0;
-+      pPg->dirty = 0;
-+      pPg->needSync = 0;
-+    }
-+  }else{
-+    assert( pPager->dirtyFile==0 || pPager->useJournal==0 );
-+  }
-+  rc = sqliteOsReadLock(&pPager->fd);
-+  if( rc==SQLITE_OK ){
-+    pPager->state = SQLITE_READLOCK;
-+  }else{
-+    /* This can only happen if a process does a BEGIN, then forks and the
-+    ** child process does the COMMIT.  Because of the semantics of unix
-+    ** file locking, the unlock will fail.
-+    */
-+    pPager->state = SQLITE_UNLOCK;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Compute and return a checksum for the page of data.
-+**
-+** This is not a real checksum.  It is really just the sum of the 
-+** random initial value and the page number.  We considered do a checksum
-+** of the database, but that was found to be too slow.
-+*/
-+static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
-+  u32 cksum = pPager->cksumInit + pgno;
-+  return cksum;
-+}
-+
-+/*
-+** Read a single page from the journal file opened on file descriptor
-+** jfd.  Playback this one page.
-+**
-+** There are three different journal formats.  The format parameter determines
-+** which format is used by the journal that is played back.
-+*/
-+static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int format){
-+  int rc;
-+  PgHdr *pPg;              /* An existing page in the cache */
-+  PageRecord pgRec;
-+  u32 cksum;
-+
-+  rc = read32bits(format, jfd, &pgRec.pgno);
-+  if( rc!=SQLITE_OK ) return rc;
-+  rc = sqliteOsRead(jfd, &pgRec.aData, sizeof(pgRec.aData));
-+  if( rc!=SQLITE_OK ) return rc;
-+
-+  /* 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( pgRec.pgno==0 ){
-+    return SQLITE_DONE;
-+  }
-+  if( pgRec.pgno>(unsigned)pPager->dbSize ){
-+    return SQLITE_OK;
-+  }
-+  if( format>=JOURNAL_FORMAT_3 ){
-+    rc = read32bits(format, jfd, &cksum);
-+    if( rc ) return rc;
-+    if( pager_cksum(pPager, pgRec.pgno, pgRec.aData)!=cksum ){
-+      return SQLITE_DONE;
-+    }
-+  }
-+
-+  /* Playback the page.  Update the in-memory copy of the page
-+  ** at the same time, if there is one.
-+  */
-+  pPg = pager_lookup(pPager, pgRec.pgno);
-+  TRACE2("PLAYBACK %d\n", pgRec.pgno);
-+  sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*(off_t)SQLITE_PAGE_SIZE);
-+  rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
-+  if( pPg ){
-+    /* No page should ever be 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.
-+    */
-+    assert( pPg->nRef==0 || pPg->pgno==1 );
-+    memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
-+    memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
-+    pPg->dirty = 0;
-+    pPg->needSync = 0;
-+    CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** 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: 
-+**
-+**    *  8 byte prefix.  One of the aJournalMagic123 vectors defined
-+**       above.  The format of the journal file is determined by which
-+**       of the three prefix vectors is seen.
-+**    *  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.  This field appears
-+**       in format 3 only.
-+**    *  4 byte big-endian integer which is the initial value for the 
-+**       sanity checksum.  This field appears in format 3 only.
-+**    *  4 byte integer which is the number of pages to truncate the
-+**       database to during a rollback.
-+**    *  Zero or more pages instances, each as follows:
-+**        +  4 byte page number.
-+**        +  SQLITE_PAGE_SIZE bytes of data.
-+**        +  4 byte checksum (format 3 only)
-+**
-+** When we speak of the journal header, we mean the first 4 bullets above.
-+** Each entry in the journal is an instance of the 5th bullet.  Note that
-+** bullets 2 and 3 only appear in format-3 journals.
-+**
-+** 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.  
-+**
-+** Journal formats 1 and 2 do not have an nRec value in the header so we
-+** have to compute nRec from the file size.  This has risks (as described
-+** above) which is why all persistent tables have been changed to use
-+** format 3.
-+**
-+** If the file opened as the journal file is not a well-formed
-+** journal file then the database will likely already be
-+** corrupted, so the PAGER_ERR_CORRUPT bit is set in pPager->errMask
-+** and SQLITE_CORRUPT is returned.  If it all works, then this routine
-+** returns SQLITE_OK.
-+*/
-+static int pager_playback(Pager *pPager, int useJournalSize){
-+  off_t szJ;               /* Size of the journal file in bytes */
-+  int nRec;                /* Number of Records in the journal */
-+  int i;                   /* Loop counter */
-+  Pgno mxPg = 0;           /* Size of the original file in pages */
-+  int format;              /* Format of the journal file. */
-+  unsigned char aMagic[sizeof(aJournalMagic1)];
-+  int rc;
-+
-+  /* Figure out how many records are in the journal.  Abort early if
-+  ** the journal is empty.
-+  */
-+  assert( pPager->journalOpen );
-+  sqliteOsSeek(&pPager->jfd, 0);
-+  rc = sqliteOsFileSize(&pPager->jfd, &szJ);
-+  if( rc!=SQLITE_OK ){
-+    goto end_playback;
-+  }
-+
-+  /* If the journal file is too small to contain a complete header,
-+  ** it must mean that the process that created the journal was just
-+  ** beginning to write the journal file when it died.  In that case,
-+  ** the database file should have still been completely unchanged.
-+  ** Nothing needs to be rolled back.  We can safely ignore this journal.
-+  */
-+  if( szJ < sizeof(aMagic)+sizeof(Pgno) ){
-+    goto end_playback;
-+  }
-+
-+  /* Read the beginning of the journal and truncate the
-+  ** database file back to its original size.
-+  */
-+  rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
-+  if( rc!=SQLITE_OK ){
-+    rc = SQLITE_PROTOCOL;
-+    goto end_playback;
-+  }
-+  if( memcmp(aMagic, aJournalMagic3, sizeof(aMagic))==0 ){
-+    format = JOURNAL_FORMAT_3;
-+  }else if( memcmp(aMagic, aJournalMagic2, sizeof(aMagic))==0 ){
-+    format = JOURNAL_FORMAT_2;
-+  }else if( memcmp(aMagic, aJournalMagic1, sizeof(aMagic))==0 ){
-+    format = JOURNAL_FORMAT_1;
-+  }else{
-+    rc = SQLITE_PROTOCOL;
-+    goto end_playback;
-+  }
-+  if( format>=JOURNAL_FORMAT_3 ){
-+    if( szJ < sizeof(aMagic) + 3*sizeof(u32) ){
-+      /* Ignore the journal if it is too small to contain a complete
-+      ** header.  We already did this test once above, but at the prior
-+      ** test, we did not know the journal format and so we had to assume
-+      ** the smallest possible header.  Now we know the header is bigger
-+      ** than the minimum so we test again.
-+      */
-+      goto end_playback;
-+    }
-+    rc = read32bits(format, &pPager->jfd, (u32*)&nRec);
-+    if( rc ) goto end_playback;
-+    rc = read32bits(format, &pPager->jfd, &pPager->cksumInit);
-+    if( rc ) goto end_playback;
-+    if( nRec==0xffffffff || useJournalSize ){
-+      nRec = (szJ - JOURNAL_HDR_SZ(3))/JOURNAL_PG_SZ(3);
-+    }
-+  }else{
-+    nRec = (szJ - JOURNAL_HDR_SZ(2))/JOURNAL_PG_SZ(2);
-+    assert( nRec*JOURNAL_PG_SZ(2)+JOURNAL_HDR_SZ(2)==szJ );
-+  }
-+  rc = read32bits(format, &pPager->jfd, &mxPg);
-+  if( rc!=SQLITE_OK ){
-+    goto end_playback;
-+  }
-+  assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
-+  rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg);
-+  if( rc!=SQLITE_OK ){
-+    goto end_playback;
-+  }
-+  pPager->dbSize = mxPg;
-+  
-+  /* Copy original pages out of the journal and back into the database file.
-+  */
-+  for(i=0; i<nRec; i++){
-+    rc = pager_playback_one_page(pPager, &pPager->jfd, format);
-+    if( rc!=SQLITE_OK ){
-+      if( rc==SQLITE_DONE ){
-+        rc = SQLITE_OK;
-+      }
-+      break;
-+    }
-+  }
-+
-+  /* Pages that have been written to the journal but never synced
-+  ** where not restored by the loop above.  We have to restore those
-+  ** pages by reading them back from the original database.
-+  */
-+  if( rc==SQLITE_OK ){
-+    PgHdr *pPg;
-+    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-+      char zBuf[SQLITE_PAGE_SIZE];
-+      if( !pPg->dirty ) continue;
-+      if( (int)pPg->pgno <= pPager->origDbSize ){
-+        sqliteOsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
-+        rc = sqliteOsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE);
-+        TRACE2("REFETCH %d\n", pPg->pgno);
-+        CODEC(pPager, zBuf, pPg->pgno, 2);
-+        if( rc ) break;
-+      }else{
-+        memset(zBuf, 0, SQLITE_PAGE_SIZE);
-+      }
-+      if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE) ){
-+        memcpy(PGHDR_TO_DATA(pPg), zBuf, SQLITE_PAGE_SIZE);
-+        memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
-+      }
-+      pPg->needSync = 0;
-+      pPg->dirty = 0;
-+    }
-+  }
-+
-+end_playback:
-+  if( rc!=SQLITE_OK ){
-+    pager_unwritelock(pPager);
-+    pPager->errMask |= PAGER_ERR_CORRUPT;
-+    rc = SQLITE_CORRUPT;
-+  }else{
-+    rc = pager_unwritelock(pPager);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Playback the checkpoint journal.
-+**
-+** This is similar to playing back the transaction journal but with
-+** a few extra twists.
-+**
-+**    (1)  The number of pages in the database file at the start of
-+**         the checkpoint is stored in pPager->ckptSize, not in the
-+**         journal file itself.
-+**
-+**    (2)  In addition to playing back the checkpoint journal, also
-+**         playback all pages of the transaction journal beginning
-+**         at offset pPager->ckptJSize.
-+*/
-+static int pager_ckpt_playback(Pager *pPager){
-+  off_t szJ;               /* Size of the full journal */
-+  int nRec;                /* Number of Records */
-+  int i;                   /* Loop counter */
-+  int rc;
-+
-+  /* Truncate the database back to its original size.
-+  */
-+  rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->ckptSize);
-+  pPager->dbSize = pPager->ckptSize;
-+
-+  /* Figure out how many records are in the checkpoint journal.
-+  */
-+  assert( pPager->ckptInUse && pPager->journalOpen );
-+  sqliteOsSeek(&pPager->cpfd, 0);
-+  nRec = pPager->ckptNRec;
-+  
-+  /* Copy original pages out of the checkpoint journal and back into the
-+  ** database file.  Note that the checkpoint journal always uses format
-+  ** 2 instead of format 3 since it does not need to be concerned with
-+  ** power failures corrupting the journal and can thus omit the checksums.
-+  */
-+  for(i=nRec-1; i>=0; i--){
-+    rc = pager_playback_one_page(pPager, &pPager->cpfd, 2);
-+    assert( rc!=SQLITE_DONE );
-+    if( rc!=SQLITE_OK ) goto end_ckpt_playback;
-+  }
-+
-+  /* Figure out how many pages need to be copied out of the transaction
-+  ** journal.
-+  */
-+  rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
-+  if( rc!=SQLITE_OK ){
-+    goto end_ckpt_playback;
-+  }
-+  rc = sqliteOsFileSize(&pPager->jfd, &szJ);
-+  if( rc!=SQLITE_OK ){
-+    goto end_ckpt_playback;
-+  }
-+  nRec = (szJ - pPager->ckptJSize)/JOURNAL_PG_SZ(journal_format);
-+  for(i=nRec-1; i>=0; i--){
-+    rc = pager_playback_one_page(pPager, &pPager->jfd, journal_format);
-+    if( rc!=SQLITE_OK ){
-+      assert( rc!=SQLITE_DONE );
-+      goto end_ckpt_playback;
-+    }
-+  }
-+  
-+end_ckpt_playback:
-+  if( rc!=SQLITE_OK ){
-+    pPager->errMask |= PAGER_ERR_CORRUPT;
-+    rc = SQLITE_CORRUPT;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Change the maximum number of in-memory pages that are allowed.
-+**
-+** The maximum number is the absolute value of the mxPage parameter.
-+** If mxPage is negative, the noSync flag is also set.  noSync bypasses
-+** calls to sqliteOsSync().  The pager runs much faster with noSync on,
-+** but if the operating system crashes or there is an abrupt power 
-+** failure, the database file might be left in an inconsistent and
-+** unrepairable state.  
-+*/
-+void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
-+  if( mxPage>=0 ){
-+    pPager->noSync = pPager->tempFile;
-+    if( pPager->noSync==0 ) pPager->needSync = 0;
-+  }else{
-+    pPager->noSync = 1;
-+    mxPage = -mxPage;
-+  }
-+  if( mxPage>10 ){
-+    pPager->mxPage = 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       sqliteOsSync() 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.
-+*/
-+void sqlitepager_set_safety_level(Pager *pPager, int level){
-+  pPager->noSync =  level==1 || pPager->tempFile;
-+  pPager->fullSync = level==3 && !pPager->tempFile;
-+  if( pPager->noSync==0 ) pPager->needSync = 0;
-+}
-+
-+/*
-+** Open a temporary file.  Write the name of the file into zName
-+** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
-+** the file descriptor into *fd.  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.
-+*/
-+static int sqlitepager_opentemp(char *zFile, OsFile *fd){
-+  int cnt = 8;
-+  int rc;
-+  do{
-+    cnt--;
-+    sqliteOsTempFileName(zFile);
-+    rc = sqliteOsOpenExclusive(zFile, fd, 1);
-+  }while( cnt>0 && rc!=SQLITE_OK );
-+  return rc;
-+}
-+
-+/*
-+** Create a new page cache and put a pointer to the page cache in *ppPager.
-+** The file to be cached need not exist.  The file is not locked until
-+** the first call to sqlitepager_get() and is only held open until the
-+** last page is released using sqlitepager_unref().
-+**
-+** If zFilename is NULL then a randomly-named temporary file is created
-+** and used as the file to be cached.  The file will be deleted
-+** automatically when it is closed.
-+*/
-+int sqlitepager_open(
-+  Pager **ppPager,         /* Return the Pager structure here */
-+  const char *zFilename,   /* Name of the database file to open */
-+  int mxPage,              /* Max number of in-memory cache pages */
-+  int nExtra,              /* Extra bytes append to each in-memory page */
-+  int useJournal           /* TRUE to use a rollback journal on this file */
-+){
-+  Pager *pPager;
-+  char *zFullPathname;
-+  int nameLen;
-+  OsFile fd;
-+  int rc, i;
-+  int tempFile;
-+  int readOnly = 0;
-+  char zTemp[SQLITE_TEMPNAME_SIZE];
-+
-+  *ppPager = 0;
-+  if( sqlite_malloc_failed ){
-+    return SQLITE_NOMEM;
-+  }
-+  if( zFilename && zFilename[0] ){
-+    zFullPathname = sqliteOsFullPathname(zFilename);
-+    rc = sqliteOsOpenReadWrite(zFullPathname, &fd, &readOnly);
-+    tempFile = 0;
-+  }else{
-+    rc = sqlitepager_opentemp(zTemp, &fd);
-+    zFilename = zTemp;
-+    zFullPathname = sqliteOsFullPathname(zFilename);
-+    tempFile = 1;
-+  }
-+  if( sqlite_malloc_failed ){
-+    return SQLITE_NOMEM;
-+  }
-+  if( rc!=SQLITE_OK ){
-+    sqliteFree(zFullPathname);
-+    return SQLITE_CANTOPEN;
-+  }
-+  nameLen = strlen(zFullPathname);
-+  pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
-+  if( pPager==0 ){
-+    sqliteOsClose(&fd);
-+    sqliteFree(zFullPathname);
-+    return SQLITE_NOMEM;
-+  }
-+  SET_PAGER(pPager);
-+  pPager->zFilename = (char*)&pPager[1];
-+  pPager->zDirectory = &pPager->zFilename[nameLen+1];
-+  pPager->zJournal = &pPager->zDirectory[nameLen+1];
-+  strcpy(pPager->zFilename, zFullPathname);
-+  strcpy(pPager->zDirectory, zFullPathname);
-+  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
-+  if( i>0 ) pPager->zDirectory[i-1] = 0;
-+  strcpy(pPager->zJournal, zFullPathname);
-+  sqliteFree(zFullPathname);
-+  strcpy(&pPager->zJournal[nameLen], "-journal");
-+  pPager->fd = fd;
-+  pPager->journalOpen = 0;
-+  pPager->useJournal = useJournal;
-+  pPager->ckptOpen = 0;
-+  pPager->ckptInUse = 0;
-+  pPager->nRef = 0;
-+  pPager->dbSize = -1;
-+  pPager->ckptSize = 0;
-+  pPager->ckptJSize = 0;
-+  pPager->nPage = 0;
-+  pPager->mxPage = mxPage>5 ? mxPage : 10;
-+  pPager->state = SQLITE_UNLOCK;
-+  pPager->errMask = 0;
-+  pPager->tempFile = tempFile;
-+  pPager->readOnly = readOnly;
-+  pPager->needSync = 0;
-+  pPager->noSync = pPager->tempFile || !useJournal;
-+  pPager->pFirst = 0;
-+  pPager->pFirstSynced = 0;
-+  pPager->pLast = 0;
-+  pPager->nExtra = nExtra;
-+  memset(pPager->aHash, 0, sizeof(pPager->aHash));
-+  *ppPager = pPager;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Set the destructor for this pager.  If not NULL, the destructor is called
-+** when the reference count on each page reaches zero.  The destructor can
-+** be used to clean up information in the extra segment appended to each page.
-+**
-+** The destructor is not called as a result sqlitepager_close().  
-+** Destructors are only called by sqlitepager_unref().
-+*/
-+void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
-+  pPager->xDestructor = xDesc;
-+}
-+
-+/*
-+** Return the total number of pages in the disk file associated with
-+** pPager.
-+*/
-+int sqlitepager_pagecount(Pager *pPager){
-+  off_t n;
-+  assert( pPager!=0 );
-+  if( pPager->dbSize>=0 ){
-+    return pPager->dbSize;
-+  }
-+  if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
-+    pPager->errMask |= PAGER_ERR_DISK;
-+    return 0;
-+  }
-+  n /= SQLITE_PAGE_SIZE;
-+  if( pPager->state!=SQLITE_UNLOCK ){
-+    pPager->dbSize = n;
-+  }
-+  return n;
-+}
-+
-+/*
-+** Forward declaration
-+*/
-+static int syncJournal(Pager*);
-+
-+/*
-+** Truncate the file to the number of pages specified.
-+*/
-+int sqlitepager_truncate(Pager *pPager, Pgno nPage){
-+  int rc;
-+  if( pPager->dbSize<0 ){
-+    sqlitepager_pagecount(pPager);
-+  }
-+  if( pPager->errMask!=0 ){
-+    rc = pager_errcode(pPager);
-+    return rc;
-+  }
-+  if( nPage>=(unsigned)pPager->dbSize ){
-+    return SQLITE_OK;
-+  }
-+  syncJournal(pPager);
-+  rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)nPage);
-+  if( rc==SQLITE_OK ){
-+    pPager->dbSize = nPage;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqlitepager_close(Pager *pPager){
-+  PgHdr *pPg, *pNext;
-+  switch( pPager->state ){
-+    case SQLITE_WRITELOCK: {
-+      sqlitepager_rollback(pPager);
-+      sqliteOsUnlock(&pPager->fd);
-+      assert( pPager->journalOpen==0 );
-+      break;
-+    }
-+    case SQLITE_READLOCK: {
-+      sqliteOsUnlock(&pPager->fd);
-+      break;
-+    }
-+    default: {
-+      /* Do nothing */
-+      break;
-+    }
-+  }
-+  for(pPg=pPager->pAll; pPg; pPg=pNext){
-+    pNext = pPg->pNextAll;
-+    sqliteFree(pPg);
-+  }
-+  sqliteOsClose(&pPager->fd);
-+  assert( pPager->journalOpen==0 );
-+  /* Temp files are automatically deleted by the OS
-+  ** if( pPager->tempFile ){
-+  **   sqliteOsDelete(pPager->zFilename);
-+  ** }
-+  */
-+  CLR_PAGER(pPager);
-+  if( pPager->zFilename!=(char*)&pPager[1] ){
-+    assert( 0 );  /* Cannot happen */
-+    sqliteFree(pPager->zFilename);
-+    sqliteFree(pPager->zJournal);
-+    sqliteFree(pPager->zDirectory);
-+  }
-+  sqliteFree(pPager);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Return the page number for the given page data.
-+*/
-+Pgno sqlitepager_pagenumber(void *pData){
-+  PgHdr *p = DATA_TO_PGHDR(pData);
-+  return p->pgno;
-+}
-+
-+/*
-+** Increment the reference count for a page.  If the page is
-+** currently on the freelist (the reference count is zero) then
-+** remove it from the freelist.
-+*/
-+#define page_ref(P)   ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++)
-+static void _page_ref(PgHdr *pPg){
-+  if( pPg->nRef==0 ){
-+    /* The page is currently on the freelist.  Remove it. */
-+    if( pPg==pPg->pPager->pFirstSynced ){
-+      PgHdr *p = pPg->pNextFree;
-+      while( p && p->needSync ){ p = p->pNextFree; }
-+      pPg->pPager->pFirstSynced = p;
-+    }
-+    if( pPg->pPrevFree ){
-+      pPg->pPrevFree->pNextFree = pPg->pNextFree;
-+    }else{
-+      pPg->pPager->pFirst = pPg->pNextFree;
-+    }
-+    if( pPg->pNextFree ){
-+      pPg->pNextFree->pPrevFree = pPg->pPrevFree;
-+    }else{
-+      pPg->pPager->pLast = pPg->pPrevFree;
-+    }
-+    pPg->pPager->nRef++;
-+  }
-+  pPg->nRef++;
-+  REFINFO(pPg);
-+}
-+
-+/*
-+** Increment the reference count for a page.  The input pointer is
-+** a reference to the page data.
-+*/
-+int sqlitepager_ref(void *pData){
-+  PgHdr *pPg = DATA_TO_PGHDR(pData);
-+  page_ref(pPg);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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.  It is not safe to modify the original database file until after
-+** the journal has been synced.  If the original database is modified before
-+** the journal is synced and a power failure occurs, the unsynced journal
-+** data would be lost and we would be unable to completely rollback the
-+** database changes.  Database corruption would occur.
-+** 
-+** This routine also updates the nRec field in the header of the journal.
-+** (See comments on the pager_playback() routine for additional information.)
-+** If the sync mode is FULL, two syncs will occur.  First the whole journal
-+** is synced, then the nRec field is updated, then a second sync occurs.
-+**
-+** For temporary databases, we do not care if we are able to rollback
-+** after a power failure, so sync occurs.
-+**
-+** This routine clears the needSync field of every page current held in
-+** memory.
-+*/
-+static int syncJournal(Pager *pPager){
-+  PgHdr *pPg;
-+  int rc = SQLITE_OK;
-+
-+  /* Sync the journal before modifying the main database
-+  ** (assuming there is a journal and it needs to be synced.)
-+  */
-+  if( pPager->needSync ){
-+    if( !pPager->tempFile ){
-+      assert( pPager->journalOpen );
-+      /* assert( !pPager->noSync ); // noSync might be set if synchronous
-+      ** was turned off after the transaction was started.  Ticket #615 */
-+#ifndef NDEBUG
-+      {
-+        /* Make sure the pPager->nRec counter we are keeping agrees
-+        ** with the nRec computed from the size of the journal file.
-+        */
-+        off_t hdrSz, pgSz, jSz;
-+        hdrSz = JOURNAL_HDR_SZ(journal_format);
-+        pgSz = JOURNAL_PG_SZ(journal_format);
-+        rc = sqliteOsFileSize(&pPager->jfd, &jSz);
-+        if( rc!=0 ) return rc;
-+        assert( pPager->nRec*pgSz+hdrSz==jSz );
-+      }
-+#endif
-+      if( journal_format>=3 ){
-+        /* Write the nRec value into the journal file header */
-+        off_t szJ;
-+        if( pPager->fullSync ){
-+          TRACE1("SYNC\n");
-+          rc = sqliteOsSync(&pPager->jfd);
-+          if( rc!=0 ) return rc;
-+        }
-+        sqliteOsSeek(&pPager->jfd, sizeof(aJournalMagic1));
-+        rc = write32bits(&pPager->jfd, pPager->nRec);
-+        if( rc ) return rc;
-+        szJ = JOURNAL_HDR_SZ(journal_format) +
-+                 pPager->nRec*JOURNAL_PG_SZ(journal_format);
-+        sqliteOsSeek(&pPager->jfd, szJ);
-+      }
-+      TRACE1("SYNC\n");
-+      rc = sqliteOsSync(&pPager->jfd);
-+      if( rc!=0 ) return rc;
-+      pPager->journalStarted = 1;
-+    }
-+    pPager->needSync = 0;
-+
-+    /* Erase the needSync flag from every page.
-+    */
-+    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-+      pPg->needSync = 0;
-+    }
-+    pPager->pFirstSynced = pPager->pFirst;
-+  }
-+
-+#ifndef NDEBUG
-+  /* If the Pager.needSync flag is clear then the PgHdr.needSync
-+  ** flag must also be clear for all pages.  Verify that this
-+  ** invariant is true.
-+  */
-+  else{
-+    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-+      assert( pPg->needSync==0 );
-+    }
-+    assert( pPager->pFirstSynced==pPager->pFirst );
-+  }
-+#endif
-+
-+  return rc;
-+}
-+
-+/*
-+** Given a list of pages (connected by the PgHdr.pDirty pointer) write
-+** every one of those pages out to the database file and mark them all
-+** as clean.
-+*/
-+static int pager_write_pagelist(PgHdr *pList){
-+  Pager *pPager;
-+  int rc;
-+
-+  if( pList==0 ) return SQLITE_OK;
-+  pPager = pList->pPager;
-+  while( pList ){
-+    assert( pList->dirty );
-+    sqliteOsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_PAGE_SIZE);
-+    CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
-+    TRACE2("STORE %d\n", pList->pgno);
-+    rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_PAGE_SIZE);
-+    CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
-+    if( rc ) return rc;
-+    pList->dirty = 0;
-+    pList = pList->pDirty;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Collect every dirty page into a dirty list and
-+** return a pointer to the head of that list.  All pages are
-+** collected even if they are still in use.
-+*/
-+static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
-+  PgHdr *p, *pList;
-+  pList = 0;
-+  for(p=pPager->pAll; p; p=p->pNextAll){
-+    if( p->dirty ){
-+      p->pDirty = pList;
-+      pList = p;
-+    }
-+  }
-+  return pList;
-+}
-+
-+/*
-+** Acquire a page.
-+**
-+** A read lock on the disk file is obtained when the first page is acquired. 
-+** This read lock is dropped when the last page is released.
-+**
-+** A _get works for any page number greater than 0.  If the database
-+** file is smaller than the requested page, then no actual disk
-+** read occurs and the memory image of the page is initialized to
-+** all zeros.  The extra data appended to a page is always initialized
-+** to zeros the first time a page is loaded into memory.
-+**
-+** The acquisition might fail for several reasons.  In all cases,
-+** an appropriate error code is returned and *ppPage is set to NULL.
-+**
-+** See also sqlitepager_lookup().  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.
-+*/
-+int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
-+  PgHdr *pPg;
-+  int rc;
-+
-+  /* Make sure we have not hit any critical errors.
-+  */ 
-+  assert( pPager!=0 );
-+  assert( pgno!=0 );
-+  *ppPage = 0;
-+  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
-+    return pager_errcode(pPager);
-+  }
-+
-+  /* If this is the first page accessed, then get a read lock
-+  ** on the database file.
-+  */
-+  if( pPager->nRef==0 ){
-+    rc = sqliteOsReadLock(&pPager->fd);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-+    }
-+    pPager->state = SQLITE_READLOCK;
-+
-+    /* If a journal file exists, try to play it back.
-+    */
-+    if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){
-+       int rc;
-+
-+       /* Get a write lock on the database
-+       */
-+       rc = sqliteOsWriteLock(&pPager->fd);
-+       if( rc!=SQLITE_OK ){
-+         if( sqliteOsUnlock(&pPager->fd)!=SQLITE_OK ){
-+           /* This should never happen! */
-+           rc = SQLITE_INTERNAL;
-+         }
-+         return rc;
-+       }
-+       pPager->state = SQLITE_WRITELOCK;
-+
-+       /* Open the journal for reading only.  Return SQLITE_BUSY if
-+       ** we are unable to open the journal file. 
-+       **
-+       ** The journal file does not need to be locked itself.  The
-+       ** journal file is never open unless the main database file holds
-+       ** a write lock, so there is never any chance of two or more
-+       ** processes opening the journal at the same time.
-+       */
-+       rc = sqliteOsOpenReadOnly(pPager->zJournal, &pPager->jfd);
-+       if( rc!=SQLITE_OK ){
-+         rc = sqliteOsUnlock(&pPager->fd);
-+         assert( rc==SQLITE_OK );
-+         return SQLITE_BUSY;
-+       }
-+       pPager->journalOpen = 1;
-+       pPager->journalStarted = 0;
-+
-+       /* Playback and delete the journal.  Drop the database write
-+       ** lock and reacquire the read lock.
-+       */
-+       rc = pager_playback(pPager, 0);
-+       if( rc!=SQLITE_OK ){
-+         return rc;
-+       }
-+    }
-+    pPg = 0;
-+  }else{
-+    /* Search for page in cache */
-+    pPg = pager_lookup(pPager, pgno);
-+  }
-+  if( pPg==0 ){
-+    /* The requested page is not in the page cache. */
-+    int h;
-+    pPager->nMiss++;
-+    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
-+      /* Create a new page */
-+      pPg = sqliteMallocRaw( sizeof(*pPg) + SQLITE_PAGE_SIZE 
-+                              + sizeof(u32) + pPager->nExtra );
-+      if( pPg==0 ){
-+        pager_unwritelock(pPager);
-+        pPager->errMask |= PAGER_ERR_MEM;
-+        return SQLITE_NOMEM;
-+      }
-+      memset(pPg, 0, sizeof(*pPg));
-+      pPg->pPager = pPager;
-+      pPg->pNextAll = pPager->pAll;
-+      if( pPager->pAll ){
-+        pPager->pAll->pPrevAll = pPg;
-+      }
-+      pPg->pPrevAll = 0;
-+      pPager->pAll = pPg;
-+      pPager->nPage++;
-+    }else{
-+      /* Find a page to recycle.  Try to locate a page that does not
-+      ** require us to do an fsync() on the journal.
-+      */
-+      pPg = pPager->pFirstSynced;
-+
-+      /* If we could not find a page that does not require an fsync()
-+      ** on the journal file then fsync the journal file.  This is a
-+      ** very slow operation, so we work hard to avoid it.  But sometimes
-+      ** it can't be helped.
-+      */
-+      if( pPg==0 ){
-+        int rc = syncJournal(pPager);
-+        if( rc!=0 ){
-+          sqlitepager_rollback(pPager);
-+          return SQLITE_IOERR;
-+        }
-+        pPg = pPager->pFirst;
-+      }
-+      assert( pPg->nRef==0 );
-+
-+      /* Write the page to the database file if it is dirty.
-+      */
-+      if( pPg->dirty ){
-+        assert( pPg->needSync==0 );
-+        pPg->pDirty = 0;
-+        rc = pager_write_pagelist( pPg );
-+        if( rc!=SQLITE_OK ){
-+          sqlitepager_rollback(pPager);
-+          return SQLITE_IOERR;
-+        }
-+      }
-+      assert( pPg->dirty==0 );
-+
-+      /* If the page we are recycling is marked as alwaysRollback, then
-+      ** set the global alwaysRollback flag, thus disabling the
-+      ** sqlite_dont_rollback() optimization for the rest of this transaction.
-+      ** It is necessary to do this because the page marked alwaysRollback
-+      ** might be reloaded at a later time but at that point we won't remember
-+      ** that is was marked alwaysRollback.  This means that all pages must
-+      ** be marked as alwaysRollback from here on out.
-+      */
-+      if( pPg->alwaysRollback ){
-+        pPager->alwaysRollback = 1;
-+      }
-+
-+      /* Unlink the old page from the free list and the hash table
-+      */
-+      if( pPg==pPager->pFirstSynced ){
-+        PgHdr *p = pPg->pNextFree;
-+        while( p && p->needSync ){ p = p->pNextFree; }
-+        pPager->pFirstSynced = p;
-+      }
-+      if( pPg->pPrevFree ){
-+        pPg->pPrevFree->pNextFree = pPg->pNextFree;
-+      }else{
-+        assert( pPager->pFirst==pPg );
-+        pPager->pFirst = pPg->pNextFree;
-+      }
-+      if( pPg->pNextFree ){
-+        pPg->pNextFree->pPrevFree = pPg->pPrevFree;
-+      }else{
-+        assert( pPager->pLast==pPg );
-+        pPager->pLast = pPg->pPrevFree;
-+      }
-+      pPg->pNextFree = pPg->pPrevFree = 0;
-+      if( pPg->pNextHash ){
-+        pPg->pNextHash->pPrevHash = pPg->pPrevHash;
-+      }
-+      if( pPg->pPrevHash ){
-+        pPg->pPrevHash->pNextHash = pPg->pNextHash;
-+      }else{
-+        h = pager_hash(pPg->pgno);
-+        assert( pPager->aHash[h]==pPg );
-+        pPager->aHash[h] = pPg->pNextHash;
-+      }
-+      pPg->pNextHash = pPg->pPrevHash = 0;
-+      pPager->nOvfl++;
-+    }
-+    pPg->pgno = pgno;
-+    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
-+      sqliteCheckMemory(pPager->aInJournal, pgno/8);
-+      assert( pPager->journalOpen );
-+      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
-+      pPg->needSync = 0;
-+    }else{
-+      pPg->inJournal = 0;
-+      pPg->needSync = 0;
-+    }
-+    if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize
-+             && (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0 ){
-+      page_add_to_ckpt_list(pPg);
-+    }else{
-+      page_remove_from_ckpt_list(pPg);
-+    }
-+    pPg->dirty = 0;
-+    pPg->nRef = 1;
-+    REFINFO(pPg);
-+    pPager->nRef++;
-+    h = pager_hash(pgno);
-+    pPg->pNextHash = pPager->aHash[h];
-+    pPager->aHash[h] = pPg;
-+    if( pPg->pNextHash ){
-+      assert( pPg->pNextHash->pPrevHash==0 );
-+      pPg->pNextHash->pPrevHash = pPg;
-+    }
-+    if( pPager->nExtra>0 ){
-+      memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
-+    }
-+    if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
-+    if( pPager->errMask!=0 ){
-+      sqlitepager_unref(PGHDR_TO_DATA(pPg));
-+      rc = pager_errcode(pPager);
-+      return rc;
-+    }
-+    if( pPager->dbSize<(int)pgno ){
-+      memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
-+    }else{
-+      int rc;
-+      sqliteOsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
-+      rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
-+      TRACE2("FETCH %d\n", pPg->pgno);
-+      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
-+      if( rc!=SQLITE_OK ){
-+        off_t fileSize;
-+        if( sqliteOsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
-+               || fileSize>=pgno*SQLITE_PAGE_SIZE ){
-+          sqlitepager_unref(PGHDR_TO_DATA(pPg));
-+          return rc;
-+        }else{
-+          memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
-+        }
-+      }
-+    }
-+  }else{
-+    /* The requested page is in the page cache. */
-+    pPager->nHit++;
-+    page_ref(pPg);
-+  }
-+  *ppPage = PGHDR_TO_DATA(pPg);
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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.
-+**
-+** See also sqlitepager_get().  The difference between this routine
-+** and sqlitepager_get() 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.
-+*/
-+void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
-+  PgHdr *pPg;
-+
-+  assert( pPager!=0 );
-+  assert( pgno!=0 );
-+  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
-+    return 0;
-+  }
-+  /* if( pPager->nRef==0 ){
-+  **  return 0;
-+  ** }
-+  */
-+  pPg = pager_lookup(pPager, pgno);
-+  if( pPg==0 ) return 0;
-+  page_ref(pPg);
-+  return PGHDR_TO_DATA(pPg);
-+}
-+
-+/*
-+** Release a page.
-+**
-+** 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.
-+*/
-+int sqlitepager_unref(void *pData){
-+  PgHdr *pPg;
-+
-+  /* Decrement the reference count for this page
-+  */
-+  pPg = DATA_TO_PGHDR(pData);
-+  assert( pPg->nRef>0 );
-+  pPg->nRef--;
-+  REFINFO(pPg);
-+
-+  /* When the number of references to a page reach 0, call the
-+  ** destructor and add the page to the freelist.
-+  */
-+  if( pPg->nRef==0 ){
-+    Pager *pPager;
-+    pPager = pPg->pPager;
-+    pPg->pNextFree = 0;
-+    pPg->pPrevFree = pPager->pLast;
-+    pPager->pLast = pPg;
-+    if( pPg->pPrevFree ){
-+      pPg->pPrevFree->pNextFree = pPg;
-+    }else{
-+      pPager->pFirst = pPg;
-+    }
-+    if( pPg->needSync==0 && pPager->pFirstSynced==0 ){
-+      pPager->pFirstSynced = pPg;
-+    }
-+    if( pPager->xDestructor ){
-+      pPager->xDestructor(pData);
-+    }
-+  
-+    /* When all pages reach the freelist, drop the read lock from
-+    ** the database file.
-+    */
-+    pPager->nRef--;
-+    assert( pPager->nRef>=0 );
-+    if( pPager->nRef==0 ){
-+      pager_reset(pPager);
-+    }
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Create a journal file for pPager.  There should already be a write
-+** lock on the database file when this routine is called.
-+**
-+** Return SQLITE_OK if everything.  Return an error code and release the
-+** write lock if anything goes wrong.
-+*/
-+static int pager_open_journal(Pager *pPager){
-+  int rc;
-+  assert( pPager->state==SQLITE_WRITELOCK );
-+  assert( pPager->journalOpen==0 );
-+  assert( pPager->useJournal );
-+  sqlitepager_pagecount(pPager);
-+  pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
-+  if( pPager->aInJournal==0 ){
-+    sqliteOsReadLock(&pPager->fd);
-+    pPager->state = SQLITE_READLOCK;
-+    return SQLITE_NOMEM;
-+  }
-+  rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
-+  if( rc!=SQLITE_OK ){
-+    sqliteFree(pPager->aInJournal);
-+    pPager->aInJournal = 0;
-+    sqliteOsReadLock(&pPager->fd);
-+    pPager->state = SQLITE_READLOCK;
-+    return SQLITE_CANTOPEN;
-+  }
-+  sqliteOsOpenDirectory(pPager->zDirectory, &pPager->jfd);
-+  pPager->journalOpen = 1;
-+  pPager->journalStarted = 0;
-+  pPager->needSync = 0;
-+  pPager->alwaysRollback = 0;
-+  pPager->nRec = 0;
-+  if( pPager->errMask!=0 ){
-+    rc = pager_errcode(pPager);
-+    return rc;
-+  }
-+  pPager->origDbSize = pPager->dbSize;
-+  if( journal_format==JOURNAL_FORMAT_3 ){
-+    rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3));
-+    if( rc==SQLITE_OK ){
-+      rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
-+    }
-+    if( rc==SQLITE_OK ){
-+      sqliteRandomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
-+      rc = write32bits(&pPager->jfd, pPager->cksumInit);
-+    }
-+  }else if( journal_format==JOURNAL_FORMAT_2 ){
-+    rc = sqliteOsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2));
-+  }else{
-+    assert( journal_format==JOURNAL_FORMAT_1 );
-+    rc = sqliteOsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1));
-+  }
-+  if( rc==SQLITE_OK ){
-+    rc = write32bits(&pPager->jfd, pPager->dbSize);
-+  }
-+  if( pPager->ckptAutoopen && rc==SQLITE_OK ){
-+    rc = sqlitepager_ckpt_begin(pPager);
-+  }
-+  if( rc!=SQLITE_OK ){
-+    rc = pager_unwritelock(pPager);
-+    if( rc==SQLITE_OK ){
-+      rc = SQLITE_FULL;
-+    }
-+  }
-+  return rc;  
-+}
-+
-+/*
-+** Acquire a write-lock on the database.  The lock is removed when
-+** the any of the following happen:
-+**
-+**   *  sqlitepager_commit() is called.
-+**   *  sqlitepager_rollback() is called.
-+**   *  sqlitepager_close() is called.
-+**   *  sqlitepager_unref() is called to on every outstanding page.
-+**
-+** The parameter to this routine is a pointer to any open page of the
-+** database file.  Nothing changes about the page - it is used merely
-+** to acquire a pointer to the Pager structure and as proof that there
-+** is already a read-lock on the database.
-+**
-+** A journal file is opened if this is not a temporary file.  For
-+** temporary files, the opening of the journal file is deferred until
-+** there is an actual need to write to the journal.
-+**
-+** If the database is already write-locked, this routine is a no-op.
-+*/
-+int sqlitepager_begin(void *pData){
-+  PgHdr *pPg = DATA_TO_PGHDR(pData);
-+  Pager *pPager = pPg->pPager;
-+  int rc = SQLITE_OK;
-+  assert( pPg->nRef>0 );
-+  assert( pPager->state!=SQLITE_UNLOCK );
-+  if( pPager->state==SQLITE_READLOCK ){
-+    assert( pPager->aInJournal==0 );
-+    rc = sqliteOsWriteLock(&pPager->fd);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-+    }
-+    pPager->state = SQLITE_WRITELOCK;
-+    pPager->dirtyFile = 0;
-+    TRACE1("TRANSACTION\n");
-+    if( pPager->useJournal && !pPager->tempFile ){
-+      rc = pager_open_journal(pPager);
-+    }
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Mark a data page as writeable.  The page is written into the journal 
-+** if it is not there already.  This routine must be called before making
-+** changes to a page.
-+**
-+** The first time this routine is called, the pager creates a new
-+** journal and acquires a write lock on the database.  If the write
-+** lock could not be acquired, this routine returns SQLITE_BUSY.  The
-+** calling routine must check for that return value and be careful not to
-+** change any page data until this routine returns SQLITE_OK.
-+**
-+** If the journal file could not be written because the disk is full,
-+** then this routine returns SQLITE_FULL and does an immediate rollback.
-+** All subsequent write attempts also return SQLITE_FULL until there
-+** is a call to sqlitepager_commit() or sqlitepager_rollback() to
-+** reset.
-+*/
-+int sqlitepager_write(void *pData){
-+  PgHdr *pPg = DATA_TO_PGHDR(pData);
-+  Pager *pPager = pPg->pPager;
-+  int rc = SQLITE_OK;
-+
-+  /* Check for errors
-+  */
-+  if( pPager->errMask ){ 
-+    return pager_errcode(pPager);
-+  }
-+  if( pPager->readOnly ){
-+    return SQLITE_PERM;
-+  }
-+
-+  /* Mark the page as dirty.  If the page has already been written
-+  ** to the journal then we can return right away.
-+  */
-+  pPg->dirty = 1;
-+  if( pPg->inJournal && (pPg->inCkpt || pPager->ckptInUse==0) ){
-+    pPager->dirtyFile = 1;
-+    return SQLITE_OK;
-+  }
-+
-+  /* If we get this far, it means that the page needs to be
-+  ** written to the transaction journal or the ckeckpoint journal
-+  ** or both.
-+  **
-+  ** First check to see that the transaction journal exists and
-+  ** create it if it does not.
-+  */
-+  assert( pPager->state!=SQLITE_UNLOCK );
-+  rc = sqlitepager_begin(pData);
-+  if( rc!=SQLITE_OK ){
-+    return rc;
-+  }
-+  assert( pPager->state==SQLITE_WRITELOCK );
-+  if( !pPager->journalOpen && pPager->useJournal ){
-+    rc = pager_open_journal(pPager);
-+    if( rc!=SQLITE_OK ) return rc;
-+  }
-+  assert( pPager->journalOpen || !pPager->useJournal );
-+  pPager->dirtyFile = 1;
-+
-+  /* The transaction journal now exists and we have a write lock on the
-+  ** main database file.  Write the current page to the transaction 
-+  ** journal if it is not there already.
-+  */
-+  if( !pPg->inJournal && pPager->useJournal ){
-+    if( (int)pPg->pgno <= pPager->origDbSize ){
-+      int szPg;
-+      u32 saved;
-+      if( journal_format>=JOURNAL_FORMAT_3 ){
-+        u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
-+        saved = *(u32*)PGHDR_TO_EXTRA(pPg);
-+        store32bits(cksum, pPg, SQLITE_PAGE_SIZE);
-+        szPg = SQLITE_PAGE_SIZE+8;
-+      }else{
-+        szPg = SQLITE_PAGE_SIZE+4;
-+      }
-+      store32bits(pPg->pgno, pPg, -4);
-+      CODEC(pPager, pData, pPg->pgno, 7);
-+      rc = sqliteOsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
-+      TRACE3("JOURNAL %d %d\n", pPg->pgno, pPg->needSync);
-+      CODEC(pPager, pData, pPg->pgno, 0);
-+      if( journal_format>=JOURNAL_FORMAT_3 ){
-+        *(u32*)PGHDR_TO_EXTRA(pPg) = saved;
-+      }
-+      if( rc!=SQLITE_OK ){
-+        sqlitepager_rollback(pPager);
-+        pPager->errMask |= PAGER_ERR_FULL;
-+        return rc;
-+      }
-+      pPager->nRec++;
-+      assert( pPager->aInJournal!=0 );
-+      pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+      pPg->needSync = !pPager->noSync;
-+      pPg->inJournal = 1;
-+      if( pPager->ckptInUse ){
-+        pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+        page_add_to_ckpt_list(pPg);
-+      }
-+    }else{
-+      pPg->needSync = !pPager->journalStarted && !pPager->noSync;
-+      TRACE3("APPEND %d %d\n", pPg->pgno, pPg->needSync);
-+    }
-+    if( pPg->needSync ){
-+      pPager->needSync = 1;
-+    }
-+  }
-+
-+  /* If the checkpoint journal is open and the page is not in it,
-+  ** then write the current page to the checkpoint journal.  Note that
-+  ** the checkpoint journal always uses the simplier format 2 that lacks
-+  ** checksums.  The header is also omitted from the checkpoint journal.
-+  */
-+  if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
-+    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
-+    store32bits(pPg->pgno, pPg, -4);
-+    CODEC(pPager, pData, pPg->pgno, 7);
-+    rc = sqliteOsWrite(&pPager->cpfd, &((char*)pData)[-4], SQLITE_PAGE_SIZE+4);
-+    TRACE2("CKPT-JOURNAL %d\n", pPg->pgno);
-+    CODEC(pPager, pData, pPg->pgno, 0);
-+    if( rc!=SQLITE_OK ){
-+      sqlitepager_rollback(pPager);
-+      pPager->errMask |= PAGER_ERR_FULL;
-+      return rc;
-+    }
-+    pPager->ckptNRec++;
-+    assert( pPager->aInCkpt!=0 );
-+    pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+    page_add_to_ckpt_list(pPg);
-+  }
-+
-+  /* Update the database size and return.
-+  */
-+  if( pPager->dbSize<(int)pPg->pgno ){
-+    pPager->dbSize = pPg->pgno;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Return TRUE if the page given in the argument was previously passed
-+** to sqlitepager_write().  In other words, return TRUE if it is ok
-+** to change the content of the page.
-+*/
-+int sqlitepager_iswriteable(void *pData){
-+  PgHdr *pPg = DATA_TO_PGHDR(pData);
-+  return pPg->dirty;
-+}
-+
-+/*
-+** Replace the content of a single page with the information in the third
-+** argument.
-+*/
-+int sqlitepager_overwrite(Pager *pPager, Pgno pgno, void *pData){
-+  void *pPage;
-+  int rc;
-+
-+  rc = sqlitepager_get(pPager, pgno, &pPage);
-+  if( rc==SQLITE_OK ){
-+    rc = sqlitepager_write(pPage);
-+    if( rc==SQLITE_OK ){
-+      memcpy(pPage, pData, SQLITE_PAGE_SIZE);
-+    }
-+    sqlitepager_unref(pPage);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** A call to this routine tells the pager that it is not necessary to
-+** write the information on page "pgno" back to the disk, even though
-+** that page might be marked as dirty.
-+**
-+** 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, together with the
-+** sqlitepager_dont_rollback() below, more than double the speed
-+** of large INSERT operations and quadruple the speed of large DELETEs.
-+**
-+** When this routine is called, set the alwaysRollback flag to true.
-+** Subsequent calls to sqlitepager_dont_rollback() for the same page
-+** will thereafter be ignored.  This is necessary to avoid a problem
-+** where a page with data is added to the freelist during one part of
-+** a transaction then removed from the freelist during a later part
-+** of the same transaction and reused for some other purpose.  When it
-+** is first added to the freelist, this routine is called.  When reused,
-+** the dont_rollback() routine is called.  But because the page contains
-+** critical data, we still need to be sure it gets rolled back in spite
-+** of the dont_rollback() call.
-+*/
-+void sqlitepager_dont_write(Pager *pPager, Pgno pgno){
-+  PgHdr *pPg;
-+
-+  pPg = pager_lookup(pPager, pgno);
-+  pPg->alwaysRollback = 1;
-+  if( pPg && pPg->dirty && !pPager->ckptInUse ){
-+    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
-+      /* If this pages is the last page in the file and the file has grown
-+      ** during the current transaction, then do NOT mark the page as clean.
-+      ** When the database file grows, we must make sure that the last page
-+      ** gets written at least once so that the disk file will be the correct
-+      ** size. If you do not write this page and the size of the file
-+      ** on the disk ends up being too small, that can lead to database
-+      ** corruption during the next transaction.
-+      */
-+    }else{
-+      TRACE2("DONT_WRITE %d\n", pgno);
-+      pPg->dirty = 0;
-+    }
-+  }
-+}
-+
-+/*
-+** A call to this routine tells the pager that if a rollback occurs,
-+** it is not necessary to restore the data on the given page.  This
-+** means that the pager does not have to record the given page in the
-+** rollback journal.
-+*/
-+void sqlitepager_dont_rollback(void *pData){
-+  PgHdr *pPg = DATA_TO_PGHDR(pData);
-+  Pager *pPager = pPg->pPager;
-+
-+  if( pPager->state!=SQLITE_WRITELOCK || pPager->journalOpen==0 ) return;
-+  if( pPg->alwaysRollback || pPager->alwaysRollback ) return;
-+  if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
-+    assert( pPager->aInJournal!=0 );
-+    pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+    pPg->inJournal = 1;
-+    if( pPager->ckptInUse ){
-+      pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+      page_add_to_ckpt_list(pPg);
-+    }
-+    TRACE2("DONT_ROLLBACK %d\n", pPg->pgno);
-+  }
-+  if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
-+    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
-+    assert( pPager->aInCkpt!=0 );
-+    pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
-+    page_add_to_ckpt_list(pPg);
-+  }
-+}
-+
-+/*
-+** Commit all changes to the database and release the write lock.
-+**
-+** If the commit fails for any reason, a rollback attempt is made
-+** and an error code is returned.  If the commit worked, SQLITE_OK
-+** is returned.
-+*/
-+int sqlitepager_commit(Pager *pPager){
-+  int rc;
-+  PgHdr *pPg;
-+
-+  if( pPager->errMask==PAGER_ERR_FULL ){
-+    rc = sqlitepager_rollback(pPager);
-+    if( rc==SQLITE_OK ){
-+      rc = SQLITE_FULL;
-+    }
-+    return rc;
-+  }
-+  if( pPager->errMask!=0 ){
-+    rc = pager_errcode(pPager);
-+    return rc;
-+  }
-+  if( pPager->state!=SQLITE_WRITELOCK ){
-+    return SQLITE_ERROR;
-+  }
-+  TRACE1("COMMIT\n");
-+  if( pPager->dirtyFile==0 ){
-+    /* Exit early (without doing the time-consuming sqliteOsSync() calls)
-+    ** if there have been no changes to the database file. */
-+    assert( pPager->needSync==0 );
-+    rc = pager_unwritelock(pPager);
-+    pPager->dbSize = -1;
-+    return rc;
-+  }
-+  assert( pPager->journalOpen );
-+  rc = syncJournal(pPager);
-+  if( rc!=SQLITE_OK ){
-+    goto commit_abort;
-+  }
-+  pPg = pager_get_all_dirty_pages(pPager);
-+  if( pPg ){
-+    rc = pager_write_pagelist(pPg);
-+    if( rc || (!pPager->noSync && sqliteOsSync(&pPager->fd)!=SQLITE_OK) ){
-+      goto commit_abort;
-+    }
-+  }
-+  rc = pager_unwritelock(pPager);
-+  pPager->dbSize = -1;
-+  return rc;
-+
-+  /* Jump here if anything goes wrong during the commit process.
-+  */
-+commit_abort:
-+  rc = sqlitepager_rollback(pPager);
-+  if( rc==SQLITE_OK ){
-+    rc = SQLITE_FULL;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Rollback all changes.  The database falls back to read-only mode.
-+** All in-memory cache pages revert to their original data contents.
-+** The journal is deleted.
-+**
-+** This routine cannot fail unless some other process is not following
-+** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
-+** process is writing trash into the journal file (SQLITE_CORRUPT) or
-+** unless a prior malloc() failed (SQLITE_NOMEM).  Appropriate error
-+** codes are returned for all these occasions.  Otherwise,
-+** SQLITE_OK is returned.
-+*/
-+int sqlitepager_rollback(Pager *pPager){
-+  int rc;
-+  TRACE1("ROLLBACK\n");
-+  if( !pPager->dirtyFile || !pPager->journalOpen ){
-+    rc = pager_unwritelock(pPager);
-+    pPager->dbSize = -1;
-+    return rc;
-+  }
-+
-+  if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
-+    if( pPager->state>=SQLITE_WRITELOCK ){
-+      pager_playback(pPager, 1);
-+    }
-+    return pager_errcode(pPager);
-+  }
-+  if( pPager->state!=SQLITE_WRITELOCK ){
-+    return SQLITE_OK;
-+  }
-+  rc = pager_playback(pPager, 1);
-+  if( rc!=SQLITE_OK ){
-+    rc = SQLITE_CORRUPT;
-+    pPager->errMask |= PAGER_ERR_CORRUPT;
-+  }
-+  pPager->dbSize = -1;
-+  return rc;
-+}
-+
-+/*
-+** Return TRUE if the database file is opened read-only.  Return FALSE
-+** if the database is (in theory) writable.
-+*/
-+int sqlitepager_isreadonly(Pager *pPager){
-+  return pPager->readOnly;
-+}
-+
-+/*
-+** This routine is used for testing and analysis only.
-+*/
-+int *sqlitepager_stats(Pager *pPager){
-+  static int a[9];
-+  a[0] = pPager->nRef;
-+  a[1] = pPager->nPage;
-+  a[2] = pPager->mxPage;
-+  a[3] = pPager->dbSize;
-+  a[4] = pPager->state;
-+  a[5] = pPager->errMask;
-+  a[6] = pPager->nHit;
-+  a[7] = pPager->nMiss;
-+  a[8] = pPager->nOvfl;
-+  return a;
-+}
-+
-+/*
-+** Set the checkpoint.
-+**
-+** This routine should be called with the transaction journal already
-+** open.  A new checkpoint journal is created that can be used to rollback
-+** changes of a single SQL command within a larger transaction.
-+*/
-+int sqlitepager_ckpt_begin(Pager *pPager){
-+  int rc;
-+  char zTemp[SQLITE_TEMPNAME_SIZE];
-+  if( !pPager->journalOpen ){
-+    pPager->ckptAutoopen = 1;
-+    return SQLITE_OK;
-+  }
-+  assert( pPager->journalOpen );
-+  assert( !pPager->ckptInUse );
-+  pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
-+  if( pPager->aInCkpt==0 ){
-+    sqliteOsReadLock(&pPager->fd);
-+    return SQLITE_NOMEM;
-+  }
-+#ifndef NDEBUG
-+  rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
-+  if( rc ) goto ckpt_begin_failed;
-+  assert( pPager->ckptJSize == 
-+    pPager->nRec*JOURNAL_PG_SZ(journal_format)+JOURNAL_HDR_SZ(journal_format) );
-+#endif
-+  pPager->ckptJSize = pPager->nRec*JOURNAL_PG_SZ(journal_format)
-+                         + JOURNAL_HDR_SZ(journal_format);
-+  pPager->ckptSize = pPager->dbSize;
-+  if( !pPager->ckptOpen ){
-+    rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
-+    if( rc ) goto ckpt_begin_failed;
-+    pPager->ckptOpen = 1;
-+    pPager->ckptNRec = 0;
-+  }
-+  pPager->ckptInUse = 1;
-+  return SQLITE_OK;
-+ 
-+ckpt_begin_failed:
-+  if( pPager->aInCkpt ){
-+    sqliteFree(pPager->aInCkpt);
-+    pPager->aInCkpt = 0;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Commit a checkpoint.
-+*/
-+int sqlitepager_ckpt_commit(Pager *pPager){
-+  if( pPager->ckptInUse ){
-+    PgHdr *pPg, *pNext;
-+    sqliteOsSeek(&pPager->cpfd, 0);
-+    /* sqliteOsTruncate(&pPager->cpfd, 0); */
-+    pPager->ckptNRec = 0;
-+    pPager->ckptInUse = 0;
-+    sqliteFree( pPager->aInCkpt );
-+    pPager->aInCkpt = 0;
-+    for(pPg=pPager->pCkpt; pPg; pPg=pNext){
-+      pNext = pPg->pNextCkpt;
-+      assert( pPg->inCkpt );
-+      pPg->inCkpt = 0;
-+      pPg->pPrevCkpt = pPg->pNextCkpt = 0;
-+    }
-+    pPager->pCkpt = 0;
-+  }
-+  pPager->ckptAutoopen = 0;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Rollback a checkpoint.
-+*/
-+int sqlitepager_ckpt_rollback(Pager *pPager){
-+  int rc;
-+  if( pPager->ckptInUse ){
-+    rc = pager_ckpt_playback(pPager);
-+    sqlitepager_ckpt_commit(pPager);
-+  }else{
-+    rc = SQLITE_OK;
-+  }
-+  pPager->ckptAutoopen = 0;
-+  return rc;
-+}
-+
-+/*
-+** Return the full pathname of the database file.
-+*/
-+const char *sqlitepager_filename(Pager *pPager){
-+  return pPager->zFilename;
-+}
-+
-+/*
-+** Set the codec for this pager
-+*/
-+void sqlitepager_set_codec(
-+  Pager *pPager,
-+  void (*xCodec)(void*,void*,Pgno,int),
-+  void *pCodecArg
-+){
-+  pPager->xCodec = xCodec;
-+  pPager->pCodecArg = pCodecArg;
-+}
-+
-+#ifdef SQLITE_TEST
-+/*
-+** Print a listing of all referenced pages and their ref count.
-+*/
-+void sqlitepager_refdump(Pager *pPager){
-+  PgHdr *pPg;
-+  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-+    if( pPg->nRef<=0 ) continue;
-+    printf("PAGE %3d addr=0x%08x nRef=%d\n", 
-+       pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
-+  }
-+}
-+#endif
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/pager.h
-@@ -0,0 +1,107 @@
-+/*
-+** 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$
-+*/
-+
-+/*
-+** The size of one page
-+**
-+** You can change this value to another (reasonable) value you want.
-+** It need not be a power of two, though the interface to the disk
-+** will likely be faster if it is.
-+**
-+** Experiments show that a page size of 1024 gives the best speed
-+** for common usages.  The speed differences for different sizes
-+** such as 512, 2048, 4096, an so forth, is minimal.  Note, however,
-+** that changing the page size results in a completely imcompatible
-+** file format.
-+*/
-+#ifndef SQLITE_PAGE_SIZE
-+#define SQLITE_PAGE_SIZE 1024
-+#endif
-+
-+/*
-+** Number of extra bytes of data allocated at the end of each page and
-+** stored on disk but not used by the higher level btree layer.  Changing
-+** this value results in a completely incompatible file format.
-+*/
-+#ifndef SQLITE_PAGE_RESERVE
-+#define SQLITE_PAGE_RESERVE 0
-+#endif
-+
-+/*
-+** The total number of usable bytes stored on disk for each page.
-+** The usable bytes come at the beginning of the page and the reserve
-+** bytes come at the end.
-+*/
-+#define SQLITE_USABLE_SIZE (SQLITE_PAGE_SIZE-SQLITE_PAGE_RESERVE)
-+
-+/*
-+** Maximum number of pages in one database.  (This is a limitation of
-+** imposed by 4GB files size limits.)
-+*/
-+#define SQLITE_MAX_PAGE 1073741823
-+
-+/*
-+** 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 unsigned int Pgno;
-+
-+/*
-+** Each open file is managed by a separate instance of the "Pager" structure.
-+*/
-+typedef struct Pager Pager;
-+
-+/*
-+** See source code comments for a detailed description of the following
-+** routines:
-+*/
-+int sqlitepager_open(Pager **ppPager, const char *zFilename,
-+                     int nPage, int nExtra, int useJournal);
-+void sqlitepager_set_destructor(Pager*, void(*)(void*));
-+void sqlitepager_set_cachesize(Pager*, int);
-+int sqlitepager_close(Pager *pPager);
-+int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage);
-+void *sqlitepager_lookup(Pager *pPager, Pgno pgno);
-+int sqlitepager_ref(void*);
-+int sqlitepager_unref(void*);
-+Pgno sqlitepager_pagenumber(void*);
-+int sqlitepager_write(void*);
-+int sqlitepager_iswriteable(void*);
-+int sqlitepager_overwrite(Pager *pPager, Pgno pgno, void*);
-+int sqlitepager_pagecount(Pager*);
-+int sqlitepager_truncate(Pager*,Pgno);
-+int sqlitepager_begin(void*);
-+int sqlitepager_commit(Pager*);
-+int sqlitepager_rollback(Pager*);
-+int sqlitepager_isreadonly(Pager*);
-+int sqlitepager_ckpt_begin(Pager*);
-+int sqlitepager_ckpt_commit(Pager*);
-+int sqlitepager_ckpt_rollback(Pager*);
-+void sqlitepager_dont_rollback(void*);
-+void sqlitepager_dont_write(Pager*, Pgno);
-+int *sqlitepager_stats(Pager*);
-+void sqlitepager_set_safety_level(Pager*,int);
-+const char *sqlitepager_filename(Pager*);
-+int sqlitepager_rename(Pager*, const char *zNewName);
-+void sqlitepager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
-+
-+#ifdef SQLITE_TEST
-+void sqlitepager_refdump(Pager*);
-+int pager_refinfo_enable;
-+int journal_format;
-+#endif
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/parse.c
-@@ -0,0 +1,3355 @@
-+/* Driver template for the LEMON parser generator.
-+** The author disclaims copyright to this source code.
-+*/
-+/* First off, code is included that follows the "include" declaration
-+** in the input grammar file. */
-+#include <stdio.h>
-+#line 33 "ext/sqlite/libsqlite/src/parse.y"
-+
-+#include "sqliteInt.h"
-+#include "parse.h"
-+
-+/*
-+** An instance of this structure holds information about the
-+** LIMIT clause of a SELECT statement.
-+*/
-+struct LimitVal {
-+  int limit;    /* The LIMIT value.  -1 if there is no limit */
-+  int offset;   /* The OFFSET.  0 if there is none */
-+};
-+
-+/*
-+** 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; };
-+
-+#line 33 "ext/sqlite/libsqlite/src/parse.c"
-+/* 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.
-+**    sqliteParserTOKENTYPE     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 sqliteParserTOKENTYPE.  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()
-+**    sqliteParserARG_SDECL     A static variable declaration for the %extra_argument
-+**    sqliteParserARG_PDECL     A parameter declaration for the %extra_argument
-+**    sqliteParserARG_STORE     Code to store %extra_argument into yypParser
-+**    sqliteParserARG_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 221
-+#define YYACTIONTYPE unsigned short int
-+#define sqliteParserTOKENTYPE Token
-+typedef union {
-+  int yyinit;
-+  sqliteParserTOKENTYPE yy0;
-+  TriggerStep * yy19;
-+  struct LimitVal yy124;
-+  Select* yy179;
-+  Expr * yy182;
-+  Expr* yy242;
-+  struct TrigEvent yy290;
-+  SrcList* yy307;
-+  IdList* yy320;
-+  ExprList* yy322;
-+  int yy372;
-+  struct {int value; int mask;} yy407;
-+} YYMINORTYPE;
-+#ifndef YYSTACKDEPTH
-+#define YYSTACKDEPTH 100
-+#endif
-+#define sqliteParserARG_SDECL Parse *pParse;
-+#define sqliteParserARG_PDECL ,Parse *pParse
-+#define sqliteParserARG_FETCH Parse *pParse = yypParser->pParse
-+#define sqliteParserARG_STORE yypParser->pParse = pParse
-+#define YYNSTATE 563
-+#define YYNRULE 293
-+#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.
-+*/
-+#define YY_ACTTAB_COUNT (1090)
-+static const YYACTIONTYPE yy_action[] = {
-+ /*     0 */   186,  561,  483,   69,   67,   70,   68,   64,   63,   62,
-+ /*    10 */    61,   58,   57,   56,   55,   54,   53,  181,  180,  179,
-+ /*    20 */   514,  421,  334,  420,  468,  515,   64,   63,   62,   61,
-+ /*    30 */    58,   57,   56,   55,   54,   53,    9,  423,  422,   71,
-+ /*    40 */    72,  129,   65,   66,  513,  510,  305,   52,  138,   69,
-+ /*    50 */    67,   70,   68,   64,   63,   62,   61,   58,   57,   56,
-+ /*    60 */    55,   54,   53,  448,  469,  175,  482,  514,  470,  344,
-+ /*    70 */   342,   36,  515,   58,   57,   56,   55,   54,   53,    8,
-+ /*    80 */   341,  281,  285,  307,  437,  178,   71,   72,  129,   65,
-+ /*    90 */    66,  513,  510,  305,   52,  138,   69,   67,   70,   68,
-+ /*   100 */    64,   63,   62,   61,   58,   57,   56,   55,   54,   53,
-+ /*   110 */   130,  362,  360,  508,  507,  267,  551,  436,  298,  297,
-+ /*   120 */   369,  368,   50,  128,  543,   29,  266,  449,  537,  447,
-+ /*   130 */   591,  528,  442,  441,  187,  132,  514,  536,   47,   48,
-+ /*   140 */   472,  515,  122,  427,  331,  409,   49,  371,  370,  518,
-+ /*   150 */   328,  363,  517,  520,   45,   71,   72,  129,   65,   66,
-+ /*   160 */   513,  510,  305,   52,  138,   69,   67,   70,   68,   64,
-+ /*   170 */    63,   62,   61,   58,   57,   56,   55,   54,   53,  185,
-+ /*   180 */   550,  549,  512,  175,  467,  516,   18,  344,  342,   36,
-+ /*   190 */   544,  175,  320,  230,  231,  344,  342,   36,  341,   56,
-+ /*   200 */    55,   54,   53,  212,  531,  514,  341,  551,    3,  213,
-+ /*   210 */   515,    2,  551,   73,    7,  551,  184,  132,  551,  172,
-+ /*   220 */   551,  309,  348,   42,   71,   72,  129,   65,   66,  513,
-+ /*   230 */   510,  305,   52,  138,   69,   67,   70,   68,   64,   63,
-+ /*   240 */    62,   61,   58,   57,   56,   55,   54,   53,  243,  197,
-+ /*   250 */   282,  358,  268,  373,  264,  372,  183,  241,  436,  169,
-+ /*   260 */   356,  171,  269,  240,  471,  426,   29,  446,  506,  514,
-+ /*   270 */   445,  550,  549,  494,  515,  354,  550,  549,  359,  550,
-+ /*   280 */   549,  144,  550,  549,  550,  549,  592,  309,   71,   72,
-+ /*   290 */   129,   65,   66,  513,  510,  305,   52,  138,   69,   67,
-+ /*   300 */    70,   68,   64,   63,   62,   61,   58,   57,   56,   55,
-+ /*   310 */    54,   53,  514,  857,   82,  377,    1,  515,  268,  373,
-+ /*   320 */   264,  372,  183,  241,  362,   12,  508,  507,  500,  240,
-+ /*   330 */    17,   71,   72,  129,   65,   66,  513,  510,  305,   52,
-+ /*   340 */   138,   69,   67,   70,   68,   64,   63,   62,   61,   58,
-+ /*   350 */    57,   56,   55,   54,   53,  362,  182,  508,  507,  514,
-+ /*   360 */   362,  527,  508,  507,  515,  563,  429,  463,  182,  444,
-+ /*   370 */   375,  338,  443,  430,  379,  378,  593,  156,   71,   72,
-+ /*   380 */   129,   65,   66,  513,  510,  305,   52,  138,   69,   67,
-+ /*   390 */    70,   68,   64,   63,   62,   61,   58,   57,   56,   55,
-+ /*   400 */    54,   53,  514,  526,  542,  450,  534,  515,  286,  493,
-+ /*   410 */   453,   17,  478,  240,   80,   11,  533,  153,  194,  155,
-+ /*   420 */   286,   71,   51,  129,   65,   66,  513,  510,  305,   52,
-+ /*   430 */   138,   69,   67,   70,   68,   64,   63,   62,   61,   58,
-+ /*   440 */    57,   56,   55,   54,   53,  514,  195,  466,  160,   17,
-+ /*   450 */   515,  454,  490,   80,  459,  440,  460,  176,  239,  238,
-+ /*   460 */    80,   80,  562,    1,   71,   40,  129,   65,   66,  513,
-+ /*   470 */   510,  305,   52,  138,   69,   67,   70,   68,   64,   63,
-+ /*   480 */    62,   61,   58,   57,   56,   55,   54,   53,  514,  365,
-+ /*   490 */   154,   19,  339,  515,   80,  232,  405,   80,  165,  404,
-+ /*   500 */   193,   32,  396,   13,   32,   86,  414,  108,   72,  129,
-+ /*   510 */    65,   66,  513,  510,  305,   52,  138,   69,   67,   70,
-+ /*   520 */    68,   64,   63,   62,   61,   58,   57,   56,   55,   54,
-+ /*   530 */    53,  514,  551,  365,  483,  192,  515,  488,  323,  207,
-+ /*   540 */   366,  249,  177,  186,   87,  483,  483,   46,   38,   44,
-+ /*   550 */   458,  108,  129,   65,   66,  513,  510,  305,   52,  138,
-+ /*   560 */    69,   67,   70,   68,   64,   63,   62,   61,   58,   57,
-+ /*   570 */    56,   55,   54,   53,  274,  457,  272,  271,  270,   23,
-+ /*   580 */     8,  551,  211,  412,  307,  257,  365,  385,  201,   31,
-+ /*   590 */   217,  388,  141,  205,  387,  219,  550,  549,  482,  511,
-+ /*   600 */   215,  376,  560,  134,   90,  477,  214,  514,  392,  482,
-+ /*   610 */   482,  152,  515,  360,  203,  212,  409,  531,  800,  284,
-+ /*   620 */   365,  145,  505,   50,  300,  365,  365,  173,  321,  212,
-+ /*   630 */   487,  137,  135,    8,   41,  136,  531,  307,   93,   47,
-+ /*   640 */    48,  346,  316,  106,  106,  550,  549,   49,  371,  370,
-+ /*   650 */   518,  509,  531,  517,  520,  504,  531,  531,  162,  495,
-+ /*   660 */   170,  317,  503,  319,  223,  231,  360,  551,  502,  283,
-+ /*   670 */   162,  207,  557,  486,  212,  191,   50,   10,  289,  304,
-+ /*   680 */   303,  556,  207,  531,    8,  531,  516,   18,  307,  498,
-+ /*   690 */   498,  189,   47,   48,  393,  531,  555,   28,  302,  554,
-+ /*   700 */    49,  371,  370,  518,  484,  480,  517,  520,  322,  299,
-+ /*   710 */   553,  418,  365,  323,   17,  365,  365,  360,  416,  207,
-+ /*   720 */   322,  417,  207,  418,  327,  212,  480,   50,  207,  326,
-+ /*   730 */   106,  550,  549,  106,  105,  247,  407,  475,  332,  516,
-+ /*   740 */    18,  326,  365,   47,   48,  207,  295,  365,  475,  294,
-+ /*   750 */   158,   49,  371,  370,  518,  293,  473,  517,  520,  485,
-+ /*   760 */   106,  391,  390,  202,  148,   93,  351,  480,  204,  301,
-+ /*   770 */   333,  190,  291,  541,   60,  531,  498,  252,  453,  498,
-+ /*   780 */   365,  365,  290,  365,  501,  475,  365,   79,  475,  531,
-+ /*   790 */   516,   18,  379,  378,  475,  365,  465,  245,   89,  112,
-+ /*   800 */   365,  109,  365,  131,  121,  288,  499,  365,  365,  439,
-+ /*   810 */   365,  475,  365,  120,  365,  365,  343,  365,  119,  365,
-+ /*   820 */   118,  365,  365,  365,  365,  117,  116,  365,  126,  365,
-+ /*   830 */   125,  365,  124,  123,  365,  115,  365,  114,  431,  140,
-+ /*   840 */   139,  255,  254,  365,  365,  253,  365,  280,  365,  107,
-+ /*   850 */   365,  365,  113,  365,  111,   26,  365,  365,  365,  365,
-+ /*   860 */   365,  279,  278,  365,  277,  365,   92,  365,  104,  103,
-+ /*   870 */   365,   91,  365,  365,  102,  101,  110,  100,   99,  347,
-+ /*   880 */    25,   98,  340,   30,   24,   97,  266,  174,   96,   85,
-+ /*   890 */    95,   94,  166,  292,   78,  165,  415,   14,  163,   60,
-+ /*   900 */   164,   22,    6,  408,    5,   77,   34,   33,  159,   16,
-+ /*   910 */   157,  151,   75,  149,   15,  146,  313,  312,  395,  384,
-+ /*   920 */   143,   20,   60,  206,   21,  273,  198,  559,  375,  548,
-+ /*   930 */   547,  546,  374,    4,  540,  539,  538,  308,  535,  532,
-+ /*   940 */   530,  212,  261,   38,  260,  352,  259,   39,  258,  367,
-+ /*   950 */   529,  196,  210,  256,  521,  522,   53,   53,  209,   43,
-+ /*   960 */   496,  188,  492,  208,  256,   81,  246,   37,  479,  349,
-+ /*   970 */   244,   37,  474,  464,  276,   27,  452,  451,  433,  432,
-+ /*   980 */   275,  235,  234,  335,  424,   35,  329,  413,  410,  127,
-+ /*   990 */   161,   84,   76,  403,   38,  400,  188,  399,  224,  398,
-+ /*  1000 */    38,  150,  318,  220,   83,  147,  315,  200,  381,  383,
-+ /*  1010 */   199,  142,  545,  265,   88,  262,  523,  361,  491,  476,
-+ /*  1020 */   463,  406,  397,  287,  389,  386,  310,  382,  552,   74,
-+ /*  1030 */   306,  525,  524,  364,  519,  357,  355,  353,  497,  489,
-+ /*  1040 */   481,  263,  242,  462,  461,  456,  455,  438,  296,  345,
-+ /*  1050 */   434,  237,  425,  337,  168,  167,  336,  236,  419,  330,
-+ /*  1060 */   233,  325,  324,  229,  228,  402,  401,  227,  226,  225,
-+ /*  1070 */   222,  221,  218,  314,  394,  311,  216,  380,  251,  250,
-+ /*  1080 */   133,  350,  248,  364,  558,   59,  435,  411,  428,  212,
-+};
-+static const YYCODETYPE yy_lookahead[] = {
-+ /*     0 */    21,    9,   23,   70,   71,   72,   73,   74,   75,   76,
-+ /*    10 */    77,   78,   79,   80,   81,   82,   83,  100,  101,  102,
-+ /*    20 */    41,  100,  101,  102,   20,   46,   74,   75,   76,   77,
-+ /*    30 */    78,   79,   80,   81,   82,   83,   19,   55,   56,   60,
-+ /*    40 */    61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
-+ /*    50 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
-+ /*    60 */    81,   82,   83,   23,  108,   90,   87,   41,  112,   94,
-+ /*    70 */    95,   96,   46,   78,   79,   80,   81,   82,   83,   19,
-+ /*    80 */   105,  149,  143,   23,  152,  153,   60,   61,   62,   63,
-+ /*    90 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
-+ /*   100 */    74,   75,   76,   77,   78,   79,   80,   81,   82,   83,
-+ /*   110 */    31,  107,   52,  109,  110,   93,   23,  140,   78,   79,
-+ /*   120 */    78,   79,   62,   22,  147,  148,  104,   87,   34,   89,
-+ /*   130 */   113,   89,   92,   93,  183,  184,   41,   43,   78,   79,
-+ /*   140 */    80,   46,  165,  166,  205,   53,   86,   87,   88,   89,
-+ /*   150 */   211,   62,   92,   93,  128,   60,   61,   62,   63,   64,
-+ /*   160 */    65,   66,   67,   68,   69,   70,   71,   72,   73,   74,
-+ /*   170 */    75,   76,   77,   78,   79,   80,   81,   82,   83,  146,
-+ /*   180 */    87,   88,   93,   90,   20,  125,  126,   94,   95,   96,
-+ /*   190 */    20,   90,  100,  101,  102,   94,   95,   96,  105,   80,
-+ /*   200 */    81,   82,   83,  111,  171,   41,  105,   23,   19,   48,
-+ /*   210 */    46,   19,   23,   19,   19,   23,  183,  184,   23,   17,
-+ /*   220 */    23,   62,  189,  128,   60,   61,   62,   63,   64,   65,
-+ /*   230 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
-+ /*   240 */    76,   77,   78,   79,   80,   81,   82,   83,   20,   90,
-+ /*   250 */    91,   15,   93,   94,   95,   96,   97,   98,  140,   57,
-+ /*   260 */    24,   59,  144,  104,   80,  147,  148,   89,   20,   41,
-+ /*   270 */    92,   87,   88,   20,   46,   39,   87,   88,   42,   87,
-+ /*   280 */    88,   19,   87,   88,   87,   88,  113,   62,   60,   61,
-+ /*   290 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
-+ /*   300 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
-+ /*   310 */    82,   83,   41,  132,  133,  134,  135,   46,   93,   94,
-+ /*   320 */    95,   96,   97,   98,  107,   63,  109,  110,   20,  104,
-+ /*   330 */    22,   60,   61,   62,   63,   64,   65,   66,   67,   68,
-+ /*   340 */    69,   70,   71,   72,   73,   74,   75,   76,   77,   78,
-+ /*   350 */    79,   80,   81,   82,   83,  107,   47,  109,  110,   41,
-+ /*   360 */   107,   89,  109,  110,   46,    0,  161,  162,   47,   89,
-+ /*   370 */    99,   62,   92,  168,    9,   10,  113,   17,   60,   61,
-+ /*   380 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
-+ /*   390 */    72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
-+ /*   400 */    82,   83,   41,   89,  155,  156,   26,   46,   99,   20,
-+ /*   410 */   161,   22,   20,  104,   22,  118,   36,   57,   22,   59,
-+ /*   420 */    99,   60,   61,   62,   63,   64,   65,   66,   67,   68,
-+ /*   430 */    69,   70,   71,   72,   73,   74,   75,   76,   77,   78,
-+ /*   440 */    79,   80,   81,   82,   83,   41,   50,   20,   22,   22,
-+ /*   450 */    46,   20,   22,   22,   91,   20,   93,   22,   20,   20,
-+ /*   460 */    22,   22,  134,  135,   60,   61,   62,   63,   64,   65,
-+ /*   470 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
-+ /*   480 */    76,   77,   78,   79,   80,   81,   82,   83,   41,  140,
-+ /*   490 */   130,   22,   20,   46,   22,   20,   20,   22,   22,   20,
-+ /*   500 */   113,   22,   20,   19,   22,   21,   18,  158,   61,   62,
-+ /*   510 */    63,   64,   65,   66,   67,   68,   69,   70,   71,   72,
-+ /*   520 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
-+ /*   530 */    83,   41,   23,  140,   23,  113,   46,   22,  140,  140,
-+ /*   540 */   191,  192,   19,   21,  114,   23,   23,  127,  122,  129,
-+ /*   550 */    29,  158,   62,   63,   64,   65,   66,   67,   68,   69,
-+ /*   560 */    70,   71,   72,   73,   74,   75,   76,   77,   78,   79,
-+ /*   570 */    80,   81,   82,   83,   11,   54,   13,   14,   15,   16,
-+ /*   580 */    19,   23,  174,   95,   23,  192,  140,   78,   79,  181,
-+ /*   590 */    27,   89,  146,  195,   92,   32,   87,   88,   87,   93,
-+ /*   600 */    37,  136,  137,   88,  158,  206,  141,   41,   99,   87,
-+ /*   610 */    87,  146,   46,   52,   51,  111,   53,  171,  130,   19,
-+ /*   620 */   140,   58,   14,   62,  103,  140,  140,  146,  124,  111,
-+ /*   630 */   115,  146,  146,   19,   68,   69,  171,   23,  158,   78,
-+ /*   640 */    79,   80,  124,  158,  158,   87,   88,   86,   87,   88,
-+ /*   650 */    89,  108,  171,   92,   93,   20,  171,  171,  146,   93,
-+ /*   660 */   146,  196,   20,  100,  101,  102,   52,   23,   20,  106,
-+ /*   670 */   146,  140,   15,  115,  111,   22,   62,  118,  198,  194,
-+ /*   680 */   194,   24,  140,  171,   19,  171,  125,  126,   23,  204,
-+ /*   690 */   204,   22,   78,   79,  140,  171,   39,   19,  167,   42,
-+ /*   700 */    86,   87,   88,   89,  115,  152,   92,   93,  196,  167,
-+ /*   710 */    53,  140,  140,  140,   22,  140,  140,   52,   25,  140,
-+ /*   720 */   196,   28,  140,  140,  212,  111,  152,   62,  140,  217,
-+ /*   730 */   158,   87,   88,  158,  158,  182,  212,  206,   45,  125,
-+ /*   740 */   126,  217,  140,   78,   79,  140,  167,  140,  206,  167,
-+ /*   750 */   146,   86,   87,   88,   89,  167,  182,   92,   93,  115,
-+ /*   760 */   158,  207,  208,  209,  146,  158,  194,  152,  195,  194,
-+ /*   770 */   199,   22,  167,  156,  200,  171,  204,  201,  161,  204,
-+ /*   780 */   140,  140,  199,  140,   20,  206,  140,   20,  206,  171,
-+ /*   790 */   125,  126,    9,   10,  206,  140,   20,  182,  158,  158,
-+ /*   800 */   140,  158,  140,  113,  158,  198,  204,  140,  140,   20,
-+ /*   810 */   140,  206,  140,  158,  140,  140,   48,  140,  158,  140,
-+ /*   820 */   158,  140,  140,  140,  140,  158,  158,  140,  158,  140,
-+ /*   830 */   158,  140,  158,  158,  140,  158,  140,  158,  139,  158,
-+ /*   840 */   158,  158,  158,  140,  140,  158,  140,  158,  140,  158,
-+ /*   850 */   140,  140,  158,  140,  158,   19,  140,  140,  140,  140,
-+ /*   860 */   140,  158,  158,  140,  158,  140,  158,  140,  158,  158,
-+ /*   870 */   140,  158,  140,  140,  158,  158,  158,  158,  158,  140,
-+ /*   880 */    19,  158,   48,  158,   19,  158,  104,   97,  158,   21,
-+ /*   890 */   158,  158,   99,   38,   49,   22,   49,  158,   99,  200,
-+ /*   900 */   130,   19,   11,   14,    9,  103,   63,   63,  123,   19,
-+ /*   910 */   114,  114,  103,  123,   19,  114,  116,   35,   87,   20,
-+ /*   920 */    21,  150,  200,  160,  160,  138,   12,  139,   99,  138,
-+ /*   930 */   138,  138,  145,   22,  139,  139,  164,   44,  139,  139,
-+ /*   940 */   171,  111,  176,  122,  177,  119,  178,  120,  179,  117,
-+ /*   950 */   180,  121,  193,   98,  151,   23,   83,   83,  202,  127,
-+ /*   960 */   186,  113,  186,  193,   98,  186,  187,   99,  188,  116,
-+ /*   970 */   187,   99,  188,  139,  159,   19,  151,  164,  139,  139,
-+ /*   980 */   159,  186,  215,   40,  216,  127,  186,  139,  169,   60,
-+ /*   990 */   169,  197,   19,  176,  122,  186,  113,  186,  186,  176,
-+ /*  1000 */   122,  169,  186,  186,  197,  169,  186,  218,   33,  219,
-+ /*  1010 */   116,  218,  142,  157,  173,  175,  157,  203,  157,  157,
-+ /*  1020 */   162,  176,  176,  152,  210,  210,  152,  152,  140,  140,
-+ /*  1030 */   154,  154,  154,  140,  140,  140,  140,  140,  140,  185,
-+ /*  1040 */   140,  172,  140,  140,  163,  163,  163,  152,  154,  154,
-+ /*  1050 */   140,  140,  140,  140,  140,  213,  214,  140,  140,  140,
-+ /*  1060 */   140,  140,  140,  140,  140,  140,  140,  140,  140,  140,
-+ /*  1070 */   140,  140,  140,  140,  140,  140,  140,  140,  140,  140,
-+ /*  1080 */   140,  140,  140,  140,  170,  200,  166,  170,  166,  111,
-+};
-+#define YY_SHIFT_USE_DFLT (-84)
-+#define YY_SHIFT_COUNT (376)
-+#define YY_SHIFT_MIN   (-83)
-+#define YY_SHIFT_MAX   (978)
-+static const short yy_shift_ofst[] = {
-+ /*     0 */   783,  563,  614,  614,   93,   92,   92,  978,  614,  561,
-+ /*    10 */   665,  665,  509,  197,  -21,  665,  665,  665,  665,  665,
-+ /*    20 */   159,  309,  197,  488,  197,  197,  197,  197,  197,  511,
-+ /*    30 */   271,   60,  665,  665,  665,  665,  665,  665,  665,  665,
-+ /*    40 */   665,  665,  665,  665,  665,  665,  665,  665,  665,  665,
-+ /*    50 */   665,  665,  665,  665,  665,  665,  665,  665,  665,  665,
-+ /*    60 */   665,  665,  665,  665,  665,  665,  665,  665,  665,  665,
-+ /*    70 */   665,  665,  665,  665,  225,  197,  197,  197,  197,  522,
-+ /*    80 */   197,  522,  365,  518,  504,  978,  978,  -84,  -84,  228,
-+ /*    90 */   164,   95,   26,  318,  318,  318,  318,  318,  318,  318,
-+ /*   100 */   318,  404,  318,  318,  318,  318,  318,  361,  318,  447,
-+ /*   110 */   490,  490,  490,  -67,  -67,  -67,  -67,  -67,  -48,  -48,
-+ /*   120 */   -48,  -48,  101,   -5,   -5,   -5,   -5,  657,  -25,  566,
-+ /*   130 */   657,  184,  195,  644,  558,  253,  192,  248,  189,  119,
-+ /*   140 */   119,    4,  197,  197,  197,  197,  197,  197,  217,  197,
-+ /*   150 */   197,  197,  217,  197,  197,  197,  197,  197,  217,  197,
-+ /*   160 */   197,  197,  217,  197,  197,  197,  197,  -79,  693,  197,
-+ /*   170 */   217,  197,  197,  217,  197,  197,   42,   42,  523,  521,
-+ /*   180 */   521,  521,  197,  197,  515,  217,  197,  515,  197,  197,
-+ /*   190 */   197,  197,  197,  197,   42,   42,   42,  197,  197,  511,
-+ /*   200 */   511,  502,  502,  511,  426,  426,  321,  380,  380,  420,
-+ /*   210 */   380,  430,  -44,  380,  484,  975,  894,  975,  883,  929,
-+ /*   220 */   973,  883,  883,  929,  878,  883,  883,  883,  872,  973,
-+ /*   230 */   929,  929,  829,  848,  858,  943,  848,  956,  829,  829,
-+ /*   240 */   893,  932,  956,  829,  853,  872,  853,  868,  848,  866,
-+ /*   250 */   848,  848,  832,  874,  874,  873,  932,  855,  830,  832,
-+ /*   260 */   827,  826,  821,  830,  829,  829,  893,  829,  829,  911,
-+ /*   270 */   914,  914,  914,  829,  914,  -84,  -84,  -84,  -84,  -84,
-+ /*   280 */   -84,  -84,   40,  360,  236,  202,  -83,  262,  482,  479,
-+ /*   290 */   476,  475,  -18,  472,  439,  438,  435,  280,  178,  431,
-+ /*   300 */   363,  427,  392,  389,  308,   89,  396,   17,   94,   22,
-+ /*   310 */   899,  899,  831,  882,  800,  801,  895,  790,  809,  797,
-+ /*   320 */   796,  890,  785,  844,  843,  802,  895,  889,  891,  882,
-+ /*   330 */   799,  770,  847,  873,  845,  855,  793,  868,  782,  790,
-+ /*   340 */   865,  834,  861,  836,  768,  789,  776,  690,  767,  678,
-+ /*   350 */   589,  692,  559,  764,  669,  648,  749,  642,  653,  635,
-+ /*   360 */   600,  608,  543,  506,  422,  387,  469,  297,  314,  272,
-+ /*   370 */   263,  173,  194,  161,  170,   79,   -8,
-+};
-+#define YY_REDUCE_USE_DFLT (-69)
-+#define YY_REDUCE_COUNT (281)
-+#define YY_REDUCE_MIN   (-68)
-+#define YY_REDUCE_MAX   (943)
-+static const short yy_reduce_ofst[] = {
-+ /*     0 */   181,  465,  486,  485,  -23,  524,  512,   33,  446,  575,
-+ /*    10 */   572,  349,  554,  118,  574,  607,  480,  602,  576,  393,
-+ /*    20 */   249,  205,  605,  -61,  588,  582,  579,  542,  531,  -68,
-+ /*    30 */   699,  739,  733,  732,  730,  727,  725,  723,  720,  719,
-+ /*    40 */   718,  717,  716,  713,  711,  710,  708,  706,  704,  703,
-+ /*    50 */   696,  694,  691,  689,  687,  684,  683,  682,  681,  679,
-+ /*    60 */   677,  675,  674,  672,  670,  668,  667,  662,  660,  655,
-+ /*    70 */   646,  643,  641,  640,  617,  573,  583,  398,  571,  615,
-+ /*    80 */   399,  553,  328,  618,  604,  514,  481,  -49,  408,  722,
-+ /*    90 */   722,  722,  722,  722,  722,  722,  722,  722,  722,  722,
-+ /*   100 */   722,  722,  722,  722,  722,  722,  722,  722,  722,  722,
-+ /*   110 */   722,  722,  722,  722,  722,  722,  722,  722,  722,  722,
-+ /*   120 */   722,  722,  922,  722,  722,  722,  722,  917,  920,  885,
-+ /*   130 */   914,  943,  942,  941,  940,  869,  939,  869,  938,  722,
-+ /*   140 */   722,  869,  937,  936,  935,  934,  933,  932,  869,  931,
-+ /*   150 */   930,  929,  869,  928,  927,  926,  925,  924,  869,  923,
-+ /*   160 */   922,  921,  869,  920,  919,  918,  917,  842,  842,  914,
-+ /*   170 */   869,  913,  912,  869,  911,  910,  895,  894,  895,  883,
-+ /*   180 */   882,  881,  903,  902,  854,  869,  900,  854,  898,  897,
-+ /*   190 */   896,  895,  894,  893,  878,  877,  876,  889,  888,  875,
-+ /*   200 */   874,  815,  814,  871,  846,  845,  858,  862,  861,  814,
-+ /*   210 */   859,  840,  841,  856,  870,  793,  790,  789,  820,  836,
-+ /*   220 */   807,  817,  816,  832,  823,  812,  811,  809,  817,  794,
-+ /*   230 */   821,  819,  848,  800,  768,  767,  795,  821,  840,  839,
-+ /*   240 */   813,  825,  815,  834,  784,  783,  780,  779,  779,  770,
-+ /*   250 */   776,  774,  756,  722,  722,  722,  803,  759,  770,  769,
-+ /*   260 */   768,  767,  766,  769,  800,  799,  772,  796,  795,  787,
-+ /*   270 */   793,  792,  791,  788,  787,  764,  763,  722,  722,  722,
-+ /*   280 */   722,  771,
-+};
-+static const YYACTIONTYPE yy_default[] = {
-+ /*     0 */   570,  856,  797,  797,  856,  839,  839,  685,  856,  797,
-+ /*    10 */   797,  856,  822,  856,  681,  856,  856,  797,  793,  856,
-+ /*    20 */   586,  649,  856,  581,  856,  856,  856,  856,  856,  594,
-+ /*    30 */   651,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*    40 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*    50 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*    60 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*    70 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  681,
-+ /*    80 */   856,  681,  570,  856,  856,  856,  856,  685,  675,  856,
-+ /*    90 */   856,  856,  856,  730,  729,  724,  723,  837,  697,  721,
-+ /*   100 */   714,  856,  789,  790,  788,  792,  796,  856,  705,  748,
-+ /*   110 */   780,  774,  747,  779,  760,  759,  754,  753,  752,  751,
-+ /*   120 */   750,  749,  640,  758,  757,  756,  755,  856,  856,  856,
-+ /*   130 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  764,
-+ /*   140 */   763,  856,  856,  856,  856,  809,  856,  856,  726,  856,
-+ /*   150 */   856,  856,  663,  856,  856,  856,  856,  856,  842,  856,
-+ /*   160 */   856,  856,  844,  856,  856,  856,  856,  856,  828,  856,
-+ /*   170 */   661,  856,  856,  583,  856,  856,  856,  856,  595,  856,
-+ /*   180 */   856,  856,  856,  856,  689,  688,  856,  683,  856,  856,
-+ /*   190 */   856,  856,  856,  856,  856,  856,  856,  856,  573,  856,
-+ /*   200 */   856,  856,  856,  856,  720,  720,  621,  708,  708,  791,
-+ /*   210 */   708,  682,  673,  708,  856,  854,  852,  854,  690,  653,
-+ /*   220 */   731,  690,  690,  653,  720,  690,  690,  690,  720,  731,
-+ /*   230 */   653,  653,  651,  690,  836,  833,  690,  801,  651,  651,
-+ /*   240 */   636,  856,  801,  651,  700,  698,  700,  698,  690,  709,
-+ /*   250 */   690,  690,  856,  767,  766,  765,  856,  709,  715,  701,
-+ /*   260 */   713,  711,  720,  856,  651,  651,  636,  651,  651,  639,
-+ /*   270 */   572,  572,  572,  651,  572,  624,  624,  777,  776,  775,
-+ /*   280 */   768,  604,  856,  856,  856,  856,  856,  816,  856,  856,
-+ /*   290 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*   300 */   856,  856,  856,  856,  856,  856,  716,  737,  856,  856,
-+ /*   310 */   856,  856,  856,  856,  808,  856,  856,  856,  856,  856,
-+ /*   320 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*   330 */   856,  856,  856,  832,  831,  856,  856,  856,  856,  856,
-+ /*   340 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*   350 */   856,  712,  856,  856,  856,  856,  856,  856,  856,  856,
-+ /*   360 */   856,  856,  666,  856,  739,  856,  702,  856,  856,  856,
-+ /*   370 */   738,  743,  856,  856,  856,  856,  856,  565,  569,  567,
-+ /*   380 */   855,  853,  851,  850,  815,  821,  818,  820,  819,  817,
-+ /*   390 */   814,  813,  812,  811,  810,  807,  725,  722,  719,  849,
-+ /*   400 */   806,  662,  660,  843,  841,  732,  840,  838,  823,  728,
-+ /*   410 */   727,  654,  799,  798,  580,  827,  826,  825,  734,  733,
-+ /*   420 */   830,  829,  835,  834,  824,  579,  585,  643,  642,  650,
-+ /*   430 */   648,  647,  646,  645,  644,  641,  587,  598,  599,  597,
-+ /*   440 */   596,  615,  612,  614,  611,  613,  610,  609,  608,  607,
-+ /*   450 */   606,  635,  623,  622,  802,  629,  628,  633,  632,  631,
-+ /*   460 */   630,  627,  626,  625,  620,  746,  745,  735,  778,  672,
-+ /*   470 */   671,  678,  677,  676,  687,  804,  805,  803,  699,  686,
-+ /*   480 */   680,  679,  590,  589,  696,  695,  694,  693,  692,  684,
-+ /*   490 */   674,  704,  786,  783,  784,  772,  785,  691,  795,  794,
-+ /*   500 */   781,  848,  847,  846,  845,  787,  782,  669,  668,  667,
-+ /*   510 */   771,  773,  770,  769,  762,  761,  744,  742,  741,  740,
-+ /*   520 */   736,  710,  588,  703,  718,  717,  602,  601,  600,  670,
-+ /*   530 */   665,  664,  619,  707,  706,  618,  638,  637,  634,  617,
-+ /*   540 */   616,  605,  603,  584,  582,  578,  577,  576,  575,  593,
-+ /*   550 */   592,  591,  574,  659,  658,  657,  656,  655,  652,  571,
-+ /*   560 */   568,  566,  564,
-+};
-+
-+/* 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,  /* END_OF_FILE => nothing */
-+    0,  /*    ILLEGAL => nothing */
-+    0,  /*      SPACE => nothing */
-+    0,  /* UNCLOSED_STRING => nothing */
-+    0,  /*    COMMENT => nothing */
-+    0,  /*   FUNCTION => nothing */
-+    0,  /*     COLUMN => nothing */
-+    0,  /* AGG_FUNCTION => nothing */
-+    0,  /*       SEMI => nothing */
-+   23,  /*    EXPLAIN => ID */
-+   23,  /*      BEGIN => ID */
-+    0,  /* TRANSACTION => nothing */
-+    0,  /*     COMMIT => nothing */
-+   23,  /*        END => ID */
-+    0,  /*   ROLLBACK => nothing */
-+    0,  /*     CREATE => nothing */
-+    0,  /*      TABLE => nothing */
-+   23,  /*       TEMP => ID */
-+    0,  /*         LP => nothing */
-+    0,  /*         RP => nothing */
-+    0,  /*         AS => nothing */
-+    0,  /*      COMMA => nothing */
-+    0,  /*         ID => nothing */
-+   23,  /*      ABORT => ID */
-+   23,  /*      AFTER => ID */
-+   23,  /*        ASC => ID */
-+   23,  /*     ATTACH => ID */
-+   23,  /*     BEFORE => ID */
-+   23,  /*    CASCADE => ID */
-+   23,  /*    CLUSTER => ID */
-+   23,  /*   CONFLICT => ID */
-+   23,  /*       COPY => ID */
-+   23,  /*   DATABASE => ID */
-+   23,  /*   DEFERRED => ID */
-+   23,  /* DELIMITERS => ID */
-+   23,  /*       DESC => ID */
-+   23,  /*     DETACH => ID */
-+   23,  /*       EACH => ID */
-+   23,  /*       FAIL => ID */
-+   23,  /*        FOR => ID */
-+   23,  /*       GLOB => ID */
-+   23,  /*     IGNORE => ID */
-+   23,  /*  IMMEDIATE => ID */
-+   23,  /*  INITIALLY => ID */
-+   23,  /*    INSTEAD => ID */
-+   23,  /*       LIKE => ID */
-+   23,  /*      MATCH => ID */
-+   23,  /*        KEY => ID */
-+   23,  /*         OF => ID */
-+   23,  /*     OFFSET => ID */
-+   23,  /*     PRAGMA => ID */
-+   23,  /*      RAISE => ID */
-+   23,  /*    REPLACE => ID */
-+   23,  /*   RESTRICT => ID */
-+   23,  /*        ROW => ID */
-+   23,  /*  STATEMENT => ID */
-+   23,  /*    TRIGGER => ID */
-+   23,  /*     VACUUM => ID */
-+   23,  /*       VIEW => 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 */
-+  sqliteParserARG_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
-+#include <stdio.h>
-+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.
-+*/
-+void sqliteParserTrace(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[] = { 
-+  "$",             "END_OF_FILE",   "ILLEGAL",       "SPACE",       
-+  "UNCLOSED_STRING",  "COMMENT",       "FUNCTION",      "COLUMN",      
-+  "AGG_FUNCTION",  "SEMI",          "EXPLAIN",       "BEGIN",       
-+  "TRANSACTION",   "COMMIT",        "END",           "ROLLBACK",    
-+  "CREATE",        "TABLE",         "TEMP",          "LP",          
-+  "RP",            "AS",            "COMMA",         "ID",          
-+  "ABORT",         "AFTER",         "ASC",           "ATTACH",      
-+  "BEFORE",        "CASCADE",       "CLUSTER",       "CONFLICT",    
-+  "COPY",          "DATABASE",      "DEFERRED",      "DELIMITERS",  
-+  "DESC",          "DETACH",        "EACH",          "FAIL",        
-+  "FOR",           "GLOB",          "IGNORE",        "IMMEDIATE",   
-+  "INITIALLY",     "INSTEAD",       "LIKE",          "MATCH",       
-+  "KEY",           "OF",            "OFFSET",        "PRAGMA",      
-+  "RAISE",         "REPLACE",       "RESTRICT",      "ROW",         
-+  "STATEMENT",     "TRIGGER",       "VACUUM",        "VIEW",        
-+  "OR",            "AND",           "NOT",           "EQ",          
-+  "NE",            "ISNULL",        "NOTNULL",       "IS",          
-+  "BETWEEN",       "IN",            "GT",            "GE",          
-+  "LT",            "LE",            "BITAND",        "BITOR",       
-+  "LSHIFT",        "RSHIFT",        "PLUS",          "MINUS",       
-+  "STAR",          "SLASH",         "REM",           "CONCAT",      
-+  "UMINUS",        "UPLUS",         "BITNOT",        "STRING",      
-+  "JOIN_KW",       "INTEGER",       "CONSTRAINT",    "DEFAULT",     
-+  "FLOAT",         "NULL",          "PRIMARY",       "UNIQUE",      
-+  "CHECK",         "REFERENCES",    "COLLATE",       "ON",          
-+  "DELETE",        "UPDATE",        "INSERT",        "SET",         
-+  "DEFERRABLE",    "FOREIGN",       "DROP",          "UNION",       
-+  "ALL",           "INTERSECT",     "EXCEPT",        "SELECT",      
-+  "DISTINCT",      "DOT",           "FROM",          "JOIN",        
-+  "USING",         "ORDER",         "BY",            "GROUP",       
-+  "HAVING",        "LIMIT",         "WHERE",         "INTO",        
-+  "VALUES",        "VARIABLE",      "CASE",          "WHEN",        
-+  "THEN",          "ELSE",          "INDEX",         "error",       
-+  "input",         "cmdlist",       "ecmd",          "explain",     
-+  "cmdx",          "cmd",           "trans_opt",     "onconf",      
-+  "nm",            "create_table",  "create_table_args",  "temp",        
-+  "columnlist",    "conslist_opt",  "select",        "column",      
-+  "columnid",      "type",          "carglist",      "id",          
-+  "ids",           "typename",      "signed",        "carg",        
-+  "ccons",         "sortorder",     "expr",          "idxlist_opt", 
-+  "refargs",       "defer_subclause",  "refarg",        "refact",      
-+  "init_deferred_pred_opt",  "conslist",      "tcons",         "idxlist",     
-+  "defer_subclause_opt",  "orconf",        "resolvetype",   "oneselect",   
-+  "multiselect_op",  "distinct",      "selcollist",    "from",        
-+  "where_opt",     "groupby_opt",   "having_opt",    "orderby_opt", 
-+  "limit_opt",     "sclp",          "as",            "seltablist",  
-+  "stl_prefix",    "joinop",        "dbnm",          "on_opt",      
-+  "using_opt",     "seltablist_paren",  "joinop2",       "sortlist",    
-+  "sortitem",      "collate",       "exprlist",      "setlist",     
-+  "insert_cmd",    "inscollist_opt",  "itemlist",      "inscollist",  
-+  "likeop",        "case_operand",  "case_exprlist",  "case_else",   
-+  "expritem",      "uniqueflag",    "idxitem",       "plus_num",    
-+  "minus_num",     "plus_opt",      "number",        "trigger_decl",
-+  "trigger_cmd_list",  "trigger_time",  "trigger_event",  "foreach_clause",
-+  "when_clause",   "trigger_cmd",   "database_kw_opt",  "key_opt",     
-+};
-+#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 ::= explain cmdx SEMI",
-+ /*   4 */ "ecmd ::= SEMI",
-+ /*   5 */ "cmdx ::= cmd",
-+ /*   6 */ "explain ::= EXPLAIN",
-+ /*   7 */ "explain ::=",
-+ /*   8 */ "cmd ::= BEGIN trans_opt onconf",
-+ /*   9 */ "trans_opt ::=",
-+ /*  10 */ "trans_opt ::= TRANSACTION",
-+ /*  11 */ "trans_opt ::= TRANSACTION nm",
-+ /*  12 */ "cmd ::= COMMIT trans_opt",
-+ /*  13 */ "cmd ::= END trans_opt",
-+ /*  14 */ "cmd ::= ROLLBACK trans_opt",
-+ /*  15 */ "cmd ::= create_table create_table_args",
-+ /*  16 */ "create_table ::= CREATE temp TABLE nm",
-+ /*  17 */ "temp ::= TEMP",
-+ /*  18 */ "temp ::=",
-+ /*  19 */ "create_table_args ::= LP columnlist conslist_opt RP",
-+ /*  20 */ "create_table_args ::= AS select",
-+ /*  21 */ "columnlist ::= columnlist COMMA column",
-+ /*  22 */ "columnlist ::= column",
-+ /*  23 */ "column ::= columnid type carglist",
-+ /*  24 */ "columnid ::= nm",
-+ /*  25 */ "id ::= ID",
-+ /*  26 */ "ids ::= ID",
-+ /*  27 */ "ids ::= STRING",
-+ /*  28 */ "nm ::= ID",
-+ /*  29 */ "nm ::= STRING",
-+ /*  30 */ "nm ::= JOIN_KW",
-+ /*  31 */ "type ::=",
-+ /*  32 */ "type ::= typename",
-+ /*  33 */ "type ::= typename LP signed RP",
-+ /*  34 */ "type ::= typename LP signed COMMA signed RP",
-+ /*  35 */ "typename ::= ids",
-+ /*  36 */ "typename ::= typename ids",
-+ /*  37 */ "signed ::= INTEGER",
-+ /*  38 */ "signed ::= PLUS INTEGER",
-+ /*  39 */ "signed ::= MINUS INTEGER",
-+ /*  40 */ "carglist ::= carglist carg",
-+ /*  41 */ "carglist ::=",
-+ /*  42 */ "carg ::= CONSTRAINT nm ccons",
-+ /*  43 */ "carg ::= ccons",
-+ /*  44 */ "carg ::= DEFAULT STRING",
-+ /*  45 */ "carg ::= DEFAULT ID",
-+ /*  46 */ "carg ::= DEFAULT INTEGER",
-+ /*  47 */ "carg ::= DEFAULT PLUS INTEGER",
-+ /*  48 */ "carg ::= DEFAULT MINUS INTEGER",
-+ /*  49 */ "carg ::= DEFAULT FLOAT",
-+ /*  50 */ "carg ::= DEFAULT PLUS FLOAT",
-+ /*  51 */ "carg ::= DEFAULT MINUS FLOAT",
-+ /*  52 */ "carg ::= DEFAULT NULL",
-+ /*  53 */ "ccons ::= NULL onconf",
-+ /*  54 */ "ccons ::= NOT NULL onconf",
-+ /*  55 */ "ccons ::= PRIMARY KEY sortorder onconf",
-+ /*  56 */ "ccons ::= UNIQUE onconf",
-+ /*  57 */ "ccons ::= CHECK LP expr RP onconf",
-+ /*  58 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
-+ /*  59 */ "ccons ::= defer_subclause",
-+ /*  60 */ "ccons ::= COLLATE id",
-+ /*  61 */ "refargs ::=",
-+ /*  62 */ "refargs ::= refargs refarg",
-+ /*  63 */ "refarg ::= MATCH nm",
-+ /*  64 */ "refarg ::= ON DELETE refact",
-+ /*  65 */ "refarg ::= ON UPDATE refact",
-+ /*  66 */ "refarg ::= ON INSERT refact",
-+ /*  67 */ "refact ::= SET NULL",
-+ /*  68 */ "refact ::= SET DEFAULT",
-+ /*  69 */ "refact ::= CASCADE",
-+ /*  70 */ "refact ::= RESTRICT",
-+ /*  71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
-+ /*  72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
-+ /*  73 */ "init_deferred_pred_opt ::=",
-+ /*  74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
-+ /*  75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
-+ /*  76 */ "conslist_opt ::=",
-+ /*  77 */ "conslist_opt ::= COMMA conslist",
-+ /*  78 */ "conslist ::= conslist COMMA tcons",
-+ /*  79 */ "conslist ::= conslist tcons",
-+ /*  80 */ "conslist ::= tcons",
-+ /*  81 */ "tcons ::= CONSTRAINT nm",
-+ /*  82 */ "tcons ::= PRIMARY KEY LP idxlist RP onconf",
-+ /*  83 */ "tcons ::= UNIQUE LP idxlist RP onconf",
-+ /*  84 */ "tcons ::= CHECK expr onconf",
-+ /*  85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
-+ /*  86 */ "defer_subclause_opt ::=",
-+ /*  87 */ "defer_subclause_opt ::= defer_subclause",
-+ /*  88 */ "onconf ::=",
-+ /*  89 */ "onconf ::= ON CONFLICT resolvetype",
-+ /*  90 */ "orconf ::=",
-+ /*  91 */ "orconf ::= OR resolvetype",
-+ /*  92 */ "resolvetype ::= ROLLBACK",
-+ /*  93 */ "resolvetype ::= ABORT",
-+ /*  94 */ "resolvetype ::= FAIL",
-+ /*  95 */ "resolvetype ::= IGNORE",
-+ /*  96 */ "resolvetype ::= REPLACE",
-+ /*  97 */ "cmd ::= DROP TABLE nm",
-+ /*  98 */ "cmd ::= CREATE temp VIEW nm AS select",
-+ /*  99 */ "cmd ::= DROP VIEW nm",
-+ /* 100 */ "cmd ::= select",
-+ /* 101 */ "select ::= oneselect",
-+ /* 102 */ "select ::= select multiselect_op oneselect",
-+ /* 103 */ "multiselect_op ::= UNION",
-+ /* 104 */ "multiselect_op ::= UNION ALL",
-+ /* 105 */ "multiselect_op ::= INTERSECT",
-+ /* 106 */ "multiselect_op ::= EXCEPT",
-+ /* 107 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
-+ /* 108 */ "distinct ::= DISTINCT",
-+ /* 109 */ "distinct ::= ALL",
-+ /* 110 */ "distinct ::=",
-+ /* 111 */ "sclp ::= selcollist COMMA",
-+ /* 112 */ "sclp ::=",
-+ /* 113 */ "selcollist ::= sclp expr as",
-+ /* 114 */ "selcollist ::= sclp STAR",
-+ /* 115 */ "selcollist ::= sclp nm DOT STAR",
-+ /* 116 */ "as ::= AS nm",
-+ /* 117 */ "as ::= ids",
-+ /* 118 */ "as ::=",
-+ /* 119 */ "from ::=",
-+ /* 120 */ "from ::= FROM seltablist",
-+ /* 121 */ "stl_prefix ::= seltablist joinop",
-+ /* 122 */ "stl_prefix ::=",
-+ /* 123 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
-+ /* 124 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
-+ /* 125 */ "seltablist_paren ::= select",
-+ /* 126 */ "seltablist_paren ::= seltablist",
-+ /* 127 */ "dbnm ::=",
-+ /* 128 */ "dbnm ::= DOT nm",
-+ /* 129 */ "joinop ::= COMMA",
-+ /* 130 */ "joinop ::= JOIN",
-+ /* 131 */ "joinop ::= JOIN_KW JOIN",
-+ /* 132 */ "joinop ::= JOIN_KW nm JOIN",
-+ /* 133 */ "joinop ::= JOIN_KW nm nm JOIN",
-+ /* 134 */ "on_opt ::= ON expr",
-+ /* 135 */ "on_opt ::=",
-+ /* 136 */ "using_opt ::= USING LP idxlist RP",
-+ /* 137 */ "using_opt ::=",
-+ /* 138 */ "orderby_opt ::=",
-+ /* 139 */ "orderby_opt ::= ORDER BY sortlist",
-+ /* 140 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
-+ /* 141 */ "sortlist ::= sortitem collate sortorder",
-+ /* 142 */ "sortitem ::= expr",
-+ /* 143 */ "sortorder ::= ASC",
-+ /* 144 */ "sortorder ::= DESC",
-+ /* 145 */ "sortorder ::=",
-+ /* 146 */ "collate ::=",
-+ /* 147 */ "collate ::= COLLATE id",
-+ /* 148 */ "groupby_opt ::=",
-+ /* 149 */ "groupby_opt ::= GROUP BY exprlist",
-+ /* 150 */ "having_opt ::=",
-+ /* 151 */ "having_opt ::= HAVING expr",
-+ /* 152 */ "limit_opt ::=",
-+ /* 153 */ "limit_opt ::= LIMIT signed",
-+ /* 154 */ "limit_opt ::= LIMIT signed OFFSET signed",
-+ /* 155 */ "limit_opt ::= LIMIT signed COMMA signed",
-+ /* 156 */ "cmd ::= DELETE FROM nm dbnm where_opt",
-+ /* 157 */ "where_opt ::=",
-+ /* 158 */ "where_opt ::= WHERE expr",
-+ /* 159 */ "cmd ::= UPDATE orconf nm dbnm SET setlist where_opt",
-+ /* 160 */ "setlist ::= setlist COMMA nm EQ expr",
-+ /* 161 */ "setlist ::= nm EQ expr",
-+ /* 162 */ "cmd ::= insert_cmd INTO nm dbnm inscollist_opt VALUES LP itemlist RP",
-+ /* 163 */ "cmd ::= insert_cmd INTO nm dbnm inscollist_opt select",
-+ /* 164 */ "insert_cmd ::= INSERT orconf",
-+ /* 165 */ "insert_cmd ::= REPLACE",
-+ /* 166 */ "itemlist ::= itemlist COMMA expr",
-+ /* 167 */ "itemlist ::= expr",
-+ /* 168 */ "inscollist_opt ::=",
-+ /* 169 */ "inscollist_opt ::= LP inscollist RP",
-+ /* 170 */ "inscollist ::= inscollist COMMA nm",
-+ /* 171 */ "inscollist ::= nm",
-+ /* 172 */ "expr ::= LP expr RP",
-+ /* 173 */ "expr ::= NULL",
-+ /* 174 */ "expr ::= ID",
-+ /* 175 */ "expr ::= JOIN_KW",
-+ /* 176 */ "expr ::= nm DOT nm",
-+ /* 177 */ "expr ::= nm DOT nm DOT nm",
-+ /* 178 */ "expr ::= INTEGER",
-+ /* 179 */ "expr ::= FLOAT",
-+ /* 180 */ "expr ::= STRING",
-+ /* 181 */ "expr ::= VARIABLE",
-+ /* 182 */ "expr ::= ID LP exprlist RP",
-+ /* 183 */ "expr ::= ID LP STAR RP",
-+ /* 184 */ "expr ::= expr AND expr",
-+ /* 185 */ "expr ::= expr OR expr",
-+ /* 186 */ "expr ::= expr LT expr",
-+ /* 187 */ "expr ::= expr GT expr",
-+ /* 188 */ "expr ::= expr LE expr",
-+ /* 189 */ "expr ::= expr GE expr",
-+ /* 190 */ "expr ::= expr NE expr",
-+ /* 191 */ "expr ::= expr EQ expr",
-+ /* 192 */ "expr ::= expr BITAND expr",
-+ /* 193 */ "expr ::= expr BITOR expr",
-+ /* 194 */ "expr ::= expr LSHIFT expr",
-+ /* 195 */ "expr ::= expr RSHIFT expr",
-+ /* 196 */ "expr ::= expr likeop expr",
-+ /* 197 */ "expr ::= expr NOT likeop expr",
-+ /* 198 */ "likeop ::= LIKE",
-+ /* 199 */ "likeop ::= GLOB",
-+ /* 200 */ "expr ::= expr PLUS expr",
-+ /* 201 */ "expr ::= expr MINUS expr",
-+ /* 202 */ "expr ::= expr STAR expr",
-+ /* 203 */ "expr ::= expr SLASH expr",
-+ /* 204 */ "expr ::= expr REM expr",
-+ /* 205 */ "expr ::= expr CONCAT expr",
-+ /* 206 */ "expr ::= expr ISNULL",
-+ /* 207 */ "expr ::= expr IS NULL",
-+ /* 208 */ "expr ::= expr NOTNULL",
-+ /* 209 */ "expr ::= expr NOT NULL",
-+ /* 210 */ "expr ::= expr IS NOT NULL",
-+ /* 211 */ "expr ::= NOT expr",
-+ /* 212 */ "expr ::= BITNOT expr",
-+ /* 213 */ "expr ::= MINUS expr",
-+ /* 214 */ "expr ::= PLUS expr",
-+ /* 215 */ "expr ::= LP select RP",
-+ /* 216 */ "expr ::= expr BETWEEN expr AND expr",
-+ /* 217 */ "expr ::= expr NOT BETWEEN expr AND expr",
-+ /* 218 */ "expr ::= expr IN LP exprlist RP",
-+ /* 219 */ "expr ::= expr IN LP select RP",
-+ /* 220 */ "expr ::= expr NOT IN LP exprlist RP",
-+ /* 221 */ "expr ::= expr NOT IN LP select RP",
-+ /* 222 */ "expr ::= expr IN nm dbnm",
-+ /* 223 */ "expr ::= expr NOT IN nm dbnm",
-+ /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END",
-+ /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
-+ /* 226 */ "case_exprlist ::= WHEN expr THEN expr",
-+ /* 227 */ "case_else ::= ELSE expr",
-+ /* 228 */ "case_else ::=",
-+ /* 229 */ "case_operand ::= expr",
-+ /* 230 */ "case_operand ::=",
-+ /* 231 */ "exprlist ::= exprlist COMMA expritem",
-+ /* 232 */ "exprlist ::= expritem",
-+ /* 233 */ "expritem ::= expr",
-+ /* 234 */ "expritem ::=",
-+ /* 235 */ "cmd ::= CREATE uniqueflag INDEX nm ON nm dbnm LP idxlist RP onconf",
-+ /* 236 */ "uniqueflag ::= UNIQUE",
-+ /* 237 */ "uniqueflag ::=",
-+ /* 238 */ "idxlist_opt ::=",
-+ /* 239 */ "idxlist_opt ::= LP idxlist RP",
-+ /* 240 */ "idxlist ::= idxlist COMMA idxitem",
-+ /* 241 */ "idxlist ::= idxitem",
-+ /* 242 */ "idxitem ::= nm sortorder",
-+ /* 243 */ "cmd ::= DROP INDEX nm dbnm",
-+ /* 244 */ "cmd ::= COPY orconf nm dbnm FROM nm USING DELIMITERS STRING",
-+ /* 245 */ "cmd ::= COPY orconf nm dbnm FROM nm",
-+ /* 246 */ "cmd ::= VACUUM",
-+ /* 247 */ "cmd ::= VACUUM nm",
-+ /* 248 */ "cmd ::= PRAGMA ids EQ nm",
-+ /* 249 */ "cmd ::= PRAGMA ids EQ ON",
-+ /* 250 */ "cmd ::= PRAGMA ids EQ plus_num",
-+ /* 251 */ "cmd ::= PRAGMA ids EQ minus_num",
-+ /* 252 */ "cmd ::= PRAGMA ids LP nm RP",
-+ /* 253 */ "cmd ::= PRAGMA ids",
-+ /* 254 */ "plus_num ::= plus_opt number",
-+ /* 255 */ "minus_num ::= MINUS number",
-+ /* 256 */ "number ::= INTEGER",
-+ /* 257 */ "number ::= FLOAT",
-+ /* 258 */ "plus_opt ::= PLUS",
-+ /* 259 */ "plus_opt ::=",
-+ /* 260 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
-+ /* 261 */ "trigger_decl ::= temp TRIGGER nm trigger_time trigger_event ON nm dbnm foreach_clause when_clause",
-+ /* 262 */ "trigger_time ::= BEFORE",
-+ /* 263 */ "trigger_time ::= AFTER",
-+ /* 264 */ "trigger_time ::= INSTEAD OF",
-+ /* 265 */ "trigger_time ::=",
-+ /* 266 */ "trigger_event ::= DELETE",
-+ /* 267 */ "trigger_event ::= INSERT",
-+ /* 268 */ "trigger_event ::= UPDATE",
-+ /* 269 */ "trigger_event ::= UPDATE OF inscollist",
-+ /* 270 */ "foreach_clause ::=",
-+ /* 271 */ "foreach_clause ::= FOR EACH ROW",
-+ /* 272 */ "foreach_clause ::= FOR EACH STATEMENT",
-+ /* 273 */ "when_clause ::=",
-+ /* 274 */ "when_clause ::= WHEN expr",
-+ /* 275 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
-+ /* 276 */ "trigger_cmd_list ::=",
-+ /* 277 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
-+ /* 278 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
-+ /* 279 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
-+ /* 280 */ "trigger_cmd ::= DELETE FROM nm where_opt",
-+ /* 281 */ "trigger_cmd ::= select",
-+ /* 282 */ "expr ::= RAISE LP IGNORE RP",
-+ /* 283 */ "expr ::= RAISE LP ROLLBACK COMMA nm RP",
-+ /* 284 */ "expr ::= RAISE LP ABORT COMMA nm RP",
-+ /* 285 */ "expr ::= RAISE LP FAIL COMMA nm RP",
-+ /* 286 */ "cmd ::= DROP TRIGGER nm dbnm",
-+ /* 287 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt",
-+ /* 288 */ "key_opt ::= USING ids",
-+ /* 289 */ "key_opt ::=",
-+ /* 290 */ "database_kw_opt ::= DATABASE",
-+ /* 291 */ "database_kw_opt ::=",
-+ /* 292 */ "cmd ::= DETACH database_kw_opt nm",
-+};
-+#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 sqliteParser and sqliteParserFree.
-+*/
-+void *sqliteParserAlloc(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 */
-+){
-+  sqliteParserARG_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 146: /* select */
-+    case 171: /* oneselect */
-+    case 189: /* seltablist_paren */
-+{
-+#line 286 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteSelectDelete((yypminor->yy179));
-+#line 1131 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 158: /* expr */
-+    case 176: /* where_opt */
-+    case 178: /* having_opt */
-+    case 187: /* on_opt */
-+    case 192: /* sortitem */
-+    case 204: /* expritem */
-+{
-+#line 533 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteExprDelete((yypminor->yy242));
-+#line 1143 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 159: /* idxlist_opt */
-+    case 167: /* idxlist */
-+    case 188: /* using_opt */
-+    case 197: /* inscollist_opt */
-+    case 199: /* inscollist */
-+{
-+#line 746 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteIdListDelete((yypminor->yy320));
-+#line 1154 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 174: /* selcollist */
-+    case 177: /* groupby_opt */
-+    case 179: /* orderby_opt */
-+    case 181: /* sclp */
-+    case 191: /* sortlist */
-+    case 194: /* exprlist */
-+    case 195: /* setlist */
-+    case 198: /* itemlist */
-+    case 202: /* case_exprlist */
-+{
-+#line 322 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteExprListDelete((yypminor->yy322));
-+#line 1169 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 175: /* from */
-+    case 183: /* seltablist */
-+    case 184: /* stl_prefix */
-+{
-+#line 353 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteSrcListDelete((yypminor->yy307));
-+#line 1178 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 212: /* trigger_cmd_list */
-+    case 217: /* trigger_cmd */
-+{
-+#line 828 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteDeleteTriggerStep((yypminor->yy19));
-+#line 1186 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      break;
-+    case 214: /* trigger_event */
-+{
-+#line 812 "ext/sqlite/libsqlite/src/parse.y"
-+sqliteIdListDelete((yypminor->yy290).b);
-+#line 1193 "ext/sqlite/libsqlite/src/parse.c"
-+}
-+      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];
-+
-+  if( 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 sqliteParserAlloc.
-+** <li>  A pointer to a function used to reclaim memory obtained
-+**       from malloc.
-+** </ul>
-+*/
-+void sqliteParserFree(
-+  void *p,                    /* The parser to be deleted */
-+  void (*freeProc)(void*)     /* Function used to reclaim memory */
-+){
-+  yyParser *pParser = (yyParser*)p;
-+  if( 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
-+int sqliteParserStackPeak(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_COUNT
-+   || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
-+    return yy_default[stateno];
-+  }
-+  assert( iLookAhead!=YYNOCODE );
-+  i += iLookAhead;
-+  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
-+    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( 
-+#if YY_SHIFT_MIN+YYWILDCARD<0
-+          j>=0 &&
-+#endif
-+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
-+          j<YY_ACTTAB_COUNT &&
-+#endif
-+          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_COUNT ){
-+    return yy_default[stateno];
-+  }
-+#else
-+  assert( stateno<=YY_REDUCE_COUNT );
-+#endif
-+  i = yy_reduce_ofst[stateno];
-+  assert( i!=YY_REDUCE_USE_DFLT );
-+  assert( iLookAhead!=YYNOCODE );
-+  i += iLookAhead;
-+#ifdef YYERRORSYMBOL
-+  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
-+    return yy_default[stateno];
-+  }
-+#else
-+  assert( i>=0 && i<YY_ACTTAB_COUNT );
-+  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){
-+   sqliteParserARG_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 */
-+   sqliteParserARG_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[] = {
-+  { 132, 1 },
-+  { 133, 2 },
-+  { 133, 1 },
-+  { 134, 3 },
-+  { 134, 1 },
-+  { 136, 1 },
-+  { 135, 1 },
-+  { 135, 0 },
-+  { 137, 3 },
-+  { 138, 0 },
-+  { 138, 1 },
-+  { 138, 2 },
-+  { 137, 2 },
-+  { 137, 2 },
-+  { 137, 2 },
-+  { 137, 2 },
-+  { 141, 4 },
-+  { 143, 1 },
-+  { 143, 0 },
-+  { 142, 4 },
-+  { 142, 2 },
-+  { 144, 3 },
-+  { 144, 1 },
-+  { 147, 3 },
-+  { 148, 1 },
-+  { 151, 1 },
-+  { 152, 1 },
-+  { 152, 1 },
-+  { 140, 1 },
-+  { 140, 1 },
-+  { 140, 1 },
-+  { 149, 0 },
-+  { 149, 1 },
-+  { 149, 4 },
-+  { 149, 6 },
-+  { 153, 1 },
-+  { 153, 2 },
-+  { 154, 1 },
-+  { 154, 2 },
-+  { 154, 2 },
-+  { 150, 2 },
-+  { 150, 0 },
-+  { 155, 3 },
-+  { 155, 1 },
-+  { 155, 2 },
-+  { 155, 2 },
-+  { 155, 2 },
-+  { 155, 3 },
-+  { 155, 3 },
-+  { 155, 2 },
-+  { 155, 3 },
-+  { 155, 3 },
-+  { 155, 2 },
-+  { 156, 2 },
-+  { 156, 3 },
-+  { 156, 4 },
-+  { 156, 2 },
-+  { 156, 5 },
-+  { 156, 4 },
-+  { 156, 1 },
-+  { 156, 2 },
-+  { 160, 0 },
-+  { 160, 2 },
-+  { 162, 2 },
-+  { 162, 3 },
-+  { 162, 3 },
-+  { 162, 3 },
-+  { 163, 2 },
-+  { 163, 2 },
-+  { 163, 1 },
-+  { 163, 1 },
-+  { 161, 3 },
-+  { 161, 2 },
-+  { 164, 0 },
-+  { 164, 2 },
-+  { 164, 2 },
-+  { 145, 0 },
-+  { 145, 2 },
-+  { 165, 3 },
-+  { 165, 2 },
-+  { 165, 1 },
-+  { 166, 2 },
-+  { 166, 6 },
-+  { 166, 5 },
-+  { 166, 3 },
-+  { 166, 10 },
-+  { 168, 0 },
-+  { 168, 1 },
-+  { 139, 0 },
-+  { 139, 3 },
-+  { 169, 0 },
-+  { 169, 2 },
-+  { 170, 1 },
-+  { 170, 1 },
-+  { 170, 1 },
-+  { 170, 1 },
-+  { 170, 1 },
-+  { 137, 3 },
-+  { 137, 6 },
-+  { 137, 3 },
-+  { 137, 1 },
-+  { 146, 1 },
-+  { 146, 3 },
-+  { 172, 1 },
-+  { 172, 2 },
-+  { 172, 1 },
-+  { 172, 1 },
-+  { 171, 9 },
-+  { 173, 1 },
-+  { 173, 1 },
-+  { 173, 0 },
-+  { 181, 2 },
-+  { 181, 0 },
-+  { 174, 3 },
-+  { 174, 2 },
-+  { 174, 4 },
-+  { 182, 2 },
-+  { 182, 1 },
-+  { 182, 0 },
-+  { 175, 0 },
-+  { 175, 2 },
-+  { 184, 2 },
-+  { 184, 0 },
-+  { 183, 6 },
-+  { 183, 7 },
-+  { 189, 1 },
-+  { 189, 1 },
-+  { 186, 0 },
-+  { 186, 2 },
-+  { 185, 1 },
-+  { 185, 1 },
-+  { 185, 2 },
-+  { 185, 3 },
-+  { 185, 4 },
-+  { 187, 2 },
-+  { 187, 0 },
-+  { 188, 4 },
-+  { 188, 0 },
-+  { 179, 0 },
-+  { 179, 3 },
-+  { 191, 5 },
-+  { 191, 3 },
-+  { 192, 1 },
-+  { 157, 1 },
-+  { 157, 1 },
-+  { 157, 0 },
-+  { 193, 0 },
-+  { 193, 2 },
-+  { 177, 0 },
-+  { 177, 3 },
-+  { 178, 0 },
-+  { 178, 2 },
-+  { 180, 0 },
-+  { 180, 2 },
-+  { 180, 4 },
-+  { 180, 4 },
-+  { 137, 5 },
-+  { 176, 0 },
-+  { 176, 2 },
-+  { 137, 7 },
-+  { 195, 5 },
-+  { 195, 3 },
-+  { 137, 9 },
-+  { 137, 6 },
-+  { 196, 2 },
-+  { 196, 1 },
-+  { 198, 3 },
-+  { 198, 1 },
-+  { 197, 0 },
-+  { 197, 3 },
-+  { 199, 3 },
-+  { 199, 1 },
-+  { 158, 3 },
-+  { 158, 1 },
-+  { 158, 1 },
-+  { 158, 1 },
-+  { 158, 3 },
-+  { 158, 5 },
-+  { 158, 1 },
-+  { 158, 1 },
-+  { 158, 1 },
-+  { 158, 1 },
-+  { 158, 4 },
-+  { 158, 4 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 4 },
-+  { 200, 1 },
-+  { 200, 1 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 3 },
-+  { 158, 2 },
-+  { 158, 3 },
-+  { 158, 2 },
-+  { 158, 3 },
-+  { 158, 4 },
-+  { 158, 2 },
-+  { 158, 2 },
-+  { 158, 2 },
-+  { 158, 2 },
-+  { 158, 3 },
-+  { 158, 5 },
-+  { 158, 6 },
-+  { 158, 5 },
-+  { 158, 5 },
-+  { 158, 6 },
-+  { 158, 6 },
-+  { 158, 4 },
-+  { 158, 5 },
-+  { 158, 5 },
-+  { 202, 5 },
-+  { 202, 4 },
-+  { 203, 2 },
-+  { 203, 0 },
-+  { 201, 1 },
-+  { 201, 0 },
-+  { 194, 3 },
-+  { 194, 1 },
-+  { 204, 1 },
-+  { 204, 0 },
-+  { 137, 11 },
-+  { 205, 1 },
-+  { 205, 0 },
-+  { 159, 0 },
-+  { 159, 3 },
-+  { 167, 3 },
-+  { 167, 1 },
-+  { 206, 2 },
-+  { 137, 4 },
-+  { 137, 9 },
-+  { 137, 6 },
-+  { 137, 1 },
-+  { 137, 2 },
-+  { 137, 4 },
-+  { 137, 4 },
-+  { 137, 4 },
-+  { 137, 4 },
-+  { 137, 5 },
-+  { 137, 2 },
-+  { 207, 2 },
-+  { 208, 2 },
-+  { 210, 1 },
-+  { 210, 1 },
-+  { 209, 1 },
-+  { 209, 0 },
-+  { 137, 5 },
-+  { 211, 10 },
-+  { 213, 1 },
-+  { 213, 1 },
-+  { 213, 2 },
-+  { 213, 0 },
-+  { 214, 1 },
-+  { 214, 1 },
-+  { 214, 1 },
-+  { 214, 3 },
-+  { 215, 0 },
-+  { 215, 3 },
-+  { 215, 3 },
-+  { 216, 0 },
-+  { 216, 2 },
-+  { 212, 3 },
-+  { 212, 0 },
-+  { 217, 6 },
-+  { 217, 8 },
-+  { 217, 5 },
-+  { 217, 4 },
-+  { 217, 1 },
-+  { 158, 4 },
-+  { 158, 6 },
-+  { 158, 6 },
-+  { 158, 6 },
-+  { 137, 4 },
-+  { 137, 6 },
-+  { 219, 2 },
-+  { 219, 0 },
-+  { 218, 1 },
-+  { 218, 0 },
-+  { 137, 3 },
-+};
-+
-+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 */
-+  sqliteParserARG_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: /* cmdx ::= cmd */
-+#line 72 "ext/sqlite/libsqlite/src/parse.y"
-+{ sqliteExec(pParse); }
-+#line 1781 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 6: /* explain ::= EXPLAIN */
-+#line 73 "ext/sqlite/libsqlite/src/parse.y"
-+{ sqliteBeginParse(pParse, 1); }
-+#line 1786 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 7: /* explain ::= */
-+#line 74 "ext/sqlite/libsqlite/src/parse.y"
-+{ sqliteBeginParse(pParse, 0); }
-+#line 1791 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 8: /* cmd ::= BEGIN trans_opt onconf */
-+#line 79 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteBeginTransaction(pParse,yymsp[0].minor.yy372);}
-+#line 1796 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 12: /* cmd ::= COMMIT trans_opt */
-+      case 13: /* cmd ::= END trans_opt */ yytestcase(yyruleno==13);
-+#line 83 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCommitTransaction(pParse);}
-+#line 1802 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 14: /* cmd ::= ROLLBACK trans_opt */
-+#line 85 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteRollbackTransaction(pParse);}
-+#line 1807 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 16: /* create_table ::= CREATE temp TABLE nm */
-+#line 90 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   sqliteStartTable(pParse,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0,yymsp[-2].minor.yy372,0);
-+}
-+#line 1814 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 17: /* temp ::= TEMP */
-+      case 74: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==74);
-+      case 108: /* distinct ::= DISTINCT */ yytestcase(yyruleno==108);
-+#line 94 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = 1;}
-+#line 1821 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 18: /* temp ::= */
-+      case 73: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==73);
-+      case 75: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==75);
-+      case 86: /* defer_subclause_opt ::= */ yytestcase(yyruleno==86);
-+      case 109: /* distinct ::= ALL */ yytestcase(yyruleno==109);
-+      case 110: /* distinct ::= */ yytestcase(yyruleno==110);
-+#line 95 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = 0;}
-+#line 1831 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 19: /* create_table_args ::= LP columnlist conslist_opt RP */
-+#line 96 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteEndTable(pParse,&yymsp[0].minor.yy0,0);
-+}
-+#line 1838 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 20: /* create_table_args ::= AS select */
-+#line 99 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteEndTable(pParse,0,yymsp[0].minor.yy179);
-+  sqliteSelectDelete(yymsp[0].minor.yy179);
-+}
-+#line 1846 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 24: /* columnid ::= nm */
-+#line 111 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddColumn(pParse,&yymsp[0].minor.yy0);}
-+#line 1851 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 25: /* id ::= ID */
-+      case 26: /* ids ::= ID */ yytestcase(yyruleno==26);
-+      case 27: /* ids ::= STRING */ yytestcase(yyruleno==27);
-+      case 28: /* nm ::= ID */ yytestcase(yyruleno==28);
-+      case 29: /* nm ::= STRING */ yytestcase(yyruleno==29);
-+      case 30: /* nm ::= JOIN_KW */ yytestcase(yyruleno==30);
-+      case 35: /* typename ::= ids */ yytestcase(yyruleno==35);
-+      case 128: /* dbnm ::= DOT nm */ yytestcase(yyruleno==128);
-+      case 254: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==254);
-+      case 255: /* minus_num ::= MINUS number */ yytestcase(yyruleno==255);
-+      case 256: /* number ::= INTEGER */ yytestcase(yyruleno==256);
-+      case 257: /* number ::= FLOAT */ yytestcase(yyruleno==257);
-+#line 117 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy0 = yymsp[0].minor.yy0;}
-+#line 1867 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 32: /* type ::= typename */
-+#line 160 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddColumnType(pParse,&yymsp[0].minor.yy0,&yymsp[0].minor.yy0);}
-+#line 1872 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 33: /* type ::= typename LP signed RP */
-+#line 161 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddColumnType(pParse,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);}
-+#line 1877 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 34: /* type ::= typename LP signed COMMA signed RP */
-+#line 163 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddColumnType(pParse,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);}
-+#line 1882 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 36: /* typename ::= typename ids */
-+      case 242: /* idxitem ::= nm sortorder */ yytestcase(yyruleno==242);
-+#line 166 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy0 = yymsp[-1].minor.yy0;}
-+#line 1888 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 37: /* signed ::= INTEGER */
-+      case 38: /* signed ::= PLUS INTEGER */ yytestcase(yyruleno==38);
-+#line 168 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = atoi(yymsp[0].minor.yy0.z); }
-+#line 1894 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 39: /* signed ::= MINUS INTEGER */
-+#line 170 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = -atoi(yymsp[0].minor.yy0.z); }
-+#line 1899 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 44: /* carg ::= DEFAULT STRING */
-+      case 45: /* carg ::= DEFAULT ID */ yytestcase(yyruleno==45);
-+      case 46: /* carg ::= DEFAULT INTEGER */ yytestcase(yyruleno==46);
-+      case 47: /* carg ::= DEFAULT PLUS INTEGER */ yytestcase(yyruleno==47);
-+      case 49: /* carg ::= DEFAULT FLOAT */ yytestcase(yyruleno==49);
-+      case 50: /* carg ::= DEFAULT PLUS FLOAT */ yytestcase(yyruleno==50);
-+#line 175 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
-+#line 1909 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 48: /* carg ::= DEFAULT MINUS INTEGER */
-+      case 51: /* carg ::= DEFAULT MINUS FLOAT */ yytestcase(yyruleno==51);
-+#line 179 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,1);}
-+#line 1915 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 54: /* ccons ::= NOT NULL onconf */
-+#line 189 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddNotNull(pParse, yymsp[0].minor.yy372);}
-+#line 1920 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 55: /* ccons ::= PRIMARY KEY sortorder onconf */
-+#line 190 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddPrimaryKey(pParse,0,yymsp[0].minor.yy372);}
-+#line 1925 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 56: /* ccons ::= UNIQUE onconf */
-+#line 191 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCreateIndex(pParse,0,0,0,yymsp[0].minor.yy372,0,0);}
-+#line 1930 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 57: /* ccons ::= CHECK LP expr RP onconf */
-+#line 192 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yy_destructor(yypParser,158,&yymsp[-2].minor);
-+}
-+#line 1937 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 58: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-+#line 194 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy320,yymsp[0].minor.yy372);}
-+#line 1942 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 59: /* ccons ::= defer_subclause */
-+#line 195 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteDeferForeignKey(pParse,yymsp[0].minor.yy372);}
-+#line 1947 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 60: /* ccons ::= COLLATE id */
-+#line 196 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   sqliteAddCollateType(pParse, sqliteCollateType(yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n));
-+}
-+#line 1954 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 61: /* refargs ::= */
-+#line 206 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Restrict * 0x010101; }
-+#line 1959 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 62: /* refargs ::= refargs refarg */
-+#line 207 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = (yymsp[-1].minor.yy372 & yymsp[0].minor.yy407.mask) | yymsp[0].minor.yy407.value; }
-+#line 1964 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 63: /* refarg ::= MATCH nm */
-+#line 209 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy407.value = 0;     yygotominor.yy407.mask = 0x000000; }
-+#line 1969 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 64: /* refarg ::= ON DELETE refact */
-+#line 210 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy407.value = yymsp[0].minor.yy372;     yygotominor.yy407.mask = 0x0000ff; }
-+#line 1974 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 65: /* refarg ::= ON UPDATE refact */
-+#line 211 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy407.value = yymsp[0].minor.yy372<<8;  yygotominor.yy407.mask = 0x00ff00; }
-+#line 1979 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 66: /* refarg ::= ON INSERT refact */
-+#line 212 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy407.value = yymsp[0].minor.yy372<<16; yygotominor.yy407.mask = 0xff0000; }
-+#line 1984 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 67: /* refact ::= SET NULL */
-+#line 214 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_SetNull; }
-+#line 1989 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 68: /* refact ::= SET DEFAULT */
-+#line 215 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_SetDflt; }
-+#line 1994 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 69: /* refact ::= CASCADE */
-+#line 216 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Cascade; }
-+#line 1999 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 70: /* refact ::= RESTRICT */
-+#line 217 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Restrict; }
-+#line 2004 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 71: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-+      case 72: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==72);
-+      case 87: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==87);
-+      case 164: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==164);
-+#line 219 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = yymsp[0].minor.yy372;}
-+#line 2012 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 82: /* tcons ::= PRIMARY KEY LP idxlist RP onconf */
-+#line 236 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteAddPrimaryKey(pParse,yymsp[-2].minor.yy320,yymsp[0].minor.yy372);}
-+#line 2017 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 83: /* tcons ::= UNIQUE LP idxlist RP onconf */
-+#line 238 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCreateIndex(pParse,0,0,yymsp[-2].minor.yy320,yymsp[0].minor.yy372,0,0);}
-+#line 2022 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 84: /* tcons ::= CHECK expr onconf */
-+#line 239 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yy_destructor(yypParser,158,&yymsp[-1].minor);
-+}
-+#line 2029 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 85: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
-+#line 241 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+    sqliteCreateForeignKey(pParse, yymsp[-6].minor.yy320, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy320, yymsp[-1].minor.yy372);
-+    sqliteDeferForeignKey(pParse, yymsp[0].minor.yy372);
-+}
-+#line 2037 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 88: /* onconf ::= */
-+      case 90: /* orconf ::= */ yytestcase(yyruleno==90);
-+#line 255 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Default; }
-+#line 2043 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 89: /* onconf ::= ON CONFLICT resolvetype */
-+      case 91: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==91);
-+#line 256 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = yymsp[0].minor.yy372; }
-+#line 2049 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 92: /* resolvetype ::= ROLLBACK */
-+#line 259 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Rollback; }
-+#line 2054 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 93: /* resolvetype ::= ABORT */
-+      case 236: /* uniqueflag ::= UNIQUE */ yytestcase(yyruleno==236);
-+#line 260 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Abort; }
-+#line 2060 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 94: /* resolvetype ::= FAIL */
-+#line 261 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Fail; }
-+#line 2065 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 95: /* resolvetype ::= IGNORE */
-+#line 262 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Ignore; }
-+#line 2070 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 96: /* resolvetype ::= REPLACE */
-+#line 263 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_Replace; }
-+#line 2075 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 97: /* cmd ::= DROP TABLE nm */
-+#line 267 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteDropTable(pParse,&yymsp[0].minor.yy0,0);}
-+#line 2080 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 98: /* cmd ::= CREATE temp VIEW nm AS select */
-+#line 271 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteCreateView(pParse, &yymsp[-5].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);
-+}
-+#line 2087 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 99: /* cmd ::= DROP VIEW nm */
-+#line 274 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteDropTable(pParse, &yymsp[0].minor.yy0, 1);
-+}
-+#line 2094 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 100: /* cmd ::= select */
-+#line 280 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteSelect(pParse, yymsp[0].minor.yy179, SRT_Callback, 0, 0, 0, 0);
-+  sqliteSelectDelete(yymsp[0].minor.yy179);
-+}
-+#line 2102 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 101: /* select ::= oneselect */
-+      case 125: /* seltablist_paren ::= select */ yytestcase(yyruleno==125);
-+#line 290 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy179 = yymsp[0].minor.yy179;}
-+#line 2108 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 102: /* select ::= select multiselect_op oneselect */
-+#line 291 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  if( yymsp[0].minor.yy179 ){
-+    yymsp[0].minor.yy179->op = yymsp[-1].minor.yy372;
-+    yymsp[0].minor.yy179->pPrior = yymsp[-2].minor.yy179;
-+  }
-+  yygotominor.yy179 = yymsp[0].minor.yy179;
-+}
-+#line 2119 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 103: /* multiselect_op ::= UNION */
-+#line 299 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_UNION;}
-+#line 2124 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 104: /* multiselect_op ::= UNION ALL */
-+#line 300 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_ALL;}
-+#line 2129 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 105: /* multiselect_op ::= INTERSECT */
-+#line 301 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_INTERSECT;}
-+#line 2134 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 106: /* multiselect_op ::= EXCEPT */
-+#line 302 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_EXCEPT;}
-+#line 2139 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 107: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-+#line 304 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy179 = sqliteSelectNew(yymsp[-6].minor.yy322,yymsp[-5].minor.yy307,yymsp[-4].minor.yy242,yymsp[-3].minor.yy322,yymsp[-2].minor.yy242,yymsp[-1].minor.yy322,yymsp[-7].minor.yy372,yymsp[0].minor.yy124.limit,yymsp[0].minor.yy124.offset);
-+}
-+#line 2146 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 111: /* sclp ::= selcollist COMMA */
-+#line 325 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = yymsp[-1].minor.yy322;}
-+#line 2151 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 112: /* sclp ::= */
-+      case 138: /* orderby_opt ::= */ yytestcase(yyruleno==138);
-+      case 148: /* groupby_opt ::= */ yytestcase(yyruleno==148);
-+#line 326 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = 0;}
-+#line 2158 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 113: /* selcollist ::= sclp expr as */
-+#line 327 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[-1].minor.yy242,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
-+}
-+#line 2165 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 114: /* selcollist ::= sclp STAR */
-+#line 330 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy322 = sqliteExprListAppend(yymsp[-1].minor.yy322, sqliteExpr(TK_ALL, 0, 0, 0), 0);
-+}
-+#line 2172 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 115: /* selcollist ::= sclp nm DOT STAR */
-+#line 333 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
-+  Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy0);
-+  yygotominor.yy322 = sqliteExprListAppend(yymsp[-3].minor.yy322, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
-+}
-+#line 2181 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 116: /* as ::= AS nm */
-+      case 117: /* as ::= ids */ yytestcase(yyruleno==117);
-+      case 288: /* key_opt ::= USING ids */ yytestcase(yyruleno==288);
-+#line 343 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy0 = yymsp[0].minor.yy0; }
-+#line 2188 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 118: /* as ::= */
-+#line 345 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy0.n = 0; }
-+#line 2193 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 119: /* from ::= */
-+#line 357 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy307 = sqliteMalloc(sizeof(*yygotominor.yy307));}
-+#line 2198 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 120: /* from ::= FROM seltablist */
-+#line 358 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy307 = yymsp[0].minor.yy307;}
-+#line 2203 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 121: /* stl_prefix ::= seltablist joinop */
-+#line 363 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   yygotominor.yy307 = yymsp[-1].minor.yy307;
-+   if( yygotominor.yy307 && yygotominor.yy307->nSrc>0 ) yygotominor.yy307->a[yygotominor.yy307->nSrc-1].jointype = yymsp[0].minor.yy372;
-+}
-+#line 2211 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 122: /* stl_prefix ::= */
-+#line 367 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy307 = 0;}
-+#line 2216 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 123: /* seltablist ::= stl_prefix nm dbnm as on_opt using_opt */
-+#line 368 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy307 = sqliteSrcListAppend(yymsp[-5].minor.yy307,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0);
-+  if( yymsp[-2].minor.yy0.n ) sqliteSrcListAddAlias(yygotominor.yy307,&yymsp[-2].minor.yy0);
-+  if( yymsp[-1].minor.yy242 ){
-+    if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pOn = yymsp[-1].minor.yy242; }
-+    else { sqliteExprDelete(yymsp[-1].minor.yy242); }
-+  }
-+  if( yymsp[0].minor.yy320 ){
-+    if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pUsing = yymsp[0].minor.yy320; }
-+    else { sqliteIdListDelete(yymsp[0].minor.yy320); }
-+  }
-+}
-+#line 2232 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 124: /* seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt */
-+#line 381 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy307 = sqliteSrcListAppend(yymsp[-6].minor.yy307,0,0);
-+  yygotominor.yy307->a[yygotominor.yy307->nSrc-1].pSelect = yymsp[-4].minor.yy179;
-+  if( yymsp[-2].minor.yy0.n ) sqliteSrcListAddAlias(yygotominor.yy307,&yymsp[-2].minor.yy0);
-+  if( yymsp[-1].minor.yy242 ){
-+    if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pOn = yymsp[-1].minor.yy242; }
-+    else { sqliteExprDelete(yymsp[-1].minor.yy242); }
-+  }
-+  if( yymsp[0].minor.yy320 ){
-+    if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pUsing = yymsp[0].minor.yy320; }
-+    else { sqliteIdListDelete(yymsp[0].minor.yy320); }
-+  }
-+}
-+#line 2249 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 126: /* seltablist_paren ::= seltablist */
-+#line 402 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   yygotominor.yy179 = sqliteSelectNew(0,yymsp[0].minor.yy307,0,0,0,0,0,-1,0);
-+}
-+#line 2256 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 127: /* dbnm ::= */
-+#line 407 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
-+#line 2261 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 129: /* joinop ::= COMMA */
-+      case 130: /* joinop ::= JOIN */ yytestcase(yyruleno==130);
-+#line 412 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = JT_INNER; }
-+#line 2267 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 131: /* joinop ::= JOIN_KW JOIN */
-+#line 414 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-+#line 2272 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 132: /* joinop ::= JOIN_KW nm JOIN */
-+#line 415 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
-+#line 2277 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 133: /* joinop ::= JOIN_KW nm nm JOIN */
-+#line 417 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
-+#line 2282 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 134: /* on_opt ::= ON expr */
-+      case 142: /* sortitem ::= expr */ yytestcase(yyruleno==142);
-+      case 151: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==151);
-+      case 158: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==158);
-+      case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227);
-+      case 229: /* case_operand ::= expr */ yytestcase(yyruleno==229);
-+      case 233: /* expritem ::= expr */ yytestcase(yyruleno==233);
-+#line 421 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = yymsp[0].minor.yy242;}
-+#line 2293 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 135: /* on_opt ::= */
-+      case 150: /* having_opt ::= */ yytestcase(yyruleno==150);
-+      case 157: /* where_opt ::= */ yytestcase(yyruleno==157);
-+      case 228: /* case_else ::= */ yytestcase(yyruleno==228);
-+      case 230: /* case_operand ::= */ yytestcase(yyruleno==230);
-+      case 234: /* expritem ::= */ yytestcase(yyruleno==234);
-+#line 422 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = 0;}
-+#line 2303 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 136: /* using_opt ::= USING LP idxlist RP */
-+      case 169: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==169);
-+      case 239: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==239);
-+#line 426 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy320 = yymsp[-1].minor.yy320;}
-+#line 2310 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 137: /* using_opt ::= */
-+      case 168: /* inscollist_opt ::= */ yytestcase(yyruleno==168);
-+      case 238: /* idxlist_opt ::= */ yytestcase(yyruleno==238);
-+#line 427 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy320 = 0;}
-+#line 2317 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 139: /* orderby_opt ::= ORDER BY sortlist */
-+      case 149: /* groupby_opt ::= GROUP BY exprlist */ yytestcase(yyruleno==149);
-+#line 438 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = yymsp[0].minor.yy322;}
-+#line 2323 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 140: /* sortlist ::= sortlist COMMA sortitem collate sortorder */
-+#line 439 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[-2].minor.yy242,0);
-+  if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
-+}
-+#line 2331 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 141: /* sortlist ::= sortitem collate sortorder */
-+#line 443 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy322 = sqliteExprListAppend(0,yymsp[-2].minor.yy242,0);
-+  if( yygotominor.yy322 ) yygotominor.yy322->a[0].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
-+}
-+#line 2339 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 143: /* sortorder ::= ASC */
-+      case 145: /* sortorder ::= */ yytestcase(yyruleno==145);
-+#line 452 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = SQLITE_SO_ASC;}
-+#line 2345 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 144: /* sortorder ::= DESC */
-+#line 453 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = SQLITE_SO_DESC;}
-+#line 2350 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 146: /* collate ::= */
-+#line 455 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = SQLITE_SO_UNK;}
-+#line 2355 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 147: /* collate ::= COLLATE id */
-+#line 456 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = sqliteCollateType(yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);}
-+#line 2360 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 152: /* limit_opt ::= */
-+#line 469 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy124.limit = -1; yygotominor.yy124.offset = 0;}
-+#line 2365 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 153: /* limit_opt ::= LIMIT signed */
-+#line 470 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = 0;}
-+#line 2370 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 154: /* limit_opt ::= LIMIT signed OFFSET signed */
-+#line 472 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy124.limit = yymsp[-2].minor.yy372; yygotominor.yy124.offset = yymsp[0].minor.yy372;}
-+#line 2375 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 155: /* limit_opt ::= LIMIT signed COMMA signed */
-+#line 474 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = yymsp[-2].minor.yy372;}
-+#line 2380 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 156: /* cmd ::= DELETE FROM nm dbnm where_opt */
-+#line 478 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+   sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0), yymsp[0].minor.yy242);
-+}
-+#line 2387 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 159: /* cmd ::= UPDATE orconf nm dbnm SET setlist where_opt */
-+#line 494 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteUpdate(pParse,sqliteSrcListAppend(0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0),yymsp[-1].minor.yy322,yymsp[0].minor.yy242,yymsp[-5].minor.yy372);}
-+#line 2392 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 160: /* setlist ::= setlist COMMA nm EQ expr */
-+#line 497 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[0].minor.yy242,&yymsp[-2].minor.yy0);}
-+#line 2397 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 161: /* setlist ::= nm EQ expr */
-+#line 498 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,&yymsp[-2].minor.yy0);}
-+#line 2402 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 162: /* cmd ::= insert_cmd INTO nm dbnm inscollist_opt VALUES LP itemlist RP */
-+#line 504 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0), yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy320, yymsp[-8].minor.yy372);}
-+#line 2407 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 163: /* cmd ::= insert_cmd INTO nm dbnm inscollist_opt select */
-+#line 506 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0), 0, yymsp[0].minor.yy179, yymsp[-1].minor.yy320, yymsp[-5].minor.yy372);}
-+#line 2412 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 165: /* insert_cmd ::= REPLACE */
-+#line 510 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = OE_Replace;}
-+#line 2417 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 166: /* itemlist ::= itemlist COMMA expr */
-+      case 231: /* exprlist ::= exprlist COMMA expritem */ yytestcase(yyruleno==231);
-+#line 516 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy242,0);}
-+#line 2423 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 167: /* itemlist ::= expr */
-+      case 232: /* exprlist ::= expritem */ yytestcase(yyruleno==232);
-+#line 517 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,0);}
-+#line 2429 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 170: /* inscollist ::= inscollist COMMA nm */
-+      case 240: /* idxlist ::= idxlist COMMA idxitem */ yytestcase(yyruleno==240);
-+#line 526 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy320 = sqliteIdListAppend(yymsp[-2].minor.yy320,&yymsp[0].minor.yy0);}
-+#line 2435 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 171: /* inscollist ::= nm */
-+      case 241: /* idxlist ::= idxitem */ yytestcase(yyruleno==241);
-+#line 527 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy320 = sqliteIdListAppend(0,&yymsp[0].minor.yy0);}
-+#line 2441 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 172: /* expr ::= LP expr RP */
-+#line 535 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = yymsp[-1].minor.yy242; sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-+#line 2446 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 173: /* expr ::= NULL */
-+#line 536 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_NULL, 0, 0, &yymsp[0].minor.yy0);}
-+#line 2451 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 174: /* expr ::= ID */
-+      case 175: /* expr ::= JOIN_KW */ yytestcase(yyruleno==175);
-+#line 537 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-+#line 2457 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 176: /* expr ::= nm DOT nm */
-+#line 539 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy0);
-+  Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);
-+  yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp2, 0);
-+}
-+#line 2466 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 177: /* expr ::= nm DOT nm DOT nm */
-+#line 544 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-4].minor.yy0);
-+  Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy0);
-+  Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);
-+  Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
-+  yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp4, 0);
-+}
-+#line 2477 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 178: /* expr ::= INTEGER */
-+#line 551 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_INTEGER, 0, 0, &yymsp[0].minor.yy0);}
-+#line 2482 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 179: /* expr ::= FLOAT */
-+#line 552 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_FLOAT, 0, 0, &yymsp[0].minor.yy0);}
-+#line 2487 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 180: /* expr ::= STRING */
-+#line 553 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_STRING, 0, 0, &yymsp[0].minor.yy0);}
-+#line 2492 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 181: /* expr ::= VARIABLE */
-+#line 554 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_VARIABLE, 0, 0, &yymsp[0].minor.yy0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->iTable = ++pParse->nVar;
-+}
-+#line 2500 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 182: /* expr ::= ID LP exprlist RP */
-+#line 558 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExprFunction(yymsp[-1].minor.yy322, &yymsp[-3].minor.yy0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-+}
-+#line 2508 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 183: /* expr ::= ID LP STAR RP */
-+#line 562 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExprFunction(0, &yymsp[-3].minor.yy0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-+}
-+#line 2516 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 184: /* expr ::= expr AND expr */
-+#line 566 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_AND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2521 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 185: /* expr ::= expr OR expr */
-+#line 567 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_OR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2526 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 186: /* expr ::= expr LT expr */
-+#line 568 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_LT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2531 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 187: /* expr ::= expr GT expr */
-+#line 569 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_GT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2536 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 188: /* expr ::= expr LE expr */
-+#line 570 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_LE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2541 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 189: /* expr ::= expr GE expr */
-+#line 571 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_GE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2546 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 190: /* expr ::= expr NE expr */
-+#line 572 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_NE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2551 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 191: /* expr ::= expr EQ expr */
-+#line 573 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_EQ, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2556 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 192: /* expr ::= expr BITAND expr */
-+#line 574 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_BITAND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2561 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 193: /* expr ::= expr BITOR expr */
-+#line 575 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_BITOR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2566 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 194: /* expr ::= expr LSHIFT expr */
-+#line 576 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_LSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2571 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 195: /* expr ::= expr RSHIFT expr */
-+#line 577 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_RSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2576 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 196: /* expr ::= expr likeop expr */
-+#line 578 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
-+  pList = sqliteExprListAppend(pList, yymsp[-2].minor.yy242, 0);
-+  yygotominor.yy242 = sqliteExprFunction(pList, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->op = yymsp[-1].minor.yy372;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-2].minor.yy242->span, &yymsp[0].minor.yy242->span);
-+}
-+#line 2587 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 197: /* expr ::= expr NOT likeop expr */
-+#line 585 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
-+  pList = sqliteExprListAppend(pList, yymsp[-3].minor.yy242, 0);
-+  yygotominor.yy242 = sqliteExprFunction(pList, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->op = yymsp[-1].minor.yy372;
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy242->span);
-+}
-+#line 2599 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 198: /* likeop ::= LIKE */
-+#line 594 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_LIKE;}
-+#line 2604 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 199: /* likeop ::= GLOB */
-+#line 595 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy372 = TK_GLOB;}
-+#line 2609 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 200: /* expr ::= expr PLUS expr */
-+#line 596 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_PLUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2614 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 201: /* expr ::= expr MINUS expr */
-+#line 597 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_MINUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2619 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 202: /* expr ::= expr STAR expr */
-+#line 598 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_STAR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2624 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 203: /* expr ::= expr SLASH expr */
-+#line 599 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_SLASH, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2629 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 204: /* expr ::= expr REM expr */
-+#line 600 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_REM, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2634 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 205: /* expr ::= expr CONCAT expr */
-+#line 601 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy242 = sqliteExpr(TK_CONCAT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
-+#line 2639 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 206: /* expr ::= expr ISNULL */
-+#line 602 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-1].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2647 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 207: /* expr ::= expr IS NULL */
-+#line 606 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-2].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2655 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 208: /* expr ::= expr NOTNULL */
-+#line 610 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-1].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2663 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 209: /* expr ::= expr NOT NULL */
-+#line 614 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-2].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2671 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 210: /* expr ::= expr IS NOT NULL */
-+#line 618 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-3].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2679 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 211: /* expr ::= NOT expr */
-+#line 622 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yymsp[0].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
-+}
-+#line 2687 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 212: /* expr ::= BITNOT expr */
-+#line 626 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_BITNOT, yymsp[0].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
-+}
-+#line 2695 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 213: /* expr ::= MINUS expr */
-+#line 630 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_UMINUS, yymsp[0].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
-+}
-+#line 2703 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 214: /* expr ::= PLUS expr */
-+#line 634 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_UPLUS, yymsp[0].minor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
-+}
-+#line 2711 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 215: /* expr ::= LP select RP */
-+#line 638 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_SELECT, 0, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
-+}
-+#line 2720 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 216: /* expr ::= expr BETWEEN expr AND expr */
-+#line 643 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
-+  pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
-+  yygotominor.yy242 = sqliteExpr(TK_BETWEEN, yymsp[-4].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pList = pList;
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy242->span);
-+}
-+#line 2731 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 217: /* expr ::= expr NOT BETWEEN expr AND expr */
-+#line 650 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
-+  pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
-+  yygotominor.yy242 = sqliteExpr(TK_BETWEEN, yymsp[-5].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pList = pList;
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy242->span);
-+}
-+#line 2743 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 218: /* expr ::= expr IN LP exprlist RP */
-+#line 658 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2752 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 219: /* expr ::= expr IN LP select RP */
-+#line 663 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2761 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 220: /* expr ::= expr NOT IN LP exprlist RP */
-+#line 668 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2771 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 221: /* expr ::= expr NOT IN LP select RP */
-+#line 674 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
-+}
-+#line 2781 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 222: /* expr ::= expr IN nm dbnm */
-+#line 680 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-3].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
-+}
-+#line 2791 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 223: /* expr ::= expr NOT IN nm dbnm */
-+#line 686 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);
-+  yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
-+  yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
-+  sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
-+}
-+#line 2802 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 224: /* expr ::= CASE case_operand case_exprlist case_else END */
-+#line 696 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_CASE, yymsp[-3].minor.yy242, yymsp[-1].minor.yy242, 0);
-+  if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-2].minor.yy322;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 2811 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 225: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-+#line 703 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322, yymsp[-2].minor.yy242, 0);
-+  yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
-+}
-+#line 2819 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 226: /* case_exprlist ::= WHEN expr THEN expr */
-+#line 707 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy322 = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
-+  yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
-+}
-+#line 2827 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 235: /* cmd ::= CREATE uniqueflag INDEX nm ON nm dbnm LP idxlist RP onconf */
-+#line 732 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-5].minor.yy0, &yymsp[-4].minor.yy0);
-+  if( yymsp[-9].minor.yy372!=OE_None ) yymsp[-9].minor.yy372 = yymsp[0].minor.yy372;
-+  if( yymsp[-9].minor.yy372==OE_Default) yymsp[-9].minor.yy372 = OE_Abort;
-+  sqliteCreateIndex(pParse, &yymsp[-7].minor.yy0, pSrc, yymsp[-2].minor.yy320, yymsp[-9].minor.yy372, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
-+}
-+#line 2837 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 237: /* uniqueflag ::= */
-+#line 741 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = OE_None; }
-+#line 2842 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 243: /* cmd ::= DROP INDEX nm dbnm */
-+#line 758 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteDropIndex(pParse, sqliteSrcListAppend(0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0));
-+}
-+#line 2849 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 244: /* cmd ::= COPY orconf nm dbnm FROM nm USING DELIMITERS STRING */
-+#line 766 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0),&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0,yymsp[-7].minor.yy372);}
-+#line 2854 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 245: /* cmd ::= COPY orconf nm dbnm FROM nm */
-+#line 768 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0),&yymsp[0].minor.yy0,0,yymsp[-4].minor.yy372);}
-+#line 2859 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 246: /* cmd ::= VACUUM */
-+#line 772 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteVacuum(pParse,0);}
-+#line 2864 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 247: /* cmd ::= VACUUM nm */
-+#line 773 "ext/sqlite/libsqlite/src/parse.y"
-+{sqliteVacuum(pParse,&yymsp[0].minor.yy0);}
-+#line 2869 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 248: /* cmd ::= PRAGMA ids EQ nm */
-+      case 249: /* cmd ::= PRAGMA ids EQ ON */ yytestcase(yyruleno==249);
-+      case 250: /* cmd ::= PRAGMA ids EQ plus_num */ yytestcase(yyruleno==250);
-+#line 777 "ext/sqlite/libsqlite/src/parse.y"
-+{sqlitePragma(pParse,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
-+#line 2876 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 251: /* cmd ::= PRAGMA ids EQ minus_num */
-+#line 780 "ext/sqlite/libsqlite/src/parse.y"
-+{sqlitePragma(pParse,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
-+#line 2881 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 252: /* cmd ::= PRAGMA ids LP nm RP */
-+#line 781 "ext/sqlite/libsqlite/src/parse.y"
-+{sqlitePragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
-+#line 2886 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 253: /* cmd ::= PRAGMA ids */
-+#line 782 "ext/sqlite/libsqlite/src/parse.y"
-+{sqlitePragma(pParse,&yymsp[0].minor.yy0,&yymsp[0].minor.yy0,0);}
-+#line 2891 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 260: /* cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END */
-+#line 792 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  Token all;
-+  all.z = yymsp[-4].minor.yy0.z;
-+  all.n = (yymsp[0].minor.yy0.z - yymsp[-4].minor.yy0.z) + yymsp[0].minor.yy0.n;
-+  sqliteFinishTrigger(pParse, yymsp[-1].minor.yy19, &all);
-+}
-+#line 2901 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 261: /* trigger_decl ::= temp TRIGGER nm trigger_time trigger_event ON nm dbnm foreach_clause when_clause */
-+#line 800 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  SrcList *pTab = sqliteSrcListAppend(0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0);
-+  sqliteBeginTrigger(pParse, &yymsp[-7].minor.yy0, yymsp[-6].minor.yy372, yymsp[-5].minor.yy290.a, yymsp[-5].minor.yy290.b, pTab, yymsp[-1].minor.yy372, yymsp[0].minor.yy182, yymsp[-9].minor.yy372);
-+}
-+#line 2909 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 262: /* trigger_time ::= BEFORE */
-+      case 265: /* trigger_time ::= */ yytestcase(yyruleno==265);
-+#line 806 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = TK_BEFORE; }
-+#line 2915 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 263: /* trigger_time ::= AFTER */
-+#line 807 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = TK_AFTER;  }
-+#line 2920 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 264: /* trigger_time ::= INSTEAD OF */
-+#line 808 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = TK_INSTEAD;}
-+#line 2925 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 266: /* trigger_event ::= DELETE */
-+#line 813 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy290.a = TK_DELETE; yygotominor.yy290.b = 0; }
-+#line 2930 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 267: /* trigger_event ::= INSERT */
-+#line 814 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy290.a = TK_INSERT; yygotominor.yy290.b = 0; }
-+#line 2935 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 268: /* trigger_event ::= UPDATE */
-+#line 815 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = 0;}
-+#line 2940 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 269: /* trigger_event ::= UPDATE OF inscollist */
-+#line 816 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = yymsp[0].minor.yy320; }
-+#line 2945 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 270: /* foreach_clause ::= */
-+      case 271: /* foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==271);
-+#line 819 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = TK_ROW; }
-+#line 2951 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 272: /* foreach_clause ::= FOR EACH STATEMENT */
-+#line 821 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy372 = TK_STATEMENT; }
-+#line 2956 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 273: /* when_clause ::= */
-+#line 824 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy182 = 0; }
-+#line 2961 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 274: /* when_clause ::= WHEN expr */
-+#line 825 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy182 = yymsp[0].minor.yy242; }
-+#line 2966 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 275: /* trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list */
-+#line 829 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yymsp[-2].minor.yy19->pNext = yymsp[0].minor.yy19;
-+  yygotominor.yy19 = yymsp[-2].minor.yy19;
-+}
-+#line 2974 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 276: /* trigger_cmd_list ::= */
-+#line 833 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy19 = 0; }
-+#line 2979 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 277: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
-+#line 839 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy19 = sqliteTriggerUpdateStep(&yymsp[-3].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy242, yymsp[-4].minor.yy372); }
-+#line 2984 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 278: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
-+#line 844 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-5].minor.yy0, yymsp[-4].minor.yy320, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy372);}
-+#line 2989 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 279: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
-+#line 847 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-2].minor.yy0, yymsp[-1].minor.yy320, 0, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);}
-+#line 2994 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 280: /* trigger_cmd ::= DELETE FROM nm where_opt */
-+#line 851 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy19 = sqliteTriggerDeleteStep(&yymsp[-1].minor.yy0, yymsp[0].minor.yy242);}
-+#line 2999 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 281: /* trigger_cmd ::= select */
-+#line 854 "ext/sqlite/libsqlite/src/parse.y"
-+{yygotominor.yy19 = sqliteTriggerSelectStep(yymsp[0].minor.yy179); }
-+#line 3004 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 282: /* expr ::= RAISE LP IGNORE RP */
-+#line 857 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, 0); 
-+  yygotominor.yy242->iColumn = OE_Ignore;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 3013 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 283: /* expr ::= RAISE LP ROLLBACK COMMA nm RP */
-+#line 862 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
-+  yygotominor.yy242->iColumn = OE_Rollback;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 3022 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 284: /* expr ::= RAISE LP ABORT COMMA nm RP */
-+#line 867 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
-+  yygotominor.yy242->iColumn = OE_Abort;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 3031 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 285: /* expr ::= RAISE LP FAIL COMMA nm RP */
-+#line 872 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
-+  yygotominor.yy242->iColumn = OE_Fail;
-+  sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 3040 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 286: /* cmd ::= DROP TRIGGER nm dbnm */
-+#line 879 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0));
-+}
-+#line 3047 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 287: /* cmd ::= ATTACH database_kw_opt ids AS nm key_opt */
-+#line 884 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteAttach(pParse, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);
-+}
-+#line 3054 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 289: /* key_opt ::= */
-+#line 889 "ext/sqlite/libsqlite/src/parse.y"
-+{ yygotominor.yy0.z = 0; yygotominor.yy0.n = 0; }
-+#line 3059 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      case 292: /* cmd ::= DETACH database_kw_opt nm */
-+#line 895 "ext/sqlite/libsqlite/src/parse.y"
-+{
-+  sqliteDetach(pParse, &yymsp[0].minor.yy0);
-+}
-+#line 3066 "ext/sqlite/libsqlite/src/parse.c"
-+        break;
-+      default:
-+      /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
-+      /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
-+      /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
-+      /* (3) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==3);
-+      /* (4) ecmd ::= SEMI */ yytestcase(yyruleno==4);
-+      /* (9) trans_opt ::= */ yytestcase(yyruleno==9);
-+      /* (10) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==10);
-+      /* (11) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==11);
-+      /* (15) cmd ::= create_table create_table_args */ yytestcase(yyruleno==15);
-+      /* (21) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==21);
-+      /* (22) columnlist ::= column */ yytestcase(yyruleno==22);
-+      /* (23) column ::= columnid type carglist */ yytestcase(yyruleno==23);
-+      /* (31) type ::= */ yytestcase(yyruleno==31);
-+      /* (40) carglist ::= carglist carg */ yytestcase(yyruleno==40);
-+      /* (41) carglist ::= */ yytestcase(yyruleno==41);
-+      /* (42) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==42);
-+      /* (43) carg ::= ccons */ yytestcase(yyruleno==43);
-+      /* (52) carg ::= DEFAULT NULL */ yytestcase(yyruleno==52);
-+      /* (53) ccons ::= NULL onconf */ yytestcase(yyruleno==53);
-+      /* (76) conslist_opt ::= */ yytestcase(yyruleno==76);
-+      /* (77) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==77);
-+      /* (78) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==78);
-+      /* (79) conslist ::= conslist tcons */ yytestcase(yyruleno==79);
-+      /* (80) conslist ::= tcons */ yytestcase(yyruleno==80);
-+      /* (81) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==81);
-+      /* (258) plus_opt ::= PLUS */ yytestcase(yyruleno==258);
-+      /* (259) plus_opt ::= */ yytestcase(yyruleno==259);
-+      /* (290) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==290);
-+      /* (291) database_kw_opt ::= */ yytestcase(yyruleno==291);
-+        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 */
-+){
-+  sqliteParserARG_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 */
-+  sqliteParserARG_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 */
-+){
-+  sqliteParserARG_FETCH;
-+#define TOKEN (yyminor.yy0)
-+#line 23 "ext/sqlite/libsqlite/src/parse.y"
-+
-+  if( pParse->zErrMsg==0 ){
-+    if( TOKEN.z[0] ){
-+      sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
-+    }else{
-+      sqliteErrorMsg(pParse, "incomplete SQL statement");
-+    }
-+  }
-+#line 3166 "ext/sqlite/libsqlite/src/parse.c"
-+  sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/*
-+** The following is executed when the parser accepts
-+*/
-+static void yy_accept(
-+  yyParser *yypParser           /* The parser */
-+){
-+  sqliteParserARG_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 */
-+  sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-+}
-+
-+/* The main parser program.
-+** The first argument is a pointer to a structure obtained from
-+** "sqliteParserAlloc" 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.
-+*/
-+void sqliteParser(
-+  void *yyp,                   /* The parser */
-+  int yymajor,                 /* The major token code number */
-+  sqliteParserTOKENTYPE yyminor       /* The value for the token */
-+  sqliteParserARG_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);
-+  sqliteParserARG_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;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/parse.h
-@@ -0,0 +1,130 @@
-+#define TK_END_OF_FILE                     1
-+#define TK_ILLEGAL                         2
-+#define TK_SPACE                           3
-+#define TK_UNCLOSED_STRING                 4
-+#define TK_COMMENT                         5
-+#define TK_FUNCTION                        6
-+#define TK_COLUMN                          7
-+#define TK_AGG_FUNCTION                    8
-+#define TK_SEMI                            9
-+#define TK_EXPLAIN                        10
-+#define TK_BEGIN                          11
-+#define TK_TRANSACTION                    12
-+#define TK_COMMIT                         13
-+#define TK_END                            14
-+#define TK_ROLLBACK                       15
-+#define TK_CREATE                         16
-+#define TK_TABLE                          17
-+#define TK_TEMP                           18
-+#define TK_LP                             19
-+#define TK_RP                             20
-+#define TK_AS                             21
-+#define TK_COMMA                          22
-+#define TK_ID                             23
-+#define TK_ABORT                          24
-+#define TK_AFTER                          25
-+#define TK_ASC                            26
-+#define TK_ATTACH                         27
-+#define TK_BEFORE                         28
-+#define TK_CASCADE                        29
-+#define TK_CLUSTER                        30
-+#define TK_CONFLICT                       31
-+#define TK_COPY                           32
-+#define TK_DATABASE                       33
-+#define TK_DEFERRED                       34
-+#define TK_DELIMITERS                     35
-+#define TK_DESC                           36
-+#define TK_DETACH                         37
-+#define TK_EACH                           38
-+#define TK_FAIL                           39
-+#define TK_FOR                            40
-+#define TK_GLOB                           41
-+#define TK_IGNORE                         42
-+#define TK_IMMEDIATE                      43
-+#define TK_INITIALLY                      44
-+#define TK_INSTEAD                        45
-+#define TK_LIKE                           46
-+#define TK_MATCH                          47
-+#define TK_KEY                            48
-+#define TK_OF                             49
-+#define TK_OFFSET                         50
-+#define TK_PRAGMA                         51
-+#define TK_RAISE                          52
-+#define TK_REPLACE                        53
-+#define TK_RESTRICT                       54
-+#define TK_ROW                            55
-+#define TK_STATEMENT                      56
-+#define TK_TRIGGER                        57
-+#define TK_VACUUM                         58
-+#define TK_VIEW                           59
-+#define TK_OR                             60
-+#define TK_AND                            61
-+#define TK_NOT                            62
-+#define TK_EQ                             63
-+#define TK_NE                             64
-+#define TK_ISNULL                         65
-+#define TK_NOTNULL                        66
-+#define TK_IS                             67
-+#define TK_BETWEEN                        68
-+#define TK_IN                             69
-+#define TK_GT                             70
-+#define TK_GE                             71
-+#define TK_LT                             72
-+#define TK_LE                             73
-+#define TK_BITAND                         74
-+#define TK_BITOR                          75
-+#define TK_LSHIFT                         76
-+#define TK_RSHIFT                         77
-+#define TK_PLUS                           78
-+#define TK_MINUS                          79
-+#define TK_STAR                           80
-+#define TK_SLASH                          81
-+#define TK_REM                            82
-+#define TK_CONCAT                         83
-+#define TK_UMINUS                         84
-+#define TK_UPLUS                          85
-+#define TK_BITNOT                         86
-+#define TK_STRING                         87
-+#define TK_JOIN_KW                        88
-+#define TK_INTEGER                        89
-+#define TK_CONSTRAINT                     90
-+#define TK_DEFAULT                        91
-+#define TK_FLOAT                          92
-+#define TK_NULL                           93
-+#define TK_PRIMARY                        94
-+#define TK_UNIQUE                         95
-+#define TK_CHECK                          96
-+#define TK_REFERENCES                     97
-+#define TK_COLLATE                        98
-+#define TK_ON                             99
-+#define TK_DELETE                         100
-+#define TK_UPDATE                         101
-+#define TK_INSERT                         102
-+#define TK_SET                            103
-+#define TK_DEFERRABLE                     104
-+#define TK_FOREIGN                        105
-+#define TK_DROP                           106
-+#define TK_UNION                          107
-+#define TK_ALL                            108
-+#define TK_INTERSECT                      109
-+#define TK_EXCEPT                         110
-+#define TK_SELECT                         111
-+#define TK_DISTINCT                       112
-+#define TK_DOT                            113
-+#define TK_FROM                           114
-+#define TK_JOIN                           115
-+#define TK_USING                          116
-+#define TK_ORDER                          117
-+#define TK_BY                             118
-+#define TK_GROUP                          119
-+#define TK_HAVING                         120
-+#define TK_LIMIT                          121
-+#define TK_WHERE                          122
-+#define TK_INTO                           123
-+#define TK_VALUES                         124
-+#define TK_VARIABLE                       125
-+#define TK_CASE                           126
-+#define TK_WHEN                           127
-+#define TK_THEN                           128
-+#define TK_ELSE                           129
-+#define TK_INDEX                          130
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/parse.y
-@@ -0,0 +1,897 @@
-+/*
-+** 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 SQLite's grammar for SQL.  Process this file
-+** using the lemon parser generator to generate C code that runs
-+** the parser.  Lemon will also generate a header file containing
-+** numeric codes for all of the tokens.
-+**
-+** @(#) $Id$
-+*/
-+%token_prefix TK_
-+%token_type {Token}
-+%default_type {Token}
-+%extra_argument {Parse *pParse}
-+%syntax_error {
-+  if( pParse->zErrMsg==0 ){
-+    if( TOKEN.z[0] ){
-+      sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
-+    }else{
-+      sqliteErrorMsg(pParse, "incomplete SQL statement");
-+    }
-+  }
-+}
-+%name sqliteParser
-+%include {
-+#include "sqliteInt.h"
-+#include "parse.h"
-+
-+/*
-+** An instance of this structure holds information about the
-+** LIMIT clause of a SELECT statement.
-+*/
-+struct LimitVal {
-+  int limit;    /* The LIMIT value.  -1 if there is no limit */
-+  int offset;   /* The OFFSET.  0 if there is none */
-+};
-+
-+/*
-+** 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; };
-+
-+} // end %include
-+
-+// These are extra tokens used by the lexer but never seen by the
-+// parser.  We put them in a rule so that the parser generator will
-+// add them to the parse.h output file.
-+//
-+%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
-+          COLUMN AGG_FUNCTION.
-+
-+// Input is a single SQL command
-+input ::= cmdlist.
-+cmdlist ::= cmdlist ecmd.
-+cmdlist ::= ecmd.
-+ecmd ::= explain cmdx SEMI.
-+ecmd ::= SEMI.
-+cmdx ::= cmd.           { sqliteExec(pParse); }
-+explain ::= EXPLAIN.    { sqliteBeginParse(pParse, 1); }
-+explain ::= .           { sqliteBeginParse(pParse, 0); }
-+
-+///////////////////// Begin and end transactions. ////////////////////////////
-+//
-+
-+cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
-+trans_opt ::= .
-+trans_opt ::= TRANSACTION.
-+trans_opt ::= TRANSACTION nm.
-+cmd ::= COMMIT trans_opt.      {sqliteCommitTransaction(pParse);}
-+cmd ::= END trans_opt.         {sqliteCommitTransaction(pParse);}
-+cmd ::= ROLLBACK trans_opt.    {sqliteRollbackTransaction(pParse);}
-+
-+///////////////////// The CREATE TABLE statement ////////////////////////////
-+//
-+cmd ::= create_table create_table_args.
-+create_table ::= CREATE(X) temp(T) TABLE nm(Y). {
-+   sqliteStartTable(pParse,&X,&Y,T,0);
-+}
-+%type temp {int}
-+temp(A) ::= TEMP.  {A = 1;}
-+temp(A) ::= .      {A = 0;}
-+create_table_args ::= LP columnlist conslist_opt RP(X). {
-+  sqliteEndTable(pParse,&X,0);
-+}
-+create_table_args ::= AS select(S). {
-+  sqliteEndTable(pParse,0,S);
-+  sqliteSelectDelete(S);
-+}
-+columnlist ::= columnlist COMMA column.
-+columnlist ::= column.
-+
-+// About the only information used for a column is the name of the
-+// column.  The type is always just "text".  But the code will accept
-+// an elaborate typename.  Perhaps someday we'll do something with it.
-+//
-+column ::= columnid type carglist. 
-+columnid ::= nm(X).                {sqliteAddColumn(pParse,&X);}
-+
-+// An IDENTIFIER can be a generic identifier, or one of several
-+// keywords.  Any non-standard keyword can also be an identifier.
-+//
-+%type id {Token}
-+id(A) ::= ID(X).         {A = X;}
-+
-+// The following directive causes tokens ABORT, AFTER, ASC, etc. to
-+// fallback to ID if they will not parse as their original value.
-+// This obviates the need for the "id" nonterminal.
-+//
-+%fallback ID
-+  ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT
-+  COPY DATABASE DEFERRED DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR
-+  GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
-+  OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
-+  TEMP TRIGGER VACUUM VIEW.
-+
-+// Define operator precedence early so that this is the first occurance
-+// of the operator tokens in the grammer.  Keeping the operators together
-+// causes them to be assigned integer values that are close together,
-+// which keeps parser tables smaller.
-+//
-+%left OR.
-+%left AND.
-+%right NOT.
-+%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
-+%left GT GE LT LE.
-+%left BITAND BITOR LSHIFT RSHIFT.
-+%left PLUS MINUS.
-+%left STAR SLASH REM.
-+%left CONCAT.
-+%right UMINUS UPLUS BITNOT.
-+
-+// And "ids" is an identifer-or-string.
-+//
-+%type ids {Token}
-+ids(A) ::= ID(X).        {A = X;}
-+ids(A) ::= STRING(X).    {A = X;}
-+
-+// The name of a column or table can be any of the following:
-+//
-+%type nm {Token}
-+nm(A) ::= ID(X).         {A = X;}
-+nm(A) ::= STRING(X).     {A = X;}
-+nm(A) ::= JOIN_KW(X).    {A = X;}
-+
-+type ::= .
-+type ::= typename(X).                    {sqliteAddColumnType(pParse,&X,&X);}
-+type ::= typename(X) LP signed RP(Y).    {sqliteAddColumnType(pParse,&X,&Y);}
-+type ::= typename(X) LP signed COMMA signed RP(Y).
-+                                         {sqliteAddColumnType(pParse,&X,&Y);}
-+%type typename {Token}
-+typename(A) ::= ids(X).           {A = X;}
-+typename(A) ::= typename(X) ids.  {A = X;}
-+%type signed {int}
-+signed(A) ::= INTEGER(X).         { A = atoi(X.z); }
-+signed(A) ::= PLUS INTEGER(X).    { A = atoi(X.z); }
-+signed(A) ::= MINUS INTEGER(X).   { A = -atoi(X.z); }
-+carglist ::= carglist carg.
-+carglist ::= .
-+carg ::= CONSTRAINT nm ccons.
-+carg ::= ccons.
-+carg ::= DEFAULT STRING(X).          {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT ID(X).              {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT INTEGER(X).         {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT PLUS INTEGER(X).    {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT MINUS INTEGER(X).   {sqliteAddDefaultValue(pParse,&X,1);}
-+carg ::= DEFAULT FLOAT(X).           {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT PLUS FLOAT(X).      {sqliteAddDefaultValue(pParse,&X,0);}
-+carg ::= DEFAULT MINUS FLOAT(X).     {sqliteAddDefaultValue(pParse,&X,1);}
-+carg ::= DEFAULT NULL. 
-+
-+// In addition to the type name, we also care about the primary key and
-+// UNIQUE constraints.
-+//
-+ccons ::= NULL onconf.
-+ccons ::= NOT NULL onconf(R).               {sqliteAddNotNull(pParse, R);}
-+ccons ::= PRIMARY KEY sortorder onconf(R).  {sqliteAddPrimaryKey(pParse,0,R);}
-+ccons ::= UNIQUE onconf(R).           {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
-+ccons ::= CHECK LP expr RP onconf.
-+ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
-+                                {sqliteCreateForeignKey(pParse,0,&T,TA,R);}
-+ccons ::= defer_subclause(D).   {sqliteDeferForeignKey(pParse,D);}
-+ccons ::= COLLATE id(C).  {
-+   sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
-+}
-+
-+// The next group of rules parses the arguments to a REFERENCES clause
-+// that determine if the referential integrity checking is deferred or
-+// or immediate and which determine what action to take if a ref-integ
-+// check fails.
-+//
-+%type refargs {int}
-+refargs(A) ::= .                     { A = OE_Restrict * 0x010101; }
-+refargs(A) ::= refargs(X) refarg(Y). { A = (X & Y.mask) | Y.value; }
-+%type refarg {struct {int value; int mask;}}
-+refarg(A) ::= MATCH nm.              { A.value = 0;     A.mask = 0x000000; }
-+refarg(A) ::= ON DELETE refact(X).   { A.value = X;     A.mask = 0x0000ff; }
-+refarg(A) ::= ON UPDATE refact(X).   { A.value = X<<8;  A.mask = 0x00ff00; }
-+refarg(A) ::= ON INSERT refact(X).   { A.value = X<<16; A.mask = 0xff0000; }
-+%type refact {int}
-+refact(A) ::= SET NULL.              { A = OE_SetNull; }
-+refact(A) ::= SET DEFAULT.           { A = OE_SetDflt; }
-+refact(A) ::= CASCADE.               { A = OE_Cascade; }
-+refact(A) ::= RESTRICT.              { A = OE_Restrict; }
-+%type defer_subclause {int}
-+defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt(X).  {A = X;}
-+defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
-+%type init_deferred_pred_opt {int}
-+init_deferred_pred_opt(A) ::= .                       {A = 0;}
-+init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
-+init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}
-+
-+// For the time being, the only constraint we care about is the primary
-+// key and UNIQUE.  Both create indices.
-+//
-+conslist_opt ::= .
-+conslist_opt ::= COMMA conslist.
-+conslist ::= conslist COMMA tcons.
-+conslist ::= conslist tcons.
-+conslist ::= tcons.
-+tcons ::= CONSTRAINT nm.
-+tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
-+                                             {sqliteAddPrimaryKey(pParse,X,R);}
-+tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
-+                                       {sqliteCreateIndex(pParse,0,0,X,R,0,0);}
-+tcons ::= CHECK expr onconf.
-+tcons ::= FOREIGN KEY LP idxlist(FA) RP
-+          REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
-+    sqliteCreateForeignKey(pParse, FA, &T, TA, R);
-+    sqliteDeferForeignKey(pParse, D);
-+}
-+%type defer_subclause_opt {int}
-+defer_subclause_opt(A) ::= .                    {A = 0;}
-+defer_subclause_opt(A) ::= defer_subclause(X).  {A = X;}
-+
-+// The following is a non-standard extension that allows us to declare the
-+// default behavior when there is a constraint conflict.
-+//
-+%type onconf {int}
-+%type orconf {int}
-+%type resolvetype {int}
-+onconf(A) ::= .                              { A = OE_Default; }
-+onconf(A) ::= ON CONFLICT resolvetype(X).    { A = X; }
-+orconf(A) ::= .                              { A = OE_Default; }
-+orconf(A) ::= OR resolvetype(X).             { A = X; }
-+resolvetype(A) ::= ROLLBACK.                 { A = OE_Rollback; }
-+resolvetype(A) ::= ABORT.                    { A = OE_Abort; }
-+resolvetype(A) ::= FAIL.                     { A = OE_Fail; }
-+resolvetype(A) ::= IGNORE.                   { A = OE_Ignore; }
-+resolvetype(A) ::= REPLACE.                  { A = OE_Replace; }
-+
-+////////////////////////// The DROP TABLE /////////////////////////////////////
-+//
-+cmd ::= DROP TABLE nm(X).          {sqliteDropTable(pParse,&X,0);}
-+
-+///////////////////// The CREATE VIEW statement /////////////////////////////
-+//
-+cmd ::= CREATE(X) temp(T) VIEW nm(Y) AS select(S). {
-+  sqliteCreateView(pParse, &X, &Y, S, T);
-+}
-+cmd ::= DROP VIEW nm(X). {
-+  sqliteDropTable(pParse, &X, 1);
-+}
-+
-+//////////////////////// The SELECT statement /////////////////////////////////
-+//
-+cmd ::= select(X).  {
-+  sqliteSelect(pParse, X, SRT_Callback, 0, 0, 0, 0);
-+  sqliteSelectDelete(X);
-+}
-+
-+%type select {Select*}
-+%destructor select {sqliteSelectDelete($$);}
-+%type oneselect {Select*}
-+%destructor oneselect {sqliteSelectDelete($$);}
-+
-+select(A) ::= oneselect(X).                      {A = X;}
-+select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
-+  if( Z ){
-+    Z->op = Y;
-+    Z->pPrior = X;
-+  }
-+  A = Z;
-+}
-+%type multiselect_op {int}
-+multiselect_op(A) ::= UNION.      {A = TK_UNION;}
-+multiselect_op(A) ::= UNION ALL.  {A = TK_ALL;}
-+multiselect_op(A) ::= INTERSECT.  {A = TK_INTERSECT;}
-+multiselect_op(A) ::= EXCEPT.     {A = TK_EXCEPT;}
-+oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
-+                 groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
-+  A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
-+}
-+
-+// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
-+// present and false (0) if it is not.
-+//
-+%type distinct {int}
-+distinct(A) ::= DISTINCT.   {A = 1;}
-+distinct(A) ::= ALL.        {A = 0;}
-+distinct(A) ::= .           {A = 0;}
-+
-+// selcollist is a list of expressions that are to become the return
-+// values of the SELECT statement.  The "*" in statements like
-+// "SELECT * FROM ..." is encoded as a special expression with an
-+// opcode of TK_ALL.
-+//
-+%type selcollist {ExprList*}
-+%destructor selcollist {sqliteExprListDelete($$);}
-+%type sclp {ExprList*}
-+%destructor sclp {sqliteExprListDelete($$);}
-+sclp(A) ::= selcollist(X) COMMA.             {A = X;}
-+sclp(A) ::= .                                {A = 0;}
-+selcollist(A) ::= sclp(P) expr(X) as(Y).     {
-+   A = sqliteExprListAppend(P,X,Y.n?&Y:0);
-+}
-+selcollist(A) ::= sclp(P) STAR. {
-+  A = sqliteExprListAppend(P, sqliteExpr(TK_ALL, 0, 0, 0), 0);
-+}
-+selcollist(A) ::= sclp(P) nm(X) DOT STAR. {
-+  Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
-+  Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &X);
-+  A = sqliteExprListAppend(P, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
-+}
-+
-+// An option "AS <id>" phrase that can follow one of the expressions that
-+// define the result set, or one of the tables in the FROM clause.
-+//
-+%type as {Token}
-+as(X) ::= AS nm(Y).    { X = Y; }
-+as(X) ::= ids(Y).      { X = Y; }
-+as(X) ::= .            { X.n = 0; }
-+
-+
-+%type seltablist {SrcList*}
-+%destructor seltablist {sqliteSrcListDelete($$);}
-+%type stl_prefix {SrcList*}
-+%destructor stl_prefix {sqliteSrcListDelete($$);}
-+%type from {SrcList*}
-+%destructor from {sqliteSrcListDelete($$);}
-+
-+// A complete FROM clause.
-+//
-+from(A) ::= .                                 {A = sqliteMalloc(sizeof(*A));}
-+from(A) ::= FROM seltablist(X).               {A = X;}
-+
-+// "seltablist" is a "Select Table List" - the content of the FROM clause
-+// in a SELECT statement.  "stl_prefix" is a prefix of this list.
-+//
-+stl_prefix(A) ::= seltablist(X) joinop(Y).    {
-+   A = X;
-+   if( A && A->nSrc>0 ) A->a[A->nSrc-1].jointype = Y;
-+}
-+stl_prefix(A) ::= .                           {A = 0;}
-+seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
-+  A = sqliteSrcListAppend(X,&Y,&D);
-+  if( Z.n ) sqliteSrcListAddAlias(A,&Z);
-+  if( N ){
-+    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
-+    else { sqliteExprDelete(N); }
-+  }
-+  if( U ){
-+    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
-+    else { sqliteIdListDelete(U); }
-+  }
-+}
-+seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
-+                  as(Z) on_opt(N) using_opt(U). {
-+  A = sqliteSrcListAppend(X,0,0);
-+  A->a[A->nSrc-1].pSelect = S;
-+  if( Z.n ) sqliteSrcListAddAlias(A,&Z);
-+  if( N ){
-+    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
-+    else { sqliteExprDelete(N); }
-+  }
-+  if( U ){
-+    if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
-+    else { sqliteIdListDelete(U); }
-+  }
-+}
-+
-+// A seltablist_paren nonterminal represents anything in a FROM that
-+// is contained inside parentheses.  This can be either a subquery or
-+// a grouping of table and subqueries.
-+//
-+%type seltablist_paren {Select*}
-+%destructor seltablist_paren {sqliteSelectDelete($$);}
-+seltablist_paren(A) ::= select(S).      {A = S;}
-+seltablist_paren(A) ::= seltablist(F).  {
-+   A = sqliteSelectNew(0,F,0,0,0,0,0,-1,0);
-+}
-+
-+%type dbnm {Token}
-+dbnm(A) ::= .          {A.z=0; A.n=0;}
-+dbnm(A) ::= DOT nm(X). {A = X;}
-+
-+%type joinop {int}
-+%type joinop2 {int}
-+joinop(X) ::= COMMA.                   { X = JT_INNER; }
-+joinop(X) ::= JOIN.                    { X = JT_INNER; }
-+joinop(X) ::= JOIN_KW(A) JOIN.         { X = sqliteJoinType(pParse,&A,0,0); }
-+joinop(X) ::= JOIN_KW(A) nm(B) JOIN.   { X = sqliteJoinType(pParse,&A,&B,0); }
-+joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
-+                                       { X = sqliteJoinType(pParse,&A,&B,&C); }
-+
-+%type on_opt {Expr*}
-+%destructor on_opt {sqliteExprDelete($$);}
-+on_opt(N) ::= ON expr(E).   {N = E;}
-+on_opt(N) ::= .             {N = 0;}
-+
-+%type using_opt {IdList*}
-+%destructor using_opt {sqliteIdListDelete($$);}
-+using_opt(U) ::= USING LP idxlist(L) RP.  {U = L;}
-+using_opt(U) ::= .                        {U = 0;}
-+
-+
-+%type orderby_opt {ExprList*}
-+%destructor orderby_opt {sqliteExprListDelete($$);}
-+%type sortlist {ExprList*}
-+%destructor sortlist {sqliteExprListDelete($$);}
-+%type sortitem {Expr*}
-+%destructor sortitem {sqliteExprDelete($$);}
-+
-+orderby_opt(A) ::= .                          {A = 0;}
-+orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
-+sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
-+  A = sqliteExprListAppend(X,Y,0);
-+  if( A ) A->a[A->nExpr-1].sortOrder = C+Z;
-+}
-+sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
-+  A = sqliteExprListAppend(0,Y,0);
-+  if( A ) A->a[0].sortOrder = C+Z;
-+}
-+sortitem(A) ::= expr(X).   {A = X;}
-+
-+%type sortorder {int}
-+%type collate {int}
-+
-+sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
-+sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
-+sortorder(A) ::= .              {A = SQLITE_SO_ASC;}
-+collate(C) ::= .                {C = SQLITE_SO_UNK;}
-+collate(C) ::= COLLATE id(X).   {C = sqliteCollateType(X.z, X.n);}
-+
-+%type groupby_opt {ExprList*}
-+%destructor groupby_opt {sqliteExprListDelete($$);}
-+groupby_opt(A) ::= .                      {A = 0;}
-+groupby_opt(A) ::= GROUP BY exprlist(X).  {A = X;}
-+
-+%type having_opt {Expr*}
-+%destructor having_opt {sqliteExprDelete($$);}
-+having_opt(A) ::= .                {A = 0;}
-+having_opt(A) ::= HAVING expr(X).  {A = X;}
-+
-+%type limit_opt {struct LimitVal}
-+limit_opt(A) ::= .                     {A.limit = -1; A.offset = 0;}
-+limit_opt(A) ::= LIMIT signed(X).      {A.limit = X; A.offset = 0;}
-+limit_opt(A) ::= LIMIT signed(X) OFFSET signed(Y). 
-+                                       {A.limit = X; A.offset = Y;}
-+limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y). 
-+                                       {A.limit = Y; A.offset = X;}
-+
-+/////////////////////////// The DELETE statement /////////////////////////////
-+//
-+cmd ::= DELETE FROM nm(X) dbnm(D) where_opt(Y). {
-+   sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&X,&D), Y);
-+}
-+
-+%type where_opt {Expr*}
-+%destructor where_opt {sqliteExprDelete($$);}
-+
-+where_opt(A) ::= .                    {A = 0;}
-+where_opt(A) ::= WHERE expr(X).       {A = X;}
-+
-+%type setlist {ExprList*}
-+%destructor setlist {sqliteExprListDelete($$);}
-+
-+////////////////////////// The UPDATE command ////////////////////////////////
-+//
-+cmd ::= UPDATE orconf(R) nm(X) dbnm(D) SET setlist(Y) where_opt(Z).
-+    {sqliteUpdate(pParse,sqliteSrcListAppend(0,&X,&D),Y,Z,R);}
-+
-+setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y).
-+    {A = sqliteExprListAppend(Z,Y,&X);}
-+setlist(A) ::= nm(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
-+
-+////////////////////////// The INSERT command /////////////////////////////////
-+//
-+cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F) 
-+        VALUES LP itemlist(Y) RP.
-+            {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), Y, 0, F, R);}
-+cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F) select(S).
-+            {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), 0, S, F, R);}
-+
-+%type insert_cmd {int}
-+insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
-+insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}
-+
-+
-+%type itemlist {ExprList*}
-+%destructor itemlist {sqliteExprListDelete($$);}
-+
-+itemlist(A) ::= itemlist(X) COMMA expr(Y).  {A = sqliteExprListAppend(X,Y,0);}
-+itemlist(A) ::= expr(X).                    {A = sqliteExprListAppend(0,X,0);}
-+
-+%type inscollist_opt {IdList*}
-+%destructor inscollist_opt {sqliteIdListDelete($$);}
-+%type inscollist {IdList*}
-+%destructor inscollist {sqliteIdListDelete($$);}
-+
-+inscollist_opt(A) ::= .                       {A = 0;}
-+inscollist_opt(A) ::= LP inscollist(X) RP.    {A = X;}
-+inscollist(A) ::= inscollist(X) COMMA nm(Y).  {A = sqliteIdListAppend(X,&Y);}
-+inscollist(A) ::= nm(Y).                      {A = sqliteIdListAppend(0,&Y);}
-+
-+/////////////////////////// Expression Processing /////////////////////////////
-+//
-+
-+%type expr {Expr*}
-+%destructor expr {sqliteExprDelete($$);}
-+
-+expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E); }
-+expr(A) ::= NULL(X).             {A = sqliteExpr(TK_NULL, 0, 0, &X);}
-+expr(A) ::= ID(X).               {A = sqliteExpr(TK_ID, 0, 0, &X);}
-+expr(A) ::= JOIN_KW(X).          {A = sqliteExpr(TK_ID, 0, 0, &X);}
-+expr(A) ::= nm(X) DOT nm(Y). {
-+  Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
-+  Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
-+  A = sqliteExpr(TK_DOT, temp1, temp2, 0);
-+}
-+expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
-+  Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
-+  Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
-+  Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &Z);
-+  Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
-+  A = sqliteExpr(TK_DOT, temp1, temp4, 0);
-+}
-+expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
-+expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
-+expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
-+expr(A) ::= VARIABLE(X).     {
-+  A = sqliteExpr(TK_VARIABLE, 0, 0, &X);
-+  if( A ) A->iTable = ++pParse->nVar;
-+}
-+expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
-+  A = sqliteExprFunction(Y, &X);
-+  sqliteExprSpan(A,&X,&E);
-+}
-+expr(A) ::= ID(X) LP STAR RP(E). {
-+  A = sqliteExprFunction(0, &X);
-+  sqliteExprSpan(A,&X,&E);
-+}
-+expr(A) ::= expr(X) AND expr(Y).   {A = sqliteExpr(TK_AND, X, Y, 0);}
-+expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
-+expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
-+expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
-+expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
-+expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
-+expr(A) ::= expr(X) NE expr(Y).    {A = sqliteExpr(TK_NE, X, Y, 0);}
-+expr(A) ::= expr(X) EQ expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
-+expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
-+expr(A) ::= expr(X) BITOR expr(Y).  {A = sqliteExpr(TK_BITOR, X, Y, 0);}
-+expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
-+expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
-+expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
-+  ExprList *pList = sqliteExprListAppend(0, Y, 0);
-+  pList = sqliteExprListAppend(pList, X, 0);
-+  A = sqliteExprFunction(pList, 0);
-+  if( A ) A->op = OP;
-+  sqliteExprSpan(A, &X->span, &Y->span);
-+}
-+expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
-+  ExprList *pList = sqliteExprListAppend(0, Y, 0);
-+  pList = sqliteExprListAppend(pList, X, 0);
-+  A = sqliteExprFunction(pList, 0);
-+  if( A ) A->op = OP;
-+  A = sqliteExpr(TK_NOT, A, 0, 0);
-+  sqliteExprSpan(A,&X->span,&Y->span);
-+}
-+%type likeop {int}
-+likeop(A) ::= LIKE. {A = TK_LIKE;}
-+likeop(A) ::= GLOB. {A = TK_GLOB;}
-+expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
-+expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
-+expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
-+expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
-+expr(A) ::= expr(X) REM expr(Y).   {A = sqliteExpr(TK_REM, X, Y, 0);}
-+expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
-+expr(A) ::= expr(X) ISNULL(E). {
-+  A = sqliteExpr(TK_ISNULL, X, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) IS NULL(E). {
-+  A = sqliteExpr(TK_ISNULL, X, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) NOTNULL(E). {
-+  A = sqliteExpr(TK_NOTNULL, X, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) NOT NULL(E). {
-+  A = sqliteExpr(TK_NOTNULL, X, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) IS NOT NULL(E). {
-+  A = sqliteExpr(TK_NOTNULL, X, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= NOT(B) expr(X). {
-+  A = sqliteExpr(TK_NOT, X, 0, 0);
-+  sqliteExprSpan(A,&B,&X->span);
-+}
-+expr(A) ::= BITNOT(B) expr(X). {
-+  A = sqliteExpr(TK_BITNOT, X, 0, 0);
-+  sqliteExprSpan(A,&B,&X->span);
-+}
-+expr(A) ::= MINUS(B) expr(X). [UMINUS] {
-+  A = sqliteExpr(TK_UMINUS, X, 0, 0);
-+  sqliteExprSpan(A,&B,&X->span);
-+}
-+expr(A) ::= PLUS(B) expr(X). [UPLUS] {
-+  A = sqliteExpr(TK_UPLUS, X, 0, 0);
-+  sqliteExprSpan(A,&B,&X->span);
-+}
-+expr(A) ::= LP(B) select(X) RP(E). {
-+  A = sqliteExpr(TK_SELECT, 0, 0, 0);
-+  if( A ) A->pSelect = X;
-+  sqliteExprSpan(A,&B,&E);
-+}
-+expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
-+  ExprList *pList = sqliteExprListAppend(0, X, 0);
-+  pList = sqliteExprListAppend(pList, Y, 0);
-+  A = sqliteExpr(TK_BETWEEN, W, 0, 0);
-+  if( A ) A->pList = pList;
-+  sqliteExprSpan(A,&W->span,&Y->span);
-+}
-+expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
-+  ExprList *pList = sqliteExprListAppend(0, X, 0);
-+  pList = sqliteExprListAppend(pList, Y, 0);
-+  A = sqliteExpr(TK_BETWEEN, W, 0, 0);
-+  if( A ) A->pList = pList;
-+  A = sqliteExpr(TK_NOT, A, 0, 0);
-+  sqliteExprSpan(A,&W->span,&Y->span);
-+}
-+expr(A) ::= expr(X) IN LP exprlist(Y) RP(E).  {
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pList = Y;
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) IN LP select(Y) RP(E).  {
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pSelect = Y;
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E).  {
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pList = Y;
-+  A = sqliteExpr(TK_NOT, A, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pSelect = Y;
-+  A = sqliteExpr(TK_NOT, A, 0, 0);
-+  sqliteExprSpan(A,&X->span,&E);
-+}
-+expr(A) ::= expr(X) IN nm(Y) dbnm(D). {
-+  SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
-+  sqliteExprSpan(A,&X->span,D.z?&D:&Y);
-+}
-+expr(A) ::= expr(X) NOT IN nm(Y) dbnm(D). {
-+  SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
-+  A = sqliteExpr(TK_IN, X, 0, 0);
-+  if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
-+  A = sqliteExpr(TK_NOT, A, 0, 0);
-+  sqliteExprSpan(A,&X->span,D.z?&D:&Y);
-+}
-+
-+
-+/* CASE expressions */
-+expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
-+  A = sqliteExpr(TK_CASE, X, Z, 0);
-+  if( A ) A->pList = Y;
-+  sqliteExprSpan(A, &C, &E);
-+}
-+%type case_exprlist {ExprList*}
-+%destructor case_exprlist {sqliteExprListDelete($$);}
-+case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
-+  A = sqliteExprListAppend(X, Y, 0);
-+  A = sqliteExprListAppend(A, Z, 0);
-+}
-+case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
-+  A = sqliteExprListAppend(0, Y, 0);
-+  A = sqliteExprListAppend(A, Z, 0);
-+}
-+%type case_else {Expr*}
-+case_else(A) ::=  ELSE expr(X).         {A = X;}
-+case_else(A) ::=  .                     {A = 0;} 
-+%type case_operand {Expr*}
-+case_operand(A) ::= expr(X).            {A = X;} 
-+case_operand(A) ::= .                   {A = 0;} 
-+
-+%type exprlist {ExprList*}
-+%destructor exprlist {sqliteExprListDelete($$);}
-+%type expritem {Expr*}
-+%destructor expritem {sqliteExprDelete($$);}
-+
-+exprlist(A) ::= exprlist(X) COMMA expritem(Y). 
-+   {A = sqliteExprListAppend(X,Y,0);}
-+exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
-+expritem(A) ::= expr(X).                {A = X;}
-+expritem(A) ::= .                       {A = 0;}
-+
-+///////////////////////////// The CREATE INDEX command ///////////////////////
-+//
-+cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X)
-+        ON nm(Y) dbnm(D) LP idxlist(Z) RP(E) onconf(R). {
-+  SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
-+  if( U!=OE_None ) U = R;
-+  if( U==OE_Default) U = OE_Abort;
-+  sqliteCreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
-+}
-+
-+%type uniqueflag {int}
-+uniqueflag(A) ::= UNIQUE.  { A = OE_Abort; }
-+uniqueflag(A) ::= .        { A = OE_None; }
-+
-+%type idxlist {IdList*}
-+%destructor idxlist {sqliteIdListDelete($$);}
-+%type idxlist_opt {IdList*}
-+%destructor idxlist_opt {sqliteIdListDelete($$);}
-+%type idxitem {Token}
-+
-+idxlist_opt(A) ::= .                         {A = 0;}
-+idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
-+idxlist(A) ::= idxlist(X) COMMA idxitem(Y).  {A = sqliteIdListAppend(X,&Y);}
-+idxlist(A) ::= idxitem(Y).                   {A = sqliteIdListAppend(0,&Y);}
-+idxitem(A) ::= nm(X) sortorder.              {A = X;}
-+
-+///////////////////////////// The DROP INDEX command /////////////////////////
-+//
-+
-+cmd ::= DROP INDEX nm(X) dbnm(Y).   {
-+  sqliteDropIndex(pParse, sqliteSrcListAppend(0,&X,&Y));
-+}
-+
-+
-+///////////////////////////// The COPY command ///////////////////////////////
-+//
-+cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y) USING DELIMITERS STRING(Z).
-+    {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,&Z,R);}
-+cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y).
-+    {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,0,R);}
-+
-+///////////////////////////// The VACUUM command /////////////////////////////
-+//
-+cmd ::= VACUUM.                {sqliteVacuum(pParse,0);}
-+cmd ::= VACUUM nm(X).         {sqliteVacuum(pParse,&X);}
-+
-+///////////////////////////// The PRAGMA command /////////////////////////////
-+//
-+cmd ::= PRAGMA ids(X) EQ nm(Y).         {sqlitePragma(pParse,&X,&Y,0);}
-+cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlitePragma(pParse,&X,&Y,0);}
-+cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlitePragma(pParse,&X,&Y,0);}
-+cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlitePragma(pParse,&X,&Y,1);}
-+cmd ::= PRAGMA ids(X) LP nm(Y) RP.      {sqlitePragma(pParse,&X,&Y,0);}
-+cmd ::= PRAGMA ids(X).                   {sqlitePragma(pParse,&X,&X,0);}
-+plus_num(A) ::= plus_opt number(X).   {A = X;}
-+minus_num(A) ::= MINUS number(X).     {A = X;}
-+number(A) ::= INTEGER(X).  {A = X;}
-+number(A) ::= FLOAT(X).    {A = X;}
-+plus_opt ::= PLUS.
-+plus_opt ::= .
-+
-+//////////////////////////// The CREATE TRIGGER command /////////////////////
-+
-+cmd ::= CREATE(A) trigger_decl BEGIN trigger_cmd_list(S) END(Z). {
-+  Token all;
-+  all.z = A.z;
-+  all.n = (Z.z - A.z) + Z.n;
-+  sqliteFinishTrigger(pParse, S, &all);
-+}
-+
-+trigger_decl ::= temp(T) TRIGGER nm(B) trigger_time(C) trigger_event(D)
-+                 ON nm(E) dbnm(DB) foreach_clause(F) when_clause(G). {
-+  SrcList *pTab = sqliteSrcListAppend(0, &E, &DB);
-+  sqliteBeginTrigger(pParse, &B, C, D.a, D.b, pTab, F, G, T);
-+}
-+
-+%type trigger_time  {int}
-+trigger_time(A) ::= BEFORE.      { A = TK_BEFORE; }
-+trigger_time(A) ::= AFTER.       { A = TK_AFTER;  }
-+trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
-+trigger_time(A) ::= .            { A = TK_BEFORE; }
-+
-+%type trigger_event {struct TrigEvent}
-+%destructor trigger_event {sqliteIdListDelete($$.b);}
-+trigger_event(A) ::= DELETE. { A.a = TK_DELETE; A.b = 0; }
-+trigger_event(A) ::= INSERT. { A.a = TK_INSERT; A.b = 0; }
-+trigger_event(A) ::= UPDATE. { A.a = TK_UPDATE; A.b = 0;}
-+trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X; }
-+
-+%type foreach_clause {int}
-+foreach_clause(A) ::= .                   { A = TK_ROW; }
-+foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
-+foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
-+
-+%type when_clause {Expr *}
-+when_clause(A) ::= .             { A = 0; }
-+when_clause(A) ::= WHEN expr(X). { A = X; }
-+
-+%type trigger_cmd_list {TriggerStep *}
-+%destructor trigger_cmd_list {sqliteDeleteTriggerStep($$);}
-+trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
-+  X->pNext = Y;
-+  A = X;
-+}
-+trigger_cmd_list(A) ::= . { A = 0; }
-+
-+%type trigger_cmd {TriggerStep *}
-+%destructor trigger_cmd {sqliteDeleteTriggerStep($$);}
-+// UPDATE 
-+trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).  
-+               { A = sqliteTriggerUpdateStep(&X, Y, Z, R); }
-+
-+// INSERT
-+trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) 
-+  VALUES LP itemlist(Y) RP.  
-+{A = sqliteTriggerInsertStep(&X, F, Y, 0, R);}
-+
-+trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S).
-+               {A = sqliteTriggerInsertStep(&X, F, 0, S, R);}
-+
-+// DELETE
-+trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y).
-+               {A = sqliteTriggerDeleteStep(&X, Y);}
-+
-+// SELECT
-+trigger_cmd(A) ::= select(X).  {A = sqliteTriggerSelectStep(X); }
-+
-+// The special RAISE expression that may occur in trigger programs
-+expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
-+  A = sqliteExpr(TK_RAISE, 0, 0, 0); 
-+  A->iColumn = OE_Ignore;
-+  sqliteExprSpan(A, &X, &Y);
-+}
-+expr(A) ::= RAISE(X) LP ROLLBACK COMMA nm(Z) RP(Y).  {
-+  A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
-+  A->iColumn = OE_Rollback;
-+  sqliteExprSpan(A, &X, &Y);
-+}
-+expr(A) ::= RAISE(X) LP ABORT COMMA nm(Z) RP(Y).  {
-+  A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
-+  A->iColumn = OE_Abort;
-+  sqliteExprSpan(A, &X, &Y);
-+}
-+expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y).  {
-+  A = sqliteExpr(TK_RAISE, 0, 0, &Z); 
-+  A->iColumn = OE_Fail;
-+  sqliteExprSpan(A, &X, &Y);
-+}
-+
-+////////////////////////  DROP TRIGGER statement //////////////////////////////
-+cmd ::= DROP TRIGGER nm(X) dbnm(D). {
-+  sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D));
-+}
-+
-+//////////////////////// ATTACH DATABASE file AS name /////////////////////////
-+cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
-+  sqliteAttach(pParse, &F, &D, &K);
-+}
-+%type key_opt {Token}
-+key_opt(A) ::= USING ids(X).  { A = X; }
-+key_opt(A) ::= .              { A.z = 0; A.n = 0; }
-+
-+database_kw_opt ::= DATABASE.
-+database_kw_opt ::= .
-+
-+//////////////////////// DETACH DATABASE name /////////////////////////////////
-+cmd ::= DETACH database_kw_opt nm(D). {
-+  sqliteDetach(pParse, &D);
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/pragma.c
-@@ -0,0 +1,712 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include <ctype.h>
-+
-+/*
-+** Interpret the given string as a boolean value.
-+*/
-+static int getBoolean(const char *z){
-+  static char *azTrue[] = { "yes", "on", "true" };
-+  int i;
-+  if( z[0]==0 ) return 0;
-+  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
-+    return atoi(z);
-+  }
-+  for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
-+    if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** 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 sqliteBtreeSetSafetyLevel().  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 int getSafetyLevel(char *z){
-+  static const struct {
-+    const char *zWord;
-+    int val;
-+  } aKey[] = {
-+    { "no",    0 },
-+    { "off",   0 },
-+    { "false", 0 },
-+    { "yes",   1 },
-+    { "on",    1 },
-+    { "true",  1 },
-+    { "full",  2 },
-+  };
-+  int i;
-+  if( z[0]==0 ) return 1;
-+  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
-+    return atoi(z);
-+  }
-+  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
-+    if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
-+  }
-+  return 1;
-+}
-+
-+/*
-+** 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( sqliteStrICmp(z, "file")==0 ){
-+    return 1;
-+  }else if( sqliteStrICmp(z, "memory")==0 ){
-+    return 2;
-+  }else{
-+    return 0;
-+  }
-+}
-+
-+/*
-+** If the TEMP database is open, close it and mark the database schema
-+** as needing reloading.  This must be done when using the TEMP_STORE
-+** or DEFAULT_TEMP_STORE pragmas.
-+*/
-+static int changeTempStorage(Parse *pParse, const char *zStorageType){
-+  int ts = getTempStore(zStorageType);
-+  sqlite *db = pParse->db;
-+  if( db->temp_store==ts ) return SQLITE_OK;
-+  if( db->aDb[1].pBt!=0 ){
-+    if( db->flags & SQLITE_InTrans ){
-+      sqliteErrorMsg(pParse, "temporary storage cannot be changed "
-+        "from within a transaction");
-+      return SQLITE_ERROR;
-+    }
-+    sqliteBtreeClose(db->aDb[1].pBt);
-+    db->aDb[1].pBt = 0;
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+  db->temp_store = ts;
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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 {
-+    const char *zName;  /* Name of the pragma */
-+    int mask;           /* Mask for the db->flags value */
-+  } aPragma[] = {
-+    { "vdbe_trace",               SQLITE_VdbeTrace     },
-+    { "full_column_names",        SQLITE_FullColNames  },
-+    { "short_column_names",       SQLITE_ShortColNames },
-+    { "show_datatypes",           SQLITE_ReportTypes   },
-+    { "count_changes",            SQLITE_CountRows     },
-+    { "empty_result_callbacks",   SQLITE_NullCallback  },
-+  };
-+  int i;
-+  for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
-+    if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
-+      sqlite *db = pParse->db;
-+      Vdbe *v;
-+      if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
-+        sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
-+        sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
-+        sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
-+                          OP_Callback, 1, 0,
-+                          0);
-+      }else if( getBoolean(zRight) ){
-+        db->flags |= aPragma[i].mask;
-+      }else{
-+        db->flags &= ~aPragma[i].mask;
-+      }
-+      return 1;
-+    }
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Process a pragma statement.  
-+**
-+** Pragmas are of this form:
-+**
-+**      PRAGMA 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.
-+*/
-+void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
-+  char *zLeft = 0;
-+  char *zRight = 0;
-+  sqlite *db = pParse->db;
-+  Vdbe *v = sqliteGetVdbe(pParse);
-+  if( v==0 ) return;
-+
-+  zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
-+  sqliteDequote(zLeft);
-+  if( minusFlag ){
-+    zRight = 0;
-+    sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
-+  }else{
-+    zRight = sqliteStrNDup(pRight->z, pRight->n);
-+    sqliteDequote(zRight);
-+  }
-+  if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
-+    sqliteFree(zLeft);
-+    sqliteFree(zRight);
-+    return;
-+  }
-+ 
-+  /*
-+  **  PRAGMA default_cache_size
-+  **  PRAGMA 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( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
-+    static VdbeOpList getCacheSize[] = {
-+      { OP_ReadCookie,  0, 2,        0},
-+      { OP_AbsValue,    0, 0,        0},
-+      { OP_Dup,         0, 0,        0},
-+      { OP_Integer,     0, 0,        0},
-+      { OP_Ne,          0, 6,        0},
-+      { OP_Integer,     0, 0,        0},  /* 5 */
-+      { OP_ColumnName,  0, 1,        "cache_size"},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+    int addr;
-+    if( pRight->z==pLeft->z ){
-+      addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
-+      sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
-+    }else{
-+      int size = atoi(zRight);
-+      if( size<0 ) size = -size;
-+      sqliteBeginWriteOperation(pParse, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Integer, size, 0);
-+      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
-+      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
-+      sqliteVdbeAddOp(v, OP_Negative, 0, 0);
-+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
-+      sqliteEndWriteOperation(pParse);
-+      db->cache_size = db->cache_size<0 ? -size : size;
-+      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-+    }
-+  }else
-+
-+  /*
-+  **  PRAGMA cache_size
-+  **  PRAGMA 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( sqliteStrICmp(zLeft,"cache_size")==0 ){
-+    static VdbeOpList getCacheSize[] = {
-+      { OP_ColumnName,  0, 1,        "cache_size"},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+    if( pRight->z==pLeft->z ){
-+      int size = db->cache_size;;
-+      if( size<0 ) size = -size;
-+      sqliteVdbeAddOp(v, OP_Integer, size, 0);
-+      sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
-+    }else{
-+      int size = atoi(zRight);
-+      if( size<0 ) size = -size;
-+      if( db->cache_size<0 ) size = -size;
-+      db->cache_size = size;
-+      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-+    }
-+  }else
-+
-+  /*
-+  **  PRAGMA default_synchronous
-+  **  PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
-+  **
-+  ** The first form returns the persistent value of the "synchronous" setting
-+  ** that is stored in the database.  This is the synchronous setting that
-+  ** is used whenever the database is opened unless overridden by a separate
-+  ** "synchronous" pragma.  The second form changes the persistent and the
-+  ** local synchronous setting to the value given.
-+  **
-+  ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
-+  ** to make sure data is committed to disk.  Write operations are very fast,
-+  ** but a power failure can leave the database in an inconsistent state.
-+  ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
-+  ** make sure data is being written to disk.  The risk of corruption due to
-+  ** a power loss in this mode is negligible but non-zero.  If synchronous
-+  ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
-+  ** zero, but with a write performance penalty.  The default mode is NORMAL.
-+  */
-+  if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
-+    static VdbeOpList getSync[] = {
-+      { OP_ColumnName,  0, 1,        "synchronous"},
-+      { OP_ReadCookie,  0, 3,        0},
-+      { OP_Dup,         0, 0,        0},
-+      { OP_If,          0, 0,        0},  /* 3 */
-+      { OP_ReadCookie,  0, 2,        0},
-+      { OP_Integer,     0, 0,        0},
-+      { OP_Lt,          0, 5,        0},
-+      { OP_AddImm,      1, 0,        0},
-+      { OP_Callback,    1, 0,        0},
-+      { OP_Halt,        0, 0,        0},
-+      { OP_AddImm,     -1, 0,        0},  /* 10 */
-+      { OP_Callback,    1, 0,        0}
-+    };
-+    if( pRight->z==pLeft->z ){
-+      int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
-+      sqliteVdbeChangeP2(v, addr+3, addr+10);
-+    }else{
-+      int addr;
-+      int size = db->cache_size;
-+      if( size<0 ) size = -size;
-+      sqliteBeginWriteOperation(pParse, 0, 0);
-+      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
-+      sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
-+      sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
-+      db->safety_level = getSafetyLevel(zRight)+1;
-+      if( db->safety_level==1 ){
-+        sqliteVdbeAddOp(v, OP_Negative, 0, 0);
-+        size = -size;
-+      }
-+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
-+      sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
-+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
-+      sqliteEndWriteOperation(pParse);
-+      db->cache_size = size;
-+      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-+      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
-+    }
-+  }else
-+
-+  /*
-+  **   PRAGMA synchronous
-+  **   PRAGMA 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( sqliteStrICmp(zLeft,"synchronous")==0 ){
-+    static VdbeOpList getSync[] = {
-+      { OP_ColumnName,  0, 1,        "synchronous"},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+    if( pRight->z==pLeft->z ){
-+      sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
-+      sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
-+    }else{
-+      int size = db->cache_size;
-+      if( size<0 ) size = -size;
-+      db->safety_level = getSafetyLevel(zRight)+1;
-+      if( db->safety_level==1 ) size = -size;
-+      db->cache_size = size;
-+      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-+      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
-+    }
-+  }else
-+
-+#ifndef NDEBUG
-+  if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
-+    if( getBoolean(zRight) ){
-+      always_code_trigger_setup = 1;
-+    }else{
-+      always_code_trigger_setup = 0;
-+    }
-+  }else
-+#endif
-+
-+  if( flagPragma(pParse, zLeft, zRight) ){
-+    /* The flagPragma() call also generates any necessary code */
-+  }else
-+
-+  if( sqliteStrICmp(zLeft, "table_info")==0 ){
-+    Table *pTab;
-+    pTab = sqliteFindTable(db, zRight, 0);
-+    if( pTab ){
-+      static VdbeOpList tableInfoPreface[] = {
-+        { OP_ColumnName,  0, 0,       "cid"},
-+        { OP_ColumnName,  1, 0,       "name"},
-+        { OP_ColumnName,  2, 0,       "type"},
-+        { OP_ColumnName,  3, 0,       "notnull"},
-+        { OP_ColumnName,  4, 0,       "dflt_value"},
-+        { OP_ColumnName,  5, 1,       "pk"},
-+      };
-+      int i;
-+      sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
-+      sqliteViewGetColumnNames(pParse, pTab);
-+      for(i=0; i<pTab->nCol; i++){
-+        sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
-+        sqliteVdbeOp3(v, OP_String, 0, 0,
-+           pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
-+        sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
-+        sqliteVdbeOp3(v, OP_String, 0, 0,
-+           pTab->aCol[i].zDflt, P3_STATIC);
-+        sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
-+        sqliteVdbeAddOp(v, OP_Callback, 6, 0);
-+      }
-+    }
-+  }else
-+
-+  if( sqliteStrICmp(zLeft, "index_info")==0 ){
-+    Index *pIdx;
-+    Table *pTab;
-+    pIdx = sqliteFindIndex(db, zRight, 0);
-+    if( pIdx ){
-+      static VdbeOpList tableInfoPreface[] = {
-+        { OP_ColumnName,  0, 0,       "seqno"},
-+        { OP_ColumnName,  1, 0,       "cid"},
-+        { OP_ColumnName,  2, 1,       "name"},
-+      };
-+      int i;
-+      pTab = pIdx->pTable;
-+      sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
-+      for(i=0; i<pIdx->nColumn; i++){
-+        int cnum = pIdx->aiColumn[i];
-+        sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+        sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
-+        assert( pTab->nCol>cnum );
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
-+        sqliteVdbeAddOp(v, OP_Callback, 3, 0);
-+      }
-+    }
-+  }else
-+
-+  if( sqliteStrICmp(zLeft, "index_list")==0 ){
-+    Index *pIdx;
-+    Table *pTab;
-+    pTab = sqliteFindTable(db, zRight, 0);
-+    if( pTab ){
-+      v = sqliteGetVdbe(pParse);
-+      pIdx = pTab->pIndex;
-+    }
-+    if( pTab && pIdx ){
-+      int i = 0; 
-+      static VdbeOpList indexListPreface[] = {
-+        { OP_ColumnName,  0, 0,       "seq"},
-+        { OP_ColumnName,  1, 0,       "name"},
-+        { OP_ColumnName,  2, 1,       "unique"},
-+      };
-+
-+      sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
-+      while(pIdx){
-+        sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+        sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
-+        sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
-+        sqliteVdbeAddOp(v, OP_Callback, 3, 0);
-+        ++i;
-+        pIdx = pIdx->pNext;
-+      }
-+    }
-+  }else
-+
-+  if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
-+    FKey *pFK;
-+    Table *pTab;
-+    pTab = sqliteFindTable(db, zRight, 0);
-+    if( pTab ){
-+      v = sqliteGetVdbe(pParse);
-+      pFK = pTab->pFKey;
-+    }
-+    if( pTab && pFK ){
-+      int i = 0; 
-+      static VdbeOpList indexListPreface[] = {
-+        { OP_ColumnName,  0, 0,       "id"},
-+        { OP_ColumnName,  1, 0,       "seq"},
-+        { OP_ColumnName,  2, 0,       "table"},
-+        { OP_ColumnName,  3, 0,       "from"},
-+        { OP_ColumnName,  4, 1,       "to"},
-+      };
-+
-+      sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
-+      while(pFK){
-+        int j;
-+        for(j=0; j<pFK->nCol; j++){
-+          sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+          sqliteVdbeAddOp(v, OP_Integer, j, 0);
-+          sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
-+          sqliteVdbeOp3(v, OP_String, 0, 0,
-+                           pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
-+          sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
-+          sqliteVdbeAddOp(v, OP_Callback, 5, 0);
-+        }
-+        ++i;
-+        pFK = pFK->pNextFrom;
-+      }
-+    }
-+  }else
-+
-+  if( sqliteStrICmp(zLeft, "database_list")==0 ){
-+    int i;
-+    static VdbeOpList indexListPreface[] = {
-+      { OP_ColumnName,  0, 0,       "seq"},
-+      { OP_ColumnName,  1, 0,       "name"},
-+      { OP_ColumnName,  2, 1,       "file"},
-+    };
-+
-+    sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
-+    for(i=0; i<db->nDb; i++){
-+      if( db->aDb[i].pBt==0 ) continue;
-+      assert( db->aDb[i].zName!=0 );
-+      sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+      sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
-+      sqliteVdbeOp3(v, OP_String, 0, 0,
-+           sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
-+      sqliteVdbeAddOp(v, OP_Callback, 3, 0);
-+    }
-+  }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( sqliteStrICmp(zLeft, "temp_store")==0 ){
-+    static VdbeOpList getTmpDbLoc[] = {
-+      { OP_ColumnName,  0, 1,        "temp_store"},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+    if( pRight->z==pLeft->z ){
-+      sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
-+      sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
-+    }else{
-+      changeTempStorage(pParse, zRight);
-+    }
-+  }else
-+
-+  /*
-+  **   PRAGMA default_temp_store
-+  **   PRAGMA default_temp_store = "default"|"memory"|"file"
-+  **
-+  ** Return or set the value of the persistent temp_store flag.  Any
-+  ** change does not take effect until the next time the database is
-+  ** opened.
-+  **
-+  ** Note that it is possible for the library compile-time options to
-+  ** override this setting
-+  */
-+  if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
-+    static VdbeOpList getTmpDbLoc[] = {
-+      { OP_ColumnName,  0, 1,        "temp_store"},
-+      { OP_ReadCookie,  0, 5,        0},
-+      { OP_Callback,    1, 0,        0}};
-+    if( pRight->z==pLeft->z ){
-+      sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
-+    }else{
-+      sqliteBeginWriteOperation(pParse, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
-+      sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
-+      sqliteEndWriteOperation(pParse);
-+    }
-+  }else
-+
-+#ifndef NDEBUG
-+  if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
-+    extern void sqliteParserTrace(FILE*, char *);
-+    if( getBoolean(zRight) ){
-+      sqliteParserTrace(stdout, "parser: ");
-+    }else{
-+      sqliteParserTrace(0, 0);
-+    }
-+  }else
-+#endif
-+
-+  if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
-+    int i, j, addr;
-+
-+    /* Code that initializes the integrity check program.  Set the
-+    ** error count 0
-+    */
-+    static VdbeOpList initCode[] = {
-+      { OP_Integer,     0, 0,        0},
-+      { OP_MemStore,    0, 1,        0},
-+      { OP_ColumnName,  0, 1,        "integrity_check"},
-+    };
-+
-+    /* Code to do an BTree integrity check on a single database file.
-+    */
-+    static VdbeOpList checkDb[] = {
-+      { OP_SetInsert,   0, 0,        "2"},
-+      { OP_Integer,     0, 0,        0},    /* 1 */
-+      { OP_OpenRead,    0, 2,        0},
-+      { OP_Rewind,      0, 7,        0},    /* 3 */
-+      { OP_Column,      0, 3,        0},    /* 4 */
-+      { OP_SetInsert,   0, 0,        0},
-+      { OP_Next,        0, 4,        0},    /* 6 */
-+      { OP_IntegrityCk, 0, 0,        0},    /* 7 */
-+      { OP_Dup,         0, 1,        0},
-+      { OP_String,      0, 0,        "ok"},
-+      { OP_StrEq,       0, 12,       0},    /* 10 */
-+      { OP_MemIncr,     0, 0,        0},
-+      { OP_String,      0, 0,        "*** in database "},
-+      { OP_String,      0, 0,        0},    /* 13 */
-+      { OP_String,      0, 0,        " ***\n"},
-+      { OP_Pull,        3, 0,        0},
-+      { OP_Concat,      4, 1,        0},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+
-+    /* 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 VdbeOpList endCode[] = {
-+      { OP_MemLoad,     0, 0,        0},
-+      { OP_Integer,     0, 0,        0},
-+      { OP_Ne,          0, 0,        0},    /* 2 */
-+      { OP_String,      0, 0,        "ok"},
-+      { OP_Callback,    1, 0,        0},
-+    };
-+
-+    /* Initialize the VDBE program */
-+    sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
-+
-+    /* Do an integrity check on each database file */
-+    for(i=0; i<db->nDb; i++){
-+      HashElem *x;
-+
-+      /* Do an integrity check of the B-Tree
-+      */
-+      addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
-+      sqliteVdbeChangeP1(v, addr+1, i);
-+      sqliteVdbeChangeP2(v, addr+3, addr+7);
-+      sqliteVdbeChangeP2(v, addr+6, addr+4);
-+      sqliteVdbeChangeP2(v, addr+7, i);
-+      sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
-+      sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
-+
-+      /* Make sure all the indices are constructed correctly.
-+      */
-+      sqliteCodeVerifySchema(pParse, i);
-+      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
-+        Table *pTab = sqliteHashData(x);
-+        Index *pIdx;
-+        int loopTop;
-+
-+        if( pTab->pIndex==0 ) continue;
-+        sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+        sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
-+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-+          if( pIdx->tnum==0 ) continue;
-+          sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
-+          sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
-+        }
-+        sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+        sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
-+        loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
-+        sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
-+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-+          int k, jmp2;
-+          static VdbeOpList idxErr[] = {
-+            { OP_MemIncr,     0,  0,  0},
-+            { OP_String,      0,  0,  "rowid "},
-+            { OP_Recno,       1,  0,  0},
-+            { OP_String,      0,  0,  " missing from index "},
-+            { OP_String,      0,  0,  0},    /* 4 */
-+            { OP_Concat,      4,  0,  0},
-+            { OP_Callback,    1,  0,  0},
-+          };
-+          sqliteVdbeAddOp(v, OP_Recno, 1, 0);
-+          for(k=0; k<pIdx->nColumn; k++){
-+            int idx = pIdx->aiColumn[k];
-+            if( idx==pTab->iPKey ){
-+              sqliteVdbeAddOp(v, OP_Recno, 1, 0);
-+            }else{
-+              sqliteVdbeAddOp(v, OP_Column, 1, idx);
-+            }
-+          }
-+          sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
-+          if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
-+          jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
-+          addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
-+          sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
-+          sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
-+        }
-+        sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
-+        sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
-+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-+          static VdbeOpList cntIdx[] = {
-+             { OP_Integer,      0,  0,  0},
-+             { OP_MemStore,     2,  1,  0},
-+             { OP_Rewind,       0,  0,  0},  /* 2 */
-+             { OP_MemIncr,      2,  0,  0},
-+             { OP_Next,         0,  0,  0},  /* 4 */
-+             { OP_MemLoad,      1,  0,  0},
-+             { OP_MemLoad,      2,  0,  0},
-+             { OP_Eq,           0,  0,  0},  /* 7 */
-+             { OP_MemIncr,      0,  0,  0},
-+             { OP_String,       0,  0,  "wrong # of entries in index "},
-+             { OP_String,       0,  0,  0},  /* 10 */
-+             { OP_Concat,       2,  0,  0},
-+             { OP_Callback,     1,  0,  0},
-+          };
-+          if( pIdx->tnum==0 ) continue;
-+          addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
-+          sqliteVdbeChangeP1(v, addr+2, j+2);
-+          sqliteVdbeChangeP2(v, addr+2, addr+5);
-+          sqliteVdbeChangeP1(v, addr+4, j+2);
-+          sqliteVdbeChangeP2(v, addr+4, addr+3);
-+          sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
-+          sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
-+        }
-+      } 
-+    }
-+    addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
-+    sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
-+  }else
-+
-+  {}
-+  sqliteFree(zLeft);
-+  sqliteFree(zRight);
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/printf.c
-@@ -0,0 +1,858 @@
-+/*
-+** 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().
-+**
-+**************************************************************************
-+**
-+** 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.
-+**
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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 */
-+#define etERROR      10 /* Used to indicate no such conversion type */
-+/* The rest are extensions, not normally found in printf() */
-+#define etCHARLIT    11 /* Literal characters.  %' */
-+#define etSQLESCAPE  12 /* Strings with '\'' doubled.  %q */
-+#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
-+                          NULL pointers replaced by SQL NULL.  %Q */
-+#define etTOKEN      14 /* a pointer to a Token structure */
-+#define etSRCLIST    15 /* a pointer to a SrcList */
-+
-+
-+/*
-+** 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 */
-+  char *charset;           /* The character set for conversion */
-+  char *prefix;            /* Prefix on non-zero values in alt format */
-+} 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 */
-+
-+
-+/*
-+** The following table is searched linearly, so it is good to put the
-+** most frequently used conversion types first.
-+*/
-+static et_info fmtinfo[] = {
-+  {  'd', 10, 1, etRADIX,      "0123456789",       0    },
-+  {  's',  0, 0, etSTRING,     0,                  0    },
-+  {  'z',  0, 2, etDYNSTRING,  0,                  0    },
-+  {  'q',  0, 0, etSQLESCAPE,  0,                  0    },
-+  {  'Q',  0, 0, etSQLESCAPE2, 0,                  0    },
-+  {  'c',  0, 0, etCHARX,      0,                  0    },
-+  {  'o',  8, 0, etRADIX,      "01234567",         "0"  },
-+  {  'u', 10, 0, etRADIX,      "0123456789",       0    },
-+  {  'x', 16, 0, etRADIX,      "0123456789abcdef", "x0" },
-+  {  'X', 16, 0, etRADIX,      "0123456789ABCDEF", "X0" },
-+  {  'f',  0, 1, etFLOAT,      0,                  0    },
-+  {  'e',  0, 1, etEXP,        "e",                0    },
-+  {  'E',  0, 1, etEXP,        "E",                0    },
-+  {  'g',  0, 1, etGENERIC,    "e",                0    },
-+  {  'G',  0, 1, etGENERIC,    "E",                0    },
-+  {  'i', 10, 1, etRADIX,      "0123456789",       0    },
-+  {  'n',  0, 0, etSIZE,       0,                  0    },
-+  {  '%',  0, 0, etPERCENT,    0,                  0    },
-+  {  'p', 10, 0, etRADIX,      "0123456789",       0    },
-+  {  'T',  0, 2, etTOKEN,      0,                  0    },
-+  {  'S',  0, 2, etSRCLIST,    0,                  0    },
-+};
-+#define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
-+
-+/*
-+** If NOFLOATINGPOINT is defined, then none of the floating point
-+** conversions will work.
-+*/
-+#ifndef etNOFLOATINGPOINT
-+/*
-+** "*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 int 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 digit;
-+}
-+#endif
-+
-+#define etBUFSIZE 1000  /* 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.
-+*/
-+static int vxprintf(
-+  void (*func)(void*,const char*,int),     /* Consumer of text */
-+  void *arg,                         /* First argument to the consumer */
-+  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 count;                 /* Total number of characters output */
-+  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_zeropad;       /* True if field width constant starts with zero */
-+  etByte flag_long;          /* True if "l" flag is present */
-+  unsigned long longvalue;   /* Value for integer types */
-+  LONGDOUBLE_TYPE realvalue; /* Value for real types */
-+  et_info *infop;            /* Pointer to the appropriate info structure */
-+  char buf[etBUFSIZE];       /* Conversion buffer */
-+  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
-+  etByte errorflag = 0;      /* True if an error is encountered */
-+  etByte xtype;              /* Conversion paradigm */
-+  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
-+  static char spaces[] = "                                                  ";
-+#define etSPACESIZE (sizeof(spaces)-1)
-+#ifndef etNOFLOATINGPOINT
-+  int  exp;                  /* 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
-+
-+  func(arg,"",0);
-+  count = length = 0;
-+  bufpt = 0;
-+  for(; (c=(*fmt))!=0; ++fmt){
-+    if( c!='%' ){
-+      int amt;
-+      bufpt = (char *)fmt;
-+      amt = 1;
-+      while( (c=(*++fmt))!='%' && c!=0 ) amt++;
-+      (*func)(arg,bufpt,amt);
-+      count += amt;
-+      if( c==0 ) break;
-+    }
-+    if( (c=(*++fmt))==0 ){
-+      errorflag = 1;
-+      (*func)(arg,"%",1);
-+      count++;
-+      break;
-+    }
-+    /* Find out what flags are present */
-+    flag_leftjustify = flag_plussign = flag_blanksign = 
-+     flag_alternateform = flag_zeropad = 0;
-+    do{
-+      switch( c ){
-+        case '-':   flag_leftjustify = 1;     c = 0;   break;
-+        case '+':   flag_plussign = 1;        c = 0;   break;
-+        case ' ':   flag_blanksign = 1;       c = 0;   break;
-+        case '#':   flag_alternateform = 1;   c = 0;   break;
-+        case '0':   flag_zeropad = 1;         c = 0;   break;
-+        default:                                       break;
-+      }
-+    }while( c==0 && (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;
-+        }
-+      }
-+      /* Limit the precision to prevent overflowing buf[] during conversion */
-+      if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
-+    }else{
-+      precision = -1;
-+    }
-+    /* Get the conversion type modifier */
-+    if( c=='l' ){
-+      flag_long = 1;
-+      c = *++fmt;
-+    }else{
-+      flag_long = 0;
-+    }
-+    /* Fetch the info entry for the field */
-+    infop = 0;
-+    xtype = etERROR;
-+    for(idx=0; idx<etNINFO; idx++){
-+      if( c==fmtinfo[idx].fmttype ){
-+        infop = &fmtinfo[idx];
-+        if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
-+          xtype = infop->type;
-+        }
-+        break;
-+      }
-+    }
-+    zExtra = 0;
-+
-+    /*
-+    ** At this point, variables are initialized as follows:
-+    **
-+    **   flag_alternateform          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_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 etRADIX:
-+        if( flag_long )  longvalue = va_arg(ap,long);
-+        else             longvalue = va_arg(ap,int);
-+#if 1
-+        /* For the format %#x, the value zero is printed "0" not "0x0".
-+        ** I think this is stupid. */
-+        if( longvalue==0 ) flag_alternateform = 0;
-+#else
-+        /* More sensible: turn off the prefix for octal (to prevent "00"),
-+        ** but leave the prefix for hex. */
-+        if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
-+#endif
-+        if( infop->flags & FLAG_SIGNED ){
-+          if( *(long*)&longvalue<0 ){
-+            longvalue = -*(long*)&longvalue;
-+            prefix = '-';
-+          }else if( flag_plussign )  prefix = '+';
-+          else if( flag_blanksign )  prefix = ' ';
-+          else                       prefix = 0;
-+        }else                        prefix = 0;
-+        if( flag_zeropad && precision<width-(prefix!=0) ){
-+          precision = width-(prefix!=0);
-+        }
-+        bufpt = &buf[etBUFSIZE-1];
-+        {
-+          register char *cset;      /* Use registers for speed */
-+          register int base;
-+          cset = infop->charset;
-+          base = infop->base;
-+          do{                                           /* Convert to ascii */
-+            *(--bufpt) = cset[longvalue%base];
-+            longvalue = longvalue/base;
-+          }while( longvalue>0 );
-+        }
-+        length = &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" */
-+          char *pre, x;
-+          pre = infop->prefix;
-+          if( *bufpt!=pre[0] ){
-+            for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
-+          }
-+        }
-+        length = &buf[etBUFSIZE-1]-bufpt;
-+        break;
-+      case etFLOAT:
-+      case etEXP:
-+      case etGENERIC:
-+        realvalue = va_arg(ap,double);
-+#ifndef etNOFLOATINGPOINT
-+        if( precision<0 ) precision = 6;         /* Set default precision */
-+        if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
-+        if( realvalue<0.0 ){
-+          realvalue = -realvalue;
-+          prefix = '-';
-+        }else{
-+          if( flag_plussign )          prefix = '+';
-+          else if( flag_blanksign )    prefix = ' ';
-+          else                         prefix = 0;
-+        }
-+        if( infop->type==etGENERIC && precision>0 ) precision--;
-+        rounder = 0.0;
-+#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( infop->type==etFLOAT ) realvalue += rounder;
-+        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
-+        exp = 0;
-+        if( realvalue>0.0 ){
-+          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
-+          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
-+          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
-+          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
-+          if( exp>350 || exp<-350 ){
-+            bufpt = "NaN";
-+            length = 3;
-+            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;
-+        }
-+        /*
-+        ** The "exp+precision" test causes output to be of type etEXP if
-+        ** the precision is too large to fit in buf[].
-+        */
-+        nsd = 0;
-+        if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
-+          flag_dp = (precision>0 || flag_alternateform);
-+          if( prefix ) *(bufpt++) = prefix;         /* Sign */
-+          if( exp<0 )  *(bufpt++) = '0';            /* Digits before "." */
-+          else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
-+          if( flag_dp ) *(bufpt++) = '.';           /* The decimal point */
-+          for(exp++; exp<0 && precision>0; precision--, exp++){
-+            *(bufpt++) = '0';
-+          }
-+          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
-+          *(bufpt--) = 0;                           /* Null terminate */
-+          if( flag_rtz && flag_dp ){     /* Remove trailing zeros and "." */
-+            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
-+            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
-+          }
-+          bufpt++;                            /* point to next free slot */
-+        }else{    /* etEXP or etGENERIC */
-+          flag_dp = (precision>0 || flag_alternateform);
-+          if( prefix ) *(bufpt++) = prefix;   /* Sign */
-+          *(bufpt++) = et_getdigit(&realvalue,&nsd);  /* First digit */
-+          if( flag_dp ) *(bufpt++) = '.';     /* Decimal point */
-+          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
-+          bufpt--;                            /* point to last digit */
-+          if( flag_rtz && flag_dp ){          /* Remove tail zeros */
-+            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
-+            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
-+          }
-+          bufpt++;                            /* point to next free slot */
-+          if( exp || flag_exp ){
-+            *(bufpt++) = infop->charset[0];
-+            if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
-+            else       { *(bufpt++) = '+'; }
-+            if( exp>=100 ){
-+              *(bufpt++) = (exp/100)+'0';                /* 100's digit */
-+              exp %= 100;
-+            }
-+            *(bufpt++) = exp/10+'0';                     /* 10's digit */
-+            *(bufpt++) = exp%10+'0';                     /* 1's digit */
-+          }
-+        }
-+        /* 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 = 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*)) = count;
-+        length = width = 0;
-+        break;
-+      case etPERCENT:
-+        buf[0] = '%';
-+        bufpt = buf;
-+        length = 1;
-+        break;
-+      case etCHARLIT:
-+      case etCHARX:
-+        c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
-+        if( precision>=0 ){
-+          for(idx=1; idx<precision; idx++) buf[idx] = 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;
-+        }
-+        length = strlen(bufpt);
-+        if( precision>=0 && precision<length ) length = precision;
-+        break;
-+      case etSQLESCAPE:
-+      case etSQLESCAPE2:
-+        {
-+          int i, j, n, c, isnull;
-+          char *arg = va_arg(ap,char*);
-+          isnull = arg==0;
-+          if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
-+          for(i=n=0; (c=arg[i])!=0; i++){
-+            if( c=='\'' )  n++;
-+          }
-+          n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0);
-+          if( n>etBUFSIZE ){
-+            bufpt = zExtra = sqliteMalloc( n );
-+            if( bufpt==0 ) return -1;
-+          }else{
-+            bufpt = buf;
-+          }
-+          j = 0;
-+          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
-+          for(i=0; (c=arg[i])!=0; i++){
-+            bufpt[j++] = c;
-+            if( c=='\'' ) bufpt[j++] = c;
-+          }
-+          if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\'';
-+          bufpt[j] = 0;
-+          length = j;
-+          if( precision>=0 && precision<length ) length = precision;
-+        }
-+        break;
-+      case etTOKEN: {
-+        Token *pToken = va_arg(ap, Token*);
-+        (*func)(arg, 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 && pItem->zDatabase[0] ){
-+          (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
-+          (*func)(arg, ".", 1);
-+        }
-+        (*func)(arg, pItem->zName, strlen(pItem->zName));
-+        length = width = 0;
-+        break;
-+      }
-+      case etERROR:
-+        buf[0] = '%';
-+        buf[1] = c;
-+        errorflag = 0;
-+        idx = 1+(c!=0);
-+        (*func)(arg,"%",idx);
-+        count += idx;
-+        if( c==0 ) fmt--;
-+        break;
-+    }/* 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 ){
-+        count += nspace;
-+        while( nspace>=etSPACESIZE ){
-+          (*func)(arg,spaces,etSPACESIZE);
-+          nspace -= etSPACESIZE;
-+        }
-+        if( nspace>0 ) (*func)(arg,spaces,nspace);
-+      }
-+    }
-+    if( length>0 ){
-+      (*func)(arg,bufpt,length);
-+      count += length;
-+    }
-+    if( flag_leftjustify ){
-+      register int nspace;
-+      nspace = width-length;
-+      if( nspace>0 ){
-+        count += nspace;
-+        while( nspace>=etSPACESIZE ){
-+          (*func)(arg,spaces,etSPACESIZE);
-+          nspace -= etSPACESIZE;
-+        }
-+        if( nspace>0 ) (*func)(arg,spaces,nspace);
-+      }
-+    }
-+    if( zExtra ){
-+      sqliteFree(zExtra);
-+    }
-+  }/* End for loop over the format string */
-+  return errorflag ? -1 : count;
-+} /* End of function */
-+
-+
-+/* This structure is used to store state information about the
-+** write to memory that is currently in progress.
-+*/
-+struct sgMprintf {
-+  char *zBase;     /* A base allocation */
-+  char *zText;     /* The string collected so far */
-+  int  nChar;      /* Length of the string so far */
-+  int  nTotal;     /* Output size if unconstrained */
-+  int  nAlloc;     /* Amount of space allocated in zText */
-+  void *(*xRealloc)(void*,int);  /* Function used to realloc memory */
-+};
-+
-+/* 
-+** This function implements the callback from vxprintf. 
-+**
-+** This routine add nNewChar characters of text in zNewText to
-+** the sgMprintf structure pointed to by "arg".
-+*/
-+static void mout(void *arg, const char *zNewText, int nNewChar){
-+  struct sgMprintf *pM = (struct sgMprintf*)arg;
-+  pM->nTotal += nNewChar;
-+  if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
-+    if( pM->xRealloc==0 ){
-+      nNewChar =  pM->nAlloc - pM->nChar - 1;
-+    }else{
-+      pM->nAlloc = pM->nChar + nNewChar*2 + 1;
-+      if( pM->zText==pM->zBase ){
-+        pM->zText = pM->xRealloc(0, pM->nAlloc);
-+        if( pM->zText && pM->nChar ){
-+          memcpy(pM->zText, pM->zBase, pM->nChar);
-+        }
-+      }else{
-+        pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
-+      }
-+    }
-+  }
-+  if( pM->zText ){
-+    if( nNewChar>0 ){
-+      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
-+      pM->nChar += nNewChar;
-+    }
-+    pM->zText[pM->nChar] = 0;
-+  }
-+}
-+
-+/*
-+** This routine is a wrapper around xprintf() that invokes mout() as
-+** the consumer.  
-+*/
-+static char *base_vprintf(
-+  void *(*xRealloc)(void*,int),   /* Routine to realloc memory. May be NULL */
-+  int useInternal,                /* Use internal %-conversions if true */
-+  char *zInitBuf,                 /* Initially write here, before mallocing */
-+  int nInitBuf,                   /* Size of zInitBuf[] */
-+  const char *zFormat,            /* format string */
-+  va_list ap                      /* arguments */
-+){
-+  struct sgMprintf sM;
-+  sM.zBase = sM.zText = zInitBuf;
-+  sM.nChar = sM.nTotal = 0;
-+  sM.nAlloc = nInitBuf;
-+  sM.xRealloc = xRealloc;
-+  vxprintf(mout, &sM, useInternal, zFormat, ap);
-+  if( xRealloc ){
-+    if( sM.zText==sM.zBase ){
-+      sM.zText = xRealloc(0, sM.nChar+1);
-+      memcpy(sM.zText, sM.zBase, sM.nChar+1);
-+    }else if( sM.nAlloc>sM.nChar+10 ){
-+      sM.zText = xRealloc(sM.zText, sM.nChar+1);
-+    }
-+  }
-+  return sM.zText;
-+}
-+
-+/*
-+** Realloc that is a real function, not a macro.
-+*/
-+static void *printf_realloc(void *old, int size){
-+  return sqliteRealloc(old,size);
-+}
-+
-+/*
-+** Print into memory obtained from sqliteMalloc().  Use the internal
-+** %-conversion extensions.
-+*/
-+char *sqliteVMPrintf(const char *zFormat, va_list ap){
-+  char zBase[1000];
-+  return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
-+}
-+
-+/*
-+** Print into memory obtained from sqliteMalloc().  Use the internal
-+** %-conversion extensions.
-+*/
-+char *sqliteMPrintf(const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
-+  char zBase[1000];
-+  va_start(ap, zFormat);
-+  z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
-+
-+/*
-+** Print into memory obtained from malloc().  Do not use the internal
-+** %-conversion extensions.  This routine is for use by external users.
-+*/
-+char *sqlite_mprintf(const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
-+  char zBuf[200];
-+
-+  va_start(ap,zFormat);
-+  z = base_vprintf((void*(*)(void*,int))realloc, 0, 
-+                   zBuf, sizeof(zBuf), zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
-+
-+/* This is the varargs version of sqlite_mprintf.  
-+*/
-+char *sqlite_vmprintf(const char *zFormat, va_list ap){
-+  char zBuf[200];
-+  return base_vprintf((void*(*)(void*,int))realloc, 0,
-+                      zBuf, sizeof(zBuf), zFormat, ap);
-+}
-+
-+/*
-+** sqlite_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.
-+*/
-+char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
-+  char *z;
-+  va_list ap;
-+
-+  va_start(ap,zFormat);
-+  z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
-+
-+/*
-+** The following four routines implement the varargs versions of the
-+** sqlite_exec() and sqlite_get_table() interfaces.  See the sqlite.h
-+** header files for a more detailed description of how these interfaces
-+** work.
-+**
-+** These routines are all just simple wrappers.
-+*/
-+int sqlite_exec_printf(
-+  sqlite *db,                   /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback xCallback,    /* Callback function */
-+  void *pArg,                   /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  ...                           /* Arguments to the format string. */
-+){
-+  va_list ap;
-+  int rc;
-+
-+  va_start(ap, errmsg);
-+  rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap);
-+  va_end(ap);
-+  return rc;
-+}
-+int sqlite_exec_vprintf(
-+  sqlite *db,                   /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback xCallback,    /* Callback function */
-+  void *pArg,                   /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  va_list ap                    /* Arguments to the format string. */
-+){
-+  char *zSql;
-+  int rc;
-+
-+  zSql = sqlite_vmprintf(sqlFormat, ap);
-+  rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg);
-+  free(zSql);
-+  return rc;
-+}
-+int sqlite_get_table_printf(
-+  sqlite *db,            /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncol,             /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  ...                    /* Arguments to the format string */
-+){
-+  va_list ap;
-+  int rc;
-+
-+  va_start(ap, errmsg);
-+  rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap);
-+  va_end(ap);
-+  return rc;
-+}
-+int sqlite_get_table_vprintf(
-+  sqlite *db,            /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  va_list ap             /* Arguments to the format string */
-+){
-+  char *zSql;
-+  int rc;
-+
-+  zSql = sqlite_vmprintf(sqlFormat, ap);
-+  rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);
-+  free(zSql);
-+  return rc;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/random.c
-@@ -0,0 +1,97 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+
-+
-+/*
-+** 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_NewRecno 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.
-+*/
-+static int randomByte(){
-+  unsigned char t;
-+
-+  /* All threads share a single random number generator.
-+  ** This structure is the current state of the generator.
-+  */
-+  static struct {
-+    unsigned char isInit;          /* True if initialized */
-+    unsigned char i, j;            /* State variables */
-+    unsigned char s[256];          /* State variables */
-+  } prng;
-+
-+  /* 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( !prng.isInit ){
-+    int i;
-+    char k[256];
-+    prng.j = 0;
-+    prng.i = 0;
-+    sqliteOsRandomSeed(k);
-+    for(i=0; i<256; i++){
-+      prng.s[i] = i;
-+    }
-+    for(i=0; i<256; i++){
-+      prng.j += prng.s[i] + k[i];
-+      t = prng.s[prng.j];
-+      prng.s[prng.j] = prng.s[i];
-+      prng.s[i] = t;
-+    }
-+    prng.isInit = 1;
-+  }
-+
-+  /* Generate and return single random byte
-+  */
-+  prng.i++;
-+  t = prng.s[prng.i];
-+  prng.j += t;
-+  prng.s[prng.i] = prng.s[prng.j];
-+  prng.s[prng.j] = t;
-+  t += prng.s[prng.i];
-+  return prng.s[t];
-+}
-+
-+/*
-+** Return N random bytes.
-+*/
-+void sqliteRandomness(int N, void *pBuf){
-+  unsigned char *zBuf = pBuf;
-+  sqliteOsEnterMutex();
-+  while( N-- ){
-+    *(zBuf++) = randomByte();
-+  }
-+  sqliteOsLeaveMutex();
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/select.c
-@@ -0,0 +1,2434 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+
-+
-+/*
-+** Allocate a new Select structure and return a pointer to that
-+** structure.
-+*/
-+Select *sqliteSelectNew(
-+  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 */
-+  int nLimit,           /* LIMIT value.  -1 means not used */
-+  int nOffset           /* OFFSET value.  0 means no offset */
-+){
-+  Select *pNew;
-+  pNew = sqliteMalloc( sizeof(*pNew) );
-+  if( pNew==0 ){
-+    sqliteExprListDelete(pEList);
-+    sqliteSrcListDelete(pSrc);
-+    sqliteExprDelete(pWhere);
-+    sqliteExprListDelete(pGroupBy);
-+    sqliteExprDelete(pHaving);
-+    sqliteExprListDelete(pOrderBy);
-+  }else{
-+    if( pEList==0 ){
-+      pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL,0,0,0), 0);
-+    }
-+    pNew->pEList = pEList;
-+    pNew->pSrc = pSrc;
-+    pNew->pWhere = pWhere;
-+    pNew->pGroupBy = pGroupBy;
-+    pNew->pHaving = pHaving;
-+    pNew->pOrderBy = pOrderBy;
-+    pNew->isDistinct = isDistinct;
-+    pNew->op = TK_SELECT;
-+    pNew->nLimit = nLimit;
-+    pNew->nOffset = nOffset;
-+    pNew->iLimit = -1;
-+    pNew->iOffset = -1;
-+  }
-+  return pNew;
-+}
-+
-+/*
-+** 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_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.
-+*/
-+int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
-+  int jointype = 0;
-+  Token *apAll[3];
-+  Token *p;
-+  static struct {
-+    const char *zKeyword;
-+    int nChar;
-+    int code;
-+  } keywords[] = {
-+    { "natural", 7, JT_NATURAL },
-+    { "left",    4, JT_LEFT|JT_OUTER },
-+    { "right",   5, JT_RIGHT|JT_OUTER },
-+    { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
-+    { "outer",   5, JT_OUTER },
-+    { "inner",   5, JT_INNER },
-+    { "cross",   5, JT_INNER },
-+  };
-+  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<sizeof(keywords)/sizeof(keywords[0]); j++){
-+      if( p->n==keywords[j].nChar 
-+          && sqliteStrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
-+        jointype |= keywords[j].code;
-+        break;
-+      }
-+    }
-+    if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
-+      jointype |= JT_ERROR;
-+      break;
-+    }
-+  }
-+  if(
-+     (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
-+     (jointype & JT_ERROR)!=0
-+  ){
-+    static Token dummy = { 0, 0 };
-+    char *zSp1 = " ", *zSp2 = " ";
-+    if( pB==0 ){ pB = &dummy; zSp1 = 0; }
-+    if( pC==0 ){ pC = &dummy; zSp2 = 0; }
-+    sqliteSetNString(&pParse->zErrMsg, "unknown or unsupported join type: ", 0,
-+       pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
-+    pParse->nErr++;
-+    jointype = JT_INNER;
-+  }else if( jointype & JT_RIGHT ){
-+    sqliteErrorMsg(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( sqliteStrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
-+  }
-+  return -1;
-+}
-+
-+/*
-+** 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(
-+  const char *zCol,        /* Name of the column */
-+  const Table *pTab1,      /* First table */
-+  const Table *pTab2,      /* Second table */
-+  Expr **ppExpr            /* Add the equality term to this expression */
-+){
-+  Token dummy;
-+  Expr *pE1a, *pE1b, *pE1c;
-+  Expr *pE2a, *pE2b, *pE2c;
-+  Expr *pE;
-+
-+  dummy.z = zCol;
-+  dummy.n = strlen(zCol);
-+  dummy.dyn = 0;
-+  pE1a = sqliteExpr(TK_ID, 0, 0, &dummy);
-+  pE2a = sqliteExpr(TK_ID, 0, 0, &dummy);
-+  dummy.z = pTab1->zName;
-+  dummy.n = strlen(dummy.z);
-+  pE1b = sqliteExpr(TK_ID, 0, 0, &dummy);
-+  dummy.z = pTab2->zName;
-+  dummy.n = strlen(dummy.z);
-+  pE2b = sqliteExpr(TK_ID, 0, 0, &dummy);
-+  pE1c = sqliteExpr(TK_DOT, pE1b, pE1a, 0);
-+  pE2c = sqliteExpr(TK_DOT, pE2b, pE2a, 0);
-+  pE = sqliteExpr(TK_EQ, pE1c, pE2c, 0);
-+  ExprSetProperty(pE, EP_FromJoin);
-+  if( *ppExpr ){
-+    *ppExpr = sqliteExpr(TK_AND, *ppExpr, pE, 0);
-+  }else{
-+    *ppExpr = pE;
-+  }
-+}
-+
-+/*
-+** Set the EP_FromJoin property on all terms of the given 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.
-+*/
-+static void setJoinExpr(Expr *p){
-+  while( p ){
-+    ExprSetProperty(p, EP_FromJoin);
-+    setJoinExpr(p->pLeft);
-+    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.
-+**
-+** This routine returns the number of errors encountered.
-+*/
-+static int sqliteProcessJoin(Parse *pParse, Select *p){
-+  SrcList *pSrc;
-+  int i, j;
-+  pSrc = p->pSrc;
-+  for(i=0; i<pSrc->nSrc-1; i++){
-+    struct SrcList_item *pTerm = &pSrc->a[i];
-+    struct SrcList_item *pOther = &pSrc->a[i+1];
-+
-+    if( pTerm->pTab==0 || pOther->pTab==0 ) continue;
-+
-+    /* When the NATURAL keyword is present, add WHERE clause terms for
-+    ** every column that the two tables have in common.
-+    */
-+    if( pTerm->jointype & JT_NATURAL ){
-+      Table *pTab;
-+      if( pTerm->pOn || pTerm->pUsing ){
-+        sqliteErrorMsg(pParse, "a NATURAL join may not have "
-+           "an ON or USING clause", 0);
-+        return 1;
-+      }
-+      pTab = pTerm->pTab;
-+      for(j=0; j<pTab->nCol; j++){
-+        if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
-+          addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
-+        }
-+      }
-+    }
-+
-+    /* Disallow both ON and USING clauses in the same join
-+    */
-+    if( pTerm->pOn && pTerm->pUsing ){
-+      sqliteErrorMsg(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
-+    ** and AND operator.
-+    */
-+    if( pTerm->pOn ){
-+      setJoinExpr(pTerm->pOn);
-+      if( p->pWhere==0 ){
-+        p->pWhere = pTerm->pOn;
-+      }else{
-+        p->pWhere = sqliteExpr(TK_AND, p->pWhere, pTerm->pOn, 0);
-+      }
-+      pTerm->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( pTerm->pUsing ){
-+      IdList *pList;
-+      int j;
-+      assert( i<pSrc->nSrc-1 );
-+      pList = pTerm->pUsing;
-+      for(j=0; j<pList->nId; j++){
-+        if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
-+            columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
-+          sqliteErrorMsg(pParse, "cannot join using column %s - column "
-+            "not present in both tables", pList->a[j].zName);
-+          return 1;
-+        }
-+        addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
-+      }
-+    }
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Delete the given Select structure and all of its substructures.
-+*/
-+void sqliteSelectDelete(Select *p){
-+  if( p==0 ) return;
-+  sqliteExprListDelete(p->pEList);
-+  sqliteSrcListDelete(p->pSrc);
-+  sqliteExprDelete(p->pWhere);
-+  sqliteExprListDelete(p->pGroupBy);
-+  sqliteExprDelete(p->pHaving);
-+  sqliteExprListDelete(p->pOrderBy);
-+  sqliteSelectDelete(p->pPrior);
-+  sqliteFree(p->zSelect);
-+  sqliteFree(p);
-+}
-+
-+/*
-+** Delete the aggregate information from the parse structure.
-+*/
-+static void sqliteAggregateInfoReset(Parse *pParse){
-+  sqliteFree(pParse->aAgg);
-+  pParse->aAgg = 0;
-+  pParse->nAgg = 0;
-+  pParse->useAgg = 0;
-+}
-+
-+/*
-+** Insert code into "v" that will push the record on the top of the
-+** stack into the sorter.
-+*/
-+static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
-+  char *zSortOrder;
-+  int i;
-+  zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
-+  if( zSortOrder==0 ) return;
-+  for(i=0; i<pOrderBy->nExpr; i++){
-+    int order = pOrderBy->a[i].sortOrder;
-+    int type;
-+    int c;
-+    if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){
-+      type = SQLITE_SO_TEXT;
-+    }else if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_NUM ){
-+      type = SQLITE_SO_NUM;
-+    }else if( pParse->db->file_format>=4 ){
-+      type = sqliteExprType(pOrderBy->a[i].pExpr);
-+    }else{
-+      type = SQLITE_SO_NUM;
-+    }
-+    if( (order & SQLITE_SO_DIRMASK)==SQLITE_SO_ASC ){
-+      c = type==SQLITE_SO_TEXT ? 'A' : '+';
-+    }else{
-+      c = type==SQLITE_SO_TEXT ? 'D' : '-';
-+    }
-+    zSortOrder[i] = c;
-+    sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
-+  }
-+  zSortOrder[pOrderBy->nExpr] = 0;
-+  sqliteVdbeOp3(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, P3_DYNAMIC);
-+  sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
-+}
-+
-+/*
-+** This routine adds a P3 argument to the last VDBE opcode that was
-+** inserted. The P3 argument added is a string suitable for the 
-+** OP_MakeKey or OP_MakeIdxKey opcodes.  The string consists of
-+** characters 't' or 'n' depending on whether or not the various
-+** fields of the key to be generated should be treated as numeric
-+** or as text.  See the OP_MakeKey and OP_MakeIdxKey opcode
-+** documentation for additional information about the P3 string.
-+** See also the sqliteAddIdxKeyType() routine.
-+*/
-+void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
-+  int nColumn = pEList->nExpr;
-+  char *zType = sqliteMalloc( nColumn+1 );
-+  int i;
-+  if( zType==0 ) return;
-+  for(i=0; i<nColumn; i++){
-+    zType[i] = sqliteExprType(pEList->a[i].pExpr)==SQLITE_SO_NUM ? 'n' : 't';
-+  }
-+  zType[i] = 0;
-+  sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
-+}
-+
-+/*
-+** Add code to implement the OFFSET and LIMIT
-+*/
-+static void codeLimiter(
-+  Vdbe *v,          /* Generate code into this VM */
-+  Select *p,        /* The SELECT statement being coded */
-+  int iContinue,    /* Jump here to skip the current record */
-+  int iBreak,       /* Jump here to end the loop */
-+  int nPop          /* Number of times to pop stack when jumping */
-+){
-+  if( p->iOffset>=0 ){
-+    int addr = sqliteVdbeCurrentAddr(v) + 2;
-+    if( nPop>0 ) addr++;
-+    sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
-+    if( nPop>0 ){
-+      sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
-+    }
-+    sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
-+  }
-+  if( p->iLimit>=0 ){
-+    sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
-+  }
-+}
-+
-+/*
-+** 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 int 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 */
-+  int eDest,              /* How to dispose of the results */
-+  int iParm,              /* An argument to the disposal method */
-+  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 */
-+
-+  if( v==0 ) return 0;
-+  assert( pEList!=0 );
-+
-+  /* If there was a LIMIT clause on the SELECT statement, then do the check
-+  ** to see if this row should be output.
-+  */
-+  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
-+  if( pOrderBy==0 && !hasDistinct ){
-+    codeLimiter(v, p, iContinue, iBreak, 0);
-+  }
-+
-+  /* Pull the requested columns.
-+  */
-+  if( nColumn>0 ){
-+    for(i=0; i<nColumn; i++){
-+      sqliteVdbeAddOp(v, OP_Column, srcTab, i);
-+    }
-+  }else{
-+    nColumn = pEList->nExpr;
-+    for(i=0; i<pEList->nExpr; i++){
-+      sqliteExprCode(pParse, pEList->a[i].pExpr);
-+    }
-+  }
-+
-+  /* 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 ){
-+#if NULL_ALWAYS_DISTINCT
-+    sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
-+#endif
-+    sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
-+    if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pEList);
-+    sqliteVdbeAddOp(v, OP_Distinct, distinct, sqliteVdbeCurrentAddr(v)+3);
-+    sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
-+    sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
-+    sqliteVdbeAddOp(v, OP_String, 0, 0);
-+    sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
-+    if( pOrderBy==0 ){
-+      codeLimiter(v, p, iContinue, iBreak, nColumn);
-+    }
-+  }
-+
-+  switch( eDest ){
-+    /* In this mode, write each query result to the key of the temporary
-+    ** table iParm.
-+    */
-+    case SRT_Union: {
-+      sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
-+      break;
-+    }
-+
-+    /* Store the result as data using a unique key.
-+    */
-+    case SRT_Table:
-+    case SRT_TempTable: {
-+      sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
-+      if( pOrderBy ){
-+        pushOntoSorter(pParse, v, pOrderBy);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
-+        sqliteVdbeAddOp(v, OP_Pull, 1, 0);
-+        sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
-+      }
-+      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: {
-+      int addr;
-+      addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
-+      sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3);
-+      sqliteVdbeAddOp(v, OP_Delete, iParm, 0);
-+      break;
-+    }
-+
-+    /* 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 addr1 = sqliteVdbeCurrentAddr(v);
-+      int addr2;
-+      assert( nColumn==1 );
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, addr1+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      addr2 = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
-+      if( pOrderBy ){
-+        pushOntoSorter(pParse, v, pOrderBy);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+        sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
-+      }
-+      sqliteVdbeChangeP2(v, addr2, sqliteVdbeCurrentAddr(v));
-+      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, v, pOrderBy);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, iBreak);
-+      }
-+      break;
-+    }
-+
-+    /* Send the data to the callback function.
-+    */
-+    case SRT_Callback:
-+    case SRT_Sorter: {
-+      if( pOrderBy ){
-+        sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
-+        pushOntoSorter(pParse, v, pOrderBy);
-+      }else{
-+        assert( eDest==SRT_Callback );
-+        sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
-+      }
-+      break;
-+    }
-+
-+    /* Invoke a subroutine to handle the results.  The subroutine itself
-+    ** is responsible for popping the results off of the stack.
-+    */
-+    case SRT_Subroutine: {
-+      if( pOrderBy ){
-+        sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
-+        pushOntoSorter(pParse, v, pOrderBy);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
-+      }
-+      break;
-+    }
-+
-+    /* 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 );
-+      sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
-+      break;
-+    }
-+  }
-+  return 0;
-+}
-+
-+/*
-+** 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(
-+  Select *p,       /* The SELECT statement */
-+  Vdbe *v,         /* Generate code into this VDBE */
-+  int nColumn,     /* Number of columns of data */
-+  int eDest,       /* Write the sorted results here */
-+  int iParm        /* Optional parameter associated with eDest */
-+){
-+  int end1 = sqliteVdbeMakeLabel(v);
-+  int end2 = sqliteVdbeMakeLabel(v);
-+  int addr;
-+  if( eDest==SRT_Sorter ) return;
-+  sqliteVdbeAddOp(v, OP_Sort, 0, 0);
-+  addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
-+  codeLimiter(v, p, addr, end2, 1);
-+  switch( eDest ){
-+    case SRT_Callback: {
-+      sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
-+      break;
-+    }
-+    case SRT_Table:
-+    case SRT_TempTable: {
-+      sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
-+      sqliteVdbeAddOp(v, OP_Pull, 1, 0);
-+      sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
-+      break;
-+    }
-+    case SRT_Set: {
-+      assert( nColumn==1 );
-+      sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, sqliteVdbeCurrentAddr(v)+3);
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
-+      break;
-+    }
-+    case SRT_Mem: {
-+      assert( nColumn==1 );
-+      sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, end1);
-+      break;
-+    }
-+    case SRT_Subroutine: {
-+      int i;
-+      for(i=0; i<nColumn; i++){
-+        sqliteVdbeAddOp(v, OP_Column, -1-i, i);
-+      }
-+      sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
-+      sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+      break;
-+    }
-+    default: {
-+      /* Do nothing */
-+      break;
-+    }
-+  }
-+  sqliteVdbeAddOp(v, OP_Goto, 0, addr);
-+  sqliteVdbeResolveLabel(v, end2);
-+  sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-+  sqliteVdbeResolveLabel(v, end1);
-+  sqliteVdbeAddOp(v, OP_SortReset, 0, 0);
-+}
-+
-+/*
-+** Generate code that will tell the VDBE the datatypes of
-+** columns in the result set.
-+**
-+** This routine only generates code if the "PRAGMA show_datatypes=on"
-+** has been executed.  The datatypes are reported out in the azCol
-+** parameter to the callback function.  The first N azCol[] entries
-+** are the names of the columns, and the second N entries are the
-+** datatypes for the columns.
-+**
-+** The "datatype" for a result that is a column of a type is the
-+** datatype definition extracted from the CREATE TABLE statement.
-+** The datatype for an expression is either TEXT or NUMERIC.  The
-+** datatype for a ROWID field is INTEGER.
-+*/
-+static void generateColumnTypes(
-+  Parse *pParse,      /* Parser context */
-+  SrcList *pTabList,  /* List of tables */
-+  ExprList *pEList    /* Expressions defining the result set */
-+){
-+  Vdbe *v = pParse->pVdbe;
-+  int i, j;
-+  for(i=0; i<pEList->nExpr; i++){
-+    Expr *p = pEList->a[i].pExpr;
-+    char *zType = 0;
-+    if( p==0 ) continue;
-+    if( p->op==TK_COLUMN && pTabList ){
-+      Table *pTab;
-+      int iCol = p->iColumn;
-+      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
-+      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 ){
-+        zType = "INTEGER";
-+      }else{
-+        zType = pTab->aCol[iCol].zType;
-+      }
-+    }else{
-+      if( sqliteExprType(p)==SQLITE_SO_TEXT ){
-+        zType = "TEXT";
-+      }else{
-+        zType = "NUMERIC";
-+      }
-+    }
-+    sqliteVdbeOp3(v, OP_ColumnName, i + pEList->nExpr, 0, zType, 0);
-+  }
-+}
-+
-+/*
-+** Generate code that will tell the VDBE the names of columns
-+** in the result set.  This information is used to provide the
-+** azCol[] values in the callback.
-+*/
-+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;
-+  sqlite *db = pParse->db;
-+  int fullNames, shortNames;
-+
-+  assert( v!=0 );
-+  if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
-+  pParse->colNamesSet = 1;
-+  fullNames = (db->flags & SQLITE_FullColNames)!=0;
-+  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
-+  for(i=0; i<pEList->nExpr; i++){
-+    Expr *p;
-+    int p2 = i==pEList->nExpr-1;
-+    p = pEList->a[i].pExpr;
-+    if( p==0 ) continue;
-+    if( pEList->a[i].zName ){
-+      char *zName = pEList->a[i].zName;
-+      sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
-+      continue;
-+    }
-+    if( p->op==TK_COLUMN && pTabList ){
-+      Table *pTab;
-+      char *zCol;
-+      int iCol = p->iColumn;
-+      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
-+      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 && p->span.z && p->span.z[0] ){
-+        int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
-+        sqliteVdbeCompressSpace(v, addr);
-+      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
-+        char *zName = 0;
-+        char *zTab;
-+ 
-+        zTab = pTabList->a[j].zAlias;
-+        if( fullNames || zTab==0 ) zTab = pTab->zName;
-+        sqliteSetString(&zName, zTab, ".", zCol, 0);
-+        sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, P3_DYNAMIC);
-+      }else{
-+        sqliteVdbeOp3(v, OP_ColumnName, i, p2, zCol, 0);
-+      }
-+    }else if( p->span.z && p->span.z[0] ){
-+      int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
-+      sqliteVdbeCompressSpace(v, addr);
-+    }else{
-+      char zName[30];
-+      assert( p->op!=TK_COLUMN || pTabList==0 );
-+      sprintf(zName, "column%d", i+1);
-+      sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
-+    }
-+  }
-+}
-+
-+/*
-+** 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;
-+}
-+
-+/*
-+** Forward declaration
-+*/
-+static int fillInColumnList(Parse*, Select*);
-+
-+/*
-+** Given a SELECT statement, generate a Table structure that describes
-+** the result set of that SELECT.
-+*/
-+Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
-+  Table *pTab;
-+  int i, j;
-+  ExprList *pEList;
-+  Column *aCol;
-+
-+  if( fillInColumnList(pParse, pSelect) ){
-+    return 0;
-+  }
-+  pTab = sqliteMalloc( sizeof(Table) );
-+  if( pTab==0 ){
-+    return 0;
-+  }
-+  pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
-+  pEList = pSelect->pEList;
-+  pTab->nCol = pEList->nExpr;
-+  assert( pTab->nCol>0 );
-+  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
-+  for(i=0; i<pTab->nCol; i++){
-+    Expr *p, *pR;
-+    if( pEList->a[i].zName ){
-+      aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
-+    }else if( (p=pEList->a[i].pExpr)->op==TK_DOT 
-+               && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
-+      int cnt;
-+      sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, 0);
-+      for(j=cnt=0; j<i; j++){
-+        if( sqliteStrICmp(aCol[j].zName, aCol[i].zName)==0 ){
-+          int n;
-+          char zBuf[30];
-+          sprintf(zBuf,"_%d",++cnt);
-+          n = strlen(zBuf);
-+          sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, zBuf, n,0);
-+          j = -1;
-+        }
-+      }
-+    }else if( p->span.z && p->span.z[0] ){
-+      sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
-+    }else{
-+      char zBuf[30];
-+      sprintf(zBuf, "column%d", i+1);
-+      aCol[i].zName = sqliteStrDup(zBuf);
-+    }
-+    sqliteDequote(aCol[i].zName);
-+  }
-+  pTab->iPKey = -1;
-+  return pTab;
-+}
-+
-+/*
-+** For the given SELECT statement, do three things.
-+**
-+**    (1)  Fill in the pTabList->a[].pTab fields in the SrcList that 
-+**         defines the set of tables that should be scanned.  For views,
-+**         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.
-+**
-+**    (2)  Add terms to the WHERE clause to accomodate the NATURAL keyword
-+**         on joins and the ON and USING clause of joins.
-+**
-+**    (3)  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.
-+**
-+** Return 0 on success.  If there are problems, leave an error message
-+** in pParse and return non-zero.
-+*/
-+static int fillInColumnList(Parse *pParse, Select *p){
-+  int i, j, k, rc;
-+  SrcList *pTabList;
-+  ExprList *pEList;
-+  Table *pTab;
-+
-+  if( p==0 || p->pSrc==0 ) return 1;
-+  pTabList = p->pSrc;
-+  pEList = p->pEList;
-+
-+  /* Look up every table in the table list.
-+  */
-+  for(i=0; i<pTabList->nSrc; i++){
-+    if( pTabList->a[i].pTab ){
-+      /* This routine has run before!  No need to continue */
-+      return 0;
-+    }
-+    if( pTabList->a[i].zName==0 ){
-+      /* A sub-query in the FROM clause of a SELECT */
-+      assert( pTabList->a[i].pSelect!=0 );
-+      if( pTabList->a[i].zAlias==0 ){
-+        char zFakeName[60];
-+        sprintf(zFakeName, "sqlite_subquery_%p_",
-+           (void*)pTabList->a[i].pSelect);
-+        sqliteSetString(&pTabList->a[i].zAlias, zFakeName, 0);
-+      }
-+      pTabList->a[i].pTab = pTab = 
-+        sqliteResultSetOfSelect(pParse, pTabList->a[i].zAlias,
-+                                        pTabList->a[i].pSelect);
-+      if( pTab==0 ){
-+        return 1;
-+      }
-+      /* The isTransient flag indicates that the Table structure has been
-+      ** dynamically allocated and may be freed at any time.  In other words,
-+      ** pTab is not pointing to a persistent table structure that defines
-+      ** part of the schema. */
-+      pTab->isTransient = 1;
-+    }else{
-+      /* An ordinary table or view name in the FROM clause */
-+      pTabList->a[i].pTab = pTab = 
-+        sqliteLocateTable(pParse,pTabList->a[i].zName,pTabList->a[i].zDatabase);
-+      if( pTab==0 ){
-+        return 1;
-+      }
-+      if( pTab->pSelect ){
-+        /* We reach here if the named table is a really a view */
-+        if( sqliteViewGetColumnNames(pParse, pTab) ){
-+          return 1;
-+        }
-+        /* If pTabList->a[i].pSelect!=0 it means we are dealing with a
-+        ** view within a view.  The SELECT structure has already been
-+        ** copied by the outer view so we can skip the copy step here
-+        ** in the inner view.
-+        */
-+        if( pTabList->a[i].pSelect==0 ){
-+          pTabList->a[i].pSelect = sqliteSelectDup(pTab->pSelect);
-+        }
-+      }
-+    }
-+  }
-+
-+  /* Process NATURAL keywords, and ON and USING clauses of joins.
-+  */
-+  if( sqliteProcessJoin(pParse, p) ) return 1;
-+
-+  /* 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;
-+    if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
-+         && pE->pLeft && pE->pLeft->op==TK_ID ) break;
-+  }
-+  rc = 0;
-+  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;
-+    for(k=0; k<pEList->nExpr; k++){
-+      Expr *pE = a[k].pExpr;
-+      if( pE->op!=TK_ALL &&
-+           (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
-+        /* This particular expression does not need to be expanded.
-+        */
-+        pNew = sqliteExprListAppend(pNew, a[k].pExpr, 0);
-+        pNew->a[pNew->nExpr-1].zName = a[k].zName;
-+        a[k].pExpr = 0;
-+        a[k].zName = 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 && pE->pLeft ){
-+          zTName = sqliteTableNameFromToken(&pE->pLeft->token);
-+        }else{
-+          zTName = 0;
-+        }
-+        for(i=0; i<pTabList->nSrc; i++){
-+          Table *pTab = pTabList->a[i].pTab;
-+          char *zTabName = pTabList->a[i].zAlias;
-+          if( zTabName==0 || zTabName[0]==0 ){ 
-+            zTabName = pTab->zName;
-+          }
-+          if( zTName && (zTabName==0 || zTabName[0]==0 || 
-+                 sqliteStrICmp(zTName, zTabName)!=0) ){
-+            continue;
-+          }
-+          tableSeen = 1;
-+          for(j=0; j<pTab->nCol; j++){
-+            Expr *pExpr, *pLeft, *pRight;
-+            char *zName = pTab->aCol[j].zName;
-+
-+            if( i>0 && (pTabList->a[i-1].jointype & JT_NATURAL)!=0 &&
-+                columnIndex(pTabList->a[i-1].pTab, zName)>=0 ){
-+              /* In a NATURAL join, omit the join columns from the 
-+              ** table on the right */
-+              continue;
-+            }
-+            if( i>0 && sqliteIdListIndex(pTabList->a[i-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 = sqliteExpr(TK_ID, 0, 0, 0);
-+            if( pRight==0 ) break;
-+            pRight->token.z = zName;
-+            pRight->token.n = strlen(zName);
-+            pRight->token.dyn = 0;
-+            if( zTabName && pTabList->nSrc>1 ){
-+              pLeft = sqliteExpr(TK_ID, 0, 0, 0);
-+              pExpr = sqliteExpr(TK_DOT, pLeft, pRight, 0);
-+              if( pExpr==0 ) break;
-+              pLeft->token.z = zTabName;
-+              pLeft->token.n = strlen(zTabName);
-+              pLeft->token.dyn = 0;
-+              sqliteSetString((char**)&pExpr->span.z, zTabName, ".", zName, 0);
-+              pExpr->span.n = strlen(pExpr->span.z);
-+              pExpr->span.dyn = 1;
-+              pExpr->token.z = 0;
-+              pExpr->token.n = 0;
-+              pExpr->token.dyn = 0;
-+            }else{
-+              pExpr = pRight;
-+              pExpr->span = pExpr->token;
-+            }
-+            pNew = sqliteExprListAppend(pNew, pExpr, 0);
-+          }
-+        }
-+        if( !tableSeen ){
-+          if( zTName ){
-+            sqliteErrorMsg(pParse, "no such table: %s", zTName);
-+          }else{
-+            sqliteErrorMsg(pParse, "no tables specified");
-+          }
-+          rc = 1;
-+        }
-+        sqliteFree(zTName);
-+      }
-+    }
-+    sqliteExprListDelete(pEList);
-+    p->pEList = pNew;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
-+** in a select structure.  It just sets the pointers to NULL.  This
-+** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
-+** pointer is not NULL, this routine is called recursively on that pointer.
-+**
-+** This routine is called on the Select structure that defines a
-+** VIEW in order to undo any bindings to tables.  This is necessary
-+** because those tables might be DROPed by a subsequent SQL command.
-+** If the bindings are not removed, then the Select.pSrc->a[].pTab field
-+** will be left pointing to a deallocated Table structure after the
-+** DROP and a coredump will occur the next time the VIEW is used.
-+*/
-+void sqliteSelectUnbind(Select *p){
-+  int i;
-+  SrcList *pSrc = p->pSrc;
-+  Table *pTab;
-+  if( p==0 ) return;
-+  for(i=0; i<pSrc->nSrc; i++){
-+    if( (pTab = pSrc->a[i].pTab)!=0 ){
-+      if( pTab->isTransient ){
-+        sqliteDeleteTable(0, pTab);
-+      }
-+      pSrc->a[i].pTab = 0;
-+      if( pSrc->a[i].pSelect ){
-+        sqliteSelectUnbind(pSrc->a[i].pSelect);
-+      }
-+    }
-+  }
-+}
-+
-+/*
-+** This routine associates entries in an ORDER BY expression list with
-+** columns in a result.  For each ORDER BY expression, the opcode of
-+** the top-level node is changed to TK_COLUMN and the iColumn value of
-+** the top-level node is filled in with column number and the iTable
-+** value of the top-level node is filled with iTable parameter.
-+**
-+** If there are prior SELECT clauses, they are processed first.  A match
-+** in an earlier SELECT takes precedence over a later SELECT.
-+**
-+** Any entry that does not match is flagged as an error.  The number
-+** of errors is returned.
-+**
-+** This routine does NOT correctly initialize the Expr.dataType  field
-+** of the ORDER BY expressions.  The multiSelectSortOrder() routine
-+** must be called to do that after the individual select statements
-+** have all been analyzed.  This routine is unable to compute Expr.dataType
-+** because it must be called before the individual select statements
-+** have been analyzed.
-+*/
-+static int matchOrderbyToColumn(
-+  Parse *pParse,          /* A place to leave error messages */
-+  Select *pSelect,        /* Match to result columns of this SELECT */
-+  ExprList *pOrderBy,     /* The ORDER BY values to match against columns */
-+  int iTable,             /* Insert this value in iTable */
-+  int mustComplete        /* If TRUE all ORDER BYs must match */
-+){
-+  int nErr = 0;
-+  int i, j;
-+  ExprList *pEList;
-+
-+  if( pSelect==0 || pOrderBy==0 ) return 1;
-+  if( mustComplete ){
-+    for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
-+  }
-+  if( fillInColumnList(pParse, pSelect) ){
-+    return 1;
-+  }
-+  if( pSelect->pPrior ){
-+    if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
-+      return 1;
-+    }
-+  }
-+  pEList = pSelect->pEList;
-+  for(i=0; i<pOrderBy->nExpr; i++){
-+    Expr *pE = pOrderBy->a[i].pExpr;
-+    int iCol = -1;
-+    if( pOrderBy->a[i].done ) continue;
-+    if( sqliteExprIsInteger(pE, &iCol) ){
-+      if( iCol<=0 || iCol>pEList->nExpr ){
-+        sqliteErrorMsg(pParse,
-+          "ORDER BY position %d should be between 1 and %d",
-+          iCol, pEList->nExpr);
-+        nErr++;
-+        break;
-+      }
-+      if( !mustComplete ) continue;
-+      iCol--;
-+    }
-+    for(j=0; iCol<0 && j<pEList->nExpr; j++){
-+      if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
-+        char *zName, *zLabel;
-+        zName = pEList->a[j].zName;
-+        assert( pE->token.z );
-+        zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
-+        sqliteDequote(zLabel);
-+        if( sqliteStrICmp(zName, zLabel)==0 ){ 
-+          iCol = j;
-+        }
-+        sqliteFree(zLabel);
-+      }
-+      if( iCol<0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){
-+        iCol = j;
-+      }
-+    }
-+    if( iCol>=0 ){
-+      pE->op = TK_COLUMN;
-+      pE->iColumn = iCol;
-+      pE->iTable = iTable;
-+      pOrderBy->a[i].done = 1;
-+    }
-+    if( iCol<0 && mustComplete ){
-+      sqliteErrorMsg(pParse,
-+        "ORDER BY term number %d does not match any result column", i+1);
-+      nErr++;
-+      break;
-+    }
-+  }
-+  return nErr;  
-+}
-+
-+/*
-+** 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.
-+*/
-+Vdbe *sqliteGetVdbe(Parse *pParse){
-+  Vdbe *v = pParse->pVdbe;
-+  if( v==0 ){
-+    v = pParse->pVdbe = sqliteVdbeCreate(pParse->db);
-+  }
-+  return v;
-+}
-+
-+/*
-+** This routine sets the Expr.dataType field on all elements of
-+** the pOrderBy expression list.  The pOrderBy list will have been
-+** set up by matchOrderbyToColumn().  Hence each expression has
-+** a TK_COLUMN as its root node.  The Expr.iColumn refers to a 
-+** column in the result set.   The datatype is set to SQLITE_SO_TEXT
-+** if the corresponding column in p and every SELECT to the left of
-+** p has a datatype of SQLITE_SO_TEXT.  If the cooressponding column
-+** in p or any of the left SELECTs is SQLITE_SO_NUM, then the datatype
-+** of the order-by expression is set to SQLITE_SO_NUM.
-+**
-+** Examples:
-+**
-+**     CREATE TABLE one(a INTEGER, b TEXT);
-+**     CREATE TABLE two(c VARCHAR(5), d FLOAT);
-+**
-+**     SELECT b, b FROM one UNION SELECT d, c FROM two ORDER BY 1, 2;
-+**
-+** The primary sort key will use SQLITE_SO_NUM because the "d" in
-+** the second SELECT is numeric.  The 1st column of the first SELECT
-+** is text but that does not matter because a numeric always overrides
-+** a text.
-+**
-+** The secondary key will use the SQLITE_SO_TEXT sort order because
-+** both the (second) "b" in the first SELECT and the "c" in the second
-+** SELECT have a datatype of text.
-+*/ 
-+static void multiSelectSortOrder(Select *p, ExprList *pOrderBy){
-+  int i;
-+  ExprList *pEList;
-+  if( pOrderBy==0 ) return;
-+  if( p==0 ){
-+    for(i=0; i<pOrderBy->nExpr; i++){
-+      pOrderBy->a[i].pExpr->dataType = SQLITE_SO_TEXT;
-+    }
-+    return;
-+  }
-+  multiSelectSortOrder(p->pPrior, pOrderBy);
-+  pEList = p->pEList;
-+  for(i=0; i<pOrderBy->nExpr; i++){
-+    Expr *pE = pOrderBy->a[i].pExpr;
-+    if( pE->dataType==SQLITE_SO_NUM ) continue;
-+    assert( pE->iColumn>=0 );
-+    if( pEList->nExpr>pE->iColumn ){
-+      pE->dataType = sqliteExprType(pEList->a[pE->iColumn].pExpr);
-+    }
-+  }
-+}
-+
-+/*
-+** Compute the iLimit and iOffset fields of the SELECT based on the
-+** nLimit and nOffset fields.  nLimit and nOffset hold the integers
-+** that appear in the original SQL statement after the LIMIT and OFFSET
-+** keywords.  Or that hold -1 and 0 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 if iLimit and iOffset only if
-+** a limit or offset is defined by nLimit and nOffset.  iLimit and
-+** iOffset should have been preset to appropriate default values
-+** (usually but not always -1) prior to calling this routine.
-+** Only if nLimit>=0 or nOffset>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){
-+  /* 
-+  ** If the comparison is p->nLimit>0 then "LIMIT 0" shows
-+  ** all rows.  It is the same as no limit. If the comparision is
-+  ** p->nLimit>=0 then "LIMIT 0" show no rows at all.
-+  ** "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.
-+  */
-+  if( p->nLimit>=0 ){
-+    int iMem = pParse->nMem++;
-+    Vdbe *v = sqliteGetVdbe(pParse);
-+    if( v==0 ) return;
-+    sqliteVdbeAddOp(v, OP_Integer, -p->nLimit, 0);
-+    sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
-+    p->iLimit = iMem;
-+  }
-+  if( p->nOffset>0 ){
-+    int iMem = pParse->nMem++;
-+    Vdbe *v = sqliteGetVdbe(pParse);
-+    if( v==0 ) return;
-+    sqliteVdbeAddOp(v, OP_Integer, -p->nOffset, 0);
-+    sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
-+    p->iOffset = iMem;
-+  }
-+}
-+
-+/*
-+** This routine is called to process a query that is really the union
-+** or intersection of two or more separate queries.
-+**
-+** "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, Select *p, int eDest, int iParm){
-+  int rc;             /* Success code from a subroutine */
-+  Select *pPrior;     /* Another SELECT immediately to our left */
-+  Vdbe *v;            /* Generate code to this VDBE */
-+
-+  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
-+  ** the last SELECT in the series may have an ORDER BY or LIMIT.
-+  */
-+  if( p==0 || p->pPrior==0 ) return 1;
-+  pPrior = p->pPrior;
-+  if( pPrior->pOrderBy ){
-+    sqliteErrorMsg(pParse,"ORDER BY clause should come after %s not before",
-+      selectOpName(p->op));
-+    return 1;
-+  }
-+  if( pPrior->nLimit>=0 || pPrior->nOffset>0 ){
-+    sqliteErrorMsg(pParse,"LIMIT clause should come after %s not before",
-+      selectOpName(p->op));
-+    return 1;
-+  }
-+
-+  /* Make sure we have a valid query engine.  If not, create a new one.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) return 1;
-+
-+  /* Create the destination temporary table if necessary
-+  */
-+  if( eDest==SRT_TempTable ){
-+    sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
-+    eDest = SRT_Table;
-+  }
-+
-+  /* Generate code for the left and right SELECT statements.
-+  */
-+  switch( p->op ){
-+    case TK_ALL: {
-+      if( p->pOrderBy==0 ){
-+        pPrior->nLimit = p->nLimit;
-+        pPrior->nOffset = p->nOffset;
-+        rc = sqliteSelect(pParse, pPrior, eDest, iParm, 0, 0, 0);
-+        if( rc ) return rc;
-+        p->pPrior = 0;
-+        p->iLimit = pPrior->iLimit;
-+        p->iOffset = pPrior->iOffset;
-+        p->nLimit = -1;
-+        p->nOffset = 0;
-+        rc = sqliteSelect(pParse, p, eDest, iParm, 0, 0, 0);
-+        p->pPrior = pPrior;
-+        if( rc ) return rc;
-+        break;
-+      }
-+      /* For UNION ALL ... ORDER BY fall through to the next case */
-+    }
-+    case TK_EXCEPT:
-+    case TK_UNION: {
-+      int unionTab;    /* Cursor number of the temporary table holding result */
-+      int op;          /* One of the SRT_ operations to apply to self */
-+      int priorOp;     /* The SRT_ operation to apply to prior selects */
-+      int nLimit, nOffset; /* Saved values of p->nLimit and p->nOffset */
-+      ExprList *pOrderBy;  /* The ORDER BY clause for the right SELECT */
-+
-+      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
-+      if( eDest==priorOp && p->pOrderBy==0 && p->nLimit<0 && p->nOffset==0 ){
-+        /* We can reuse a temporary table generated by a SELECT to our
-+        ** right.
-+        */
-+        unionTab = iParm;
-+      }else{
-+        /* We will need to create our own temporary table to hold the
-+        ** intermediate results.
-+        */
-+        unionTab = pParse->nTab++;
-+        if( p->pOrderBy 
-+        && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
-+          return 1;
-+        }
-+        if( p->op!=TK_ALL ){
-+          sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 1);
-+          sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1);
-+        }else{
-+          sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
-+        }
-+      }
-+
-+      /* Code the SELECT statements to our left
-+      */
-+      rc = sqliteSelect(pParse, pPrior, priorOp, unionTab, 0, 0, 0);
-+      if( rc ) return rc;
-+
-+      /* Code the current SELECT statement
-+      */
-+      switch( p->op ){
-+         case TK_EXCEPT:  op = SRT_Except;   break;
-+         case TK_UNION:   op = SRT_Union;    break;
-+         case TK_ALL:     op = SRT_Table;    break;
-+      }
-+      p->pPrior = 0;
-+      pOrderBy = p->pOrderBy;
-+      p->pOrderBy = 0;
-+      nLimit = p->nLimit;
-+      p->nLimit = -1;
-+      nOffset = p->nOffset;
-+      p->nOffset = 0;
-+      rc = sqliteSelect(pParse, p, op, unionTab, 0, 0, 0);
-+      p->pPrior = pPrior;
-+      p->pOrderBy = pOrderBy;
-+      p->nLimit = nLimit;
-+      p->nOffset = nOffset;
-+      if( rc ) return rc;
-+
-+      /* Convert the data in the temporary table into whatever form
-+      ** it is that we currently need.
-+      */      
-+      if( eDest!=priorOp || unionTab!=iParm ){
-+        int iCont, iBreak, iStart;
-+        assert( p->pEList );
-+        if( eDest==SRT_Callback ){
-+          generateColumnNames(pParse, 0, p->pEList);
-+          generateColumnTypes(pParse, p->pSrc, p->pEList);
-+        }
-+        iBreak = sqliteVdbeMakeLabel(v);
-+        iCont = sqliteVdbeMakeLabel(v);
-+        sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak);
-+        computeLimitRegisters(pParse, p);
-+        iStart = sqliteVdbeCurrentAddr(v);
-+        multiSelectSortOrder(p, p->pOrderBy);
-+        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
-+                             p->pOrderBy, -1, eDest, iParm, 
-+                             iCont, iBreak);
-+        if( rc ) return 1;
-+        sqliteVdbeResolveLabel(v, iCont);
-+        sqliteVdbeAddOp(v, OP_Next, unionTab, iStart);
-+        sqliteVdbeResolveLabel(v, iBreak);
-+        sqliteVdbeAddOp(v, OP_Close, unionTab, 0);
-+        if( p->pOrderBy ){
-+          generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
-+        }
-+      }
-+      break;
-+    }
-+    case TK_INTERSECT: {
-+      int tab1, tab2;
-+      int iCont, iBreak, iStart;
-+      int nLimit, nOffset;
-+
-+      /* 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++;
-+      if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
-+        return 1;
-+      }
-+      sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 1);
-+      sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1);
-+
-+      /* Code the SELECTs to our left into temporary table "tab1".
-+      */
-+      rc = sqliteSelect(pParse, pPrior, SRT_Union, tab1, 0, 0, 0);
-+      if( rc ) return rc;
-+
-+      /* Code the current SELECT into temporary table "tab2"
-+      */
-+      sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 1);
-+      sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1);
-+      p->pPrior = 0;
-+      nLimit = p->nLimit;
-+      p->nLimit = -1;
-+      nOffset = p->nOffset;
-+      p->nOffset = 0;
-+      rc = sqliteSelect(pParse, p, SRT_Union, tab2, 0, 0, 0);
-+      p->pPrior = pPrior;
-+      p->nLimit = nLimit;
-+      p->nOffset = nOffset;
-+      if( rc ) return rc;
-+
-+      /* Generate code to take the intersection of the two temporary
-+      ** tables.
-+      */
-+      assert( p->pEList );
-+      if( eDest==SRT_Callback ){
-+        generateColumnNames(pParse, 0, p->pEList);
-+        generateColumnTypes(pParse, p->pSrc, p->pEList);
-+      }
-+      iBreak = sqliteVdbeMakeLabel(v);
-+      iCont = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak);
-+      computeLimitRegisters(pParse, p);
-+      iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
-+      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
-+      multiSelectSortOrder(p, p->pOrderBy);
-+      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
-+                             p->pOrderBy, -1, eDest, iParm, 
-+                             iCont, iBreak);
-+      if( rc ) return 1;
-+      sqliteVdbeResolveLabel(v, iCont);
-+      sqliteVdbeAddOp(v, OP_Next, tab1, iStart);
-+      sqliteVdbeResolveLabel(v, iBreak);
-+      sqliteVdbeAddOp(v, OP_Close, tab2, 0);
-+      sqliteVdbeAddOp(v, OP_Close, tab1, 0);
-+      if( p->pOrderBy ){
-+        generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
-+      }
-+      break;
-+    }
-+  }
-+  assert( p->pEList && pPrior->pEList );
-+  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
-+    sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
-+      " do not have the same number of result columns", selectOpName(p->op));
-+    return 1;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** 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 void substExprList(ExprList*,int,ExprList*);  /* Forward Decl */
-+static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){
-+  if( pExpr==0 ) return;
-+  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 && pExpr->pList==0 );
-+      pNew = pEList->a[pExpr->iColumn].pExpr;
-+      assert( pNew!=0 );
-+      pExpr->op = pNew->op;
-+      pExpr->dataType = pNew->dataType;
-+      assert( pExpr->pLeft==0 );
-+      pExpr->pLeft = sqliteExprDup(pNew->pLeft);
-+      assert( pExpr->pRight==0 );
-+      pExpr->pRight = sqliteExprDup(pNew->pRight);
-+      assert( pExpr->pList==0 );
-+      pExpr->pList = sqliteExprListDup(pNew->pList);
-+      pExpr->iTable = pNew->iTable;
-+      pExpr->iColumn = pNew->iColumn;
-+      pExpr->iAgg = pNew->iAgg;
-+      sqliteTokenCopy(&pExpr->token, &pNew->token);
-+      sqliteTokenCopy(&pExpr->span, &pNew->span);
-+    }
-+  }else{
-+    substExpr(pExpr->pLeft, iTable, pEList);
-+    substExpr(pExpr->pRight, iTable, pEList);
-+    substExprList(pExpr->pList, iTable, pEList);
-+  }
-+}
-+static void 
-+substExprList(ExprList *pList, int iTable, ExprList *pEList){
-+  int i;
-+  if( pList==0 ) return;
-+  for(i=0; i<pList->nExpr; i++){
-+    substExpr(pList->a[i].pExpr, iTable, pEList);
-+  }
-+}
-+
-+/*
-+** 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, or
-+**        the subquery is not itself a join.  (Ticket #306)
-+**
-+**   (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)  The subquery is not the right term of a LEFT OUTER JOIN or the
-+**        subquery has no WHERE clause.  (added by ticket #350)
-+**
-+** 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,       /* The 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 */
-+){
-+  Select *pSub;       /* The inner query or "subquery" */
-+  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;
-+  Expr *pWhere;
-+
-+  /* Check to see if flattening is permitted.  Return 0 if not.
-+  */
-+  if( p==0 ) return 0;
-+  pSrc = p->pSrc;
-+  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
-+  pSub = pSrc->a[iFrom].pSelect;
-+  assert( pSub!=0 );
-+  if( isAgg && subqueryIsAgg ) return 0;
-+  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
-+  pSubSrc = pSub->pSrc;
-+  assert( pSubSrc );
-+  if( pSubSrc->nSrc==0 ) return 0;
-+  if( (pSub->isDistinct || pSub->nLimit>=0) &&  (pSrc->nSrc>1 || isAgg) ){
-+     return 0;
-+  }
-+  if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0;
-+  if( p->pOrderBy && pSub->pOrderBy ) return 0;
-+
-+  /* Restriction 3:  If the subquery is a join, make sure the subquery is 
-+  ** not used as the right operand of an outer join.  Examples of why this
-+  ** is not allowed:
-+  **
-+  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
-+  **
-+  ** If we flatten the above, we would get
-+  **
-+  **         (t1 LEFT OUTER JOIN t2) JOIN t3
-+  **
-+  ** which is not at all the same thing.
-+  */
-+  if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
-+    return 0;
-+  }
-+
-+  /* 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.
-+  */
-+  if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 
-+      && pSub->pWhere!=0 ){
-+    return 0;
-+  }
-+
-+  /* If we reach this point, it means flattening is permitted for the
-+  ** iFrom-th entry of the FROM clause in the outer query.
-+  */
-+
-+  /* Move 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.
-+  */
-+  iParent = pSrc->a[iFrom].iCursor;
-+  {
-+    int nSubSrc = pSubSrc->nSrc;
-+    int jointype = pSrc->a[iFrom].jointype;
-+
-+    if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
-+      sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
-+    }
-+    sqliteFree(pSrc->a[iFrom].zDatabase);
-+    sqliteFree(pSrc->a[iFrom].zName);
-+    sqliteFree(pSrc->a[iFrom].zAlias);
-+    if( nSubSrc>1 ){
-+      int extra = nSubSrc - 1;
-+      for(i=1; i<nSubSrc; i++){
-+        pSrc = sqliteSrcListAppend(pSrc, 0, 0);
-+      }
-+      p->pSrc = pSrc;
-+      for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
-+        pSrc->a[i] = pSrc->a[i-extra];
-+      }
-+    }
-+    for(i=0; i<nSubSrc; i++){
-+      pSrc->a[i+iFrom] = pSubSrc->a[i];
-+      memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
-+    }
-+    pSrc->a[iFrom+nSubSrc-1].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".
-+  */
-+  substExprList(p->pEList, iParent, pSub->pEList);
-+  pList = p->pEList;
-+  for(i=0; i<pList->nExpr; i++){
-+    Expr *pExpr;
-+    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
-+      pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
-+    }
-+  }
-+  if( isAgg ){
-+    substExprList(p->pGroupBy, iParent, pSub->pEList);
-+    substExpr(p->pHaving, iParent, pSub->pEList);
-+  }
-+  if( pSub->pOrderBy ){
-+    assert( p->pOrderBy==0 );
-+    p->pOrderBy = pSub->pOrderBy;
-+    pSub->pOrderBy = 0;
-+  }else if( p->pOrderBy ){
-+    substExprList(p->pOrderBy, iParent, pSub->pEList);
-+  }
-+  if( pSub->pWhere ){
-+    pWhere = sqliteExprDup(pSub->pWhere);
-+  }else{
-+    pWhere = 0;
-+  }
-+  if( subqueryIsAgg ){
-+    assert( p->pHaving==0 );
-+    p->pHaving = p->pWhere;
-+    p->pWhere = pWhere;
-+    substExpr(p->pHaving, iParent, pSub->pEList);
-+    if( pSub->pHaving ){
-+      Expr *pHaving = sqliteExprDup(pSub->pHaving);
-+      if( p->pHaving ){
-+        p->pHaving = sqliteExpr(TK_AND, p->pHaving, pHaving, 0);
-+      }else{
-+        p->pHaving = pHaving;
-+      }
-+    }
-+    assert( p->pGroupBy==0 );
-+    p->pGroupBy = sqliteExprListDup(pSub->pGroupBy);
-+  }else if( p->pWhere==0 ){
-+    p->pWhere = pWhere;
-+  }else{
-+    substExpr(p->pWhere, iParent, pSub->pEList);
-+    if( pWhere ){
-+      p->pWhere = sqliteExpr(TK_AND, p->pWhere, pWhere, 0);
-+    }
-+  }
-+
-+  /* The flattened query is distinct if either the inner or the
-+  ** outer query is distinct. 
-+  */
-+  p->isDistinct = p->isDistinct || pSub->isDistinct;
-+
-+  /* Transfer the limit expression from the subquery to the outer
-+  ** query.
-+  */
-+  if( pSub->nLimit>=0 ){
-+    if( p->nLimit<0 ){
-+      p->nLimit = pSub->nLimit;
-+    }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){
-+      p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset;
-+    }
-+  }
-+  p->nOffset += pSub->nOffset;
-+
-+  /* Finially, delete what is left of the subquery and return
-+  ** success.
-+  */
-+  sqliteSelectDelete(pSub);
-+  return 1;
-+}
-+
-+/*
-+** Analyze the SELECT statement passed in as an argument to see if it
-+** is a simple min() or max() query.  If it is and this query can be
-+** satisfied using a single seek to the beginning or end of an index,
-+** then generate the code for this SELECT and return 1.  If this is not a 
-+** simple min() or max() query, then return 0;
-+**
-+** A simply min() or max() query looks like this:
-+**
-+**    SELECT min(a) FROM table;
-+**    SELECT max(a) FROM table;
-+**
-+** The query may have only a single table in its FROM argument.  There
-+** can be no GROUP BY or HAVING or WHERE clauses.  The result set must
-+** be the min() or max() of a single column of the table.  The column
-+** in the min() or max() function must be indexed.
-+**
-+** The parameters to this routine are the same as for sqliteSelect().
-+** See the header comment on that routine for additional information.
-+*/
-+static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
-+  Expr *pExpr;
-+  int iCol;
-+  Table *pTab;
-+  Index *pIdx;
-+  int base;
-+  Vdbe *v;
-+  int seekOp;
-+  int cont;
-+  ExprList *pEList, *pList, eList;
-+  struct ExprList_item eListItem;
-+  SrcList *pSrc;
-+  
-+
-+  /* Check to see if this query is a simple min() or max() query.  Return
-+  ** zero if it is  not.
-+  */
-+  if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
-+  pSrc = p->pSrc;
-+  if( pSrc->nSrc!=1 ) return 0;
-+  pEList = p->pEList;
-+  if( pEList->nExpr!=1 ) return 0;
-+  pExpr = pEList->a[0].pExpr;
-+  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
-+  pList = pExpr->pList;
-+  if( pList==0 || pList->nExpr!=1 ) return 0;
-+  if( pExpr->token.n!=3 ) return 0;
-+  if( sqliteStrNICmp(pExpr->token.z,"min",3)==0 ){
-+    seekOp = OP_Rewind;
-+  }else if( sqliteStrNICmp(pExpr->token.z,"max",3)==0 ){
-+    seekOp = OP_Last;
-+  }else{
-+    return 0;
-+  }
-+  pExpr = pList->a[0].pExpr;
-+  if( pExpr->op!=TK_COLUMN ) return 0;
-+  iCol = pExpr->iColumn;
-+  pTab = pSrc->a[0].pTab;
-+
-+  /* If we get to here, it means the query is of the correct form.
-+  ** Check to make sure we have an index and make pIdx point to the
-+  ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
-+  ** key column, no index is necessary so set pIdx to NULL.  If no
-+  ** usable index is found, return 0.
-+  */
-+  if( iCol<0 ){
-+    pIdx = 0;
-+  }else{
-+    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-+      assert( pIdx->nColumn>=1 );
-+      if( pIdx->aiColumn[0]==iCol ) break;
-+    }
-+    if( pIdx==0 ) return 0;
-+  }
-+
-+  /* Identify column types if we will be using the callback.  This
-+  ** step is skipped if the output is going to a table or a memory cell.
-+  ** The column names have already been generated in the calling function.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) return 0;
-+  if( eDest==SRT_Callback ){
-+    generateColumnTypes(pParse, p->pSrc, p->pEList);
-+  }
-+
-+  /* If the output is destined for a temporary table, open that table.
-+  */
-+  if( eDest==SRT_TempTable ){
-+    sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
-+  }
-+
-+  /* Generating code to find the min or the max.  Basically all we have
-+  ** to do is find the first or the last entry in the chosen index.  If
-+  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
-+  ** or last entry in the main table.
-+  */
-+  sqliteCodeVerifySchema(pParse, pTab->iDb);
-+  base = pSrc->a[0].iCursor;
-+  computeLimitRegisters(pParse, p);
-+  if( pSrc->a[0].pSelect==0 ){
-+    sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+    sqliteVdbeOp3(v, OP_OpenRead, base, pTab->tnum, pTab->zName, 0);
-+  }
-+  cont = sqliteVdbeMakeLabel(v);
-+  if( pIdx==0 ){
-+    sqliteVdbeAddOp(v, seekOp, base, 0);
-+  }else{
-+    sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
-+    sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
-+    if( seekOp==OP_Rewind ){
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
-+      sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
-+      seekOp = OP_MoveTo;
-+    }
-+    sqliteVdbeAddOp(v, seekOp, base+1, 0);
-+    sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
-+    sqliteVdbeAddOp(v, OP_Close, base+1, 0);
-+    sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
-+  }
-+  eList.nExpr = 1;
-+  memset(&eListItem, 0, sizeof(eListItem));
-+  eList.a = &eListItem;
-+  eList.a[0].pExpr = pExpr;
-+  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont);
-+  sqliteVdbeResolveLabel(v, cont);
-+  sqliteVdbeAddOp(v, OP_Close, base, 0);
-+  
-+  return 1;
-+}
-+
-+/*
-+** Generate code for the given SELECT statement.
-+**
-+** The results are distributed in various ways depending on the
-+** value of eDest and iParm.
-+**
-+**     eDest Value       Result
-+**     ------------    -------------------------------------------
-+**     SRT_Callback    Invoke the callback for each row of the result.
-+**
-+**     SRT_Mem         Store first result in memory cell iParm
-+**
-+**     SRT_Set         Store results as keys of a table with cursor iParm
-+**
-+**     SRT_Union       Store results as a key in a temporary table iParm
-+**
-+**     SRT_Except      Remove results from the temporary table iParm.
-+**
-+**     SRT_Table       Store results in temporary table iParm
-+**
-+** The table above is incomplete.  Additional eDist value have be added
-+** since this comment was written.  See the selectInnerLoop() function for
-+** a complete listing of the allowed values of eDest and their meanings.
-+**
-+** 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.
-+**
-+** The pParent, parentTab, and *pParentAgg fields are filled in if this
-+** SELECT is a subquery.  This routine may try to combine this SELECT
-+** with its parent to form a single flat query.  In so doing, it might
-+** change the parent query from a non-aggregate to an aggregate query.
-+** For that reason, the pParentAgg flag is passed as a pointer, so it
-+** can be changed.
-+**
-+** Example 1:   The meaning of the pParent parameter.
-+**
-+**    SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
-+**    \                      \_______ subquery _______/        /
-+**     \                                                      /
-+**      \____________________ outer query ___________________/
-+**
-+** This routine is called for the outer query first.   For that call,
-+** pParent will be NULL.  During the processing of the outer query, this 
-+** routine is called recursively to handle the subquery.  For the recursive
-+** call, pParent will point to the outer query.  Because the subquery is
-+** the second element in a three-way join, the parentTab parameter will
-+** be 1 (the 2nd value of a 0-indexed array.)
-+*/
-+int sqliteSelect(
-+  Parse *pParse,         /* The parser context */
-+  Select *p,             /* The SELECT statement being coded. */
-+  int eDest,             /* How to dispose of the results */
-+  int iParm,             /* A parameter used by the eDest disposal method */
-+  Select *pParent,       /* Another SELECT for which this is a sub-query */
-+  int parentTab,         /* Index in pParent->pSrc of this query */
-+  int *pParentAgg        /* True if pParent uses aggregate functions */
-+){
-+  int i;
-+  WhereInfo *pWInfo;
-+  Vdbe *v;
-+  int isAgg = 0;         /* 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 */
-+
-+  if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;
-+  if( sqliteAuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
-+
-+  /* If there is are a sequence of queries, do the earlier ones first.
-+  */
-+  if( p->pPrior ){
-+    return multiSelect(pParse, p, eDest, iParm);
-+  }
-+
-+  /* Make local copies of the parameters for this query.
-+  */
-+  pTabList = p->pSrc;
-+  pWhere = p->pWhere;
-+  pOrderBy = p->pOrderBy;
-+  pGroupBy = p->pGroupBy;
-+  pHaving = p->pHaving;
-+  isDistinct = p->isDistinct;
-+
-+  /* Allocate VDBE cursors for each table in the FROM clause
-+  */
-+  sqliteSrcListAssignCursors(pParse, pTabList);
-+
-+  /* 
-+  ** Do not even attempt to generate any code if we have already seen
-+  ** errors before this routine starts.
-+  */
-+  if( pParse->nErr>0 ) goto select_end;
-+
-+  /* Expand any "*" terms in the result set.  (For example the "*" in
-+  ** "SELECT * FROM t1")  The fillInColumnlist() routine also does some
-+  ** other housekeeping - see the header comment for details.
-+  */
-+  if( fillInColumnList(pParse, p) ){
-+    goto select_end;
-+  }
-+  pWhere = p->pWhere;
-+  pEList = p->pEList;
-+  if( pEList==0 ) goto select_end;
-+
-+  /* If writing to memory or generating a set
-+  ** only a single column may be output.
-+  */
-+  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
-+    sqliteErrorMsg(pParse, "only a single result allowed for "
-+       "a SELECT that is part of an expression");
-+    goto select_end;
-+  }
-+
-+  /* ORDER BY is ignored for some destinations.
-+  */
-+  switch( eDest ){
-+    case SRT_Union:
-+    case SRT_Except:
-+    case SRT_Discard:
-+      pOrderBy = 0;
-+      break;
-+    default:
-+      break;
-+  }
-+
-+  /* At this point, we should have allocated all the cursors that we
-+  ** need to handle subquerys and temporary tables.  
-+  **
-+  ** Resolve the column names and do a semantics check on all the expressions.
-+  */
-+  for(i=0; i<pEList->nExpr; i++){
-+    if( sqliteExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
-+      goto select_end;
-+    }
-+    if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
-+      goto select_end;
-+    }
-+  }
-+  if( pWhere ){
-+    if( sqliteExprResolveIds(pParse, pTabList, pEList, pWhere) ){
-+      goto select_end;
-+    }
-+    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
-+      goto select_end;
-+    }
-+  }
-+  if( pHaving ){
-+    if( pGroupBy==0 ){
-+      sqliteErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
-+      goto select_end;
-+    }
-+    if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
-+      goto select_end;
-+    }
-+    if( sqliteExprCheck(pParse, pHaving, 1, &isAgg) ){
-+      goto select_end;
-+    }
-+  }
-+  if( pOrderBy ){
-+    for(i=0; i<pOrderBy->nExpr; i++){
-+      int iCol;
-+      Expr *pE = pOrderBy->a[i].pExpr;
-+      if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
-+        sqliteExprDelete(pE);
-+        pE = pOrderBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
-+      }
-+      if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
-+        goto select_end;
-+      }
-+      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
-+        goto select_end;
-+      }
-+      if( sqliteExprIsConstant(pE) ){
-+        if( sqliteExprIsInteger(pE, &iCol)==0 ){
-+          sqliteErrorMsg(pParse,
-+             "ORDER BY terms must not be non-integer constants");
-+          goto select_end;
-+        }else if( iCol<=0 || iCol>pEList->nExpr ){
-+          sqliteErrorMsg(pParse, 
-+             "ORDER BY column number %d out of range - should be "
-+             "between 1 and %d", iCol, pEList->nExpr);
-+          goto select_end;
-+        }
-+      }
-+    }
-+  }
-+  if( pGroupBy ){
-+    for(i=0; i<pGroupBy->nExpr; i++){
-+      int iCol;
-+      Expr *pE = pGroupBy->a[i].pExpr;
-+      if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
-+        sqliteExprDelete(pE);
-+        pE = pGroupBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
-+      }
-+      if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
-+        goto select_end;
-+      }
-+      if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
-+        goto select_end;
-+      }
-+      if( sqliteExprIsConstant(pE) ){
-+        if( sqliteExprIsInteger(pE, &iCol)==0 ){
-+          sqliteErrorMsg(pParse,
-+            "GROUP BY terms must not be non-integer constants");
-+          goto select_end;
-+        }else if( iCol<=0 || iCol>pEList->nExpr ){
-+          sqliteErrorMsg(pParse,
-+             "GROUP BY column number %d out of range - should be "
-+             "between 1 and %d", iCol, pEList->nExpr);
-+          goto select_end;
-+        }
-+      }
-+    }
-+  }
-+
-+  /* Begin generating code.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) goto select_end;
-+
-+  /* Identify column names if we will be using them in a callback.  This
-+  ** step is skipped if the output is going to some other destination.
-+  */
-+  if( eDest==SRT_Callback ){
-+    generateColumnNames(pParse, pTabList, pEList);
-+  }
-+
-+  /* Generate code for all sub-queries in the FROM clause
-+  */
-+  for(i=0; i<pTabList->nSrc; i++){
-+    const char *zSavedAuthContext;
-+    int needRestoreContext;
-+
-+    if( pTabList->a[i].pSelect==0 ) continue;
-+    if( pTabList->a[i].zName!=0 ){
-+      zSavedAuthContext = pParse->zAuthContext;
-+      pParse->zAuthContext = pTabList->a[i].zName;
-+      needRestoreContext = 1;
-+    }else{
-+      needRestoreContext = 0;
-+    }
-+    sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_TempTable, 
-+                 pTabList->a[i].iCursor, p, i, &isAgg);
-+    if( needRestoreContext ){
-+      pParse->zAuthContext = zSavedAuthContext;
-+    }
-+    pTabList = p->pSrc;
-+    pWhere = p->pWhere;
-+    if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
-+      pOrderBy = p->pOrderBy;
-+    }
-+    pGroupBy = p->pGroupBy;
-+    pHaving = p->pHaving;
-+    isDistinct = p->isDistinct;
-+  }
-+
-+  /* Check for the special case of a min() or max() function by itself
-+  ** in the result set.
-+  */
-+  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
-+    rc = 0;
-+    goto select_end;
-+  }
-+
-+  /* Check to see if this is a subquery that can be "flattened" into its parent.
-+  ** If flattening is a possiblity, do so and return immediately.  
-+  */
-+  if( pParent && pParentAgg &&
-+      flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
-+    if( isAgg ) *pParentAgg = 1;
-+    return rc;
-+  }
-+
-+  /* Set the limiter.
-+  */
-+  computeLimitRegisters(pParse, p);
-+
-+  /* Identify column types if we will be using a callback.  This
-+  ** step is skipped if the output is going to a destination other
-+  ** than a callback.
-+  **
-+  ** We have to do this separately from the creation of column names
-+  ** above because if the pTabList contains views then they will not
-+  ** have been resolved and we will not know the column types until
-+  ** now.
-+  */
-+  if( eDest==SRT_Callback ){
-+    generateColumnTypes(pParse, pTabList, pEList);
-+  }
-+
-+  /* If the output is destined for a temporary table, open that table.
-+  */
-+  if( eDest==SRT_TempTable ){
-+    sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
-+  }
-+
-+  /* Do an analysis of aggregate expressions.
-+  */
-+  sqliteAggregateInfoReset(pParse);
-+  if( isAgg || pGroupBy ){
-+    assert( pParse->nAgg==0 );
-+    isAgg = 1;
-+    for(i=0; i<pEList->nExpr; i++){
-+      if( sqliteExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){
-+        goto select_end;
-+      }
-+    }
-+    if( pGroupBy ){
-+      for(i=0; i<pGroupBy->nExpr; i++){
-+        if( sqliteExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){
-+          goto select_end;
-+        }
-+      }
-+    }
-+    if( pHaving && sqliteExprAnalyzeAggregates(pParse, pHaving) ){
-+      goto select_end;
-+    }
-+    if( pOrderBy ){
-+      for(i=0; i<pOrderBy->nExpr; i++){
-+        if( sqliteExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){
-+          goto select_end;
-+        }
-+      }
-+    }
-+  }
-+
-+  /* Reset the aggregator
-+  */
-+  if( isAgg ){
-+    sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
-+    for(i=0; i<pParse->nAgg; i++){
-+      FuncDef *pFunc;
-+      if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
-+        sqliteVdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_POINTER);
-+      }
-+    }
-+    if( pGroupBy==0 ){
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
-+    }
-+  }
-+
-+  /* Initialize the memory cell to NULL
-+  */
-+  if( eDest==SRT_Mem ){
-+    sqliteVdbeAddOp(v, OP_String, 0, 0);
-+    sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
-+  }
-+
-+  /* Open a temporary table to use for the distinct set.
-+  */
-+  if( isDistinct ){
-+    distinct = pParse->nTab++;
-+    sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 1);
-+  }else{
-+    distinct = -1;
-+  }
-+
-+  /* Begin the database scan
-+  */
-+  pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0, 
-+                            pGroupBy ? 0 : &pOrderBy);
-+  if( pWInfo==0 ) goto select_end;
-+
-+  /* Use the standard inner loop if we are not dealing with
-+  ** aggregates
-+  */
-+  if( !isAgg ){
-+    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
-+                    iParm, pWInfo->iContinue, pWInfo->iBreak) ){
-+       goto select_end;
-+    }
-+  }
-+
-+  /* If we are dealing with aggregates, then do the special aggregate
-+  ** processing.  
-+  */
-+  else{
-+    AggExpr *pAgg;
-+    if( pGroupBy ){
-+      int lbl1;
-+      for(i=0; i<pGroupBy->nExpr; i++){
-+        sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
-+      }
-+      sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
-+      if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pGroupBy);
-+      lbl1 = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
-+      for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
-+        if( pAgg->isAgg ) continue;
-+        sqliteExprCode(pParse, pAgg->pExpr);
-+        sqliteVdbeAddOp(v, OP_AggSet, 0, i);
-+      }
-+      sqliteVdbeResolveLabel(v, lbl1);
-+    }
-+    for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
-+      Expr *pE;
-+      int nExpr;
-+      FuncDef *pDef;
-+      if( !pAgg->isAgg ) continue;
-+      assert( pAgg->pFunc!=0 );
-+      assert( pAgg->pFunc->xStep!=0 );
-+      pDef = pAgg->pFunc;
-+      pE = pAgg->pExpr;
-+      assert( pE!=0 );
-+      assert( pE->op==TK_AGG_FUNCTION );
-+      nExpr = sqliteExprCodeExprList(pParse, pE->pList, pDef->includeTypes);
-+      sqliteVdbeAddOp(v, OP_Integer, i, 0);
-+      sqliteVdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
-+    }
-+  }
-+
-+  /* End the database scan loop.
-+  */
-+  sqliteWhereEnd(pWInfo);
-+
-+  /* If we are processing aggregates, we need to set up a second loop
-+  ** over all of the aggregate values and process them.
-+  */
-+  if( isAgg ){
-+    int endagg = sqliteVdbeMakeLabel(v);
-+    int startagg;
-+    startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg);
-+    pParse->useAgg = 1;
-+    if( pHaving ){
-+      sqliteExprIfFalse(pParse, pHaving, startagg, 1);
-+    }
-+    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
-+                    iParm, startagg, endagg) ){
-+      goto select_end;
-+    }
-+    sqliteVdbeAddOp(v, OP_Goto, 0, startagg);
-+    sqliteVdbeResolveLabel(v, endagg);
-+    sqliteVdbeAddOp(v, OP_Noop, 0, 0);
-+    pParse->useAgg = 0;
-+  }
-+
-+  /* 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(p, v, pEList->nExpr, eDest, iParm);
-+  }
-+
-+  /* If this was a subquery, we have now converted the subquery into a
-+  ** temporary table.  So delete the subquery structure from the parent
-+  ** to prevent this subquery from being evaluated again and to force the
-+  ** the use of the temporary table.
-+  */
-+  if( pParent ){
-+    assert( pParent->pSrc->nSrc>parentTab );
-+    assert( pParent->pSrc->a[parentTab].pSelect==p );
-+    sqliteSelectDelete(p);
-+    pParent->pSrc->a[parentTab].pSelect = 0;
-+  }
-+
-+  /* 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:
-+  sqliteAggregateInfoReset(pParse);
-+  return rc;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/sqlite_config.w32.h
-@@ -0,0 +1,8 @@
-+#include "config.w32.h"
-+#if ZTS
-+# define THREADSAFE 1
-+#endif
-+#if !ZEND_DEBUG && !defined(NDEBUG)
-+# define NDEBUG
-+#endif
-+#define SQLITE_PTR_SZ 4
-\ No newline at end of file
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/sqlite.h.in
-@@ -0,0 +1,886 @@
-+/*
-+** 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.
-+**
-+** @(#) $Id$
-+*/
-+#ifndef _SQLITE_H_
-+#define _SQLITE_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
-+
-+/*
-+** The version of the SQLite library.
-+*/
-+#ifdef SQLITE_VERSION
-+# undef SQLITE_VERSION
-+#else
-+# define SQLITE_VERSION         "--VERS--"
-+#endif
-+
-+/*
-+** The version string is also compiled into the library so that a program
-+** can check to make sure that the lib*.a file and the *.h file are from
-+** the same version.
-+*/
-+extern const char sqlite_version[];
-+
-+/*
-+** The SQLITE_UTF8 macro is defined if the library expects to see
-+** UTF-8 encoded data.  The SQLITE_ISO8859 macro is defined if the
-+** iso8859 encoded should be used.
-+*/
-+#define SQLITE_--ENCODING-- 1
-+
-+/*
-+** The following constant holds one of two strings, "UTF-8" or "iso8859",
-+** depending on which character encoding the SQLite library expects to
-+** see.  The character encoding makes a difference for the LIKE and GLOB
-+** operators and for the LENGTH() and SUBSTR() functions.
-+*/
-+extern const char sqlite_encoding[];
-+
-+/*
-+** Each open sqlite database is represented by an instance of the
-+** following opaque structure.
-+*/
-+typedef struct sqlite sqlite;
-+
-+/*
-+** A function to open a new sqlite database.  
-+**
-+** If the database does not exist and mode indicates write
-+** permission, then a new database is created.  If the database
-+** does not exist and mode does not indicate write permission,
-+** then the open fails, an error message generated (if errmsg!=0)
-+** and the function returns 0.
-+** 
-+** If mode does not indicates user write permission, then the 
-+** database is opened read-only.
-+**
-+** The Truth:  As currently implemented, all databases are opened
-+** for writing all the time.  Maybe someday we will provide the
-+** ability to open a database readonly.  The mode parameters is
-+** provided in anticipation of that enhancement.
-+*/
-+sqlite *sqlite_open(const char *filename, int mode, char **errmsg);
-+
-+/*
-+** A function to close the database.
-+**
-+** Call this function with a pointer to a structure that was previously
-+** returned from sqlite_open() and the corresponding database will by closed.
-+*/
-+void sqlite_close(sqlite *);
-+
-+/*
-+** The type for a callback function.
-+*/
-+typedef int (*sqlite_callback)(void*,int,char**, char**);
-+
-+/*
-+** A function to executes one or more statements of SQL.
-+**
-+** If one or more of the SQL statements are queries, then
-+** the callback function specified by the 3rd parameter is
-+** invoked once for each row of the query result.  This callback
-+** should normally return 0.  If the callback returns a non-zero
-+** value then the query is aborted, all subsequent SQL statements
-+** are skipped and the sqlite_exec() function returns the SQLITE_ABORT.
-+**
-+** The 4th parameter is an arbitrary pointer that is passed
-+** to the callback function as its first parameter.
-+**
-+** The 2nd parameter to the callback function is the number of
-+** columns in the query result.  The 3rd parameter to the callback
-+** is an array of strings holding the values for each column.
-+** The 4th parameter to the callback is an array of strings holding
-+** the names of each column.
-+**
-+** The callback function may be NULL, even for queries.  A NULL
-+** callback is not an error.  It just means that no callback
-+** will be invoked.
-+**
-+** If an error occurs while parsing or evaluating the SQL (but
-+** not while executing the callback) then an appropriate error
-+** message is written into memory obtained from malloc() and
-+** *errmsg is made to point to that message.  The calling function
-+** is responsible for freeing the memory that holds the error
-+** message.   Use sqlite_freemem() for this.  If errmsg==NULL,
-+** then no error message is ever written.
-+**
-+** The return value is is SQLITE_OK if there are no errors and
-+** some other return code if there is an error.  The particular
-+** return value depends on the type of error. 
-+**
-+** If the query could not be executed because a database file is
-+** locked or busy, then this function returns SQLITE_BUSY.  (This
-+** behavior can be modified somewhat using the sqlite_busy_handler()
-+** and sqlite_busy_timeout() functions below.)
-+*/
-+int sqlite_exec(
-+  sqlite*,                      /* An open database */
-+  const char *sql,              /* SQL to be executed */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg                 /* Error msg written here */
-+);
-+
-+/*
-+** Return values for sqlite_exec() and sqlite_step()
-+*/
-+#define SQLITE_OK           0   /* Successful result */
-+#define SQLITE_ERROR        1   /* SQL error or missing database */
-+#define SQLITE_INTERNAL     2   /* An 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 sqlite_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   /* (Internal Only) 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   /* Database lock protocol error */
-+#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
-+#define SQLITE_SCHEMA      17   /* The database schema changed */
-+#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
-+#define SQLITE_CONSTRAINT  19   /* Abort due to contraint 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 sqlite_bind out of range */
-+#define SQLITE_NOTADB      26   /* File opened that is not a database file */
-+#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
-+#define SQLITE_DONE        101  /* sqlite_step() has finished executing */
-+
-+/*
-+** Each entry in an SQLite table has a unique integer key.  (The key is
-+** the value of the INTEGER PRIMARY KEY column if there is such a column,
-+** otherwise the key is generated at random.  The unique key is always
-+** available as the ROWID, OID, or _ROWID_ column.)  The following routine
-+** returns the integer key of the most recent insert in the database.
-+**
-+** This function is similar to the mysql_insert_id() function from MySQL.
-+*/
-+int sqlite_last_insert_rowid(sqlite*);
-+
-+/*
-+** This function returns the number of database rows that were changed
-+** (or inserted or deleted) by the most recent called sqlite_exec().
-+**
-+** All changes are counted, even if they were later undone by a
-+** ROLLBACK or ABORT.  Except, changes associated with creating and
-+** dropping tables are not counted.
-+**
-+** If a callback invokes sqlite_exec() recursively, then the changes
-+** in the inner, recursive call are counted together with the changes
-+** in the outer call.
-+**
-+** SQLite implements the command "DELETE FROM table" without a WHERE clause
-+** by dropping and recreating the table.  (This is much faster than going
-+** through and deleting individual elements form the table.)  Because of
-+** this optimization, the change count for "DELETE FROM table" will be
-+** zero regardless of the number of elements that were originally in the
-+** table. To get an accurate count of the number of rows deleted, use
-+** "DELETE FROM table WHERE 1" instead.
-+*/
-+int sqlite_changes(sqlite*);
-+
-+/*
-+** This function returns the number of database rows that were changed
-+** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(),
-+** or by the last VM to run to completion. The change count is not updated
-+** by SQL statements other than INSERT, UPDATE or DELETE.
-+**
-+** Changes are counted, even if they are later undone by a ROLLBACK or
-+** ABORT. Changes associated with trigger programs that execute as a
-+** result of the INSERT, UPDATE, or DELETE statement are not counted.
-+**
-+** If a callback invokes sqlite_exec() recursively, then the changes
-+** in the inner, recursive call are counted together with the changes
-+** in the outer call.
-+**
-+** SQLite implements the command "DELETE FROM table" without a WHERE clause
-+** by dropping and recreating the table.  (This is much faster than going
-+** through and deleting individual elements form the table.)  Because of
-+** this optimization, the change count for "DELETE FROM table" will be
-+** zero regardless of the number of elements that were originally in the
-+** table. To get an accurate count of the number of rows deleted, use
-+** "DELETE FROM table WHERE 1" instead.
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+int sqlite_last_statement_changes(sqlite*);
-+
-+/* If the parameter to this routine is one of the return value constants
-+** defined above, then this routine returns a constant text string which
-+** descripts (in English) the meaning of the return value.
-+*/
-+const char *sqlite_error_string(int);
-+#define sqliteErrStr sqlite_error_string  /* Legacy. Do not use in new code. */
-+
-+/* 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.
-+*/
-+void sqlite_interrupt(sqlite*);
-+
-+
-+/* This function returns true if the given input string comprises
-+** one or more complete SQL statements.
-+**
-+** The algorithm is simple.  If the last token other than spaces
-+** and comments is a semicolon, then return true.  otherwise return
-+** false.
-+*/
-+int sqlite_complete(const char *sql);
-+
-+/*
-+** This routine identifies a callback function that is invoked
-+** whenever an attempt is made to open a database table that is
-+** currently locked by another process or thread.  If the busy callback
-+** is NULL, then sqlite_exec() returns SQLITE_BUSY immediately if
-+** it finds a locked table.  If the busy callback is not NULL, then
-+** sqlite_exec() invokes the callback with three arguments.  The
-+** second argument is the name of the locked table and the third
-+** argument is the number of times the table has been busy.  If the
-+** busy callback returns 0, then sqlite_exec() immediately returns
-+** SQLITE_BUSY.  If the callback returns non-zero, then sqlite_exec()
-+** tries to open the table again and the cycle repeats.
-+**
-+** The default busy callback is NULL.
-+**
-+** Sqlite is re-entrant, so the busy handler may start a new query. 
-+** (It is not clear why anyone would every want to do this, but it
-+** is allowed, in theory.)  But the busy handler may not close the
-+** database.  Closing the database from a busy handler will delete 
-+** data structures out from under the executing query and will 
-+** probably result in a coredump.
-+*/
-+void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*);
-+
-+/*
-+** This routine sets a busy handler that sleeps for a while when a
-+** table is locked.  The handler will sleep multiple times until 
-+** at least "ms" milleseconds of sleeping have been done.  After
-+** "ms" milleseconds of sleeping, the handler returns 0 which
-+** causes sqlite_exec() to return SQLITE_BUSY.
-+**
-+** Calling this routine with an argument less than or equal to zero
-+** turns off all busy handlers.
-+*/
-+void sqlite_busy_timeout(sqlite*, int ms);
-+
-+/*
-+** This next routine is really just a wrapper around sqlite_exec().
-+** Instead of invoking a user-supplied callback for each row of the
-+** result, this routine remembers each row of the result in memory
-+** obtained from malloc(), then returns all of the result after the
-+** query has finished. 
-+**
-+** As an example, suppose the query result where this table:
-+**
-+**        Name        | Age
-+**        -----------------------
-+**        Alice       | 43
-+**        Bob         | 28
-+**        Cindy       | 21
-+**
-+** If the 3rd argument were &azResult then after the function returns
-+** azResult will contain the following data:
-+**
-+**        azResult[0] = "Name";
-+**        azResult[1] = "Age";
-+**        azResult[2] = "Alice";
-+**        azResult[3] = "43";
-+**        azResult[4] = "Bob";
-+**        azResult[5] = "28";
-+**        azResult[6] = "Cindy";
-+**        azResult[7] = "21";
-+**
-+** Notice that there is an extra row of data containing the column
-+** headers.  But the *nrow return value is still 3.  *ncolumn is
-+** set to 2.  In general, the number of values inserted into azResult
-+** will be ((*nrow) + 1)*(*ncolumn).
-+**
-+** After the calling function has finished using the result, it should 
-+** pass the result data pointer to sqlite_free_table() in order to 
-+** release the memory that was malloc-ed.  Because of the way the 
-+** malloc() happens, the calling function must not try to call 
-+** malloc() directly.  Only sqlite_free_table() is able to release 
-+** the memory properly and safely.
-+**
-+** The return value of this routine is the same as from sqlite_exec().
-+*/
-+int sqlite_get_table(
-+  sqlite*,               /* An open database */
-+  const char *sql,       /* SQL to be executed */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg          /* Error msg written here */
-+);
-+
-+/*
-+** Call this routine to free the memory that sqlite_get_table() allocated.
-+*/
-+void sqlite_free_table(char **result);
-+
-+/*
-+** The following routines are wrappers around sqlite_exec() and
-+** sqlite_get_table().  The only difference between the routines that
-+** follow and the originals is that the second argument to the 
-+** routines that follow is really a printf()-style format
-+** string describing the SQL to be executed.  Arguments to the format
-+** string appear at the end of the argument list.
-+**
-+** All of the usual printf formatting options apply.  In addition, there
-+** is a "%q" option.  %q 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, so some string variable contains text as follows:
-+**
-+**      char *zText = "It's a happy day!";
-+**
-+** We can use this text in an SQL statement as follows:
-+**
-+**      sqlite_exec_printf(db, "INSERT INTO table VALUES('%q')",
-+**          callback1, 0, 0, zText);
-+**
-+** Because the %q format string is used, the '\'' character in zText
-+** is escaped and the SQL generated is as follows:
-+**
-+**      INSERT INTO table1 VALUES('It''s a happy day!')
-+**
-+** This is correct.  Had we used %s instead of %q, the generated SQL
-+** would have looked like this:
-+**
-+**      INSERT INTO table1 VALUES('It's a happy day!');
-+**
-+** 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.
-+*/
-+int sqlite_exec_printf(
-+  sqlite*,                      /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  ...                           /* Arguments to the format string. */
-+);
-+int sqlite_exec_vprintf(
-+  sqlite*,                      /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  va_list ap                    /* Arguments to the format string. */
-+);
-+int sqlite_get_table_printf(
-+  sqlite*,               /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  ...                    /* Arguments to the format string */
-+);
-+int sqlite_get_table_vprintf(
-+  sqlite*,               /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  va_list ap             /* Arguments to the format string */
-+);
-+char *sqlite_mprintf(const char*,...);
-+char *sqlite_vmprintf(const char*, va_list);
-+
-+/*
-+** Windows systems should call this routine to free memory that
-+** is returned in the in the errmsg parameter of sqlite_open() when
-+** SQLite is a DLL.  For some reason, it does not work to call free()
-+** directly.
-+*/
-+void sqlite_freemem(void *p);
-+
-+/*
-+** Windows systems need functions to call to return the sqlite_version
-+** and sqlite_encoding strings.
-+*/
-+const char *sqlite_libversion(void);
-+const char *sqlite_libencoding(void);
-+
-+/*
-+** A pointer to the following structure is used to communicate with
-+** the implementations of user-defined functions.
-+*/
-+typedef struct sqlite_func sqlite_func;
-+
-+/*
-+** Use the following routines to create new user-defined functions.  See
-+** the documentation for details.
-+*/
-+int sqlite_create_function(
-+  sqlite*,                  /* Database where the new function is registered */
-+  const char *zName,        /* Name of the new function */
-+  int nArg,                 /* Number of arguments.  -1 means any number */
-+  void (*xFunc)(sqlite_func*,int,const char**),  /* C code to implement */
-+  void *pUserData           /* Available via the sqlite_user_data() call */
-+);
-+int sqlite_create_aggregate(
-+  sqlite*,                  /* Database where the new function is registered */
-+  const char *zName,        /* Name of the function */
-+  int nArg,                 /* Number of arguments */
-+  void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */
-+  void (*xFinalize)(sqlite_func*),       /* Called once to get final result */
-+  void *pUserData           /* Available via the sqlite_user_data() call */
-+);
-+
-+/*
-+** Use the following routine to define the datatype returned by a
-+** user-defined function.  The second argument can be one of the
-+** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it
-+** can be an integer greater than or equal to zero.  When the datatype
-+** parameter is non-negative, the type of the result will be the
-+** same as the datatype-th argument.  If datatype==SQLITE_NUMERIC
-+** then the result is always numeric.  If datatype==SQLITE_TEXT then
-+** the result is always text.  If datatype==SQLITE_ARGS then the result
-+** is numeric if any argument is numeric and is text otherwise.
-+*/
-+int sqlite_function_type(
-+  sqlite *db,               /* The database there the function is registered */
-+  const char *zName,        /* Name of the function */
-+  int datatype              /* The datatype for this function */
-+);
-+#define SQLITE_NUMERIC     (-1)
-+/* #define SQLITE_TEXT     (-2)  // See below */
-+#define SQLITE_ARGS        (-3)
-+
-+/*
-+** SQLite version 3 defines SQLITE_TEXT differently.  To allow both
-+** version 2 and version 3 to be included, undefine them both if a
-+** conflict is seen.  Define SQLITE2_TEXT to be the version 2 value.
-+*/
-+#ifdef SQLITE_TEXT
-+# undef SQLITE_TEXT
-+#else
-+# define SQLITE_TEXT     (-2)
-+#endif
-+#define SQLITE2_TEXT     (-2)
-+
-+
-+
-+/*
-+** The user function implementations call one of the following four routines
-+** in order to return their results.  The first parameter to each of these
-+** routines is a copy of the first argument to xFunc() or xFinialize().
-+** The second parameter to these routines is the result to be returned.
-+** A NULL can be passed as the second parameter to sqlite_set_result_string()
-+** in order to return a NULL result.
-+**
-+** The 3rd argument to _string and _error is the number of characters to
-+** take from the string.  If this argument is negative, then all characters
-+** up to and including the first '\000' are used.
-+**
-+** The sqlite_set_result_string() function allocates a buffer to hold the
-+** result and returns a pointer to this buffer.  The calling routine
-+** (that is, the implmentation of a user function) can alter the content
-+** of this buffer if desired.
-+*/
-+char *sqlite_set_result_string(sqlite_func*,const char*,int);
-+void sqlite_set_result_int(sqlite_func*,int);
-+void sqlite_set_result_double(sqlite_func*,double);
-+void sqlite_set_result_error(sqlite_func*,const char*,int);
-+
-+/*
-+** The pUserData parameter to the sqlite_create_function() and
-+** sqlite_create_aggregate() routines used to register user functions
-+** is available to the implementation of the function using this
-+** call.
-+*/
-+void *sqlite_user_data(sqlite_func*);
-+
-+/*
-+** Aggregate functions use the following routine to allocate
-+** a structure for storing their state.  The first time this routine
-+** is called for a particular aggregate, a new structure of size nBytes
-+** is allocated, zeroed, and returned.  On subsequent calls (for the
-+** same aggregate instance) the same buffer is returned.  The implementation
-+** of the aggregate can use the returned buffer to accumulate data.
-+**
-+** The buffer allocated is freed automatically be SQLite.
-+*/
-+void *sqlite_aggregate_context(sqlite_func*, int nBytes);
-+
-+/*
-+** The next routine returns the number of calls to xStep for a particular
-+** aggregate function instance.  The current call to xStep counts so this
-+** routine always returns at least 1.
-+*/
-+int sqlite_aggregate_count(sqlite_func*);
-+
-+/*
-+** This routine registers a callback with the SQLite library.  The
-+** callback is invoked (at compile-time, not at run-time) for each
-+** attempt to access a column of a table in the database.  The callback
-+** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire
-+** SQL statement should be aborted with an error and SQLITE_IGNORE
-+** if the column should be treated as a NULL value.
-+*/
-+int sqlite_set_authorizer(
-+  sqlite*,
-+  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
-+  void *pUserData
-+);
-+
-+/*
-+** The second parameter to the access authorization function above will
-+** be one of the values below.  These values signify what kind of operation
-+** is to be authorized.  The 3rd and 4th parameters to the authorization
-+** function will be parameters or NULL depending on which of the following
-+** codes is used as the second parameter.  The 5th parameter is the name
-+** of the database ("main", "temp", etc.) if applicable.  The 6th parameter
-+** 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 
-+** input SQL code.
-+**
-+**                                          Arg-3           Arg-4
-+*/
-+#define SQLITE_COPY                  0   /* Table Name      File Name       */
-+#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   /* NULL            NULL            */
-+#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
-+#define SQLITE_ATTACH               24   /* Filename        NULL            */
-+#define SQLITE_DETACH               25   /* Database Name   NULL            */
-+
-+
-+/*
-+** The return value of the authorization function should be one of the
-+** following constants:
-+*/
-+/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
-+#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 */
-+
-+/*
-+** Register a function that is called at every invocation of sqlite_exec()
-+** or sqlite_compile().  This function can be used (for example) to generate
-+** a log file of all SQL executed against a database.
-+*/
-+void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*);
-+
-+/*** The Callback-Free API
-+** 
-+** The following routines implement a new way to access SQLite that does not
-+** involve the use of callbacks.
-+**
-+** An sqlite_vm is an opaque object that represents a single SQL statement
-+** that is ready to be executed.
-+*/
-+typedef struct sqlite_vm sqlite_vm;
-+
-+/*
-+** To execute an SQLite query without the use of callbacks, you first have
-+** to compile the SQL using this routine.  The 1st parameter "db" is a pointer
-+** to an sqlite object obtained from sqlite_open().  The 2nd parameter
-+** "zSql" is the text of the SQL to be compiled.   The remaining parameters
-+** are all outputs.
-+**
-+** *pzTail is made to point to the first character past the end of the first
-+** SQL statement in zSql.  This routine only compiles the first statement
-+** in zSql, so *pzTail is left pointing to what remains uncompiled.
-+**
-+** *ppVm is left pointing to a "virtual machine" that can be used to execute
-+** the compiled statement.  Or if there is an error, *ppVm may be set to NULL.
-+** If the input text contained no SQL (if the input is and empty string or
-+** a comment) then *ppVm is set to NULL.
-+**
-+** If any errors are detected during compilation, an error message is written
-+** into space obtained from malloc() and *pzErrMsg is made to point to that
-+** error message.  The calling routine is responsible for freeing the text
-+** of this message when it has finished with it.  Use sqlite_freemem() to
-+** free the message.  pzErrMsg may be NULL in which case no error message
-+** will be generated.
-+**
-+** On success, SQLITE_OK is returned.  Otherwise and error code is returned.
-+*/
-+int sqlite_compile(
-+  sqlite *db,                   /* The open database */
-+  const char *zSql,             /* SQL statement to be compiled */
-+  const char **pzTail,          /* OUT: uncompiled tail of zSql */
-+  sqlite_vm **ppVm,             /* OUT: the virtual machine to execute zSql */
-+  char **pzErrmsg               /* OUT: Error message. */
-+);
-+
-+/*
-+** After an SQL statement has been compiled, it is handed to this routine
-+** to be executed.  This routine executes the statement as far as it can
-+** go then returns.  The return value will be one of SQLITE_DONE,
-+** SQLITE_ERROR, SQLITE_BUSY, SQLITE_ROW, or SQLITE_MISUSE.
-+**
-+** SQLITE_DONE means that the execute of the SQL statement is complete
-+** an no errors have occurred.  sqlite_step() should not be called again
-+** for the same virtual machine.  *pN is set to the number of columns in
-+** the result set and *pazColName is set to an array of strings that
-+** describe the column names and datatypes.  The name of the i-th column
-+** is (*pazColName)[i] and the datatype of the i-th column is
-+** (*pazColName)[i+*pN].  *pazValue is set to NULL.
-+**
-+** SQLITE_ERROR means that the virtual machine encountered a run-time
-+** error.  sqlite_step() should not be called again for the same
-+** virtual machine.  *pN is set to 0 and *pazColName and *pazValue are set
-+** to NULL.  Use sqlite_finalize() to obtain the specific error code
-+** and the error message text for the error.
-+**
-+** SQLITE_BUSY means that an attempt to open the database failed because
-+** another thread or process is holding a lock.  The calling routine
-+** can try again to open the database by calling sqlite_step() again.
-+** The return code will only be SQLITE_BUSY if no busy handler is registered
-+** using the sqlite_busy_handler() or sqlite_busy_timeout() routines.  If
-+** a busy handler callback has been registered but returns 0, then this
-+** routine will return SQLITE_ERROR and sqltie_finalize() will return
-+** SQLITE_BUSY when it is called.
-+**
-+** SQLITE_ROW means that a single row of the result is now available.
-+** The data is contained in *pazValue.  The value of the i-th column is
-+** (*azValue)[i].  *pN and *pazColName are set as described in SQLITE_DONE.
-+** Invoke sqlite_step() again to advance to the next row.
-+**
-+** SQLITE_MISUSE is returned if sqlite_step() is called incorrectly.
-+** For example, if you call sqlite_step() after the virtual machine
-+** has halted (after a prior call to sqlite_step() has returned SQLITE_DONE)
-+** or if you call sqlite_step() with an incorrectly initialized virtual
-+** machine or a virtual machine that has been deleted or that is associated
-+** with an sqlite structure that has been closed.
-+*/
-+int sqlite_step(
-+  sqlite_vm *pVm,              /* The virtual machine to execute */
-+  int *pN,                     /* OUT: Number of columns in result */
-+  const char ***pazValue,      /* OUT: Column data */
-+  const char ***pazColName     /* OUT: Column names and datatypes */
-+);
-+
-+/*
-+** This routine is called to delete a virtual machine after it has finished
-+** executing.  The return value is the result code.  SQLITE_OK is returned
-+** if the statement executed successfully and some other value is returned if
-+** there was any kind of error.  If an error occurred and pzErrMsg is not
-+** NULL, then an error message is written into memory obtained from malloc()
-+** and *pzErrMsg is made to point to that error message.  The calling routine
-+** should use sqlite_freemem() to delete this message when it has finished
-+** with it.
-+**
-+** This routine can be called at any point during the execution of the
-+** virtual machine.  If the virtual machine has not completed execution
-+** when this routine is called, that is like encountering an error or
-+** an interrupt.  (See sqlite_interrupt().)  Incomplete updates may be
-+** rolled back and transactions cancelled,  depending on the circumstances,
-+** and the result code returned will be SQLITE_ABORT.
-+*/
-+int sqlite_finalize(sqlite_vm*, char **pzErrMsg);
-+
-+/*
-+** This routine deletes the virtual machine, writes any error message to
-+** *pzErrMsg and returns an SQLite return code in the same way as the
-+** sqlite_finalize() function.
-+**
-+** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
-+** machine loaded with the compiled version of the original query ready for
-+** execution.
-+**
-+** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+int sqlite_reset(sqlite_vm*, char **pzErrMsg);
-+
-+/*
-+** If the SQL that was handed to sqlite_compile contains variables that
-+** are represeted in the SQL text by a question mark ('?').  This routine
-+** is used to assign values to those variables.
-+**
-+** The first parameter is a virtual machine obtained from sqlite_compile().
-+** The 2nd "idx" parameter determines which variable in the SQL statement
-+** to bind the value to.  The left most '?' is 1.  The 3rd parameter is
-+** the value to assign to that variable.  The 4th parameter is the number
-+** of bytes in the value, including the terminating \000 for strings.
-+** Finally, the 5th "copy" parameter is TRUE if SQLite should make its
-+** own private copy of this value, or false if the space that the 3rd
-+** parameter points to will be unchanging and can be used directly by
-+** SQLite.
-+**
-+** Unbound variables are treated as having a value of NULL.  To explicitly
-+** set a variable to NULL, call this routine with the 3rd parameter as a
-+** NULL pointer.
-+**
-+** If the 4th "len" parameter is -1, then strlen() is used to find the
-+** length.
-+**
-+** This routine can only be called immediately after sqlite_compile()
-+** or sqlite_reset() and before any calls to sqlite_step().
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy);
-+
-+/*
-+** This routine configures a callback function - the progress callback - that
-+** is invoked periodically during long running calls to sqlite_exec(),
-+** sqlite_step() and sqlite_get_table(). An example use for this API is to keep
-+** a GUI updated during a large query.
-+**
-+** The progress callback is invoked once for every N virtual machine opcodes,
-+** where N is the second argument to this function. The progress callback
-+** itself is identified by the third argument to this function. The fourth
-+** argument to this function is a void pointer passed to the progress callback
-+** function each time it is invoked.
-+**
-+** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results 
-+** in less than N opcodes being executed, then the progress callback is not
-+** invoked.
-+** 
-+** Calling this routine overwrites any previously installed progress callback.
-+** To remove the progress callback altogether, pass NULL as the third
-+** argument to this function.
-+**
-+** If the progress callback returns a result other than 0, then the current 
-+** query is immediately terminated and any database changes rolled back. If the
-+** query was part of a larger transaction, then the transaction is not rolled
-+** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. 
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*);
-+
-+/*
-+** Register a callback function to be invoked whenever a new transaction
-+** is committed.  The pArg argument is passed through to the callback.
-+** callback.  If the callback 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.
-+**
-+** Registering a NULL function disables the callback.
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+void *sqlite_commit_hook(sqlite*, int(*)(void*), void*);
-+
-+/*
-+** Open an encrypted SQLite database.  If pKey==0 or nKey==0, this routine
-+** is the same as sqlite_open().
-+**
-+** The code to implement this API is not available in the public release
-+** of SQLite.
-+*/
-+sqlite *sqlite_open_encrypted(
-+  const char *zFilename,   /* Name of the encrypted database */
-+  const void *pKey,        /* Pointer to the key */
-+  int nKey,                /* Number of bytes in the key */
-+  int *pErrcode,           /* Write error code here */
-+  char **pzErrmsg          /* Write error message here */
-+);
-+
-+/*
-+** 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.
-+*/
-+int sqlite_rekey(
-+  sqlite *db,                    /* Database to be rekeyed */
-+  const void *pKey, int nKey     /* The new key */
-+);
-+
-+/*
-+** Encode a binary buffer "in" of size n bytes so that it contains
-+** no instances of characters '\'' or '\000'.  The output is 
-+** null-terminated and can be used as a string value in an INSERT
-+** or UPDATE statement.  Use sqlite_decode_binary() to convert the
-+** string back into its original binary.
-+**
-+** The result is written into a preallocated output buffer "out".
-+** "out" must be able to hold at least 2 +(257*n)/254 bytes.
-+** In other words, the output will be expanded by as much as 3
-+** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
-+** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
-+**
-+** The return value is the number of characters in the encoded
-+** string, excluding the "\000" terminator.
-+**
-+** If out==NULL then no output is generated but the routine still returns
-+** the number of characters that would have been generated if out had
-+** not been NULL.
-+*/
-+int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
-+
-+/*
-+** Decode the string "in" into binary data and write it into "out".
-+** This routine reverses the encoding created by sqlite_encode_binary().
-+** The output will always be a few bytes less than the input.  The number
-+** of bytes of output is returned.  If the input is not a well-formed
-+** encoding, -1 is returned.
-+**
-+** The "in" and "out" parameters may point to the same buffer in order
-+** to decode a string in place.
-+*/
-+int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
-+
-+#ifdef __cplusplus
-+}  /* End of the 'extern "C"' block */
-+#endif
-+
-+#endif /* _SQLITE_H_ */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/sqliteInt.h
-@@ -0,0 +1,1270 @@
-+/*
-+** 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.
-+**
-+** @(#) $Id$
-+*/
-+#include "config.h"
-+#include "sqlite.h"
-+#include "hash.h"
-+#include "parse.h"
-+#include "btree.h"
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <assert.h>
-+
-+/*
-+** The maximum number of in-memory pages to use for the main database
-+** table and for temporary tables.
-+*/
-+#define MAX_PAGES   2000
-+#define TEMP_PAGES   500
-+
-+/*
-+** If the following macro is set to 1, then NULL values are considered
-+** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
-+** compound queries.  No other SQL database engine (among those tested) 
-+** works this way except for OCELOT.  But the SQL92 spec implies that
-+** this is how things should work.
-+**
-+** If the following macro is set to 0, then NULLs are indistinct for
-+** SELECT DISTINCT and for UNION.
-+*/
-+#define NULL_ALWAYS_DISTINCT 0
-+
-+/*
-+** 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 maximum number of attached databases.  This must be at least 2
-+** in order to support the main database file (0) and the file used to
-+** hold temporary tables (1).  And it must be less than 256 because
-+** an unsigned character is used to stored the database index.
-+*/
-+#define MAX_ATTACHED 10
-+
-+/*
-+** The next macro is used to determine where TEMP tables and indices
-+** are stored.  Possible values:
-+**
-+**   0    Always use a temporary files
-+**   1    Use a file unless overridden by "PRAGMA temp_store"
-+**   2    Use memory unless overridden by "PRAGMA temp_store"
-+**   3    Always use memory
-+*/
-+#ifndef TEMP_STORE
-+# define TEMP_STORE 1
-+#endif
-+
-+/*
-+** When building SQLite for embedded systems where memory is scarce,
-+** you can define one or more of the following macros to omit extra
-+** features of the library and thus keep the size of the library to
-+** a minimum.
-+*/
-+/* #define SQLITE_OMIT_AUTHORIZATION  1 */
-+/* #define SQLITE_OMIT_INMEMORYDB     1 */
-+/* #define SQLITE_OMIT_VACUUM         1 */
-+/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
-+/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */
-+
-+/*
-+** 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
-+# define UINT32_TYPE unsigned int
-+#endif
-+#ifndef UINT16_TYPE
-+# define UINT16_TYPE unsigned short int
-+#endif
-+#ifndef INT16_TYPE
-+# define INT16_TYPE short int
-+#endif
-+#ifndef UINT8_TYPE
-+# define UINT8_TYPE unsigned char
-+#endif
-+#ifndef INT8_TYPE
-+# define INT8_TYPE signed char
-+#endif
-+#ifndef INTPTR_TYPE
-+# if SQLITE_PTR_SZ==4
-+#   define INTPTR_TYPE int
-+# else
-+#   define INTPTR_TYPE long long
-+# endif
-+#endif
-+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 UINT8_TYPE i8;             /* 1-byte signed integer */
-+typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
-+typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
-+
-+/*
-+** Defer sourcing vdbe.h until after the "u8" typedef is defined.
-+*/
-+#include "vdbe.h"
-+
-+/*
-+** Most C compilers these days recognize "long double", don't they?
-+** Just in case we encounter one that does not, we will create a macro
-+** for long double so that it can be easily changed to just "double".
-+*/
-+#ifndef LONGDOUBLE_TYPE
-+# define LONGDOUBLE_TYPE long double
-+#endif
-+
-+/*
-+** This macro casts a pointer to an integer.  Useful for doing
-+** pointer arithmetic.
-+*/
-+#define Addr(X)  ((uptr)X)
-+
-+/*
-+** The maximum number of bytes of data that can be put into a single
-+** row of a single table.  The upper bound on this limit is 16777215
-+** bytes (or 16MB-1).  We have arbitrarily set the limit to just 1MB
-+** here because the overflow page chain is inefficient for really big
-+** records and we want to discourage people from thinking that 
-+** multi-megabyte records are OK.  If your needs are different, you can
-+** change this define and recompile to increase or decrease the record
-+** size.
-+**
-+** The 16777198 is computed as follows:  238 bytes of payload on the
-+** original pages plus 16448 overflow pages each holding 1020 bytes of
-+** data.
-+*/
-+#define MAX_BYTES_PER_ROW  1048576
-+/* #define MAX_BYTES_PER_ROW 16777198 */
-+
-+/*
-+** If memory allocation problems are found, recompile with
-+**
-+**      -DMEMORY_DEBUG=1
-+**
-+** to enable some sanity checking on malloc() and free().  To
-+** check for memory leaks, recompile with
-+**
-+**      -DMEMORY_DEBUG=2
-+**
-+** and a line of text will be written to standard error for
-+** each malloc() and free().  This output can be analyzed
-+** by an AWK script to determine if there are any leaks.
-+*/
-+#ifdef MEMORY_DEBUG
-+# define sqliteMalloc(X)    sqliteMalloc_(X,1,__FILE__,__LINE__)
-+# define sqliteMallocRaw(X) sqliteMalloc_(X,0,__FILE__,__LINE__)
-+# define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
-+# define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
-+# define sqliteStrDup(X)    sqliteStrDup_(X,__FILE__,__LINE__)
-+# define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
-+  void sqliteStrRealloc(char**);
-+#else
-+# define sqliteRealloc_(X,Y) sqliteRealloc(X,Y)
-+# define sqliteStrRealloc(X)
-+#endif
-+
-+/*
-+** This variable gets set if malloc() ever fails.  After it gets set,
-+** the SQLite library shuts down permanently.
-+*/
-+extern int sqlite_malloc_failed;
-+
-+/*
-+** The following global variables are used for testing and debugging
-+** only.  They only work if MEMORY_DEBUG is defined.
-+*/
-+#ifdef MEMORY_DEBUG
-+extern int sqlite_nMalloc;       /* Number of sqliteMalloc() calls */
-+extern int sqlite_nFree;         /* Number of sqliteFree() calls */
-+extern int sqlite_iMallocFail;   /* Fail sqliteMalloc() after this many calls */
-+#endif
-+
-+/*
-+** 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 name of the schema table.
-+*/
-+#define SCHEMA_TABLE(x)  (x?TEMP_MASTER_NAME:MASTER_NAME)
-+
-+/*
-+** A convenience macro that returns the number of elements in
-+** an array.
-+*/
-+#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))
-+
-+/*
-+** Forward references to structures
-+*/
-+typedef struct Column Column;
-+typedef struct Table Table;
-+typedef struct Index Index;
-+typedef struct Instruction Instruction;
-+typedef struct Expr Expr;
-+typedef struct ExprList ExprList;
-+typedef struct Parse Parse;
-+typedef struct Token Token;
-+typedef struct IdList IdList;
-+typedef struct SrcList SrcList;
-+typedef struct WhereInfo WhereInfo;
-+typedef struct WhereLevel WhereLevel;
-+typedef struct Select Select;
-+typedef struct AggExpr AggExpr;
-+typedef struct FuncDef FuncDef;
-+typedef struct Trigger Trigger;
-+typedef struct TriggerStep TriggerStep;
-+typedef struct TriggerStack TriggerStack;
-+typedef struct FKey FKey;
-+typedef struct Db Db;
-+typedef struct AuthContext AuthContext;
-+
-+/*
-+** 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 */
-+  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 */
-+  Hash aFKey;          /* Foreign keys indexed by to-table */
-+  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
-+  u16 flags;           /* Flags associated with this database */
-+  void *pAux;          /* Auxiliary data.  Usually NULL */
-+  void (*xFreeAux)(void*);  /* Routine to free pAux */
-+};
-+
-+/*
-+** These macros can be used to test, set, or clear bits in the 
-+** Db.flags field.
-+*/
-+#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
-+#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].flags&(P))!=0)
-+#define DbSetProperty(D,I,P)     (D)->aDb[I].flags|=(P)
-+#define DbClearProperty(D,I,P)   (D)->aDb[I].flags&=~(P)
-+
-+/*
-+** Allowed values for the DB.flags field.
-+**
-+** The DB_Locked flag is set when the first OP_Transaction or OP_Checkpoint
-+** opcode is emitted for a database.  This prevents multiple occurances
-+** of those opcodes for the same database in the same program.  Similarly,
-+** the DB_Cookie flag is set when the OP_VerifyCookie opcode is emitted,
-+** and prevents duplicate OP_VerifyCookies from taking up space and slowing
-+** down execution.
-+**
-+** 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_Locked          0x0001  /* OP_Transaction opcode has been emitted */
-+#define DB_Cookie          0x0002  /* OP_VerifyCookie opcode has been emiited */
-+#define DB_SchemaLoaded    0x0004  /* The schema has been loaded */
-+#define DB_UnresetViews    0x0008  /* Some views have defined column names */
-+
-+
-+/*
-+** Each database is an instance of the following structure.
-+**
-+** The sqlite.file_format is initialized by the database file
-+** and helps determines how the data in the database file is
-+** represented.  This field allows newer versions of the library
-+** to read and write older databases.  The various file formats
-+** are as follows:
-+**
-+**     file_format==1    Version 2.1.0.
-+**     file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.
-+**     file_format==3    Version 2.6.0. Fix empty-string index bug.
-+**     file_format==4    Version 2.7.0. Add support for separate numeric and
-+**                       text datatypes.
-+**
-+** The sqlite.temp_store determines where temporary database files
-+** are stored.  If 1, then a file is created to hold those tables.  If
-+** 2, then they are held in memory.  0 means use the default value in
-+** the TEMP_STORE macro.
-+**
-+** 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 sqlite_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.
-+*/
-+struct sqlite {
-+  int nDb;                      /* Number of backends currently in use */
-+  Db *aDb;                      /* All backends */
-+  Db aDbStatic[2];              /* Static space for the 2 default backends */
-+  int flags;                    /* Miscellanous flags. See below */
-+  u8 file_format;               /* What file format version is this database? */
-+  u8 safety_level;              /* How aggressive at synching data to disk */
-+  u8 want_to_close;             /* Close after all VDBEs are deallocated */
-+  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
-+  u8 onError;                   /* Default conflict algorithm */
-+  int next_cookie;              /* Next value of aDb[0].schema_cookie */
-+  int cache_size;               /* Number of pages to use in the cache */
-+  int nTable;                   /* Number of tables in the database */
-+  void *pBusyArg;               /* 1st Argument to the busy callback */
-+  int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
-+  void *pCommitArg;             /* Argument to xCommitCallback() */   
-+  int (*xCommitCallback)(void*);/* Invoked at every commit. */
-+  Hash aFunc;                   /* All functions that can be in SQL exprs */
-+  int lastRowid;                /* ROWID of most recent insert (see above) */
-+  int priorNewRowid;            /* Last randomly generated ROWID */
-+  int magic;                    /* Magic number for detect library misuse */
-+  int nChange;                  /* Number of rows changed (see above) */
-+  int lsChange;                 /* Last statement change count (see above) */
-+  int csChange;                 /* Current statement change count (see above) */
-+  struct sqliteInitInfo {       /* Information used during initialization */
-+    int iDb;                       /* When back is being initialized */
-+    int newTnum;                   /* Rootpage of table being initialized */
-+    u8 busy;                       /* TRUE if currently initializing */
-+  } init;
-+  struct Vdbe *pVdbe;           /* List of active virtual machines */
-+  void (*xTrace)(void*,const char*);     /* Trace function */
-+  void *pTraceArg;                       /* Argument to the trace function */
-+#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
-+};
-+
-+/*
-+** 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_Initialized    0x00000002  /* True after initialization */
-+#define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
-+#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_ReportTypes    0x00000200  /* Include information on datatypes */
-+                                          /*   in 4th argument of callback */
-+
-+/*
-+** 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_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 {
-+  void (*xFunc)(sqlite_func*,int,const char**);  /* Regular function */
-+  void (*xStep)(sqlite_func*,int,const char**);  /* Aggregate function step */
-+  void (*xFinalize)(sqlite_func*);           /* Aggregate function finializer */
-+  signed char nArg;         /* Number of arguments.  -1 means unlimited */
-+  signed char dataType;     /* Arg that determines datatype.  -1=NUMERIC, */
-+                            /* -2=TEXT. -3=SQLITE_ARGS */
-+  u8 includeTypes;          /* Add datatypes to args of xFunc and xStep */
-+  void *pUserData;          /* User data parameter */
-+  FuncDef *pNext;           /* Next function with same name */
-+};
-+
-+/*
-+** information about each column of an SQL table is held in an instance
-+** of this structure.
-+*/
-+struct Column {
-+  char *zName;     /* Name of this column */
-+  char *zDflt;     /* Default value of this column */
-+  char *zType;     /* Data type for this column */
-+  u8 notNull;      /* True if there is a NOT NULL constraint */
-+  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
-+  u8 sortOrder;    /* Some combination of SQLITE_SO_... values */
-+  u8 dottedName;   /* True if zName contains a "." character */
-+};
-+
-+/*
-+** The allowed sort orders.
-+**
-+** The TEXT and NUM values use bits that do not overlap with DESC and ASC.
-+** That way the two can be combined into a single number.
-+*/
-+#define SQLITE_SO_UNK       0  /* Use the default collating type.  (SCT_NUM) */
-+#define SQLITE_SO_TEXT      2  /* Sort using memcmp() */
-+#define SQLITE_SO_NUM       4  /* Sort using sqliteCompare() */
-+#define SQLITE_SO_TYPEMASK  6  /* Mask to extract the collating sequence */
-+#define SQLITE_SO_ASC       0  /* Sort in ascending order */
-+#define SQLITE_SO_DESC      1  /* Sort in descending order */
-+#define SQLITE_SO_DIRMASK   1  /* Mask to extract the sort direction */
-+
-+/*
-+** 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.  Table.hasPrimKey is true 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 Table.isTransient
-+** is true, 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 {
-+  char *zName;     /* Name of the table */
-+  int nCol;        /* Number of columns in this table */
-+  Column *aCol;    /* Information about each column */
-+  int iPKey;       /* If not less then 0, use aCol[iPKey] as the primary key */
-+  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. */
-+  u8 readOnly;     /* True if this table should not be written by the user */
-+  u8 iDb;          /* Index into sqlite.aDb[] of the backend for this table */
-+  u8 isTransient;  /* True if automatically deleted when VDBE finishes */
-+  u8 hasPrimKey;   /* True if there exists a primary key */
-+  u8 keyConf;      /* What to do in case of uniqueness conflict on iPKey */
-+  Trigger *pTrigger; /* List of SQL triggers on this table */
-+  FKey *pFKey;       /* Linked list of all foreign keys in this table */
-+};
-+
-+/*
-+** 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 existance of the to-table is not checked
-+** until an attempt is made to insert data into the from-table.
-+**
-+** The sqlite.aFKey hash table stores pointers to this structure
-+** given the name of a to-table.  For each to-table, all foreign keys
-+** associated with that table are on a linked list using the FKey.pNextTo
-+** field.
-+*/
-+struct FKey {
-+  Table *pFrom;     /* The table that constains the REFERENCES clause */
-+  FKey *pNextFrom;  /* Next foreign key in pFrom */
-+  char *zTo;        /* Name of table that the key points to */
-+  FKey *pNextTo;    /* Next foreign key that points to zTo */
-+  int nCol;         /* Number of columns in this key */
-+  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;          /* One entry for each of nCol column s */
-+  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 */
-+};
-+
-+/*
-+** SQLite supports many different ways to resolve a contraint
-+** 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 */
-+
-+/*
-+** 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 */
-+  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) */
-+  u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
-+  Index *pNext;    /* The next index associated with the same table */
-+};
-+
-+/*
-+** 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 assuptions about Token.dyn
-+** and Token.n when Token.z==0.
-+*/
-+struct Token {
-+  const char *z;      /* Text of the token.  Not NULL-terminated! */
-+  unsigned dyn  : 1;  /* True for malloced memory, false for static */
-+  unsigned n    : 31; /* Number of characters in this token */
-+};
-+
-+/*
-+** 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.
-+**
-+** Expr.pRight and Expr.pLeft are subexpressions.  Expr.pList is a list
-+** of argument if the expression is a function.
-+**
-+** Expr.token is the operator token for this node.  For some expressions
-+** that have subexpressions, Expr.token can be the complete text that gave
-+** rise to the Expr.  In the latter case, the token is marked as being
-+** a compound token.
-+**
-+** 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 a function, the Expr.iTable is an integer code
-+** representing which function.  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.
-+**
-+** The Expr.pSelect field points to a SELECT statement.  The SELECT might
-+** be the right operand of an IN operator.  Or, if a scalar SELECT appears
-+** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
-+** operand.
-+*/
-+struct Expr {
-+  u8 op;                 /* Operation performed by this node */
-+  u8 dataType;           /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */
-+  u8 iDb;                /* Database referenced by this expression */
-+  u8 flags;              /* Various flags.  See below */
-+  Expr *pLeft, *pRight;  /* Left and right subnodes */
-+  ExprList *pList;       /* A list of expressions used as function arguments
-+                         ** or in "<expr> IN (<expr-list)" */
-+  Token token;           /* An operand token */
-+  Token span;            /* Complete text of the expression */
-+  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
-+                         ** iColumn-th field of the iTable-th table. */
-+  int iAgg;              /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull
-+                         ** result from the iAgg-th element of the aggregator */
-+  Select *pSelect;       /* When the expression is a sub-select.  Also the
-+                         ** right side of "<expr> IN (<select>)" */
-+};
-+
-+/*
-+** 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 */
-+
-+/*
-+** 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)
-+
-+/*
-+** 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 */
-+  struct ExprList_item {
-+    Expr *pExpr;           /* The list of expressions */
-+    char *zName;           /* Token associated with this expression */
-+    u8 sortOrder;          /* 1 for DESC or 0 for ASC */
-+    u8 isAgg;              /* True if this is an aggregate like count(*) */
-+    u8 done;               /* A flag to indicate when processing is finished */
-+  } *a;                  /* One entry for each expression */
-+};
-+
-+/*
-+** 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 {
-+  int nId;         /* Number of identifiers on the list */
-+  int nAlloc;      /* Number of entries allocated for a[] below */
-+  struct IdList_item {
-+    char *zName;      /* Name of the identifier */
-+    int idx;          /* Index in some Table.aCol[] of a column named zName */
-+  } *a;
-+};
-+
-+/*
-+** 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.
-+*/
-+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 */
-+    int jointype;     /* Type of join between this table and the next */
-+    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 */
-+  } 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_NATURAL   0x0002    /* True for a "natural" join */
-+#define JT_LEFT      0x0004    /* Left outer join */
-+#define JT_RIGHT     0x0008    /* Right outer join */
-+#define JT_OUTER     0x0010    /* The "OUTER" keyword is present */
-+#define JT_ERROR     0x0020    /* unknown or unsupported join type */
-+
-+/*
-+** 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.
-+*/
-+struct WhereLevel {
-+  int iMem;            /* Memory cell used by this level */
-+  Index *pIdx;         /* Index used */
-+  int iCur;            /* Cursor number used for this index */
-+  int score;           /* How well this indexed scored */
-+  int brk;             /* Jump here to break out of the loop */
-+  int cont;            /* Jump here to continue with the next loop cycle */
-+  int op, p1, p2;      /* Opcode used to terminate the loop */
-+  int iLeftJoin;       /* Memory cell used to implement LEFT OUTER JOIN */
-+  int top;             /* First instruction of interior of the loop */
-+  int inOp, inP1, inP2;/* Opcode used to implement an IN operator */
-+  int bRev;            /* Do the scan in the reverse direction */
-+};
-+
-+/*
-+** 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;
-+  SrcList *pTabList;   /* List of tables in the join */
-+  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 */
-+  int savedNTab;       /* Value of pParse->nTab before WhereBegin() */
-+  int peakNTab;        /* Value of pParse->nTab after WhereBegin() */
-+  WhereLevel a[1];     /* Information about each nest loop in the WHERE */
-+};
-+
-+/*
-+** An instance of the following structure contains all information
-+** needed to generate code for a single SELECT statement.
-+**
-+** The zSelect field is used when the Select structure must be persistent.
-+** Normally, the expression tree points to tokens in the original input
-+** string that encodes the select.  But if the Select structure must live
-+** longer than its input string (for example when it is used to describe
-+** a VIEW) we have to make a copy of the input string so that the nodes
-+** of the expression tree will have something to point to.  zSelect is used
-+** to hold that copy.
-+**
-+** 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.
-+*/
-+struct Select {
-+  ExprList *pEList;      /* The fields of the result */
-+  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
-+  u8 isDistinct;         /* True if the DISTINCT keyword is present */
-+  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 */
-+  int nLimit, nOffset;   /* LIMIT and OFFSET values.  -1 means not used */
-+  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
-+  char *zSelect;         /* Complete text of the SELECT command */
-+};
-+
-+/*
-+** The results of a select can be distributed in several ways.
-+*/
-+#define SRT_Callback     1  /* Invoke a callback with each row of result */
-+#define SRT_Mem          2  /* Store result in a memory cell */
-+#define SRT_Set          3  /* Store result as unique keys in a table */
-+#define SRT_Union        5  /* Store result as keys in a table */
-+#define SRT_Except       6  /* Remove result from a UNION table */
-+#define SRT_Table        7  /* Store result as data with a unique key */
-+#define SRT_TempTable    8  /* Store result in a trasient table */
-+#define SRT_Discard      9  /* Do not save the results anywhere */
-+#define SRT_Sorter      10  /* Store results in the sorter */
-+#define SRT_Subroutine  11  /* Call a subroutine to handle results */
-+
-+/*
-+** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
-+** we have to do some additional analysis of expressions.  An instance
-+** of the following structure holds information about a single subexpression
-+** somewhere in the SELECT statement.  An array of these structures holds
-+** all the information we need to generate code for aggregate
-+** expressions.
-+**
-+** Note that when analyzing a SELECT containing aggregates, both
-+** non-aggregate field variables and aggregate functions are stored
-+** in the AggExpr array of the Parser structure.
-+**
-+** The pExpr field points to an expression that is part of either the
-+** field list, the GROUP BY clause, the HAVING clause or the ORDER BY
-+** clause.  The expression will be freed when those clauses are cleaned
-+** up.  Do not try to delete the expression attached to AggExpr.pExpr.
-+**
-+** If AggExpr.pExpr==0, that means the expression is "count(*)".
-+*/
-+struct AggExpr {
-+  int isAgg;        /* if TRUE contains an aggregate function */
-+  Expr *pExpr;      /* The expression */
-+  FuncDef *pFunc;   /* Information about the aggregate function */
-+};
-+
-+/*
-+** 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.
-+*/
-+struct Parse {
-+  sqlite *db;          /* The main database structure */
-+  int rc;              /* Return code from execution */
-+  char *zErrMsg;       /* An error message */
-+  Token sErrToken;     /* The token at which the error occurred */
-+  Token sFirstToken;   /* The first token parsed */
-+  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 */
-+  Vdbe *pVdbe;         /* An engine for executing database bytecode */
-+  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
-+  u8 explain;          /* True if the EXPLAIN flag is found on the query */
-+  u8 nameClash;        /* A permanent table name clashes with temp table name */
-+  u8 useAgg;           /* If true, extract field values from the aggregator
-+                       ** while generating expressions.  Normally false */
-+  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 nAgg;            /* Number of aggregate expressions */
-+  int nVar;            /* Number of '?' variables seen in the SQL so far */
-+  AggExpr *aAgg;       /* An array of aggregate expressions */
-+  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
-+  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
-+  TriggerStack *trigStack;  /* Trigger actions being coded */
-+};
-+
-+/*
-+** 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 P2 value in OP_PutIntKey and OP_Delete
-+*/
-+#define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
-+#define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
-+#define OPFLAG_CSCHANGE  4    /* Set to update db->csChange */
-+
-+/*
-+ * 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 sqlite* 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 *name;             /* The name of the trigger                        */
-+  char *table;            /* The table or view to which the trigger applies */
-+  u8 iDb;                 /* Database containing this trigger               */
-+  u8 iTabDb;              /* Database containing Trigger.table              */
-+  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
-+  u8 tr_tm;               /* One of TK_BEFORE, TK_AFTER */
-+  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
-+  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
-+                             the <column-list> is stored here */
-+  int foreach;            /* One of TK_ROW or TK_STATEMENT */
-+  Token nameToken;        /* Token containing zName. Use during parsing only */
-+
-+  TriggerStep *step_list; /* Link list of trigger program steps             */
-+  Trigger *pNext;         /* Next trigger associated with the table */
-+};
-+
-+/*
-+ * 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 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 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 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 sqliteUpdate() documentation of "pChanges"
-+ *              argument.
-+ * 
-+ */
-+struct TriggerStep {
-+  int op;              /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
-+  int orconf;          /* OE_Rollback etc. */
-+  Trigger *pTrig;      /* The trigger that this step is a part of */
-+
-+  Select *pSelect;     /* Valid for SELECT and sometimes 
-+                        INSERT steps (when pExprList == 0) */
-+  Token target;        /* Valid for DELETE, UPDATE, INSERT steps */
-+  Expr *pWhere;        /* Valid for DELETE, UPDATE steps */
-+  ExprList *pExprList; /* Valid for UPDATE statements and sometimes 
-+                         INSERT steps (when pSelect == 0)         */
-+  IdList *pIdList;     /* Valid for INSERT statements only */
-+
-+  TriggerStep * pNext; /* Next in the link-list */
-+};
-+
-+/*
-+ * An instance of struct TriggerStack stores information required during code
-+ * generation of a single trigger program. While the trigger program is being
-+ * coded, its associated TriggerStack instance is pointed to by the
-+ * "pTriggerStack" member of the Parse structure.
-+ *
-+ * The pTab member points to the table that triggers are being coded on. The 
-+ * newIdx member contains the index of the vdbe cursor that points at the temp
-+ * table that stores the new.* references. If new.* references are not valid
-+ * for the trigger being coded (for example an ON DELETE trigger), then newIdx
-+ * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
-+ *
-+ * The ON CONFLICT policy to be used for the trigger program steps is stored 
-+ * as the orconf member. If this is OE_Default, then the ON CONFLICT clause 
-+ * specified for individual triggers steps is used.
-+ *
-+ * struct TriggerStack has a "pNext" member, to allow linked lists to be
-+ * constructed. When coding nested triggers (triggers fired by other triggers)
-+ * each nested trigger stores its parent trigger's TriggerStack as the "pNext" 
-+ * pointer. Once the nested trigger has been coded, the pNext value is restored
-+ * to the pTriggerStack member of the Parse stucture and coding of the parent
-+ * trigger continues.
-+ *
-+ * Before a nested trigger is coded, the linked list pointed to by the 
-+ * pTriggerStack is scanned to ensure that the trigger is not about to be coded
-+ * recursively. If this condition is detected, the nested trigger is not coded.
-+ */
-+struct TriggerStack {
-+  Table *pTab;         /* Table that triggers are currently being coded on */
-+  int newIdx;          /* Index of vdbe cursor to "new" temp table */
-+  int oldIdx;          /* Index of vdbe cursor to "old" temp table */
-+  int orconf;          /* Current orconf policy */
-+  int ignoreJump;      /* where to jump to for a RAISE(IGNORE) */
-+  Trigger *pTrigger;   /* The trigger currently being coded */
-+  TriggerStack *pNext; /* Next trigger down on the trigger stack */
-+};
-+
-+/*
-+** 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 */
-+};
-+
-+/*
-+ * This global flag is set for performance testing of triggers. When it is set
-+ * SQLite will perform the overhead of building new and old trigger references 
-+ * even when no triggers exist
-+ */
-+extern int always_code_trigger_setup;
-+
-+/*
-+** Internal function prototypes
-+*/
-+int sqliteStrICmp(const char *, const char *);
-+int sqliteStrNICmp(const char *, const char *, int);
-+int sqliteHashNoCase(const char *, int);
-+int sqliteIsNumber(const char*);
-+int sqliteCompare(const char *, const char *);
-+int sqliteSortCompare(const char *, const char *);
-+void sqliteRealToSortable(double r, char *);
-+#ifdef MEMORY_DEBUG
-+  void *sqliteMalloc_(int,int,char*,int);
-+  void sqliteFree_(void*,char*,int);
-+  void *sqliteRealloc_(void*,int,char*,int);
-+  char *sqliteStrDup_(const char*,char*,int);
-+  char *sqliteStrNDup_(const char*, int,char*,int);
-+  void sqliteCheckMemory(void*,int);
-+#else
-+  void *sqliteMalloc(int);
-+  void *sqliteMallocRaw(int);
-+  void sqliteFree(void*);
-+  void *sqliteRealloc(void*,int);
-+  char *sqliteStrDup(const char*);
-+  char *sqliteStrNDup(const char*, int);
-+# define sqliteCheckMemory(a,b)
-+#endif
-+char *sqliteMPrintf(const char*, ...);
-+char *sqliteVMPrintf(const char*, va_list);
-+void sqliteSetString(char **, ...);
-+void sqliteSetNString(char **, ...);
-+void sqliteErrorMsg(Parse*, const char*, ...);
-+void sqliteDequote(char*);
-+int sqliteKeywordCode(const char*, int);
-+int sqliteRunParser(Parse*, const char*, char **);
-+void sqliteExec(Parse*);
-+Expr *sqliteExpr(int, Expr*, Expr*, Token*);
-+void sqliteExprSpan(Expr*,Token*,Token*);
-+Expr *sqliteExprFunction(ExprList*, Token*);
-+void sqliteExprDelete(Expr*);
-+ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
-+void sqliteExprListDelete(ExprList*);
-+int sqliteInit(sqlite*, char**);
-+void sqlitePragma(Parse*,Token*,Token*,int);
-+void sqliteResetInternalSchema(sqlite*, int);
-+void sqliteBeginParse(Parse*,int);
-+void sqliteRollbackInternalChanges(sqlite*);
-+void sqliteCommitInternalChanges(sqlite*);
-+Table *sqliteResultSetOfSelect(Parse*,char*,Select*);
-+void sqliteOpenMasterTable(Vdbe *v, int);
-+void sqliteStartTable(Parse*,Token*,Token*,int,int);
-+void sqliteAddColumn(Parse*,Token*);
-+void sqliteAddNotNull(Parse*, int);
-+void sqliteAddPrimaryKey(Parse*, IdList*, int);
-+void sqliteAddColumnType(Parse*,Token*,Token*);
-+void sqliteAddDefaultValue(Parse*,Token*,int);
-+int sqliteCollateType(const char*, int);
-+void sqliteAddCollateType(Parse*, int);
-+void sqliteEndTable(Parse*,Token*,Select*);
-+void sqliteCreateView(Parse*,Token*,Token*,Select*,int);
-+int sqliteViewGetColumnNames(Parse*,Table*);
-+void sqliteDropTable(Parse*, Token*, int);
-+void sqliteDeleteTable(sqlite*, Table*);
-+void sqliteInsert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
-+IdList *sqliteIdListAppend(IdList*, Token*);
-+int sqliteIdListIndex(IdList*,const char*);
-+SrcList *sqliteSrcListAppend(SrcList*, Token*, Token*);
-+void sqliteSrcListAddAlias(SrcList*, Token*);
-+void sqliteSrcListAssignCursors(Parse*, SrcList*);
-+void sqliteIdListDelete(IdList*);
-+void sqliteSrcListDelete(SrcList*);
-+void sqliteCreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
-+void sqliteDropIndex(Parse*, SrcList*);
-+void sqliteAddKeyType(Vdbe*, ExprList*);
-+void sqliteAddIdxKeyType(Vdbe*, Index*);
-+int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
-+Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
-+                        int,int,int);
-+void sqliteSelectDelete(Select*);
-+void sqliteSelectUnbind(Select*);
-+Table *sqliteSrcListLookup(Parse*, SrcList*);
-+int sqliteIsReadOnly(Parse*, Table*, int);
-+void sqliteDeleteFrom(Parse*, SrcList*, Expr*);
-+void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int);
-+WhereInfo *sqliteWhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
-+void sqliteWhereEnd(WhereInfo*);
-+void sqliteExprCode(Parse*, Expr*);
-+int sqliteExprCodeExprList(Parse*, ExprList*, int);
-+void sqliteExprIfTrue(Parse*, Expr*, int, int);
-+void sqliteExprIfFalse(Parse*, Expr*, int, int);
-+Table *sqliteFindTable(sqlite*,const char*, const char*);
-+Table *sqliteLocateTable(Parse*,const char*, const char*);
-+Index *sqliteFindIndex(sqlite*,const char*, const char*);
-+void sqliteUnlinkAndDeleteIndex(sqlite*,Index*);
-+void sqliteCopy(Parse*, SrcList*, Token*, Token*, int);
-+void sqliteVacuum(Parse*, Token*);
-+int sqliteRunVacuum(char**, sqlite*);
-+int sqliteGlobCompare(const unsigned char*,const unsigned char*);
-+int sqliteLikeCompare(const unsigned char*,const unsigned char*);
-+char *sqliteTableNameFromToken(Token*);
-+int sqliteExprCheck(Parse*, Expr*, int, int*);
-+int sqliteExprType(Expr*);
-+int sqliteExprCompare(Expr*, Expr*);
-+int sqliteFuncId(Token*);
-+int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
-+int sqliteExprAnalyzeAggregates(Parse*, Expr*);
-+Vdbe *sqliteGetVdbe(Parse*);
-+void sqliteRandomness(int, void*);
-+void sqliteRollbackAll(sqlite*);
-+void sqliteCodeVerifySchema(Parse*, int);
-+void sqliteBeginTransaction(Parse*, int);
-+void sqliteCommitTransaction(Parse*);
-+void sqliteRollbackTransaction(Parse*);
-+int sqliteExprIsConstant(Expr*);
-+int sqliteExprIsInteger(Expr*, int*);
-+int sqliteIsRowid(const char*);
-+void sqliteGenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
-+void sqliteGenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
-+void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
-+void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int, int);
-+int sqliteOpenTableAndIndices(Parse*, Table*, int);
-+void sqliteBeginWriteOperation(Parse*, int, int);
-+void sqliteEndWriteOperation(Parse*);
-+Expr *sqliteExprDup(Expr*);
-+void sqliteTokenCopy(Token*, Token*);
-+ExprList *sqliteExprListDup(ExprList*);
-+SrcList *sqliteSrcListDup(SrcList*);
-+IdList *sqliteIdListDup(IdList*);
-+Select *sqliteSelectDup(Select*);
-+FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
-+void sqliteRegisterBuiltinFunctions(sqlite*);
-+void sqliteRegisterDateTimeFunctions(sqlite*);
-+int sqliteSafetyOn(sqlite*);
-+int sqliteSafetyOff(sqlite*);
-+int sqliteSafetyCheck(sqlite*);
-+void sqliteChangeCookie(sqlite*, Vdbe*);
-+void sqliteBeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
-+void sqliteFinishTrigger(Parse*, TriggerStep*, Token*);
-+void sqliteDropTrigger(Parse*, SrcList*);
-+void sqliteDropTriggerPtr(Parse*, Trigger*, int);
-+int sqliteTriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
-+int sqliteCodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
-+                         int, int);
-+void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
-+void sqliteDeleteTriggerStep(TriggerStep*);
-+TriggerStep *sqliteTriggerSelectStep(Select*);
-+TriggerStep *sqliteTriggerInsertStep(Token*, IdList*, ExprList*, Select*, int);
-+TriggerStep *sqliteTriggerUpdateStep(Token*, ExprList*, Expr*, int);
-+TriggerStep *sqliteTriggerDeleteStep(Token*, Expr*);
-+void sqliteDeleteTrigger(Trigger*);
-+int sqliteJoinType(Parse*, Token*, Token*, Token*);
-+void sqliteCreateForeignKey(Parse*, IdList*, Token*, IdList*, int);
-+void sqliteDeferForeignKey(Parse*, int);
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  void sqliteAuthRead(Parse*,Expr*,SrcList*);
-+  int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*);
-+  void sqliteAuthContextPush(Parse*, AuthContext*, const char*);
-+  void sqliteAuthContextPop(AuthContext*);
-+#else
-+# define sqliteAuthRead(a,b,c)
-+# define sqliteAuthCheck(a,b,c,d,e)    SQLITE_OK
-+# define sqliteAuthContextPush(a,b,c)
-+# define sqliteAuthContextPop(a)  ((void)(a))
-+#endif
-+void sqliteAttach(Parse*, Token*, Token*, Token*);
-+void sqliteDetach(Parse*, Token*);
-+int sqliteBtreeFactory(const sqlite *db, const char *zFilename,
-+                       int mode, int nPg, Btree **ppBtree);
-+int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
-+int sqliteFixSrcList(DbFixer*, SrcList*);
-+int sqliteFixSelect(DbFixer*, Select*);
-+int sqliteFixExpr(DbFixer*, Expr*);
-+int sqliteFixExprList(DbFixer*, ExprList*);
-+int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
-+double sqliteAtoF(const char *z, const char **);
-+char *sqlite_snprintf(int,char*,const char*,...);
-+int sqliteFitsIn32Bits(const char *);
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/sqlite.w32.h
-@@ -0,0 +1,764 @@
-+/*
-+** 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.
-+**
-+** @(#) $Id$
-+*/
-+#ifndef _SQLITE_H_
-+#define _SQLITE_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
-+
-+/*
-+** The version of the SQLite library.
-+*/
-+#define SQLITE_VERSION         "2.8.17"
-+
-+/*
-+** The version string is also compiled into the library so that a program
-+** can check to make sure that the lib*.a file and the *.h file are from
-+** the same version.
-+*/
-+extern const char sqlite_version[];
-+
-+/*
-+** The SQLITE_UTF8 macro is defined if the library expects to see
-+** UTF-8 encoded data.  The SQLITE_ISO8859 macro is defined if the
-+** iso8859 encoded should be used.
-+*/
-+#define SQLITE_ISO8859 1
-+
-+/*
-+** The following constant holds one of two strings, "UTF-8" or "iso8859",
-+** depending on which character encoding the SQLite library expects to
-+** see.  The character encoding makes a difference for the LIKE and GLOB
-+** operators and for the LENGTH() and SUBSTR() functions.
-+*/
-+extern const char sqlite_encoding[];
-+
-+/*
-+** Each open sqlite database is represented by an instance of the
-+** following opaque structure.
-+*/
-+typedef struct sqlite sqlite;
-+
-+/*
-+** A function to open a new sqlite database.  
-+**
-+** If the database does not exist and mode indicates write
-+** permission, then a new database is created.  If the database
-+** does not exist and mode does not indicate write permission,
-+** then the open fails, an error message generated (if errmsg!=0)
-+** and the function returns 0.
-+** 
-+** If mode does not indicates user write permission, then the 
-+** database is opened read-only.
-+**
-+** The Truth:  As currently implemented, all databases are opened
-+** for writing all the time.  Maybe someday we will provide the
-+** ability to open a database readonly.  The mode parameters is
-+** provided in anticipation of that enhancement.
-+*/
-+sqlite *sqlite_open(const char *filename, int mode, char **errmsg);
-+
-+/*
-+** A function to close the database.
-+**
-+** Call this function with a pointer to a structure that was previously
-+** returned from sqlite_open() and the corresponding database will by closed.
-+*/
-+void sqlite_close(sqlite *);
-+
-+/*
-+** The type for a callback function.
-+*/
-+typedef int (*sqlite_callback)(void*,int,char**, char**);
-+
-+/*
-+** A function to executes one or more statements of SQL.
-+**
-+** If one or more of the SQL statements are queries, then
-+** the callback function specified by the 3rd parameter is
-+** invoked once for each row of the query result.  This callback
-+** should normally return 0.  If the callback returns a non-zero
-+** value then the query is aborted, all subsequent SQL statements
-+** are skipped and the sqlite_exec() function returns the SQLITE_ABORT.
-+**
-+** The 4th parameter is an arbitrary pointer that is passed
-+** to the callback function as its first parameter.
-+**
-+** The 2nd parameter to the callback function is the number of
-+** columns in the query result.  The 3rd parameter to the callback
-+** is an array of strings holding the values for each column.
-+** The 4th parameter to the callback is an array of strings holding
-+** the names of each column.
-+**
-+** The callback function may be NULL, even for queries.  A NULL
-+** callback is not an error.  It just means that no callback
-+** will be invoked.
-+**
-+** If an error occurs while parsing or evaluating the SQL (but
-+** not while executing the callback) then an appropriate error
-+** message is written into memory obtained from malloc() and
-+** *errmsg is made to point to that message.  The calling function
-+** is responsible for freeing the memory that holds the error
-+** message.   Use sqlite_freemem() for this.  If errmsg==NULL,
-+** then no error message is ever written.
-+**
-+** The return value is is SQLITE_OK if there are no errors and
-+** some other return code if there is an error.  The particular
-+** return value depends on the type of error. 
-+**
-+** If the query could not be executed because a database file is
-+** locked or busy, then this function returns SQLITE_BUSY.  (This
-+** behavior can be modified somewhat using the sqlite_busy_handler()
-+** and sqlite_busy_timeout() functions below.)
-+*/
-+int sqlite_exec(
-+  sqlite*,                      /* An open database */
-+  const char *sql,              /* SQL to be executed */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg                 /* Error msg written here */
-+);
-+
-+/*
-+** Return values for sqlite_exec() and sqlite_step()
-+*/
-+#define SQLITE_OK           0   /* Successful result */
-+#define SQLITE_ERROR        1   /* SQL error or missing database */
-+#define SQLITE_INTERNAL     2   /* An 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 sqlite_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   /* (Internal Only) 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   /* Database lock protocol error */
-+#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
-+#define SQLITE_SCHEMA      17   /* The database schema changed */
-+#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
-+#define SQLITE_CONSTRAINT  19   /* Abort due to contraint 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 sqlite_bind out of range */
-+#define SQLITE_NOTADB      26   /* File opened that is not a database file */
-+#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
-+#define SQLITE_DONE        101  /* sqlite_step() has finished executing */
-+
-+/*
-+** Each entry in an SQLite table has a unique integer key.  (The key is
-+** the value of the INTEGER PRIMARY KEY column if there is such a column,
-+** otherwise the key is generated at random.  The unique key is always
-+** available as the ROWID, OID, or _ROWID_ column.)  The following routine
-+** returns the integer key of the most recent insert in the database.
-+**
-+** This function is similar to the mysql_insert_id() function from MySQL.
-+*/
-+int sqlite_last_insert_rowid(sqlite*);
-+
-+/*
-+** This function returns the number of database rows that were changed
-+** (or inserted or deleted) by the most recent called sqlite_exec().
-+**
-+** All changes are counted, even if they were later undone by a
-+** ROLLBACK or ABORT.  Except, changes associated with creating and
-+** dropping tables are not counted.
-+**
-+** If a callback invokes sqlite_exec() recursively, then the changes
-+** in the inner, recursive call are counted together with the changes
-+** in the outer call.
-+**
-+** SQLite implements the command "DELETE FROM table" without a WHERE clause
-+** by dropping and recreating the table.  (This is much faster than going
-+** through and deleting individual elements form the table.)  Because of
-+** this optimization, the change count for "DELETE FROM table" will be
-+** zero regardless of the number of elements that were originally in the
-+** table. To get an accurate count of the number of rows deleted, use
-+** "DELETE FROM table WHERE 1" instead.
-+*/
-+int sqlite_changes(sqlite*);
-+
-+/* If the parameter to this routine is one of the return value constants
-+** defined above, then this routine returns a constant text string which
-+** descripts (in English) the meaning of the return value.
-+*/
-+const char *sqlite_error_string(int);
-+#define sqliteErrStr sqlite_error_string  /* Legacy. Do not use in new code. */
-+
-+/* 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.
-+*/
-+void sqlite_interrupt(sqlite*);
-+
-+
-+/* This function returns true if the given input string comprises
-+** one or more complete SQL statements.
-+**
-+** The algorithm is simple.  If the last token other than spaces
-+** and comments is a semicolon, then return true.  otherwise return
-+** false.
-+*/
-+int sqlite_complete(const char *sql);
-+
-+/*
-+** This routine identifies a callback function that is invoked
-+** whenever an attempt is made to open a database table that is
-+** currently locked by another process or thread.  If the busy callback
-+** is NULL, then sqlite_exec() returns SQLITE_BUSY immediately if
-+** it finds a locked table.  If the busy callback is not NULL, then
-+** sqlite_exec() invokes the callback with three arguments.  The
-+** second argument is the name of the locked table and the third
-+** argument is the number of times the table has been busy.  If the
-+** busy callback returns 0, then sqlite_exec() immediately returns
-+** SQLITE_BUSY.  If the callback returns non-zero, then sqlite_exec()
-+** tries to open the table again and the cycle repeats.
-+**
-+** The default busy callback is NULL.
-+**
-+** Sqlite is re-entrant, so the busy handler may start a new query. 
-+** (It is not clear why anyone would every want to do this, but it
-+** is allowed, in theory.)  But the busy handler may not close the
-+** database.  Closing the database from a busy handler will delete 
-+** data structures out from under the executing query and will 
-+** probably result in a coredump.
-+*/
-+void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*);
-+
-+/*
-+** This routine sets a busy handler that sleeps for a while when a
-+** table is locked.  The handler will sleep multiple times until 
-+** at least "ms" milleseconds of sleeping have been done.  After
-+** "ms" milleseconds of sleeping, the handler returns 0 which
-+** causes sqlite_exec() to return SQLITE_BUSY.
-+**
-+** Calling this routine with an argument less than or equal to zero
-+** turns off all busy handlers.
-+*/
-+void sqlite_busy_timeout(sqlite*, int ms);
-+
-+/*
-+** This next routine is really just a wrapper around sqlite_exec().
-+** Instead of invoking a user-supplied callback for each row of the
-+** result, this routine remembers each row of the result in memory
-+** obtained from malloc(), then returns all of the result after the
-+** query has finished. 
-+**
-+** As an example, suppose the query result where this table:
-+**
-+**        Name        | Age
-+**        -----------------------
-+**        Alice       | 43
-+**        Bob         | 28
-+**        Cindy       | 21
-+**
-+** If the 3rd argument were &azResult then after the function returns
-+** azResult will contain the following data:
-+**
-+**        azResult[0] = "Name";
-+**        azResult[1] = "Age";
-+**        azResult[2] = "Alice";
-+**        azResult[3] = "43";
-+**        azResult[4] = "Bob";
-+**        azResult[5] = "28";
-+**        azResult[6] = "Cindy";
-+**        azResult[7] = "21";
-+**
-+** Notice that there is an extra row of data containing the column
-+** headers.  But the *nrow return value is still 3.  *ncolumn is
-+** set to 2.  In general, the number of values inserted into azResult
-+** will be ((*nrow) + 1)*(*ncolumn).
-+**
-+** After the calling function has finished using the result, it should 
-+** pass the result data pointer to sqlite_free_table() in order to 
-+** release the memory that was malloc-ed.  Because of the way the 
-+** malloc() happens, the calling function must not try to call 
-+** malloc() directly.  Only sqlite_free_table() is able to release 
-+** the memory properly and safely.
-+**
-+** The return value of this routine is the same as from sqlite_exec().
-+*/
-+int sqlite_get_table(
-+  sqlite*,               /* An open database */
-+  const char *sql,       /* SQL to be executed */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg          /* Error msg written here */
-+);
-+
-+/*
-+** Call this routine to free the memory that sqlite_get_table() allocated.
-+*/
-+void sqlite_free_table(char **result);
-+
-+/*
-+** The following routines are wrappers around sqlite_exec() and
-+** sqlite_get_table().  The only difference between the routines that
-+** follow and the originals is that the second argument to the 
-+** routines that follow is really a printf()-style format
-+** string describing the SQL to be executed.  Arguments to the format
-+** string appear at the end of the argument list.
-+**
-+** All of the usual printf formatting options apply.  In addition, there
-+** is a "%q" option.  %q 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, so some string variable contains text as follows:
-+**
-+**      char *zText = "It's a happy day!";
-+**
-+** We can use this text in an SQL statement as follows:
-+**
-+**      sqlite_exec_printf(db, "INSERT INTO table VALUES('%q')",
-+**          callback1, 0, 0, zText);
-+**
-+** Because the %q format string is used, the '\'' character in zText
-+** is escaped and the SQL generated is as follows:
-+**
-+**      INSERT INTO table1 VALUES('It''s a happy day!')
-+**
-+** This is correct.  Had we used %s instead of %q, the generated SQL
-+** would have looked like this:
-+**
-+**      INSERT INTO table1 VALUES('It's a happy day!');
-+**
-+** 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.
-+*/
-+int sqlite_exec_printf(
-+  sqlite*,                      /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  ...                           /* Arguments to the format string. */
-+);
-+int sqlite_exec_vprintf(
-+  sqlite*,                      /* An open database */
-+  const char *sqlFormat,        /* printf-style format string for the SQL */
-+  sqlite_callback,              /* Callback function */
-+  void *,                       /* 1st argument to callback function */
-+  char **errmsg,                /* Error msg written here */
-+  va_list ap                    /* Arguments to the format string. */
-+);
-+int sqlite_get_table_printf(
-+  sqlite*,               /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  ...                    /* Arguments to the format string */
-+);
-+int sqlite_get_table_vprintf(
-+  sqlite*,               /* An open database */
-+  const char *sqlFormat, /* printf-style format string for the SQL */
-+  char ***resultp,       /* Result written to a char *[]  that this points to */
-+  int *nrow,             /* Number of result rows written here */
-+  int *ncolumn,          /* Number of result columns written here */
-+  char **errmsg,         /* Error msg written here */
-+  va_list ap             /* Arguments to the format string */
-+);
-+char *sqlite_mprintf(const char*,...);
-+char *sqlite_vmprintf(const char*, va_list);
-+
-+/*
-+** Windows systems should call this routine to free memory that
-+** is returned in the in the errmsg parameter of sqlite_open() when
-+** SQLite is a DLL.  For some reason, it does not work to call free()
-+** directly.
-+*/
-+void sqlite_freemem(void *p);
-+
-+/*
-+** Windows systems need functions to call to return the sqlite_version
-+** and sqlite_encoding strings.
-+*/
-+const char *sqlite_libversion(void);
-+const char *sqlite_libencoding(void);
-+
-+/*
-+** A pointer to the following structure is used to communicate with
-+** the implementations of user-defined functions.
-+*/
-+typedef struct sqlite_func sqlite_func;
-+
-+/*
-+** Use the following routines to create new user-defined functions.  See
-+** the documentation for details.
-+*/
-+int sqlite_create_function(
-+  sqlite*,                  /* Database where the new function is registered */
-+  const char *zName,        /* Name of the new function */
-+  int nArg,                 /* Number of arguments.  -1 means any number */
-+  void (*xFunc)(sqlite_func*,int,const char**),  /* C code to implement */
-+  void *pUserData           /* Available via the sqlite_user_data() call */
-+);
-+int sqlite_create_aggregate(
-+  sqlite*,                  /* Database where the new function is registered */
-+  const char *zName,        /* Name of the function */
-+  int nArg,                 /* Number of arguments */
-+  void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */
-+  void (*xFinalize)(sqlite_func*),       /* Called once to get final result */
-+  void *pUserData           /* Available via the sqlite_user_data() call */
-+);
-+
-+/*
-+** Use the following routine to define the datatype returned by a
-+** user-defined function.  The second argument can be one of the
-+** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it
-+** can be an integer greater than or equal to zero.  The datatype
-+** will be numeric or text (the only two types supported) if the
-+** argument is SQLITE_NUMERIC or SQLITE_TEXT.  If the argument is
-+** SQLITE_ARGS, then the datatype is numeric if any argument to the
-+** function is numeric and is text otherwise.  If the second argument
-+** is an integer, then the datatype of the result is the same as the
-+** parameter to the function that corresponds to that integer.
-+*/
-+int sqlite_function_type(
-+  sqlite *db,               /* The database there the function is registered */
-+  const char *zName,        /* Name of the function */
-+  int datatype              /* The datatype for this function */
-+);
-+#define SQLITE_NUMERIC     (-1)
-+#define SQLITE_TEXT        (-2)
-+#define SQLITE_ARGS        (-3)
-+
-+/*
-+** The user function implementations call one of the following four routines
-+** in order to return their results.  The first parameter to each of these
-+** routines is a copy of the first argument to xFunc() or xFinialize().
-+** The second parameter to these routines is the result to be returned.
-+** A NULL can be passed as the second parameter to sqlite_set_result_string()
-+** in order to return a NULL result.
-+**
-+** The 3rd argument to _string and _error is the number of characters to
-+** take from the string.  If this argument is negative, then all characters
-+** up to and including the first '\000' are used.
-+**
-+** The sqlite_set_result_string() function allocates a buffer to hold the
-+** result and returns a pointer to this buffer.  The calling routine
-+** (that is, the implmentation of a user function) can alter the content
-+** of this buffer if desired.
-+*/
-+char *sqlite_set_result_string(sqlite_func*,const char*,int);
-+void sqlite_set_result_int(sqlite_func*,int);
-+void sqlite_set_result_double(sqlite_func*,double);
-+void sqlite_set_result_error(sqlite_func*,const char*,int);
-+
-+/*
-+** The pUserData parameter to the sqlite_create_function() and
-+** sqlite_create_aggregate() routines used to register user functions
-+** is available to the implementation of the function using this
-+** call.
-+*/
-+void *sqlite_user_data(sqlite_func*);
-+
-+/*
-+** Aggregate functions use the following routine to allocate
-+** a structure for storing their state.  The first time this routine
-+** is called for a particular aggregate, a new structure of size nBytes
-+** is allocated, zeroed, and returned.  On subsequent calls (for the
-+** same aggregate instance) the same buffer is returned.  The implementation
-+** of the aggregate can use the returned buffer to accumulate data.
-+**
-+** The buffer allocated is freed automatically be SQLite.
-+*/
-+void *sqlite_aggregate_context(sqlite_func*, int nBytes);
-+
-+/*
-+** The next routine returns the number of calls to xStep for a particular
-+** aggregate function instance.  The current call to xStep counts so this
-+** routine always returns at least 1.
-+*/
-+int sqlite_aggregate_count(sqlite_func*);
-+
-+/*
-+** This routine registers a callback with the SQLite library.  The
-+** callback is invoked (at compile-time, not at run-time) for each
-+** attempt to access a column of a table in the database.  The callback
-+** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire
-+** SQL statement should be aborted with an error and SQLITE_IGNORE
-+** if the column should be treated as a NULL value.
-+*/
-+int sqlite_set_authorizer(
-+  sqlite*,
-+  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
-+  void *pUserData
-+);
-+
-+/*
-+** The second parameter to the access authorization function above will
-+** be one of the values below.  These values signify what kind of operation
-+** is to be authorized.  The 3rd and 4th parameters to the authorization
-+** function will be parameters or NULL depending on which of the following
-+** codes is used as the second parameter.  The 5th parameter is the name
-+** of the database ("main", "temp", etc.) if applicable.  The 6th parameter
-+** 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 
-+** input SQL code.
-+**
-+**                                          Arg-3           Arg-4
-+*/
-+#define SQLITE_COPY                  0   /* Table Name      File Name       */
-+#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   /* NULL            NULL            */
-+#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
-+#define SQLITE_ATTACH               24   /* Filename        NULL            */
-+#define SQLITE_DETACH               25   /* Database Name   NULL            */
-+
-+
-+/*
-+** The return value of the authorization function should be one of the
-+** following constants:
-+*/
-+/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
-+#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 */
-+
-+/*
-+** Register a function that is called at every invocation of sqlite_exec()
-+** or sqlite_compile().  This function can be used (for example) to generate
-+** a log file of all SQL executed against a database.
-+*/
-+void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*);
-+
-+/*** The Callback-Free API
-+** 
-+** The following routines implement a new way to access SQLite that does not
-+** involve the use of callbacks.
-+**
-+** An sqlite_vm is an opaque object that represents a single SQL statement
-+** that is ready to be executed.
-+*/
-+typedef struct sqlite_vm sqlite_vm;
-+
-+/*
-+** To execute an SQLite query without the use of callbacks, you first have
-+** to compile the SQL using this routine.  The 1st parameter "db" is a pointer
-+** to an sqlite object obtained from sqlite_open().  The 2nd parameter
-+** "zSql" is the text of the SQL to be compiled.   The remaining parameters
-+** are all outputs.
-+**
-+** *pzTail is made to point to the first character past the end of the first
-+** SQL statement in zSql.  This routine only compiles the first statement
-+** in zSql, so *pzTail is left pointing to what remains uncompiled.
-+**
-+** *ppVm is left pointing to a "virtual machine" that can be used to execute
-+** the compiled statement.  Or if there is an error, *ppVm may be set to NULL.
-+** If the input text contained no SQL (if the input is and empty string or
-+** a comment) then *ppVm is set to NULL.
-+**
-+** If any errors are detected during compilation, an error message is written
-+** into space obtained from malloc() and *pzErrMsg is made to point to that
-+** error message.  The calling routine is responsible for freeing the text
-+** of this message when it has finished with it.  Use sqlite_freemem() to
-+** free the message.  pzErrMsg may be NULL in which case no error message
-+** will be generated.
-+**
-+** On success, SQLITE_OK is returned.  Otherwise and error code is returned.
-+*/
-+int sqlite_compile(
-+  sqlite *db,                   /* The open database */
-+  const char *zSql,             /* SQL statement to be compiled */
-+  const char **pzTail,          /* OUT: uncompiled tail of zSql */
-+  sqlite_vm **ppVm,             /* OUT: the virtual machine to execute zSql */
-+  char **pzErrmsg               /* OUT: Error message. */
-+);
-+
-+/*
-+** After an SQL statement has been compiled, it is handed to this routine
-+** to be executed.  This routine executes the statement as far as it can
-+** go then returns.  The return value will be one of SQLITE_DONE,
-+** SQLITE_ERROR, SQLITE_BUSY, SQLITE_ROW, or SQLITE_MISUSE.
-+**
-+** SQLITE_DONE means that the execute of the SQL statement is complete
-+** an no errors have occurred.  sqlite_step() should not be called again
-+** for the same virtual machine.  *pN is set to the number of columns in
-+** the result set and *pazColName is set to an array of strings that
-+** describe the column names and datatypes.  The name of the i-th column
-+** is (*pazColName)[i] and the datatype of the i-th column is
-+** (*pazColName)[i+*pN].  *pazValue is set to NULL.
-+**
-+** SQLITE_ERROR means that the virtual machine encountered a run-time
-+** error.  sqlite_step() should not be called again for the same
-+** virtual machine.  *pN is set to 0 and *pazColName and *pazValue are set
-+** to NULL.  Use sqlite_finalize() to obtain the specific error code
-+** and the error message text for the error.
-+**
-+** SQLITE_BUSY means that an attempt to open the database failed because
-+** another thread or process is holding a lock.  The calling routine
-+** can try again to open the database by calling sqlite_step() again.
-+** The return code will only be SQLITE_BUSY if no busy handler is registered
-+** using the sqlite_busy_handler() or sqlite_busy_timeout() routines.  If
-+** a busy handler callback has been registered but returns 0, then this
-+** routine will return SQLITE_ERROR and sqltie_finalize() will return
-+** SQLITE_BUSY when it is called.
-+**
-+** SQLITE_ROW means that a single row of the result is now available.
-+** The data is contained in *pazValue.  The value of the i-th column is
-+** (*azValue)[i].  *pN and *pazColName are set as described in SQLITE_DONE.
-+** Invoke sqlite_step() again to advance to the next row.
-+**
-+** SQLITE_MISUSE is returned if sqlite_step() is called incorrectly.
-+** For example, if you call sqlite_step() after the virtual machine
-+** has halted (after a prior call to sqlite_step() has returned SQLITE_DONE)
-+** or if you call sqlite_step() with an incorrectly initialized virtual
-+** machine or a virtual machine that has been deleted or that is associated
-+** with an sqlite structure that has been closed.
-+*/
-+int sqlite_step(
-+  sqlite_vm *pVm,              /* The virtual machine to execute */
-+  int *pN,                     /* OUT: Number of columns in result */
-+  const char ***pazValue,      /* OUT: Column data */
-+  const char ***pazColName     /* OUT: Column names and datatypes */
-+);
-+
-+/*
-+** This routine is called to delete a virtual machine after it has finished
-+** executing.  The return value is the result code.  SQLITE_OK is returned
-+** if the statement executed successfully and some other value is returned if
-+** there was any kind of error.  If an error occurred and pzErrMsg is not
-+** NULL, then an error message is written into memory obtained from malloc()
-+** and *pzErrMsg is made to point to that error message.  The calling routine
-+** should use sqlite_freemem() to delete this message when it has finished
-+** with it.
-+**
-+** This routine can be called at any point during the execution of the
-+** virtual machine.  If the virtual machine has not completed execution
-+** when this routine is called, that is like encountering an error or
-+** an interrupt.  (See sqlite_interrupt().)  Incomplete updates may be
-+** rolled back and transactions cancelled,  depending on the circumstances,
-+** and the result code returned will be SQLITE_ABORT.
-+*/
-+int sqlite_finalize(sqlite_vm*, char **pzErrMsg);
-+
-+/*
-+** This routine deletes the virtual machine, writes any error message to
-+** *pzErrMsg and returns an SQLite return code in the same way as the
-+** sqlite_finalize() function.
-+**
-+** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
-+** machine loaded with the compiled version of the original query ready for
-+** execution.
-+**
-+** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+int sqlite_reset(sqlite_vm*, char **pzErrMsg);
-+
-+/*
-+** If the SQL that was handed to sqlite_compile contains variables that
-+** are represeted in the SQL text by a question mark ('?').  This routine
-+** is used to assign values to those variables.
-+**
-+** The first parameter is a virtual machine obtained from sqlite_compile().
-+** The 2nd "idx" parameter determines which variable in the SQL statement
-+** to bind the value to.  The left most '?' is 1.  The 3rd parameter is
-+** the value to assign to that variable.  The 4th parameter is the number
-+** of bytes in the value, including the terminating \000 for strings.
-+** Finally, the 5th "copy" parameter is TRUE if SQLite should make its
-+** own private copy of this value, or false if the space that the 3rd
-+** parameter points to will be unchanging and can be used directly by
-+** SQLite.
-+**
-+** Unbound variables are treated as having a value of NULL.  To explicitly
-+** set a variable to NULL, call this routine with the 3rd parameter as a
-+** NULL pointer.
-+**
-+** If the 4th "len" parameter is -1, then strlen() is used to find the
-+** length.
-+**
-+** This routine can only be called immediately after sqlite_compile()
-+** or sqlite_reset() and before any calls to sqlite_step().
-+**
-+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-+*/
-+int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy);
-+
-+/*
-+** This routine configures a callback function - the progress callback - that
-+** is invoked periodically during long running calls to sqlite_exec(),
-+** sqlite_step() and sqlite_get_table(). An example use for this API is to keep
-+** a GUI updated during a large query.
-+**
-+** The progress callback is invoked once for every N virtual machine opcodes,
-+** where N is the second argument to this function. The progress callback
-+** itself is identified by the third argument to this function. The fourth
-+** argument to this function is a void pointer passed to the progress callback
-+** function each time it is invoked.
-+**
-+** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results 
-+** in less than N opcodes being executed, then the progress callback is not
-+** invoked.
-+** 
-+** Calling this routine overwrites any previously installed progress callback.
-+** To remove the progress callback altogether, pass NULL as the third
-+** argument to this function.
-+**
-+** If the progress callback returns a result other than 0, then the current 
-+** query is immediately terminated and any database changes rolled back. If the
-+** query was part of a larger transaction, then the transaction is not rolled
-+** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. 
-+*/
-+void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*);
-+
-+#ifdef __cplusplus
-+}  /* End of the 'extern "C"' block */
-+#endif
-+
-+#endif /* _SQLITE_H_ */
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/table.c
-@@ -0,0 +1,203 @@
-+/*
-+** 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 sqlite_get_table() and sqlite_free_table()
-+** interface routines.  These are just wrappers around the main
-+** interface routine of sqlite_exec().
-+**
-+** These routines are in a separate files so that they will not be linked
-+** if they are not used.
-+*/
-+#include <stdlib.h>
-+#include <string.h>
-+#include "sqliteInt.h"
-+
-+/*
-+** This structure is used to pass data from sqlite_get_table() through
-+** to the callback function is uses to build the result.
-+*/
-+typedef struct TabResult {
-+  char **azResult;
-+  char *zErrMsg;
-+  int nResult;
-+  int nAlloc;
-+  int nRow;
-+  int nColumn;
-+  long nData;
-+  int rc;
-+} 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 sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
-+  TabResult *p = (TabResult*)pArg;
-+  int need;
-+  int i;
-+  char *z;
-+
-+  /* 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 + 1;
-+    azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
-+    if( azNew==0 ){
-+      p->rc = SQLITE_NOMEM;
-+      return 1;
-+    }
-+    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++){
-+      if( colv[i]==0 ){
-+        z = 0;
-+      }else{
-+        z = malloc( strlen(colv[i])+1 );
-+        if( z==0 ){
-+          p->rc = SQLITE_NOMEM;
-+          return 1;
-+        }
-+        strcpy(z, colv[i]);
-+      }
-+      p->azResult[p->nData++] = z;
-+    }
-+  }else if( p->nColumn!=nCol ){
-+    sqliteSetString(&p->zErrMsg,
-+       "sqlite_get_table() called with two or more incompatible queries",
-+       (char*)0);
-+    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{
-+        z = malloc( strlen(argv[i])+1 );
-+        if( z==0 ){
-+          p->rc = SQLITE_NOMEM;
-+          return 1;
-+        }
-+        strcpy(z, argv[i]);
-+      }
-+      p->azResult[p->nData++] = z;
-+    }
-+    p->nRow++;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** 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 sqlite_free_table() when
-+** the calling procedure is finished using it.
-+*/
-+int sqlite_get_table(
-+  sqlite *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;
-+  if( pazResult==0 ){ return SQLITE_ERROR; }
-+  *pazResult = 0;
-+  if( pnColumn ) *pnColumn = 0;
-+  if( pnRow ) *pnRow = 0;
-+  res.zErrMsg = 0;
-+  res.nResult = 0;
-+  res.nRow = 0;
-+  res.nColumn = 0;
-+  res.nData = 1;
-+  res.nAlloc = 20;
-+  res.rc = SQLITE_OK;
-+  res.azResult = malloc( sizeof(char*)*res.nAlloc );
-+  if( res.azResult==0 ){
-+    return SQLITE_NOMEM;
-+  }
-+  res.azResult[0] = 0;
-+  rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
-+  if( res.azResult ){
-+    res.azResult[0] = (char*)res.nData;
-+  }
-+  if( rc==SQLITE_ABORT ){
-+    sqlite_free_table(&res.azResult[1]);
-+    if( res.zErrMsg ){
-+      if( pzErrMsg ){
-+        free(*pzErrMsg);
-+        *pzErrMsg = res.zErrMsg;
-+        sqliteStrRealloc(pzErrMsg);
-+      }else{
-+        sqliteFree(res.zErrMsg);
-+      }
-+    }
-+    return res.rc;
-+  }
-+  sqliteFree(res.zErrMsg);
-+  if( rc!=SQLITE_OK ){
-+    sqlite_free_table(&res.azResult[1]);
-+    return rc;
-+  }
-+  if( res.nAlloc>res.nData ){
-+    char **azNew;
-+    azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
-+    if( azNew==0 ){
-+      sqlite_free_table(&res.azResult[1]);
-+      return SQLITE_NOMEM;
-+    }
-+    res.nAlloc = res.nData+1;
-+    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 sqlite_get_table() malloced.
-+*/
-+void sqlite_free_table(
-+  char **azResult             /* Result returned from from sqlite_get_table() */
-+){
-+  if( azResult ){
-+    int i, n;
-+    azResult--;
-+    if( azResult==0 ) return;
-+    n = (int)(long)azResult[0];
-+    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
-+    free(azResult);
-+  }
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/tokenize.c
-@@ -0,0 +1,679 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+#include <ctype.h>
-+#include <stdlib.h>
-+
-+/*
-+** All the keywords of the SQL language are stored as in a hash
-+** table composed of instances of the following structure.
-+*/
-+typedef struct Keyword Keyword;
-+struct Keyword {
-+  char *zName;             /* The keyword name */
-+  u8 tokenType;            /* Token value for this keyword */
-+  u8 len;                  /* Length of this keyword */
-+  u8 iNext;                /* Index in aKeywordTable[] of next with same hash */
-+};
-+
-+/*
-+** These are the keywords
-+*/
-+static Keyword aKeywordTable[] = {
-+  { "ABORT",             TK_ABORT,        },
-+  { "AFTER",             TK_AFTER,        },
-+  { "ALL",               TK_ALL,          },
-+  { "AND",               TK_AND,          },
-+  { "AS",                TK_AS,           },
-+  { "ASC",               TK_ASC,          },
-+  { "ATTACH",            TK_ATTACH,       },
-+  { "BEFORE",            TK_BEFORE,       },
-+  { "BEGIN",             TK_BEGIN,        },
-+  { "BETWEEN",           TK_BETWEEN,      },
-+  { "BY",                TK_BY,           },
-+  { "CASCADE",           TK_CASCADE,      },
-+  { "CASE",              TK_CASE,         },
-+  { "CHECK",             TK_CHECK,        },
-+  { "CLUSTER",           TK_CLUSTER,      },
-+  { "COLLATE",           TK_COLLATE,      },
-+  { "COMMIT",            TK_COMMIT,       },
-+  { "CONFLICT",          TK_CONFLICT,     },
-+  { "CONSTRAINT",        TK_CONSTRAINT,   },
-+  { "COPY",              TK_COPY,         },
-+  { "CREATE",            TK_CREATE,       },
-+  { "CROSS",             TK_JOIN_KW,      },
-+  { "DATABASE",          TK_DATABASE,     },
-+  { "DEFAULT",           TK_DEFAULT,      },
-+  { "DEFERRED",          TK_DEFERRED,     },
-+  { "DEFERRABLE",        TK_DEFERRABLE,   },
-+  { "DELETE",            TK_DELETE,       },
-+  { "DELIMITERS",        TK_DELIMITERS,   },
-+  { "DESC",              TK_DESC,         },
-+  { "DETACH",            TK_DETACH,       },
-+  { "DISTINCT",          TK_DISTINCT,     },
-+  { "DROP",              TK_DROP,         },
-+  { "END",               TK_END,          },
-+  { "EACH",              TK_EACH,         },
-+  { "ELSE",              TK_ELSE,         },
-+  { "EXCEPT",            TK_EXCEPT,       },
-+  { "EXPLAIN",           TK_EXPLAIN,      },
-+  { "FAIL",              TK_FAIL,         },
-+  { "FOR",               TK_FOR,          },
-+  { "FOREIGN",           TK_FOREIGN,      },
-+  { "FROM",              TK_FROM,         },
-+  { "FULL",              TK_JOIN_KW,      },
-+  { "GLOB",              TK_GLOB,         },
-+  { "GROUP",             TK_GROUP,        },
-+  { "HAVING",            TK_HAVING,       },
-+  { "IGNORE",            TK_IGNORE,       },
-+  { "IMMEDIATE",         TK_IMMEDIATE,    },
-+  { "IN",                TK_IN,           },
-+  { "INDEX",             TK_INDEX,        },
-+  { "INITIALLY",         TK_INITIALLY,    },
-+  { "INNER",             TK_JOIN_KW,      },
-+  { "INSERT",            TK_INSERT,       },
-+  { "INSTEAD",           TK_INSTEAD,      },
-+  { "INTERSECT",         TK_INTERSECT,    },
-+  { "INTO",              TK_INTO,         },
-+  { "IS",                TK_IS,           },
-+  { "ISNULL",            TK_ISNULL,       },
-+  { "JOIN",              TK_JOIN,         },
-+  { "KEY",               TK_KEY,          },
-+  { "LEFT",              TK_JOIN_KW,      },
-+  { "LIKE",              TK_LIKE,         },
-+  { "LIMIT",             TK_LIMIT,        },
-+  { "MATCH",             TK_MATCH,        },
-+  { "NATURAL",           TK_JOIN_KW,      },
-+  { "NOT",               TK_NOT,          },
-+  { "NOTNULL",           TK_NOTNULL,      },
-+  { "NULL",              TK_NULL,         },
-+  { "OF",                TK_OF,           },
-+  { "OFFSET",            TK_OFFSET,       },
-+  { "ON",                TK_ON,           },
-+  { "OR",                TK_OR,           },
-+  { "ORDER",             TK_ORDER,        },
-+  { "OUTER",             TK_JOIN_KW,      },
-+  { "PRAGMA",            TK_PRAGMA,       },
-+  { "PRIMARY",           TK_PRIMARY,      },
-+  { "RAISE",             TK_RAISE,        },
-+  { "REFERENCES",        TK_REFERENCES,   },
-+  { "REPLACE",           TK_REPLACE,      },
-+  { "RESTRICT",          TK_RESTRICT,     },
-+  { "RIGHT",             TK_JOIN_KW,      },
-+  { "ROLLBACK",          TK_ROLLBACK,     },
-+  { "ROW",               TK_ROW,          },
-+  { "SELECT",            TK_SELECT,       },
-+  { "SET",               TK_SET,          },
-+  { "STATEMENT",         TK_STATEMENT,    },
-+  { "TABLE",             TK_TABLE,        },
-+  { "TEMP",              TK_TEMP,         },
-+  { "TEMPORARY",         TK_TEMP,         },
-+  { "THEN",              TK_THEN,         },
-+  { "TRANSACTION",       TK_TRANSACTION,  },
-+  { "TRIGGER",           TK_TRIGGER,      },
-+  { "UNION",             TK_UNION,        },
-+  { "UNIQUE",            TK_UNIQUE,       },
-+  { "UPDATE",            TK_UPDATE,       },
-+  { "USING",             TK_USING,        },
-+  { "VACUUM",            TK_VACUUM,       },
-+  { "VALUES",            TK_VALUES,       },
-+  { "VIEW",              TK_VIEW,         },
-+  { "WHEN",              TK_WHEN,         },
-+  { "WHERE",             TK_WHERE,        },
-+};
-+
-+/*
-+** This is the hash table
-+*/
-+#define KEY_HASH_SIZE 101
-+static u8 aiHashTable[KEY_HASH_SIZE];
-+
-+
-+/*
-+** This 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.
-+*/
-+int sqliteKeywordCode(const char *z, int n){
-+  int h, i;
-+  Keyword *p;
-+  static char needInit = 1;
-+  if( needInit ){
-+    /* Initialize the keyword hash table */
-+    sqliteOsEnterMutex();
-+    if( needInit ){
-+      int nk;
-+      nk = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
-+      for(i=0; i<nk; i++){
-+        aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
-+        h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
-+        h %= KEY_HASH_SIZE;
-+        aKeywordTable[i].iNext = aiHashTable[h];
-+        aiHashTable[h] = i+1;
-+      }
-+      needInit = 0;
-+    }
-+    sqliteOsLeaveMutex();
-+  }
-+  h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
-+  for(i=aiHashTable[h]; i; i=p->iNext){
-+    p = &aKeywordTable[i-1];
-+    if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
-+      return p->tokenType;
-+    }
-+  }
-+  return TK_ID;
-+}
-+
-+
-+/*
-+** If X is a character that can be used in an identifier and
-+** X&0x80==0 then isIdChar[X] will be 1.  If X&0x80==0x80 then
-+** X is always an identifier character.  (Hence all UTF-8
-+** characters can be part of an identifier).  isIdChar[X] will
-+** be 0 for every character in the lower 128 ASCII characters
-+** that cannot be used as part of an identifier.
-+**
-+** In this implementation, an identifier can be a string of
-+** alphabetic characters, digits, and "_" plus any character
-+** with the high-order bit set.  The latter rule means that
-+** any sequence of UTF-8 characters or characters taken from
-+** an extended ISO8859 character set can form an identifier.
-+*/
-+static const char isIdChar[] = {
-+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
-+    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 */
-+    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 */
-+};
-+
-+
-+/*
-+** Return the length of the token that begins at z[0]. 
-+** Store the token type in *tokenType before returning.
-+*/
-+static int sqliteGetToken(const unsigned char *z, int *tokenType){
-+  int i;
-+  switch( *z ){
-+    case ' ': case '\t': case '\n': case '\f': case '\r': {
-+      for(i=1; isspace(z[i]); i++){}
-+      *tokenType = TK_SPACE;
-+      return i;
-+    }
-+    case '-': {
-+      if( z[1]=='-' ){
-+        for(i=2; z[i] && z[i]!='\n'; i++){}
-+        *tokenType = TK_COMMENT;
-+        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; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
-+      if( z[i] ) i++;
-+      *tokenType = TK_COMMENT;
-+      return i;
-+    }
-+    case '%': {
-+      *tokenType = TK_REM;
-+      return 1;
-+    }
-+    case '=': {
-+      *tokenType = TK_EQ;
-+      return 1 + (z[1]=='=');
-+    }
-+    case '<': {
-+      if( z[1]=='=' ){
-+        *tokenType = TK_LE;
-+        return 2;
-+      }else if( z[1]=='>' ){
-+        *tokenType = TK_NE;
-+        return 2;
-+      }else if( z[1]=='<' ){
-+        *tokenType = TK_LSHIFT;
-+        return 2;
-+      }else{
-+        *tokenType = TK_LT;
-+        return 1;
-+      }
-+    }
-+    case '>': {
-+      if( z[1]=='=' ){
-+        *tokenType = TK_GE;
-+        return 2;
-+      }else if( z[1]=='>' ){
-+        *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 '"': {
-+      int delim = z[0];
-+      for(i=1; z[i]; i++){
-+        if( z[i]==delim ){
-+          if( z[i+1]==delim ){
-+            i++;
-+          }else{
-+            break;
-+          }
-+        }
-+      }
-+      if( z[i] ) i++;
-+      *tokenType = TK_STRING;
-+      return i;
-+    }
-+    case '.': {
-+      *tokenType = TK_DOT;
-+      return 1;
-+    }
-+    case '0': case '1': case '2': case '3': case '4':
-+    case '5': case '6': case '7': case '8': case '9': {
-+      *tokenType = TK_INTEGER;
-+      for(i=1; isdigit(z[i]); i++){}
-+      if( z[i]=='.' && isdigit(z[i+1]) ){
-+        i += 2;
-+        while( isdigit(z[i]) ){ i++; }
-+        *tokenType = TK_FLOAT;
-+      }
-+      if( (z[i]=='e' || z[i]=='E') &&
-+           ( isdigit(z[i+1]) 
-+            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
-+           )
-+      ){
-+        i += 2;
-+        while( isdigit(z[i]) ){ i++; }
-+        *tokenType = TK_FLOAT;
-+      }
-+      return i;
-+    }
-+    case '[': {
-+      for(i=1; z[i] && z[i-1]!=']'; i++){}
-+      *tokenType = TK_ID;
-+      return i;
-+    }
-+    case '?': {
-+      *tokenType = TK_VARIABLE;
-+      return 1;
-+    }
-+    default: {
-+      if( (*z&0x80)==0 && !isIdChar[*z] ){
-+        break;
-+      }
-+      for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}
-+      *tokenType = sqliteKeywordCode((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
-+** and pzErrMsg!=NULL then an error message might be written into 
-+** memory obtained from malloc() and *pzErrMsg made to point to that
-+** error message.  Or maybe not.
-+*/
-+int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
-+  int nErr = 0;
-+  int i;
-+  void *pEngine;
-+  int tokenType;
-+  int lastTokenParsed = -1;
-+  sqlite *db = pParse->db;
-+  extern void *sqliteParserAlloc(void*(*)(int));
-+  extern void sqliteParserFree(void*, void(*)(void*));
-+  extern int sqliteParser(void*, int, Token, Parse*);
-+
-+  db->flags &= ~SQLITE_Interrupt;
-+  pParse->rc = SQLITE_OK;
-+  i = 0;
-+  pEngine = sqliteParserAlloc((void*(*)(int))malloc);
-+  if( pEngine==0 ){
-+    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
-+    return 1;
-+  }
-+  pParse->sLastToken.dyn = 0;
-+  pParse->zTail = zSql;
-+  while( sqlite_malloc_failed==0 && zSql[i]!=0 ){
-+    assert( i>=0 );
-+    pParse->sLastToken.z = &zSql[i];
-+    assert( pParse->sLastToken.dyn==0 );
-+    pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
-+    i += pParse->sLastToken.n;
-+    switch( tokenType ){
-+      case TK_SPACE:
-+      case TK_COMMENT: {
-+        if( (db->flags & SQLITE_Interrupt)!=0 ){
-+          pParse->rc = SQLITE_INTERRUPT;
-+          sqliteSetString(pzErrMsg, "interrupt", (char*)0);
-+          goto abort_parse;
-+        }
-+        break;
-+      }
-+      case TK_ILLEGAL: {
-+        sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, 
-+           pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
-+        nErr++;
-+        goto abort_parse;
-+      }
-+      case TK_SEMI: {
-+        pParse->zTail = &zSql[i];
-+        /* Fall thru into the default case */
-+      }
-+      default: {
-+        sqliteParser(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 ){
-+      sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
-+      pParse->zTail = &zSql[i];
-+    }
-+    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
-+  }
-+  sqliteParserFree(pEngine, free);
-+  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
-+    sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),
-+                    (char*)0);
-+  }
-+  if( pParse->zErrMsg ){
-+    if( pzErrMsg && *pzErrMsg==0 ){
-+      *pzErrMsg = pParse->zErrMsg;
-+    }else{
-+      sqliteFree(pParse->zErrMsg);
-+    }
-+    pParse->zErrMsg = 0;
-+    if( !nErr ) nErr++;
-+  }
-+  if( pParse->pVdbe && pParse->nErr>0 ){
-+    sqliteVdbeDelete(pParse->pVdbe);
-+    pParse->pVdbe = 0;
-+  }
-+  if( pParse->pNewTable ){
-+    sqliteDeleteTable(pParse->db, pParse->pNewTable);
-+    pParse->pNewTable = 0;
-+  }
-+  if( pParse->pNewTrigger ){
-+    sqliteDeleteTrigger(pParse->pNewTrigger);
-+    pParse->pNewTrigger = 0;
-+  }
-+  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
-+    pParse->rc = SQLITE_ERROR;
-+  }
-+  return nErr;
-+}
-+
-+/*
-+** Token types used by the sqlite_complete() routine.  See the header
-+** comments on that procedure for additional information.
-+*/
-+#define tkEXPLAIN 0
-+#define tkCREATE  1
-+#define tkTEMP    2
-+#define tkTRIGGER 3
-+#define tkEND     4
-+#define tkSEMI    5
-+#define tkWS      6
-+#define tkOTHER   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) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
-+**                 a statement.
-+**
-+**   (2) CREATE    The keyword CREATE has been seen at the beginning of a
-+**                 statement, possibly preceeded by EXPLAIN and/or followed by
-+**                 TEMP or TEMPORARY
-+**
-+**   (3) NORMAL    We are in the middle of statement which ends with a single
-+**                 semicolon.
-+**
-+**   (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) tkEXPLAIN   The "explain" keyword.
-+**   (1) tkCREATE    The "create" keyword.
-+**   (2) tkTEMP      The "temp" or "temporary" keyword.
-+**   (3) tkTRIGGER   The "trigger" keyword.
-+**   (4) tkEND       The "end" keyword.
-+**   (5) tkSEMI      A semicolon.
-+**   (6) tkWS        Whitespace
-+**   (7) tkOTHER     Any other SQL token.
-+**
-+** Whitespace never causes a state transition and is always ignored.
-+*/
-+int sqlite_complete(const char *zSql){
-+  u8 state = 0;   /* Current state, using numbers defined in header comment */
-+  u8 token;       /* Value of the next token */
-+
-+  /* The following matrix defines the transition from one state to another
-+  ** according to what token is seen.  trans[state][token] returns the
-+  ** next state.
-+  */
-+  static const u8 trans[7][8] = {
-+                     /* Token:                                                */
-+     /* State:       **  EXPLAIN  CREATE  TEMP  TRIGGER  END  SEMI  WS  OTHER */
-+     /* 0   START: */ {       1,      2,    3,       3,   3,    0,  0,     3, },
-+     /* 1 EXPLAIN: */ {       3,      2,    3,       3,   3,    0,  1,     3, },
-+     /* 2  CREATE: */ {       3,      3,    2,       4,   3,    0,  2,     3, },
-+     /* 3  NORMAL: */ {       3,      3,    3,       3,   3,    0,  3,     3, },
-+     /* 4 TRIGGER: */ {       4,      4,    4,       4,   4,    5,  4,     4, },
-+     /* 5    SEMI: */ {       4,      4,    4,       4,   6,    5,  5,     4, },
-+     /* 6     END: */ {       4,      4,    4,       4,   4,    0,  6,     4, },
-+  };
-+
-+  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 '"':     /* single- and double-quoted strings */
-+      case '\'': {
-+        int c = *zSql;
-+        zSql++;
-+        while( *zSql && *zSql!=c ){ zSql++; }
-+        if( *zSql==0 ) return 0;
-+        token = tkOTHER;
-+        break;
-+      }
-+      default: {
-+        if( isIdChar[(u8)*zSql] ){
-+          /* Keywords and unquoted identifiers */
-+          int nId;
-+          for(nId=1; isIdChar[(u8)zSql[nId]]; nId++){}
-+          switch( *zSql ){
-+            case 'c': case 'C': {
-+              if( nId==6 && sqliteStrNICmp(zSql, "create", 6)==0 ){
-+                token = tkCREATE;
-+              }else{
-+                token = tkOTHER;
-+              }
-+              break;
-+            }
-+            case 't': case 'T': {
-+              if( nId==7 && sqliteStrNICmp(zSql, "trigger", 7)==0 ){
-+                token = tkTRIGGER;
-+              }else if( nId==4 && sqliteStrNICmp(zSql, "temp", 4)==0 ){
-+                token = tkTEMP;
-+              }else if( nId==9 && sqliteStrNICmp(zSql, "temporary", 9)==0 ){
-+                token = tkTEMP;
-+              }else{
-+                token = tkOTHER;
-+              }
-+              break;
-+            }
-+            case 'e':  case 'E': {
-+              if( nId==3 && sqliteStrNICmp(zSql, "end", 3)==0 ){
-+                token = tkEND;
-+              }else if( nId==7 && sqliteStrNICmp(zSql, "explain", 7)==0 ){
-+                token = tkEXPLAIN;
-+              }else{
-+                token = tkOTHER;
-+              }
-+              break;
-+            }
-+            default: {
-+              token = tkOTHER;
-+              break;
-+            }
-+          }
-+          zSql += nId-1;
-+        }else{
-+          /* Operators and special symbols */
-+          token = tkOTHER;
-+        }
-+        break;
-+      }
-+    }
-+    state = trans[state][token];
-+    zSql++;
-+  }
-+  return state==0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/trigger.c
-@@ -0,0 +1,764 @@
-+/*
-+**
-+** 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 "sqliteInt.h"
-+
-+/*
-+** Delete a linked list of TriggerStep structures.
-+*/
-+void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
-+  while( pTriggerStep ){
-+    TriggerStep * pTmp = pTriggerStep;
-+    pTriggerStep = pTriggerStep->pNext;
-+
-+    if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
-+    sqliteExprDelete(pTmp->pWhere);
-+    sqliteExprListDelete(pTmp->pExprList);
-+    sqliteSelectDelete(pTmp->pSelect);
-+    sqliteIdListDelete(pTmp->pIdList);
-+
-+    sqliteFree(pTmp);
-+  }
-+}
-+
-+/*
-+** 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
-+** sqliteFinishTrigger() function is called to complete the trigger
-+** construction process.
-+*/
-+void sqliteBeginTrigger(
-+  Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
-+  Token *pName,       /* 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 */
-+  int foreach,        /* One of TK_ROW or TK_STATEMENT */
-+  Expr *pWhen,        /* WHEN clause */
-+  int isTemp          /* True if the TEMPORARY keyword is present */
-+){
-+  Trigger *nt;
-+  Table   *tab;
-+  char *zName = 0;        /* Name of the trigger */
-+  sqlite *db = pParse->db;
-+  int iDb;                /* When database to store the trigger in */
-+  DbFixer sFix;
-+
-+  /* Check that: 
-+  ** 1. the trigger name does not already exist.
-+  ** 2. the table (or view) does exist in the same database as the trigger.
-+  ** 3. that we are not trying to create a trigger on the sqlite_master table
-+  ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
-+  ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
-+  */
-+  if( sqlite_malloc_failed ) goto trigger_cleanup;
-+  assert( pTableName->nSrc==1 );
-+  if( db->init.busy
-+   && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
-+   && sqliteFixSrcList(&sFix, pTableName)
-+  ){
-+    goto trigger_cleanup;
-+  }
-+  tab = sqliteSrcListLookup(pParse, pTableName);
-+  if( !tab ){
-+    goto trigger_cleanup;
-+  }
-+  iDb = isTemp ? 1 : tab->iDb;
-+  if( iDb>=2 && !db->init.busy ){
-+    sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
-+       "database %s", db->aDb[tab->iDb].zName);
-+    goto trigger_cleanup;
-+  }
-+
-+  zName = sqliteStrNDup(pName->z, pName->n);
-+  sqliteDequote(zName);
-+  if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
-+    sqliteErrorMsg(pParse, "trigger %T already exists", pName);
-+    goto trigger_cleanup;
-+  }
-+  if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
-+    sqliteErrorMsg(pParse, "cannot create trigger on system table");
-+    pParse->nErr++;
-+    goto trigger_cleanup;
-+  }
-+  if( tab->pSelect && tr_tm != TK_INSTEAD ){
-+    sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S", 
-+        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
-+    goto trigger_cleanup;
-+  }
-+  if( !tab->pSelect && tr_tm == TK_INSTEAD ){
-+    sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
-+        " trigger on table: %S", pTableName, 0);
-+    goto trigger_cleanup;
-+  }
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  {
-+    int code = SQLITE_CREATE_TRIGGER;
-+    const char *zDb = db->aDb[tab->iDb].zName;
-+    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
-+    if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
-+    if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
-+      goto trigger_cleanup;
-+    }
-+    if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
-+      goto trigger_cleanup;
-+    }
-+  }
-+#endif
-+
-+  /* INSTEAD OF triggers can only appear on views and BEGIN 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 */
-+  nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
-+  if( nt==0 ) goto trigger_cleanup;
-+  nt->name = zName;
-+  zName = 0;
-+  nt->table = sqliteStrDup(pTableName->a[0].zName);
-+  if( sqlite_malloc_failed ) goto trigger_cleanup;
-+  nt->iDb = iDb;
-+  nt->iTabDb = tab->iDb;
-+  nt->op = op;
-+  nt->tr_tm = tr_tm;
-+  nt->pWhen = sqliteExprDup(pWhen);
-+  nt->pColumns = sqliteIdListDup(pColumns);
-+  nt->foreach = foreach;
-+  sqliteTokenCopy(&nt->nameToken,pName);
-+  assert( pParse->pNewTrigger==0 );
-+  pParse->pNewTrigger = nt;
-+
-+trigger_cleanup:
-+  sqliteFree(zName);
-+  sqliteSrcListDelete(pTableName);
-+  sqliteIdListDelete(pColumns);
-+  sqliteExprDelete(pWhen);
-+}
-+
-+/*
-+** This routine is called after all of the trigger actions have been parsed
-+** in order to complete the process of building the trigger.
-+*/
-+void sqliteFinishTrigger(
-+  Parse *pParse,          /* Parser context */
-+  TriggerStep *pStepList, /* The triggered program */
-+  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
-+){
-+  Trigger *nt = 0;          /* The trigger whose construction is finishing up */
-+  sqlite *db = pParse->db;  /* The database */
-+  DbFixer sFix;
-+
-+  if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
-+  nt = pParse->pNewTrigger;
-+  pParse->pNewTrigger = 0;
-+  nt->step_list = pStepList;
-+  while( pStepList ){
-+    pStepList->pTrig = nt;
-+    pStepList = pStepList->pNext;
-+  }
-+  if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken) 
-+          && sqliteFixTriggerStep(&sFix, nt->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 ){
-+    static VdbeOpList insertTrig[] = {
-+      { OP_NewRecno,   0, 0,  0          },
-+      { OP_String,     0, 0,  "trigger"  },
-+      { OP_String,     0, 0,  0          },  /* 2: trigger name */
-+      { OP_String,     0, 0,  0          },  /* 3: table name */
-+      { OP_Integer,    0, 0,  0          },
-+      { OP_String,     0, 0,  0          },  /* 5: SQL */
-+      { OP_MakeRecord, 5, 0,  0          },
-+      { OP_PutIntKey,  0, 0,  0          },
-+    };
-+    int addr;
-+    Vdbe *v;
-+
-+    /* Make an entry in the sqlite_master table */
-+    v = sqliteGetVdbe(pParse);
-+    if( v==0 ) goto triggerfinish_cleanup;
-+    sqliteBeginWriteOperation(pParse, 0, 0);
-+    sqliteOpenMasterTable(v, nt->iDb);
-+    addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
-+    sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
-+    sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
-+    sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
-+    if( nt->iDb==0 ){
-+      sqliteChangeCookie(db, v);
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+    sqliteEndWriteOperation(pParse);
-+  }
-+
-+  if( !pParse->explain ){
-+    Table *pTab;
-+    sqliteHashInsert(&db->aDb[nt->iDb].trigHash, 
-+                     nt->name, strlen(nt->name)+1, nt);
-+    pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
-+    assert( pTab!=0 );
-+    nt->pNext = pTab->pTrigger;
-+    pTab->pTrigger = nt;
-+    nt = 0;
-+  }
-+
-+triggerfinish_cleanup:
-+  sqliteDeleteTrigger(nt);
-+  sqliteDeleteTrigger(pParse->pNewTrigger);
-+  pParse->pNewTrigger = 0;
-+  sqliteDeleteTriggerStep(pStepList);
-+}
-+
-+/*
-+** Make a copy of all components of the given trigger step.  This has
-+** the effect of copying all Expr.token.z values into memory obtained
-+** from sqliteMalloc().  As initially created, the Expr.token.z values
-+** all point to the input string that was fed to the parser.  But that
-+** string is ephemeral - it will go away as soon as the sqlite_exec()
-+** call that started the parser exits.  This routine makes a persistent
-+** copy of all the Expr.token.z strings so that the TriggerStep structure
-+** will be valid even after the sqlite_exec() call returns.
-+*/
-+static void sqlitePersistTriggerStep(TriggerStep *p){
-+  if( p->target.z ){
-+    p->target.z = sqliteStrNDup(p->target.z, p->target.n);
-+    p->target.dyn = 1;
-+  }
-+  if( p->pSelect ){
-+    Select *pNew = sqliteSelectDup(p->pSelect);
-+    sqliteSelectDelete(p->pSelect);
-+    p->pSelect = pNew;
-+  }
-+  if( p->pWhere ){
-+    Expr *pNew = sqliteExprDup(p->pWhere);
-+    sqliteExprDelete(p->pWhere);
-+    p->pWhere = pNew;
-+  }
-+  if( p->pExprList ){
-+    ExprList *pNew = sqliteExprListDup(p->pExprList);
-+    sqliteExprListDelete(p->pExprList);
-+    p->pExprList = pNew;
-+  }
-+  if( p->pIdList ){
-+    IdList *pNew = sqliteIdListDup(p->pIdList);
-+    sqliteIdListDelete(p->pIdList);
-+    p->pIdList = pNew;
-+  }
-+}
-+
-+/*
-+** 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.  
-+*/
-+TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
-+  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-+  if( pTriggerStep==0 ) return 0;
-+
-+  pTriggerStep->op = TK_SELECT;
-+  pTriggerStep->pSelect = pSelect;
-+  pTriggerStep->orconf = OE_Default;
-+  sqlitePersistTriggerStep(pTriggerStep);
-+
-+  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.
-+*/
-+TriggerStep *sqliteTriggerInsertStep(
-+  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 */
-+  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
-+){
-+  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-+  if( pTriggerStep==0 ) return 0;
-+
-+  assert(pEList == 0 || pSelect == 0);
-+  assert(pEList != 0 || pSelect != 0);
-+
-+  pTriggerStep->op = TK_INSERT;
-+  pTriggerStep->pSelect = pSelect;
-+  pTriggerStep->target  = *pTableName;
-+  pTriggerStep->pIdList = pColumn;
-+  pTriggerStep->pExprList = pEList;
-+  pTriggerStep->orconf = orconf;
-+  sqlitePersistTriggerStep(pTriggerStep);
-+
-+  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.
-+*/
-+TriggerStep *sqliteTriggerUpdateStep(
-+  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 */
-+  int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
-+){
-+  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-+  if( pTriggerStep==0 ) return 0;
-+
-+  pTriggerStep->op = TK_UPDATE;
-+  pTriggerStep->target  = *pTableName;
-+  pTriggerStep->pExprList = pEList;
-+  pTriggerStep->pWhere = pWhere;
-+  pTriggerStep->orconf = orconf;
-+  sqlitePersistTriggerStep(pTriggerStep);
-+
-+  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.
-+*/
-+TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
-+  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
-+  if( pTriggerStep==0 ) return 0;
-+
-+  pTriggerStep->op = TK_DELETE;
-+  pTriggerStep->target  = *pTableName;
-+  pTriggerStep->pWhere = pWhere;
-+  pTriggerStep->orconf = OE_Default;
-+  sqlitePersistTriggerStep(pTriggerStep);
-+
-+  return pTriggerStep;
-+}
-+
-+/* 
-+** Recursively delete a Trigger structure
-+*/
-+void sqliteDeleteTrigger(Trigger *pTrigger){
-+  if( pTrigger==0 ) return;
-+  sqliteDeleteTriggerStep(pTrigger->step_list);
-+  sqliteFree(pTrigger->name);
-+  sqliteFree(pTrigger->table);
-+  sqliteExprDelete(pTrigger->pWhen);
-+  sqliteIdListDelete(pTrigger->pColumns);
-+  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
-+  sqliteFree(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 sqliteDropTriggerPtr() routine does the
-+ * same job as this routine except it take a spointer to the trigger
-+ * instead of the trigger name.
-+ *
-+ * Note that this function does not delete the trigger entirely. Instead it
-+ * removes it from the internal schema and places it in the trigDrop hash 
-+ * table. This is so that the trigger can be restored into the database schema
-+ * if the transaction is rolled back.
-+ */
-+void sqliteDropTrigger(Parse *pParse, SrcList *pName){
-+  Trigger *pTrigger;
-+  int i;
-+  const char *zDb;
-+  const char *zName;
-+  int nName;
-+  sqlite *db = pParse->db;
-+
-+  if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
-+  assert( pName->nSrc==1 );
-+  zDb = pName->a[0].zDatabase;
-+  zName = pName->a[0].zName;
-+  nName = strlen(zName);
-+  for(i=0; i<db->nDb; i++){
-+    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
-+    if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
-+    pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
-+    if( pTrigger ) break;
-+  }
-+  if( !pTrigger ){
-+    sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
-+    goto drop_trigger_cleanup;
-+  }
-+  sqliteDropTriggerPtr(pParse, pTrigger, 0);
-+
-+drop_trigger_cleanup:
-+  sqliteSrcListDelete(pName);
-+}
-+
-+/*
-+** Drop a trigger given a pointer to that trigger.  If nested is false,
-+** then also generate code to remove the trigger from the SQLITE_MASTER
-+** table.
-+*/
-+void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
-+  Table   *pTable;
-+  Vdbe *v;
-+  sqlite *db = pParse->db;
-+
-+  assert( pTrigger->iDb<db->nDb );
-+  if( pTrigger->iDb>=2 ){
-+    sqliteErrorMsg(pParse, "triggers may not be removed from "
-+       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
-+    return;
-+  }
-+  pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
-+  assert(pTable);
-+  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+  {
-+    int code = SQLITE_DROP_TRIGGER;
-+    const char *zDb = db->aDb[pTrigger->iDb].zName;
-+    const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
-+    if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
-+    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
-+      sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
-+      return;
-+    }
-+  }
-+#endif
-+
-+  /* Generate code to destroy the database record of the trigger.
-+  */
-+  if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
-+    int base;
-+    static VdbeOpList dropTrigger[] = {
-+      { OP_Rewind,     0, ADDR(9),  0},
-+      { OP_String,     0, 0,        0}, /* 1 */
-+      { OP_Column,     0, 1,        0},
-+      { OP_Ne,         0, ADDR(8),  0},
-+      { OP_String,     0, 0,        "trigger"},
-+      { OP_Column,     0, 0,        0},
-+      { OP_Ne,         0, ADDR(8),  0},
-+      { OP_Delete,     0, 0,        0},
-+      { OP_Next,       0, ADDR(1),  0}, /* 8 */
-+    };
-+
-+    sqliteBeginWriteOperation(pParse, 0, 0);
-+    sqliteOpenMasterTable(v, pTrigger->iDb);
-+    base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
-+    sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
-+    if( pTrigger->iDb==0 ){
-+      sqliteChangeCookie(db, v);
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, 0, 0);
-+    sqliteEndWriteOperation(pParse);
-+  }
-+
-+  /*
-+   * If this is not an "explain", then delete the trigger structure.
-+   */
-+  if( !pParse->explain ){
-+    const char *zName = pTrigger->name;
-+    int nName = strlen(zName);
-+    if( pTable->pTrigger == pTrigger ){
-+      pTable->pTrigger = pTrigger->pNext;
-+    }else{
-+      Trigger *cc = pTable->pTrigger;
-+      while( cc ){ 
-+        if( cc->pNext == pTrigger ){
-+          cc->pNext = cc->pNext->pNext;
-+          break;
-+        }
-+        cc = cc->pNext;
-+      }
-+      assert(cc);
-+    }
-+    sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
-+    sqliteDeleteTrigger(pTrigger);
-+  }
-+}
-+
-+/*
-+** 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 || !pEList ) return 1;
-+  for(e=0; e<pEList->nExpr; e++){
-+    if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
-+  }
-+  return 0; 
-+}
-+
-+/* A global variable that is TRUE if we should always set up temp tables for
-+ * for triggers, even if there are no triggers to code. This is used to test 
-+ * how much overhead the triggers algorithm is causing.
-+ *
-+ * This flag can be set or cleared using the "trigger_overhead_test" pragma.
-+ * The pragma is not documented since it is not really part of the interface
-+ * to SQLite, just the test procedure.
-+*/
-+int always_code_trigger_setup = 0;
-+
-+/*
-+ * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
-+ * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
-+ * found in the list specified as pTrigger.
-+ */
-+int sqliteTriggersExist(
-+  Parse *pParse,          /* Used to check for recursive triggers */
-+  Trigger *pTrigger,      /* A list of triggers associated with a table */
-+  int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
-+  int tr_tm,              /* one of TK_BEFORE, TK_AFTER */
-+  int foreach,            /* one of TK_ROW or TK_STATEMENT */
-+  ExprList *pChanges      /* Columns that change in an UPDATE statement */
-+){
-+  Trigger * pTriggerCursor;
-+
-+  if( always_code_trigger_setup ){
-+    return 1;
-+  }
-+
-+  pTriggerCursor = pTrigger;
-+  while( pTriggerCursor ){
-+    if( pTriggerCursor->op == op && 
-+      pTriggerCursor->tr_tm == tr_tm && 
-+      pTriggerCursor->foreach == foreach &&
-+      checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
-+      TriggerStack * ss;
-+      ss = pParse->trigStack;
-+      while( ss && ss->pTrigger != pTrigger ){
-+      ss = ss->pNext;
-+      }
-+      if( !ss )return 1;
-+    }
-+    pTriggerCursor = pTriggerCursor->pNext;
-+  }
-+
-+  return 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 */
-+){
-+  Token sDb;           /* Dummy database name token */
-+  int iDb;             /* Index of the database to use */
-+  SrcList *pSrc;       /* SrcList to be returned */
-+
-+  iDb = pStep->pTrig->iDb;
-+  if( iDb==0 || iDb>=2 ){
-+    assert( iDb<pParse->db->nDb );
-+    sDb.z = pParse->db->aDb[iDb].zName;
-+    sDb.n = strlen(sDb.z);
-+    pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
-+  } else {
-+    pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
-+  }
-+  return pSrc;
-+}
-+
-+/*
-+** Generate VDBE code for zero or more statements inside the body of a
-+** trigger.  
-+*/
-+static int codeTriggerProgram(
-+  Parse *pParse,            /* The parser context */
-+  TriggerStep *pStepList,   /* List of statements inside the trigger body */
-+  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
-+){
-+  TriggerStep * pTriggerStep = pStepList;
-+  int orconf;
-+
-+  while( pTriggerStep ){
-+    int saveNTab = pParse->nTab;
-+ 
-+    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
-+    pParse->trigStack->orconf = orconf;
-+    switch( pTriggerStep->op ){
-+      case TK_SELECT: {
-+      Select * ss = sqliteSelectDup(pTriggerStep->pSelect);             
-+      assert(ss);
-+      assert(ss->pSrc);
-+      sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
-+      sqliteSelectDelete(ss);
-+      break;
-+      }
-+      case TK_UPDATE: {
-+        SrcList *pSrc;
-+        pSrc = targetSrcList(pParse, pTriggerStep);
-+        sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
-+        sqliteUpdate(pParse, pSrc,
-+              sqliteExprListDup(pTriggerStep->pExprList), 
-+              sqliteExprDup(pTriggerStep->pWhere), orconf);
-+        sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
-+        break;
-+      }
-+      case TK_INSERT: {
-+        SrcList *pSrc;
-+        pSrc = targetSrcList(pParse, pTriggerStep);
-+        sqliteInsert(pParse, pSrc,
-+          sqliteExprListDup(pTriggerStep->pExprList), 
-+          sqliteSelectDup(pTriggerStep->pSelect), 
-+          sqliteIdListDup(pTriggerStep->pIdList), orconf);
-+        break;
-+      }
-+      case TK_DELETE: {
-+        SrcList *pSrc;
-+        sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
-+        pSrc = targetSrcList(pParse, pTriggerStep);
-+        sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
-+        sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
-+        break;
-+      }
-+      default:
-+        assert(0);
-+    } 
-+    pParse->nTab = saveNTab;
-+    pTriggerStep = pTriggerStep->pNext;
-+  }
-+
-+  return 0;
-+}
-+
-+/*
-+** 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).
-+**
-+*/
-+int sqliteCodeRowTrigger(
-+  Parse *pParse,       /* Parse context */
-+  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
-+  ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
-+  int tr_tm,           /* One of TK_BEFORE, TK_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 * pTrigger;
-+  TriggerStack * pTriggerStack;
-+
-+  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
-+  assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
-+
-+  assert(newIdx != -1 || oldIdx != -1);
-+
-+  pTrigger = pTab->pTrigger;
-+  while( pTrigger ){
-+    int fire_this = 0;
-+
-+    /* determine whether we should code this trigger */
-+    if( pTrigger->op == op && pTrigger->tr_tm == tr_tm && 
-+        pTrigger->foreach == TK_ROW ){
-+      fire_this = 1;
-+      pTriggerStack = pParse->trigStack;
-+      while( pTriggerStack ){
-+        if( pTriggerStack->pTrigger == pTrigger ){
-+        fire_this = 0;
-+      }
-+        pTriggerStack = pTriggerStack->pNext;
-+      }
-+      if( op == TK_UPDATE && pTrigger->pColumns &&
-+          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
-+        fire_this = 0;
-+      }
-+    }
-+
-+    if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
-+      int endTrigger;
-+      SrcList dummyTablist;
-+      Expr * whenExpr;
-+      AuthContext sContext;
-+
-+      dummyTablist.nSrc = 0;
-+
-+      /* Push an entry on to the trigger stack */
-+      pTriggerStack->pTrigger = pTrigger;
-+      pTriggerStack->newIdx = newIdx;
-+      pTriggerStack->oldIdx = oldIdx;
-+      pTriggerStack->pTab = pTab;
-+      pTriggerStack->pNext = pParse->trigStack;
-+      pTriggerStack->ignoreJump = ignoreJump;
-+      pParse->trigStack = pTriggerStack;
-+      sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
-+
-+      /* code the WHEN clause */
-+      endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
-+      whenExpr = sqliteExprDup(pTrigger->pWhen);
-+      if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
-+        pParse->trigStack = pParse->trigStack->pNext;
-+        sqliteFree(pTriggerStack);
-+        sqliteExprDelete(whenExpr);
-+        return 1;
-+      }
-+      sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
-+      sqliteExprDelete(whenExpr);
-+
-+      sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
-+      codeTriggerProgram(pParse, pTrigger->step_list, orconf); 
-+      sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
-+
-+      /* Pop the entry off the trigger stack */
-+      pParse->trigStack = pParse->trigStack->pNext;
-+      sqliteAuthContextPop(&sContext);
-+      sqliteFree(pTriggerStack);
-+
-+      sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
-+    }
-+    pTrigger = pTrigger->pNext;
-+  }
-+
-+  return 0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/update.c
-@@ -0,0 +1,459 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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
-+*/
-+void sqliteUpdate(
-+  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 loopStart;         /* VDBE instruction address of the start of the loop */
-+  int jumpInst;          /* Addr of VDBE instruction to jump out of 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 nIdxTotal;         /* Total number of indices */
-+  int iCur;              /* VDBE Cursor number of pTab */
-+  sqlite *db;            /* The database structure */
-+  Index **apIdx = 0;     /* An array of indices that need updating too */
-+  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
-+  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 chngRecno;         /* True if the record number is being changed */
-+  Expr *pRecnoExpr;      /* Expression defining the new record number */
-+  int openAll;           /* True if all indices need to be opened */
-+  int isView;            /* Trying to update a view */
-+  int iStackDepth;       /* Index of memory cell holding stack depth */
-+  AuthContext sContext;  /* The authorization context */
-+
-+  int before_triggers;         /* True if there are any BEFORE triggers */
-+  int after_triggers;          /* True if there are any AFTER triggers */
-+  int row_triggers_exist = 0;  /* True if any row triggers exist */
-+
-+  int newIdx      = -1;  /* index of trigger "new" temp table       */
-+  int oldIdx      = -1;  /* index of trigger "old" temp table       */
-+
-+  sContext.pParse = 0;
-+  if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
-+  db = pParse->db;
-+  assert( pTabList->nSrc==1 );
-+  iStackDepth = pParse->nMem++;
-+
-+  /* Locate the table which we want to update. 
-+  */
-+  pTab = sqliteSrcListLookup(pParse, pTabList);
-+  if( pTab==0 ) goto update_cleanup;
-+  before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, 
-+            TK_UPDATE, TK_BEFORE, TK_ROW, pChanges);
-+  after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, 
-+            TK_UPDATE, TK_AFTER, TK_ROW, pChanges);
-+  row_triggers_exist = before_triggers || after_triggers;
-+  isView = pTab->pSelect!=0;
-+  if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
-+    goto update_cleanup;
-+  }
-+  if( isView ){
-+    if( sqliteViewGetColumnNames(pParse, pTab) ){
-+      goto update_cleanup;
-+    }
-+  }
-+  aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
-+  if( aXRef==0 ) goto update_cleanup;
-+  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
-+
-+  /* If there are FOR EACH ROW triggers, allocate cursors for the
-+  ** special OLD and NEW tables
-+  */
-+  if( row_triggers_exist ){
-+    newIdx = pParse->nTab++;
-+    oldIdx = pParse->nTab++;
-+  }
-+
-+  /* 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++;
-+  }
-+
-+  /* 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.
-+  */
-+  chngRecno = 0;
-+  for(i=0; i<pChanges->nExpr; i++){
-+    if( sqliteExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
-+      goto update_cleanup;
-+    }
-+    if( sqliteExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
-+      goto update_cleanup;
-+    }
-+    for(j=0; j<pTab->nCol; j++){
-+      if( sqliteStrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
-+        if( j==pTab->iPKey ){
-+          chngRecno = 1;
-+          pRecnoExpr = pChanges->a[i].pExpr;
-+        }
-+        aXRef[j] = i;
-+        break;
-+      }
-+    }
-+    if( j>=pTab->nCol ){
-+      if( sqliteIsRowid(pChanges->a[i].zName) ){
-+        chngRecno = 1;
-+        pRecnoExpr = pChanges->a[i].pExpr;
-+      }else{
-+        sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
-+        goto update_cleanup;
-+      }
-+    }
-+#ifndef SQLITE_OMIT_AUTHORIZATION
-+    {
-+      int rc;
-+      rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
-+                           pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
-+      if( rc==SQLITE_DENY ){
-+        goto update_cleanup;
-+      }else if( rc==SQLITE_IGNORE ){
-+        aXRef[j] = -1;
-+      }
-+    }
-+#endif
-+  }
-+
-+  /* Allocate memory for the array apIdx[] and fill it with pointers to every
-+  ** index that needs to be updated.  Indices only need updating if their
-+  ** key includes one of the columns named in pChanges or if the record
-+  ** number of the original table entry is changing.
-+  */
-+  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
-+    if( chngRecno ){
-+      i = 0;
-+    }else {
-+      for(i=0; i<pIdx->nColumn; i++){
-+        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
-+      }
-+    }
-+    if( i<pIdx->nColumn ) nIdx++;
-+  }
-+  if( nIdxTotal>0 ){
-+    apIdx = sqliteMalloc( sizeof(Index*) * nIdx + nIdxTotal );
-+    if( apIdx==0 ) goto update_cleanup;
-+    aIdxUsed = (char*)&apIdx[nIdx];
-+  }
-+  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-+    if( chngRecno ){
-+      i = 0;
-+    }else{
-+      for(i=0; i<pIdx->nColumn; i++){
-+        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
-+      }
-+    }
-+    if( i<pIdx->nColumn ){
-+      apIdx[nIdx++] = pIdx;
-+      aIdxUsed[j] = 1;
-+    }else{
-+      aIdxUsed[j] = 0;
-+    }
-+  }
-+
-+  /* Resolve the column names in all the expressions in the
-+  ** WHERE clause.
-+  */
-+  if( pWhere ){
-+    if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
-+      goto update_cleanup;
-+    }
-+    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
-+      goto update_cleanup;
-+    }
-+  }
-+
-+  /* Start the view context
-+  */
-+  if( isView ){
-+    sqliteAuthContextPush(pParse, &sContext, pTab->zName);
-+  }
-+
-+  /* Begin generating code.
-+  */
-+  v = sqliteGetVdbe(pParse);
-+  if( v==0 ) goto update_cleanup;
-+  sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
-+
-+  /* If we are trying to update a view, construct that view into
-+  ** a temporary table.
-+  */
-+  if( isView ){
-+    Select *pView;
-+    pView = sqliteSelectDup(pTab->pSelect);
-+    sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
-+    sqliteSelectDelete(pView);
-+  }
-+
-+  /* Begin the database scan
-+  */
-+  pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
-+  if( pWInfo==0 ) goto update_cleanup;
-+
-+  /* Remember the index of every item to be updated.
-+  */
-+  sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
-+
-+  /* End the database scan loop.
-+  */
-+  sqliteWhereEnd(pWInfo);
-+
-+  /* Initialize the count of updated rows
-+  */
-+  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
-+    sqliteVdbeAddOp(v, OP_Integer, 0, 0);
-+  }
-+
-+  if( row_triggers_exist ){
-+    /* Create pseudo-tables for NEW and OLD
-+    */
-+    sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
-+    sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
-+
-+    /* The top of the update loop for when there are triggers.
-+    */
-+    sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
-+    sqliteVdbeAddOp(v, OP_StackDepth, 0, 0);
-+    sqliteVdbeAddOp(v, OP_MemStore, iStackDepth, 1);
-+    loopStart = sqliteVdbeAddOp(v, OP_MemLoad, iStackDepth, 0);
-+    sqliteVdbeAddOp(v, OP_StackReset, 0, 0);
-+    jumpInst = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
-+    sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+
-+    /* Open a cursor and make it point to the record that is
-+    ** being updated.
-+    */
-+    sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+    if( !isView ){
-+      sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+      sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
-+    }
-+    sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+
-+    /* Generate the OLD table
-+    */
-+    sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
-+    sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
-+
-+    /* Generate the NEW table
-+    */
-+    if( chngRecno ){
-+      sqliteExprCode(pParse, pRecnoExpr);
-+    }else{
-+      sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
-+    }
-+    for(i=0; i<pTab->nCol; i++){
-+      if( i==pTab->iPKey ){
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+        continue;
-+      }
-+      j = aXRef[i];
-+      if( j<0 ){
-+        sqliteVdbeAddOp(v, OP_Column, iCur, i);
-+      }else{
-+        sqliteExprCode(pParse, pChanges->a[j].pExpr);
-+      }
-+    }
-+    sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
-+    sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
-+    if( !isView ){
-+      sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+    }
-+
-+    /* Fire the BEFORE and INSTEAD OF triggers
-+    */
-+    if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab, 
-+          newIdx, oldIdx, onError, loopStart) ){
-+      goto update_cleanup;
-+    }
-+  }
-+
-+  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.
-+    */
-+    sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+    sqliteVdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
-+    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 || aIdxUsed[i] ){
-+        sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
-+        sqliteVdbeAddOp(v, OP_OpenWrite, iCur+i+1, pIdx->tnum);
-+        assert( pParse->nTab>iCur+i+1 );
-+      }
-+    }
-+
-+    /* Loop over every record that needs updating.  We have to load
-+    ** the old data for each record to be updated because some columns
-+    ** might not change and we will need to copy the old value.
-+    ** Also, the old data is needed to delete the old index entires.
-+    ** So make the cursor point at the old record.
-+    */
-+    if( !row_triggers_exist ){
-+      sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
-+      jumpInst = loopStart = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
-+      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+    }
-+    sqliteVdbeAddOp(v, OP_NotExists, iCur, loopStart);
-+
-+    /* If the record number will change, push the record number as it
-+    ** will be after the update. (The old record number is currently
-+    ** on top of the stack.)
-+    */
-+    if( chngRecno ){
-+      sqliteExprCode(pParse, pRecnoExpr);
-+      sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
-+    }
-+
-+    /* Compute new data for this record.  
-+    */
-+    for(i=0; i<pTab->nCol; i++){
-+      if( i==pTab->iPKey ){
-+        sqliteVdbeAddOp(v, OP_String, 0, 0);
-+        continue;
-+      }
-+      j = aXRef[i];
-+      if( j<0 ){
-+        sqliteVdbeAddOp(v, OP_Column, iCur, i);
-+      }else{
-+        sqliteExprCode(pParse, pChanges->a[j].pExpr);
-+      }
-+    }
-+
-+    /* Do constraint checks
-+    */
-+    sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
-+                                   onError, loopStart);
-+
-+    /* Delete the old indices for the current record.
-+    */
-+    sqliteGenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
-+
-+    /* If changing the record number, delete the old record.
-+    */
-+    if( chngRecno ){
-+      sqliteVdbeAddOp(v, OP_Delete, iCur, 0);
-+    }
-+
-+    /* Create the new index entries and the new record.
-+    */
-+    sqliteCompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
-+  }
-+
-+  /* Increment the row counter 
-+  */
-+  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
-+    sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
-+  }
-+
-+  /* If there are triggers, close all the cursors after each iteration
-+  ** through the loop.  The fire the after triggers.
-+  */
-+  if( row_triggers_exist ){
-+    if( !isView ){
-+      for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
-+        if( openAll || aIdxUsed[i] )
-+          sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
-+      }
-+      sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+      pParse->nTab = iCur;
-+    }
-+    if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab, 
-+          newIdx, oldIdx, onError, loopStart) ){
-+      goto update_cleanup;
-+    }
-+  }
-+
-+  /* Repeat the above with the next record to be updated, until
-+  ** all record selected by the WHERE clause have been updated.
-+  */
-+  sqliteVdbeAddOp(v, OP_Goto, 0, loopStart);
-+  sqliteVdbeChangeP2(v, jumpInst, sqliteVdbeCurrentAddr(v));
-+  sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
-+
-+  /* Close all tables if there were no FOR EACH ROW triggers */
-+  if( !row_triggers_exist ){
-+    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
-+      if( openAll || aIdxUsed[i] ){
-+        sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
-+      }
-+    }
-+    sqliteVdbeAddOp(v, OP_Close, iCur, 0);
-+    pParse->nTab = iCur;
-+  }else{
-+    sqliteVdbeAddOp(v, OP_Close, newIdx, 0);
-+    sqliteVdbeAddOp(v, OP_Close, oldIdx, 0);
-+  }
-+
-+  sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
-+  sqliteEndWriteOperation(pParse);
-+
-+  /*
-+  ** Return the number of rows that were changed.
-+  */
-+  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
-+    sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows updated", P3_STATIC);
-+    sqliteVdbeAddOp(v, OP_Callback, 1, 0);
-+  }
-+
-+update_cleanup:
-+  sqliteAuthContextPop(&sContext);
-+  sqliteFree(apIdx);
-+  sqliteFree(aXRef);
-+  sqliteSrcListDelete(pTabList);
-+  sqliteExprListDelete(pChanges);
-+  sqliteExprDelete(pWhere);
-+  return;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/util.c
-@@ -0,0 +1,1134 @@
-+/*
-+** 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.
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+#include <stdarg.h>
-+#include <ctype.h>
-+
-+/*
-+** If malloc() ever fails, this global variable gets set to 1.
-+** This causes the library to abort and never again function.
-+*/
-+int sqlite_malloc_failed = 0;
-+
-+/*
-+** If MEMORY_DEBUG is defined, then use versions of malloc() and
-+** free() that track memory usage and check for buffer overruns.
-+*/
-+#ifdef MEMORY_DEBUG
-+
-+/*
-+** For keeping track of the number of mallocs and frees.   This
-+** is used to check for memory leaks.
-+*/
-+int sqlite_nMalloc;         /* Number of sqliteMalloc() calls */
-+int sqlite_nFree;           /* Number of sqliteFree() calls */
-+int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
-+#if MEMORY_DEBUG>1
-+static int memcnt = 0;
-+#endif
-+
-+/*
-+** Number of 32-bit guard words
-+*/
-+#define N_GUARD 1
-+
-+/*
-+** Allocate new memory and set it to zero.  Return NULL if
-+** no memory is available.
-+*/
-+void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
-+  void *p;
-+  int *pi;
-+  int i, k;
-+  if( sqlite_iMallocFail>=0 ){
-+    sqlite_iMallocFail--;
-+    if( sqlite_iMallocFail==0 ){
-+      sqlite_malloc_failed++;
-+#if MEMORY_DEBUG>1
-+      fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
-+              n, zFile,line);
-+#endif
-+      sqlite_iMallocFail--;
-+      return 0;
-+    }
-+  }
-+  if( n==0 ) return 0;
-+  k = (n+sizeof(int)-1)/sizeof(int);
-+  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
-+  if( pi==0 ){
-+    sqlite_malloc_failed++;
-+    return 0;
-+  }
-+  sqlite_nMalloc++;
-+  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
-+  pi[N_GUARD] = n;
-+  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
-+  p = &pi[N_GUARD+1];
-+  memset(p, bZero==0, n);
-+#if MEMORY_DEBUG>1
-+  fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
-+      ++memcnt, n, (int)p, zFile,line);
-+#endif
-+  return p;
-+}
-+
-+/*
-+** Check to see if the given pointer was obtained from sqliteMalloc()
-+** and is able to hold at least N bytes.  Raise an exception if this
-+** is not the case.
-+**
-+** This routine is used for testing purposes only.
-+*/
-+void sqliteCheckMemory(void *p, int N){
-+  int *pi = p;
-+  int n, i, k;
-+  pi -= N_GUARD+1;
-+  for(i=0; i<N_GUARD; i++){
-+    assert( pi[i]==0xdead1122 );
-+  }
-+  n = pi[N_GUARD];
-+  assert( N>=0 && N<n );
-+  k = (n+sizeof(int)-1)/sizeof(int);
-+  for(i=0; i<N_GUARD; i++){
-+    assert( pi[k+N_GUARD+1+i]==0xdead3344 );
-+  }
-+}
-+
-+/*
-+** Free memory previously obtained from sqliteMalloc()
-+*/
-+void sqliteFree_(void *p, char *zFile, int line){
-+  if( p ){
-+    int *pi, i, k, n;
-+    pi = p;
-+    pi -= N_GUARD+1;
-+    sqlite_nFree++;
-+    for(i=0; i<N_GUARD; i++){
-+      if( pi[i]!=0xdead1122 ){
-+        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
-+        return;
-+      }
-+    }
-+    n = pi[N_GUARD];
-+    k = (n+sizeof(int)-1)/sizeof(int);
-+    for(i=0; i<N_GUARD; i++){
-+      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
-+        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
-+        return;
-+      }
-+    }
-+    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
-+#if MEMORY_DEBUG>1
-+    fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
-+         ++memcnt, n, (int)p, zFile,line);
-+#endif
-+    free(pi);
-+  }
-+}
-+
-+/*
-+** Resize a prior allocation.  If p==0, then this routine
-+** works just like sqliteMalloc().  If n==0, then this routine
-+** works just like sqliteFree().
-+*/
-+void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
-+  int *oldPi, *pi, i, k, oldN, oldK;
-+  void *p;
-+  if( oldP==0 ){
-+    return sqliteMalloc_(n,1,zFile,line);
-+  }
-+  if( n==0 ){
-+    sqliteFree_(oldP,zFile,line);
-+    return 0;
-+  }
-+  oldPi = oldP;
-+  oldPi -= N_GUARD+1;
-+  if( oldPi[0]!=0xdead1122 ){
-+    fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
-+    return 0;
-+  }
-+  oldN = oldPi[N_GUARD];
-+  oldK = (oldN+sizeof(int)-1)/sizeof(int);
-+  for(i=0; i<N_GUARD; i++){
-+    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
-+      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
-+              (int)oldP);
-+      return 0;
-+    }
-+  }
-+  k = (n + sizeof(int) - 1)/sizeof(int);
-+  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
-+  if( pi==0 ){
-+    sqlite_malloc_failed++;
-+    return 0;
-+  }
-+  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
-+  pi[N_GUARD] = n;
-+  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
-+  p = &pi[N_GUARD+1];
-+  memcpy(p, oldP, n>oldN ? oldN : n);
-+  if( n>oldN ){
-+    memset(&((char*)p)[oldN], 0, n-oldN);
-+  }
-+  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
-+  free(oldPi);
-+#if MEMORY_DEBUG>1
-+  fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
-+    ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
-+#endif
-+  return p;
-+}
-+
-+/*
-+** Make a duplicate of a string into memory obtained from malloc()
-+** Free the original string using sqliteFree().
-+**
-+** This routine is called on all strings that are passed outside of
-+** the SQLite library.  That way clients can free the string using free()
-+** rather than having to call sqliteFree().
-+*/
-+void sqliteStrRealloc(char **pz){
-+  char *zNew;
-+  if( pz==0 || *pz==0 ) return;
-+  zNew = malloc( strlen(*pz) + 1 );
-+  if( zNew==0 ){
-+    sqlite_malloc_failed++;
-+    sqliteFree(*pz);
-+    *pz = 0;
-+  }
-+  strcpy(zNew, *pz);
-+  sqliteFree(*pz);
-+  *pz = zNew;
-+}
-+
-+/*
-+** Make a copy of a string in memory obtained from sqliteMalloc()
-+*/
-+char *sqliteStrDup_(const char *z, char *zFile, int line){
-+  char *zNew;
-+  if( z==0 ) return 0;
-+  zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line);
-+  if( zNew ) strcpy(zNew, z);
-+  return zNew;
-+}
-+char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
-+  char *zNew;
-+  if( z==0 ) return 0;
-+  zNew = sqliteMalloc_(n+1, 0, zFile, line);
-+  if( zNew ){
-+    memcpy(zNew, z, n);
-+    zNew[n] = 0;
-+  }
-+  return zNew;
-+}
-+#endif /* MEMORY_DEBUG */
-+
-+/*
-+** The following versions of malloc() and free() are for use in a
-+** normal build.
-+*/
-+#if !defined(MEMORY_DEBUG)
-+
-+/*
-+** Allocate new memory and set it to zero.  Return NULL if
-+** no memory is available.  See also sqliteMallocRaw().
-+*/
-+void *sqliteMalloc(int n){
-+  void *p;
-+  if( (p = malloc(n))==0 ){
-+    if( n>0 ) sqlite_malloc_failed++;
-+  }else{
-+    memset(p, 0, n);
-+  }
-+  return p;
-+}
-+
-+/*
-+** Allocate new memory but do not set it to zero.  Return NULL if
-+** no memory is available.  See also sqliteMalloc().
-+*/
-+void *sqliteMallocRaw(int n){
-+  void *p;
-+  if( (p = malloc(n))==0 ){
-+    if( n>0 ) sqlite_malloc_failed++;
-+  }
-+  return p;
-+}
-+
-+/*
-+** Free memory previously obtained from sqliteMalloc()
-+*/
-+void sqliteFree(void *p){
-+  if( p ){
-+    free(p);
-+  }
-+}
-+
-+/*
-+** Resize a prior allocation.  If p==0, then this routine
-+** works just like sqliteMalloc().  If n==0, then this routine
-+** works just like sqliteFree().
-+*/
-+void *sqliteRealloc(void *p, int n){
-+  void *p2;
-+  if( p==0 ){
-+    return sqliteMalloc(n);
-+  }
-+  if( n==0 ){
-+    sqliteFree(p);
-+    return 0;
-+  }
-+  p2 = realloc(p, n);
-+  if( p2==0 ){
-+    sqlite_malloc_failed++;
-+  }
-+  return p2;
-+}
-+
-+/*
-+** Make a copy of a string in memory obtained from sqliteMalloc()
-+*/
-+char *sqliteStrDup(const char *z){
-+  char *zNew;
-+  if( z==0 ) return 0;
-+  zNew = sqliteMallocRaw(strlen(z)+1);
-+  if( zNew ) strcpy(zNew, z);
-+  return zNew;
-+}
-+char *sqliteStrNDup(const char *z, int n){
-+  char *zNew;
-+  if( z==0 ) return 0;
-+  zNew = sqliteMallocRaw(n+1);
-+  if( zNew ){
-+    memcpy(zNew, z, n);
-+    zNew[n] = 0;
-+  }
-+  return zNew;
-+}
-+#endif /* !defined(MEMORY_DEBUG) */
-+
-+/*
-+** Create a string from the 2nd and subsequent arguments (up to the
-+** first NULL argument), store the string in memory obtained from
-+** sqliteMalloc() and make the pointer indicated by the 1st argument
-+** point to that string.  The 1st argument must either be NULL or 
-+** point to memory obtained from sqliteMalloc().
-+*/
-+void sqliteSetString(char **pz, ...){
-+  va_list ap;
-+  int nByte;
-+  const char *z;
-+  char *zResult;
-+
-+  if( pz==0 ) return;
-+  nByte = 1;
-+  va_start(ap, pz);
-+  while( (z = va_arg(ap, const char*))!=0 ){
-+    nByte += strlen(z);
-+  }
-+  va_end(ap);
-+  sqliteFree(*pz);
-+  *pz = zResult = sqliteMallocRaw( nByte );
-+  if( zResult==0 ){
-+    return;
-+  }
-+  *zResult = 0;
-+  va_start(ap, pz);
-+  while( (z = va_arg(ap, const char*))!=0 ){
-+    strcpy(zResult, z);
-+    zResult += strlen(zResult);
-+  }
-+  va_end(ap);
-+#ifdef MEMORY_DEBUG
-+#if MEMORY_DEBUG>1
-+  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
-+#endif
-+#endif
-+}
-+
-+/*
-+** Works like sqliteSetString, but each string is now followed by
-+** a length integer which specifies how much of the source string 
-+** to copy (in bytes).  -1 means use the whole string.  The 1st 
-+** argument must either be NULL or point to memory obtained from 
-+** sqliteMalloc().
-+*/
-+void sqliteSetNString(char **pz, ...){
-+  va_list ap;
-+  int nByte;
-+  const char *z;
-+  char *zResult;
-+  int n;
-+
-+  if( pz==0 ) return;
-+  nByte = 0;
-+  va_start(ap, pz);
-+  while( (z = va_arg(ap, const char*))!=0 ){
-+    n = va_arg(ap, int);
-+    if( n<=0 ) n = strlen(z);
-+    nByte += n;
-+  }
-+  va_end(ap);
-+  sqliteFree(*pz);
-+  *pz = zResult = sqliteMallocRaw( nByte + 1 );
-+  if( zResult==0 ) return;
-+  va_start(ap, pz);
-+  while( (z = va_arg(ap, const char*))!=0 ){
-+    n = va_arg(ap, int);
-+    if( n<=0 ) n = strlen(z);
-+    strncpy(zResult, z, n);
-+    zResult += n;
-+  }
-+  *zResult = 0;
-+#ifdef MEMORY_DEBUG
-+#if MEMORY_DEBUG>1
-+  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
-+#endif
-+#endif
-+  va_end(ap);
-+}
-+
-+/*
-+** 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
-+*/
-+void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
-+  va_list ap;
-+  pParse->nErr++;
-+  sqliteFree(pParse->zErrMsg);
-+  va_start(ap, zFormat);
-+  pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);
-+  va_end(ap);
-+}
-+
-+/*
-+** 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.
-+**
-+** 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".
-+*/
-+void sqliteDequote(char *z){
-+  int quote;
-+  int i, j;
-+  if( z==0 ) return;
-+  quote = z[0];
-+  switch( quote ){
-+    case '\'':  break;
-+    case '"':   break;
-+    case '[':   quote = ']';  break;
-+    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];
-+    }
-+  }
-+}
-+
-+/* An array to map all upper-case characters into their corresponding
-+** lower-case character. 
-+*/
-+static unsigned char UpperToLower[] = {
-+      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 function computes a hash on the name of a keyword.
-+** Case is not significant.
-+*/
-+int sqliteHashNoCase(const char *z, int n){
-+  int h = 0;
-+  if( n<=0 ) n = strlen(z);
-+  while( n > 0  ){
-+    h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++];
-+    n--;
-+  }
-+  return h & 0x7fffffff;
-+}
-+
-+/*
-+** Some systems have stricmp().  Others have strcasecmp().  Because
-+** there is no consistency, we will define our own.
-+*/
-+int sqliteStrICmp(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];
-+}
-+int sqliteStrNICmp(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 if the
-+** string contains any character which is not part of a number.
-+**
-+** Am empty string is considered non-numeric.
-+*/
-+int sqliteIsNumber(const char *z){
-+  if( *z=='-' || *z=='+' ) z++;
-+  if( !isdigit(*z) ){
-+    return 0;
-+  }
-+  z++;
-+  while( isdigit(*z) ){ z++; }
-+  if( *z=='.' ){
-+    z++;
-+    if( !isdigit(*z) ) return 0;
-+    while( isdigit(*z) ){ z++; }
-+  }
-+  if( *z=='e' || *z=='E' ){
-+    z++;
-+    if( *z=='+' || *z=='-' ) z++;
-+    if( !isdigit(*z) ) return 0;
-+    while( isdigit(*z) ){ z++; }
-+  }
-+  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.
-+*/
-+double sqliteAtoF(const char *z, const char **pzEnd){
-+  int sign = 1;
-+  LONGDOUBLE_TYPE v1 = 0.0;
-+  if( *z=='-' ){
-+    sign = -1;
-+    z++;
-+  }else if( *z=='+' ){
-+    z++;
-+  }
-+  while( isdigit(*z) ){
-+    v1 = v1*10.0 + (*z - '0');
-+    z++;
-+  }
-+  if( *z=='.' ){
-+    LONGDOUBLE_TYPE divisor = 1.0;
-+    z++;
-+    while( isdigit(*z) ){
-+      v1 = v1*10.0 + (*z - '0');
-+      divisor *= 10.0;
-+      z++;
-+    }
-+    v1 /= divisor;
-+  }
-+  if( *z=='e' || *z=='E' ){
-+    int esign = 1;
-+    int eval = 0;
-+    LONGDOUBLE_TYPE scale = 1.0;
-+    z++;
-+    if( *z=='-' ){
-+      esign = -1;
-+      z++;
-+    }else if( *z=='+' ){
-+      z++;
-+    }
-+    while( isdigit(*z) ){
-+      eval = eval*10 + *z - '0';
-+      z++;
-+    }
-+    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
-+    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
-+    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
-+    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
-+    if( esign<0 ){
-+      v1 /= scale;
-+    }else{
-+      v1 *= scale;
-+    }
-+  }
-+  if( pzEnd ) *pzEnd = z;
-+  return sign<0 ? -v1 : v1;
-+}
-+
-+/*
-+** The string zNum represents an integer.  There might be some other
-+** information following the integer too, but that part is ignored.
-+** If the integer that the prefix of zNum represents will fit in a
-+** 32-bit signed integer, return TRUE.  Otherwise return FALSE.
-+**
-+** This routine returns FALSE for the string -2147483648 even that
-+** that number will, in theory fit in a 32-bit integer.  But positive
-+** 2147483648 will not fit in 32 bits.  So it seems safer to return
-+** false.
-+*/
-+int sqliteFitsIn32Bits(const char *zNum){
-+  int i, c;
-+  if( *zNum=='-' || *zNum=='+' ) zNum++;
-+  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
-+  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
-+}
-+
-+/* This comparison routine is what we use for comparison operations
-+** between numeric values in an SQL expression.  "Numeric" is a little
-+** bit misleading here.  What we mean is that the strings have a
-+** type of "numeric" from the point of view of SQL.  The strings
-+** do not necessarily contain numbers.  They could contain text.
-+**
-+** If the input strings both look like actual numbers then they
-+** compare in numerical order.  Numerical strings are always less 
-+** than non-numeric strings so if one input string looks like a
-+** number and the other does not, then the one that looks like
-+** a number is the smaller.  Non-numeric strings compare in 
-+** lexigraphical order (the same order as strcmp()).
-+*/
-+int sqliteCompare(const char *atext, const char *btext){
-+  int result;
-+  int isNumA, isNumB;
-+  if( atext==0 ){
-+    return -1;
-+  }else if( btext==0 ){
-+    return 1;
-+  }
-+  isNumA = sqliteIsNumber(atext);
-+  isNumB = sqliteIsNumber(btext);
-+  if( isNumA ){
-+    if( !isNumB ){
-+      result = -1;
-+    }else{
-+      double rA, rB;
-+      rA = sqliteAtoF(atext, 0);
-+      rB = sqliteAtoF(btext, 0);
-+      if( rA<rB ){
-+        result = -1;
-+      }else if( rA>rB ){
-+        result = +1;
-+      }else{
-+        result = 0;
-+      }
-+    }
-+  }else if( isNumB ){
-+    result = +1;
-+  }else {
-+    result = strcmp(atext, btext);
-+  }
-+  return result; 
-+}
-+
-+/*
-+** This routine is used for sorting.  Each key is a list of one or more
-+** null-terminated elements.  The list is terminated by two nulls in
-+** a row.  For example, the following text is a key with three elements
-+**
-+**            Aone\000Dtwo\000Athree\000\000
-+**
-+** All elements begin with one of the characters "+-AD" and end with "\000"
-+** with zero or more text elements in between.  Except, NULL elements
-+** consist of the special two-character sequence "N\000".
-+**
-+** Both arguments will have the same number of elements.  This routine
-+** returns negative, zero, or positive if the first argument is less
-+** than, equal to, or greater than the first.  (Result is a-b).
-+**
-+** Each element begins with one of the characters "+", "-", "A", "D".
-+** This character determines the sort order and collating sequence:
-+**
-+**     +      Sort numerically in ascending order
-+**     -      Sort numerically in descending order
-+**     A      Sort as strings in ascending order
-+**     D      Sort as strings in descending order.
-+**
-+** For the "+" and "-" sorting, pure numeric strings (strings for which the
-+** isNum() function above returns TRUE) always compare less than strings
-+** that are not pure numerics.  Non-numeric strings compare in memcmp()
-+** order.  This is the same sort order as the sqliteCompare() function
-+** above generates.
-+**
-+** The last point is a change from version 2.6.3 to version 2.7.0.  In
-+** version 2.6.3 and earlier, substrings of digits compare in numerical 
-+** and case was used only to break a tie.
-+**
-+** Elements that begin with 'A' or 'D' compare in memcmp() order regardless
-+** of whether or not they look like a number.
-+**
-+** Note that the sort order imposed by the rules above is the same
-+** from the ordering defined by the "<", "<=", ">", and ">=" operators
-+** of expressions and for indices.  This was not the case for version
-+** 2.6.3 and earlier.
-+*/
-+int sqliteSortCompare(const char *a, const char *b){
-+  int res = 0;
-+  int isNumA, isNumB;
-+  int dir = 0;
-+
-+  while( res==0 && *a && *b ){
-+    if( a[0]=='N' || b[0]=='N' ){
-+      if( a[0]==b[0] ){
-+        a += 2;
-+        b += 2;
-+        continue;
-+      }
-+      if( a[0]=='N' ){
-+        dir = b[0];
-+        res = -1;
-+      }else{
-+        dir = a[0];
-+        res = +1;
-+      }
-+      break;
-+    }
-+    assert( a[0]==b[0] );
-+    if( (dir=a[0])=='A' || a[0]=='D' ){
-+      res = strcmp(&a[1],&b[1]);
-+      if( res ) break;
-+    }else{
-+      isNumA = sqliteIsNumber(&a[1]);
-+      isNumB = sqliteIsNumber(&b[1]);
-+      if( isNumA ){
-+        double rA, rB;
-+        if( !isNumB ){
-+          res = -1;
-+          break;
-+        }
-+        rA = sqliteAtoF(&a[1], 0);
-+        rB = sqliteAtoF(&b[1], 0);
-+        if( rA<rB ){
-+          res = -1;
-+          break;
-+        }
-+        if( rA>rB ){
-+          res = +1;
-+          break;
-+        }
-+      }else if( isNumB ){
-+        res = +1;
-+        break;
-+      }else{
-+        res = strcmp(&a[1],&b[1]);
-+        if( res ) break;
-+      }
-+    }
-+    a += strlen(&a[1]) + 2;
-+    b += strlen(&b[1]) + 2;
-+  }
-+  if( dir=='-' || dir=='D' ) res = -res;
-+  return res;
-+}
-+
-+/*
-+** Some powers of 64.  These constants are needed in the
-+** sqliteRealToSortable() routine below.
-+*/
-+#define _64e3  (64.0 * 64.0 * 64.0)
-+#define _64e4  (64.0 * 64.0 * 64.0 * 64.0)
-+#define _64e15 (_64e3 * _64e4 * _64e4 * _64e4)
-+#define _64e16 (_64e4 * _64e4 * _64e4 * _64e4)
-+#define _64e63 (_64e15 * _64e16 * _64e16 * _64e16)
-+#define _64e64 (_64e16 * _64e16 * _64e16 * _64e16)
-+
-+/*
-+** The following procedure converts a double-precision floating point
-+** number into a string.  The resulting string has the property that
-+** two such strings comparied using strcmp() or memcmp() will give the
-+** same results as a numeric comparison of the original floating point
-+** numbers.
-+**
-+** This routine is used to generate database keys from floating point
-+** numbers such that the keys sort in the same order as the original
-+** floating point numbers even though the keys are compared using
-+** memcmp().
-+**
-+** The calling function should have allocated at least 14 characters
-+** of space for the buffer z[].
-+*/
-+void sqliteRealToSortable(double r, char *z){
-+  int neg;
-+  int exp;
-+  int cnt = 0;
-+
-+  /* This array maps integers between 0 and 63 into base-64 digits.
-+  ** The digits must be chosen such at their ASCII codes are increasing.
-+  ** This means we can not use the traditional base-64 digit set. */
-+  static const char zDigit[] = 
-+     "0123456789"
-+     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+     "abcdefghijklmnopqrstuvwxyz"
-+     "|~";
-+  if( r<0.0 ){
-+    neg = 1;
-+    r = -r;
-+    *z++ = '-';
-+  } else {
-+    neg = 0;
-+    *z++ = '0';
-+  }
-+  exp = 0;
-+
-+  if( r==0.0 ){
-+    exp = -1024;
-+  }else if( r<(0.5/64.0) ){
-+    while( r < 0.5/_64e64 && exp > -961  ){ r *= _64e64;  exp -= 64; }
-+    while( r < 0.5/_64e16 && exp > -1009 ){ r *= _64e16;  exp -= 16; }
-+    while( r < 0.5/_64e4  && exp > -1021 ){ r *= _64e4;   exp -= 4; }
-+    while( r < 0.5/64.0   && exp > -1024 ){ r *= 64.0;    exp -= 1; }
-+  }else if( r>=0.5 ){
-+    while( r >= 0.5*_64e63 && exp < 960  ){ r *= 1.0/_64e64; exp += 64; }
-+    while( r >= 0.5*_64e15 && exp < 1008 ){ r *= 1.0/_64e16; exp += 16; }
-+    while( r >= 0.5*_64e3  && exp < 1020 ){ r *= 1.0/_64e4;  exp += 4; }
-+    while( r >= 0.5        && exp < 1023 ){ r *= 1.0/64.0;   exp += 1; }
-+  }
-+  if( neg ){
-+    exp = -exp;
-+    r = -r;
-+  }
-+  exp += 1024;
-+  r += 0.5;
-+  if( exp<0 ) return;
-+  if( exp>=2048 || r>=1.0 ){
-+    strcpy(z, "~~~~~~~~~~~~");
-+    return;
-+  }
-+  *z++ = zDigit[(exp>>6)&0x3f];
-+  *z++ = zDigit[exp & 0x3f];
-+  while( r>0.0 && cnt<10 ){
-+    int digit;
-+    r *= 64.0;
-+    digit = (int)r;
-+    assert( digit>=0 && digit<64 );
-+    *z++ = zDigit[digit & 0x3f];
-+    r -= digit;
-+    cnt++;
-+  }
-+  *z = 0;
-+}
-+
-+#ifdef SQLITE_UTF8
-+/*
-+** X is a pointer to the first byte of a UTF-8 character.  Increment
-+** X so that it points to the next character.  This only works right
-+** if X points to a well-formed UTF-8 string.
-+*/
-+#define sqliteNextChar(X)  while( (0xc0&*++(X))==0x80 ){}
-+#define sqliteCharVal(X)   sqlite_utf8_to_int(X)
-+
-+#else /* !defined(SQLITE_UTF8) */
-+/*
-+** For iso8859 encoding, the next character is just the next byte.
-+*/
-+#define sqliteNextChar(X)  (++(X));
-+#define sqliteCharVal(X)   ((int)*(X))
-+
-+#endif /* defined(SQLITE_UTF8) */
-+
-+
-+#ifdef SQLITE_UTF8
-+/*
-+** Convert the UTF-8 character to which z points into a 31-bit
-+** UCS character.  This only works right if z points to a well-formed
-+** UTF-8 string.
-+*/
-+static int sqlite_utf8_to_int(const unsigned char *z){
-+  int c;
-+  static const int initVal[] = {
-+      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,  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,  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,   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,   0,
-+      1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
-+      0,   1,   2,   3,   4,   5,   6,   7,   0,   1,   2,   3,   0,   1, 254,
-+    255,
-+  };
-+  c = initVal[*(z++)];
-+  while( (0xc0&*z)==0x80 ){
-+    c = (c<<6) | (0x3f&*(z++));
-+  }
-+  return c;
-+}
-+#endif
-+
-+/*
-+** 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
-+*/
-+int 
-+sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
-+  register int c;
-+  int invert;
-+  int seen;
-+  int c2;
-+
-+  while( (c = *zPattern)!=0 ){
-+    switch( c ){
-+      case '*':
-+        while( (c=zPattern[1]) == '*' || c == '?' ){
-+          if( c=='?' ){
-+            if( *zString==0 ) return 0;
-+            sqliteNextChar(zString);
-+          }
-+          zPattern++;
-+        }
-+        if( c==0 ) return 1;
-+        if( c=='[' ){
-+          while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
-+            sqliteNextChar(zString);
-+          }
-+          return *zString!=0;
-+        }else{
-+          while( (c2 = *zString)!=0 ){
-+            while( c2 != 0 && c2 != c ){ c2 = *++zString; }
-+            if( c2==0 ) return 0;
-+            if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
-+            sqliteNextChar(zString);
-+          }
-+          return 0;
-+        }
-+      case '?': {
-+        if( *zString==0 ) return 0;
-+        sqliteNextChar(zString);
-+        zPattern++;
-+        break;
-+      }
-+      case '[': {
-+        int prior_c = 0;
-+        seen = 0;
-+        invert = 0;
-+        c = sqliteCharVal(zString);
-+        if( c==0 ) return 0;
-+        c2 = *++zPattern;
-+        if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
-+        if( c2==']' ){
-+          if( c==']' ) seen = 1;
-+          c2 = *++zPattern;
-+        }
-+        while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
-+          if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
-+            zPattern++;
-+            c2 = sqliteCharVal(zPattern);
-+            if( c>=prior_c && c<=c2 ) seen = 1;
-+            prior_c = 0;
-+          }else if( c==c2 ){
-+            seen = 1;
-+            prior_c = c2;
-+          }else{
-+            prior_c = c2;
-+          }
-+          sqliteNextChar(zPattern);
-+        }
-+        if( c2==0 || (seen ^ invert)==0 ) return 0;
-+        sqliteNextChar(zString);
-+        zPattern++;
-+        break;
-+      }
-+      default: {
-+        if( c != *zString ) return 0;
-+        zPattern++;
-+        zString++;
-+        break;
-+      }
-+    }
-+  }
-+  return *zString==0;
-+}
-+
-+/*
-+** Compare two UTF-8 strings for equality using the "LIKE" operator of
-+** SQL.  The '%' character matches any sequence of 0 or more
-+** characters and '_' matches any single character.  Case is
-+** not significant.
-+**
-+** This routine is just an adaptation of the sqliteGlobCompare()
-+** routine above.
-+*/
-+int 
-+sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
-+  register int c;
-+  int c2;
-+
-+  while( (c = UpperToLower[*zPattern])!=0 ){
-+    switch( c ){
-+      case '%': {
-+        while( (c=zPattern[1]) == '%' || c == '_' ){
-+          if( c=='_' ){
-+            if( *zString==0 ) return 0;
-+            sqliteNextChar(zString);
-+          }
-+          zPattern++;
-+        }
-+        if( c==0 ) return 1;
-+        c = UpperToLower[c];
-+        while( (c2=UpperToLower[*zString])!=0 ){
-+          while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
-+          if( c2==0 ) return 0;
-+          if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
-+          sqliteNextChar(zString);
-+        }
-+        return 0;
-+      }
-+      case '_': {
-+        if( *zString==0 ) return 0;
-+        sqliteNextChar(zString);
-+        zPattern++;
-+        break;
-+      }
-+      default: {
-+        if( c != UpperToLower[*zString] ) return 0;
-+        zPattern++;
-+        zString++;
-+        break;
-+      }
-+    }
-+  }
-+  return *zString==0;
-+}
-+
-+/*
-+** 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 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 sqlite_close(db) and db has been deallocated.  And we do
-+** not want to write into deallocated memory.
-+*/
-+int sqliteSafetyOn(sqlite *db){
-+  if( db->magic==SQLITE_MAGIC_OPEN ){
-+    db->magic = SQLITE_MAGIC_BUSY;
-+    return 0;
-+  }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR
-+             || db->want_to_close ){
-+    db->magic = SQLITE_MAGIC_ERROR;
-+    db->flags |= SQLITE_Interrupt;
-+  }
-+  return 1;
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteSafetyOff(sqlite *db){
-+  if( db->magic==SQLITE_MAGIC_BUSY ){
-+    db->magic = SQLITE_MAGIC_OPEN;
-+    return 0;
-+  }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR
-+             || db->want_to_close ){
-+    db->magic = SQLITE_MAGIC_ERROR;
-+    db->flags |= SQLITE_Interrupt;
-+  }
-+  return 1;
-+}
-+
-+/*
-+** Check to make sure we are not currently executing an sqlite_exec().
-+** If we are currently in an sqlite_exec(), return true and set
-+** sqlite.magic to SQLITE_MAGIC_ERROR.  This will cause a complete
-+** shutdown of the database.
-+**
-+** This routine is used to try to detect when API routines are called
-+** at the wrong time or in the wrong sequence.
-+*/
-+int sqliteSafetyCheck(sqlite *db){
-+  if( db->pVdbe!=0 ){
-+    db->magic = SQLITE_MAGIC_ERROR;
-+    return 1;
-+  }
-+  return 0;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/vacuum.c
-@@ -0,0 +1,305 @@
-+/*
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+
-+/*
-+** A structure for holding a dynamic string - a string that can grow
-+** without bound. 
-+*/
-+typedef struct dynStr dynStr;
-+struct dynStr {
-+  char *z;        /* Text of the string in space obtained from sqliteMalloc() */
-+  int nAlloc;     /* Amount of space allocated to z[] */
-+  int nUsed;      /* Next unused slot in z[] */
-+};
-+
-+/*
-+** A structure that holds the vacuum context
-+*/
-+typedef struct vacuumStruct vacuumStruct;
-+struct vacuumStruct {
-+  sqlite *dbOld;       /* Original database */
-+  sqlite *dbNew;       /* New database */
-+  char **pzErrMsg;     /* Write errors here */
-+  int rc;              /* Set to non-zero on an error */
-+  const char *zTable;  /* Name of a table being copied */
-+  const char *zPragma; /* Pragma to execute with results */
-+  dynStr s1, s2;       /* Two dynamic strings */
-+};
-+
-+#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
-+/*
-+** Append text to a dynamic string
-+*/
-+static void appendText(dynStr *p, const char *zText, int nText){
-+  if( nText<0 ) nText = strlen(zText);
-+  if( p->z==0 || p->nUsed + nText + 1 >= p->nAlloc ){
-+    char *zNew;
-+    p->nAlloc = p->nUsed + nText + 1000;
-+    zNew = sqliteRealloc(p->z, p->nAlloc);
-+    if( zNew==0 ){
-+      sqliteFree(p->z);
-+      memset(p, 0, sizeof(*p));
-+      return;
-+    }
-+    p->z = zNew;
-+  }
-+  memcpy(&p->z[p->nUsed], zText, nText+1);
-+  p->nUsed += nText;
-+}
-+
-+/*
-+** Append text to a dynamic string, having first put the text in quotes.
-+*/
-+static void appendQuoted(dynStr *p, const char *zText){
-+  int i, j;
-+  appendText(p, "'", 1);
-+  for(i=j=0; zText[i]; i++){
-+    if( zText[i]=='\'' ){
-+      appendText(p, &zText[j], i-j+1);
-+      j = i + 1;
-+      appendText(p, "'", 1);
-+    }
-+  }
-+  if( j<i ){
-+    appendText(p, &zText[j], i-j);
-+  }
-+  appendText(p, "'", 1);
-+}
-+
-+/*
-+** Execute statements of SQL.  If an error occurs, write the error
-+** message into *pzErrMsg and return non-zero.
-+*/
-+static int execsql(char **pzErrMsg, sqlite *db, const char *zSql){ 
-+  char *zErrMsg = 0;
-+  int rc;
-+
-+  /* printf("***** executing *****\n%s\n", zSql); */
-+  rc = sqlite_exec(db, zSql, 0, 0, &zErrMsg);
-+  if( zErrMsg ){
-+    sqliteSetString(pzErrMsg, zErrMsg, (char*)0);
-+    sqlite_freemem(zErrMsg);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** This is the second stage callback.  Each invocation contains all the
-+** data for a single row of a single table in the original database.  This
-+** routine must write that information into the new database.
-+*/
-+static int vacuumCallback2(void *pArg, int argc, char **argv, char **NotUsed){
-+  vacuumStruct *p = (vacuumStruct*)pArg;
-+  const char *zSep = "(";
-+  int i;
-+
-+  if( argv==0 ) return 0;
-+  p->s2.nUsed = 0;
-+  appendText(&p->s2, "INSERT INTO ", -1);
-+  appendQuoted(&p->s2, p->zTable);
-+  appendText(&p->s2, " VALUES", -1);
-+  for(i=0; i<argc; i++){
-+    appendText(&p->s2, zSep, 1);
-+    zSep = ",";
-+    if( argv[i]==0 ){
-+      appendText(&p->s2, "NULL", 4);
-+    }else{
-+      appendQuoted(&p->s2, argv[i]);
-+    }
-+  }
-+  appendText(&p->s2,")", 1);
-+  p->rc = execsql(p->pzErrMsg, p->dbNew, p->s2.z);
-+  return p->rc;
-+}
-+
-+/*
-+** This is the first stage callback.  Each invocation contains three
-+** arguments where are taken from the SQLITE_MASTER table of the original
-+** database:  (1) the entry type, (2) the entry name, and (3) the SQL for
-+** the entry.  In all cases, execute the SQL of the third argument.
-+** For tables, run a query to select all entries in that table and 
-+** transfer them to the second-stage callback.
-+*/
-+static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
-+  vacuumStruct *p = (vacuumStruct*)pArg;
-+  int rc = 0;
-+  assert( argc==3 );
-+  if( argv==0 ) return 0;
-+  assert( argv[0]!=0 );
-+  assert( argv[1]!=0 );
-+  assert( argv[2]!=0 );
-+  rc = execsql(p->pzErrMsg, p->dbNew, argv[2]);
-+  if( rc==SQLITE_OK && strcmp(argv[0],"table")==0 ){
-+    char *zErrMsg = 0;
-+    p->s1.nUsed = 0;
-+    appendText(&p->s1, "SELECT * FROM ", -1);
-+    appendQuoted(&p->s1, argv[1]);
-+    p->zTable = argv[1];
-+    rc = sqlite_exec(p->dbOld, p->s1.z, vacuumCallback2, p, &zErrMsg);
-+    if( zErrMsg ){
-+      sqliteSetString(p->pzErrMsg, zErrMsg, (char*)0);
-+      sqlite_freemem(zErrMsg);
-+    }
-+  }
-+  if( rc!=SQLITE_ABORT ) p->rc = rc;
-+  return rc;
-+}
-+
-+/*
-+** Generate a random name of 20 character in length.
-+*/
-+static void randomName(unsigned char *zBuf){
-+  static const unsigned char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "0123456789";
-+  int i;
-+  sqliteRandomness(20, zBuf);
-+  for(i=0; i<20; i++){
-+    zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
-+  }
-+}
-+#endif
-+
-+/*
-+** 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.
-+*/
-+void sqliteVacuum(Parse *pParse, Token *pTableName){
-+  Vdbe *v = sqliteGetVdbe(pParse);
-+  sqliteVdbeAddOp(v, OP_Vacuum, 0, 0);
-+  return;
-+}
-+
-+/*
-+** This routine implements the OP_Vacuum opcode of the VDBE.
-+*/
-+int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
-+#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
-+  const char *zFilename;  /* full pathname of the database file */
-+  int nFilename;          /* number of characters  in zFilename[] */
-+  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
-+  sqlite *dbNew = 0;      /* The new vacuumed database */
-+  int rc = SQLITE_OK;     /* Return code from service routines */
-+  int i;                  /* Loop counter */
-+  char *zErrMsg;          /* Error message */
-+  vacuumStruct sVac;      /* Information passed to callbacks */
-+
-+  if( db->flags & SQLITE_InTrans ){
-+    sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
-+       (char*)0);
-+    return SQLITE_ERROR;
-+  }
-+  if( db->flags & SQLITE_Interrupt ){
-+    return SQLITE_INTERRUPT;
-+  }
-+  memset(&sVac, 0, sizeof(sVac));
-+
-+  /* Get the full pathname of the database file and create two
-+  ** temporary filenames in the same directory as the original file.
-+  */
-+  zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
-+  if( zFilename==0 ){
-+    /* This only happens with the in-memory database.  VACUUM is a no-op
-+    ** there, so just return */
-+    return SQLITE_OK;
-+  }
-+  nFilename = strlen(zFilename);
-+  zTemp = sqliteMalloc( nFilename+100 );
-+  if( zTemp==0 ) return SQLITE_NOMEM;
-+  strcpy(zTemp, zFilename);
-+  for(i=0; i<10; i++){
-+    zTemp[nFilename] = '-';
-+    randomName((unsigned char*)&zTemp[nFilename+1]);
-+    if( !sqliteOsFileExists(zTemp) ) break;
-+  }
-+  if( i>=10 ){
-+    sqliteSetString(pzErrMsg, "unable to create a temporary database file "
-+       "in the same directory as the original database", (char*)0);
-+    goto end_of_vacuum;
-+  }
-+
-+  
-+  dbNew = sqlite_open(zTemp, 0, &zErrMsg);
-+  if( dbNew==0 ){
-+    sqliteSetString(pzErrMsg, "unable to open a temporary database at ",
-+       zTemp, " - ", zErrMsg, (char*)0);
-+    goto end_of_vacuum;
-+  }
-+  if( (rc = execsql(pzErrMsg, db, "BEGIN"))!=0 ) goto end_of_vacuum;
-+  if( (rc = execsql(pzErrMsg, dbNew, "PRAGMA synchronous=off; BEGIN"))!=0 ){
-+    goto end_of_vacuum;
-+  }
-+  
-+  sVac.dbOld = db;
-+  sVac.dbNew = dbNew;
-+  sVac.pzErrMsg = pzErrMsg;
-+  if( rc==SQLITE_OK ){
-+    rc = sqlite_exec(db, 
-+      "SELECT type, name, sql FROM sqlite_master "
-+      "WHERE sql NOT NULL AND type!='view' "
-+      "UNION ALL "
-+      "SELECT type, name, sql FROM sqlite_master "
-+      "WHERE sql NOT NULL AND type=='view'",
-+      vacuumCallback1, &sVac, &zErrMsg);
-+  }
-+  if( rc==SQLITE_OK ){
-+    int meta1[SQLITE_N_BTREE_META];
-+    int meta2[SQLITE_N_BTREE_META];
-+    sqliteBtreeGetMeta(db->aDb[0].pBt, meta1);
-+    sqliteBtreeGetMeta(dbNew->aDb[0].pBt, meta2);
-+    meta2[1] = meta1[1]+1;
-+    meta2[3] = meta1[3];
-+    meta2[4] = meta1[4];
-+    meta2[6] = meta1[6];
-+    rc = sqliteBtreeUpdateMeta(dbNew->aDb[0].pBt, meta2);
-+  }
-+  if( rc==SQLITE_OK ){
-+    rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
-+    sqlite_exec(db, "COMMIT", 0, 0, 0);
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+
-+end_of_vacuum:
-+  if( rc && zErrMsg!=0 ){
-+    sqliteSetString(pzErrMsg, "unable to vacuum database - ", 
-+       zErrMsg, (char*)0);
-+  }
-+  sqlite_exec(db, "ROLLBACK", 0, 0, 0);
-+  if( (dbNew && (dbNew->flags & SQLITE_Interrupt)) 
-+         || (db->flags & SQLITE_Interrupt) ){
-+    rc = SQLITE_INTERRUPT;
-+  }
-+  if( dbNew ) sqlite_close(dbNew);
-+  sqliteOsDelete(zTemp);
-+  sqliteFree(zTemp);
-+  sqliteFree(sVac.s1.z);
-+  sqliteFree(sVac.s2.z);
-+  if( zErrMsg ) sqlite_freemem(zErrMsg);
-+  if( rc==SQLITE_ABORT && sVac.rc!=SQLITE_INTERRUPT ) sVac.rc = SQLITE_ERROR;
-+  return sVac.rc;
-+#endif
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/vdbeaux.c
-@@ -0,0 +1,1061 @@
-+/*
-+** 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 "sqlite_vm" 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.
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+#include <ctype.h>
-+#include "vdbeInt.h"
-+
-+
-+/*
-+** When debugging the code generator in a symbolic debugger, one can
-+** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed
-+** as they are added to the instruction stream.
-+*/
-+#ifndef NDEBUG
-+int sqlite_vdbe_addop_trace = 0;
-+#endif
-+
-+
-+/*
-+** Create a new virtual database engine.
-+*/
-+Vdbe *sqliteVdbeCreate(sqlite *db){
-+  Vdbe *p;
-+  p = sqliteMalloc( 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;
-+}
-+
-+/*
-+** Turn tracing on or off
-+*/
-+void sqliteVdbeTrace(Vdbe *p, FILE *trace){
-+  p->trace = trace;
-+}
-+
-+/*
-+** 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          First two of the three possible operands.
-+**
-+** Use the sqliteVdbeResolveLabel() function to fix an address and
-+** the sqliteVdbeChangeP3() function to change the value of the P3
-+** operand.
-+*/
-+int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
-+  int i;
-+  VdbeOp *pOp;
-+
-+  i = p->nOp;
-+  p->nOp++;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( i>=p->nOpAlloc ){
-+    int oldSize = p->nOpAlloc;
-+    Op *aNew;
-+    p->nOpAlloc = p->nOpAlloc*2 + 100;
-+    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
-+    if( aNew==0 ){
-+      p->nOpAlloc = oldSize;
-+      return 0;
-+    }
-+    p->aOp = aNew;
-+    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
-+  }
-+  pOp = &p->aOp[i];
-+  pOp->opcode = op;
-+  pOp->p1 = p1;
-+  if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
-+    p2 = p->aLabel[-1-p2];
-+  }
-+  pOp->p2 = p2;
-+  pOp->p3 = 0;
-+  pOp->p3type = P3_NOTUSED;
-+#ifndef NDEBUG
-+  if( sqlite_vdbe_addop_trace ) sqliteVdbePrintOp(0, i, &p->aOp[i]);
-+#endif
-+  return i;
-+}
-+
-+/*
-+** Add an opcode that includes the p3 value.
-+*/
-+int sqliteVdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
-+  int addr = sqliteVdbeAddOp(p, op, p1, p2);
-+  sqliteVdbeChangeP3(p, addr, zP3, p3type);
-+  return addr;
-+}
-+
-+/*
-+** Add multiple opcodes.  The list is terminated by an opcode of 0.
-+*/
-+int sqliteVdbeCode(Vdbe *p, ...){
-+  int addr;
-+  va_list ap;
-+  int opcode, p1, p2;
-+  va_start(ap, p);
-+  addr = p->nOp;
-+  while( (opcode = va_arg(ap,int))!=0 ){
-+    p1 = va_arg(ap,int);
-+    p2 = va_arg(ap,int);
-+    sqliteVdbeAddOp(p, opcode, p1, p2);
-+  }
-+  va_end(ap);
-+  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.
-+*/
-+int sqliteVdbeMakeLabel(Vdbe *p){
-+  int i;
-+  i = p->nLabel++;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( i>=p->nLabelAlloc ){
-+    int *aNew;
-+    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
-+    aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
-+    if( aNew==0 ){
-+      sqliteFree(p->aLabel);
-+    }
-+    p->aLabel = aNew;
-+  }
-+  if( p->aLabel==0 ){
-+    p->nLabel = 0;
-+    p->nLabelAlloc = 0;
-+    return 0;
-+  }
-+  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 sqliteVdbeMakeLabel().
-+*/
-+void sqliteVdbeResolveLabel(Vdbe *p, int x){
-+  int j;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( x<0 && (-x)<=p->nLabel && p->aOp ){
-+    if( p->aLabel[-1-x]==p->nOp ) return;
-+    assert( p->aLabel[-1-x]<0 );
-+    p->aLabel[-1-x] = p->nOp;
-+    for(j=0; j<p->nOp; j++){
-+      if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
-+    }
-+  }
-+}
-+
-+/*
-+** Return the address of the next instruction to be inserted.
-+*/
-+int sqliteVdbeCurrentAddr(Vdbe *p){
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  return p->nOp;
-+}
-+
-+/*
-+** Add a whole list of operations to the operation stack.  Return the
-+** address of the first operation added.
-+*/
-+int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
-+  int addr;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p->nOp + nOp >= p->nOpAlloc ){
-+    int oldSize = p->nOpAlloc;
-+    Op *aNew;
-+    p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
-+    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
-+    if( aNew==0 ){
-+      p->nOpAlloc = oldSize;
-+      return 0;
-+    }
-+    p->aOp = aNew;
-+    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
-+  }
-+  addr = p->nOp;
-+  if( 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;
-+      pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
-+      pOut->p3 = pIn->p3;
-+      pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
-+#ifndef NDEBUG
-+      if( sqlite_vdbe_addop_trace ){
-+        sqliteVdbePrintOp(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 sqliteVdbeAddOpList but we want to make a
-+** few minor changes to the program.
-+*/
-+void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p && addr>=0 && p->nOp>addr && p->aOp ){
-+    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.
-+*/
-+void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
-+  assert( val>=0 );
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p && addr>=0 && p->nOp>addr && p->aOp ){
-+    p->aOp[addr].p2 = val;
-+  }
-+}
-+
-+/*
-+** Change the value of the P3 operand for a specific instruction.
-+** This routine is useful when a large program is loaded from a
-+** static array using sqliteVdbeAddOpList but we want to make a
-+** few minor changes to the program.
-+**
-+** If n>=0 then the P3 operand is dynamic, meaning that a copy of
-+** the string is made into memory obtained from sqliteMalloc().
-+** A value of n==0 means copy bytes of zP3 up to and including the
-+** first null byte.  If n>0 then copy n+1 bytes of zP3.
-+**
-+** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
-+** string and we can just copy the pointer.  n==P3_POINTER means zP3 is
-+** a pointer to some object other than a string.
-+**
-+** If addr<0 then change P3 on the most recently inserted instruction.
-+*/
-+void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
-+  Op *pOp;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p==0 || p->aOp==0 ) return;
-+  if( addr<0 || addr>=p->nOp ){
-+    addr = p->nOp - 1;
-+    if( addr<0 ) return;
-+  }
-+  pOp = &p->aOp[addr];
-+  if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
-+    sqliteFree(pOp->p3);
-+    pOp->p3 = 0;
-+  }
-+  if( zP3==0 ){
-+    pOp->p3 = 0;
-+    pOp->p3type = P3_NOTUSED;
-+  }else if( n<0 ){
-+    pOp->p3 = (char*)zP3;
-+    pOp->p3type = n;
-+  }else{
-+    sqliteSetNString(&pOp->p3, zP3, n, 0);
-+    pOp->p3type = P3_DYNAMIC;
-+  }
-+}
-+
-+/*
-+** If the P3 operand to the specified instruction appears
-+** to be a quoted string token, then this procedure removes 
-+** the quotes.
-+**
-+** The quoting operator can be either a grave ascent (ASCII 0x27)
-+** or a double quote character (ASCII 0x22).  Two quotes in a row
-+** resolve to be a single actual quote character within the string.
-+*/
-+void sqliteVdbeDequoteP3(Vdbe *p, int addr){
-+  Op *pOp;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p->aOp==0 ) return;
-+  if( addr<0 || addr>=p->nOp ){
-+    addr = p->nOp - 1;
-+    if( addr<0 ) return;
-+  }
-+  pOp = &p->aOp[addr];
-+  if( pOp->p3==0 || pOp->p3[0]==0 ) return;
-+  if( pOp->p3type==P3_POINTER ) return;
-+  if( pOp->p3type!=P3_DYNAMIC ){
-+    pOp->p3 = sqliteStrDup(pOp->p3);
-+    pOp->p3type = P3_DYNAMIC;
-+  }
-+  sqliteDequote(pOp->p3);
-+}
-+
-+/*
-+** On the P3 argument of the given instruction, change all
-+** strings of whitespace characters into a single space and
-+** delete leading and trailing whitespace.
-+*/
-+void sqliteVdbeCompressSpace(Vdbe *p, int addr){
-+  unsigned char *z;
-+  int i, j;
-+  Op *pOp;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
-+  pOp = &p->aOp[addr];
-+  if( pOp->p3type==P3_POINTER ){
-+    return;
-+  }
-+  if( pOp->p3type!=P3_DYNAMIC ){
-+    pOp->p3 = sqliteStrDup(pOp->p3);
-+    pOp->p3type = P3_DYNAMIC;
-+  }
-+  z = (unsigned char*)pOp->p3;
-+  if( z==0 ) return;
-+  i = j = 0;
-+  while( isspace(z[i]) ){ i++; }
-+  while( z[i] ){
-+    if( isspace(z[i]) ){
-+      z[j++] = ' ';
-+      while( isspace(z[++i]) ){}
-+    }else{
-+      z[j++] = z[i++];
-+    }
-+  }
-+  while( j>0 && isspace(z[j-1]) ){ j--; }
-+  z[j] = 0;
-+}
-+
-+/*
-+** Search for the current program for the given opcode and P2
-+** value.  Return the address plus 1 if found and 0 if not found.
-+*/
-+int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
-+  int i;
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  for(i=0; i<p->nOp; i++){
-+    if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Return the opcode for a given address.
-+*/
-+VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+  assert( addr>=0 && addr<p->nOp );
-+  return &p->aOp[addr];
-+}
-+
-+/*
-+** The following group or routines are employed by installable functions
-+** to return their results.
-+**
-+** The sqlite_set_result_string() routine can be used to return a string
-+** value or to return a NULL.  To return a NULL, pass in NULL for zResult.
-+** A copy is made of the string before this routine returns so it is safe
-+** to pass in an ephemeral string.
-+**
-+** sqlite_set_result_error() works like sqlite_set_result_string() except
-+** that it signals a fatal error.  The string argument, if any, is the
-+** error message.  If the argument is NULL a generic substitute error message
-+** is used.
-+**
-+** The sqlite_set_result_int() and sqlite_set_result_double() set the return
-+** value of the user function to an integer or a double.
-+**
-+** These routines are defined here in vdbe.c because they depend on knowing
-+** the internals of the sqlite_func structure which is only defined in 
-+** this source file.
-+*/
-+char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
-+  assert( !p->isStep );
-+  if( p->s.flags & MEM_Dyn ){
-+    sqliteFree(p->s.z);
-+  }
-+  if( zResult==0 ){
-+    p->s.flags = MEM_Null;
-+    n = 0;
-+    p->s.z = 0;
-+    p->s.n = 0;
-+  }else{
-+    if( n<0 ) n = strlen(zResult);
-+    if( n<NBFS-1 ){
-+      memcpy(p->s.zShort, zResult, n);
-+      p->s.zShort[n] = 0;
-+      p->s.flags = MEM_Str | MEM_Short;
-+      p->s.z = p->s.zShort;
-+    }else{
-+      p->s.z = sqliteMallocRaw( n+1 );
-+      if( p->s.z ){
-+        memcpy(p->s.z, zResult, n);
-+        p->s.z[n] = 0;
-+      }
-+      p->s.flags = MEM_Str | MEM_Dyn;
-+    }
-+    p->s.n = n+1;
-+  }
-+  return p->s.z;
-+}
-+void sqlite_set_result_int(sqlite_func *p, int iResult){
-+  assert( !p->isStep );
-+  if( p->s.flags & MEM_Dyn ){
-+    sqliteFree(p->s.z);
-+  }
-+  p->s.i = iResult;
-+  p->s.flags = MEM_Int;
-+}
-+void sqlite_set_result_double(sqlite_func *p, double rResult){
-+  assert( !p->isStep );
-+  if( p->s.flags & MEM_Dyn ){
-+    sqliteFree(p->s.z);
-+  }
-+  p->s.r = rResult;
-+  p->s.flags = MEM_Real;
-+}
-+void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
-+  assert( !p->isStep );
-+  sqlite_set_result_string(p, zMsg, n);
-+  p->isError = 1;
-+}
-+
-+/*
-+** Extract the user data from a sqlite_func structure and return a
-+** pointer to it.
-+*/
-+void *sqlite_user_data(sqlite_func *p){
-+  assert( p && p->pFunc );
-+  return p->pFunc->pUserData;
-+}
-+
-+/*
-+** 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.
-+**
-+** This routine is defined here in vdbe.c because it depends on knowing
-+** the internals of the sqlite_func structure which is only defined in
-+** this source file.
-+*/
-+void *sqlite_aggregate_context(sqlite_func *p, int nByte){
-+  assert( p && p->pFunc && p->pFunc->xStep );
-+  if( p->pAgg==0 ){
-+    if( nByte<=NBFS ){
-+      p->pAgg = (void*)p->s.z;
-+      memset(p->pAgg, 0, nByte);
-+    }else{
-+      p->pAgg = sqliteMalloc( nByte );
-+    }
-+  }
-+  return p->pAgg;
-+}
-+
-+/*
-+** Return the number of times the Step function of a aggregate has been 
-+** called.
-+**
-+** This routine is defined here in vdbe.c because it depends on knowing
-+** the internals of the sqlite_func structure which is only defined in
-+** this source file.
-+*/
-+int sqlite_aggregate_count(sqlite_func *p){
-+  assert( p && p->pFunc && p->pFunc->xStep );
-+  return p->cnt;
-+}
-+
-+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
-+/*
-+** Print a single opcode.  This routine is used for debugging only.
-+*/
-+void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
-+  char *zP3;
-+  char zPtr[40];
-+  if( pOp->p3type==P3_POINTER ){
-+    sprintf(zPtr, "ptr(%#lx)", (long)pOp->p3);
-+    zP3 = zPtr;
-+  }else{
-+    zP3 = pOp->p3;
-+  }
-+  if( pOut==0 ) pOut = stdout;
-+  fprintf(pOut,"%4d %-12s %4d %4d %s\n",
-+      pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
-+  fflush(pOut);
-+}
-+#endif
-+
-+/*
-+** Give a listing of the program in the virtual machine.
-+**
-+** The interface is the same as sqliteVdbeExec().  But instead of
-+** running the code, it invokes the callback once for each instruction.
-+** This feature is used to implement "EXPLAIN".
-+*/
-+int sqliteVdbeList(
-+  Vdbe *p                   /* The VDBE */
-+){
-+  sqlite *db = p->db;
-+  int i;
-+  int rc = SQLITE_OK;
-+  static char *azColumnNames[] = {
-+     "addr", "opcode", "p1",  "p2",  "p3", 
-+     "int",  "text",   "int", "int", "text",
-+     0
-+  };
-+
-+  assert( p->popStack==0 );
-+  assert( p->explain );
-+  p->azColName = azColumnNames;
-+  p->azResColumn = p->zArgv;
-+  for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;
-+  i = p->pc;
-+  if( i>=p->nOp ){
-+    p->rc = SQLITE_OK;
-+    rc = SQLITE_DONE;
-+  }else if( db->flags & SQLITE_Interrupt ){
-+    db->flags &= ~SQLITE_Interrupt;
-+    if( db->magic!=SQLITE_MAGIC_BUSY ){
-+      p->rc = SQLITE_MISUSE;
-+    }else{
-+      p->rc = SQLITE_INTERRUPT;
-+    }
-+    rc = SQLITE_ERROR;
-+    sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
-+  }else{
-+    sprintf(p->zArgv[0],"%d",i);
-+    sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
-+    sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
-+    if( p->aOp[i].p3type==P3_POINTER ){
-+      sprintf(p->aStack[4].zShort, "ptr(%#lx)", (long)p->aOp[i].p3);
-+      p->zArgv[4] = p->aStack[4].zShort;
-+    }else{
-+      p->zArgv[4] = p->aOp[i].p3;
-+    }
-+    p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];
-+    p->pc = i+1;
-+    p->azResColumn = p->zArgv;
-+    p->nResColumn = 5;
-+    p->rc = SQLITE_OK;
-+    rc = SQLITE_ROW;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** 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 sqliteVdbeExec().  
-+*/
-+void sqliteVdbeMakeReady(
-+  Vdbe *p,                       /* The VDBE */
-+  int nVar,                      /* Number of '?' see in the SQL statement */
-+  int isExplain                  /* True if the EXPLAIN keywords is present */
-+){
-+  int n;
-+
-+  assert( p!=0 );
-+  assert( p->magic==VDBE_MAGIC_INIT );
-+
-+  /* Add a HALT instruction to the very end of the program.
-+  */
-+  if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
-+    sqliteVdbeAddOp(p, OP_Halt, 0, 0);
-+  }
-+
-+  /* No instruction ever pushes more than a single element onto the
-+  ** stack.  And the stack never grows on successive executions of the
-+  ** same loop.  So the total number of instructions is an upper bound
-+  ** on the maximum stack depth required.
-+  **
-+  ** Allocation all the stack space we will ever need.
-+  */
-+  if( p->aStack==0 ){
-+    p->nVar = nVar;
-+    assert( nVar>=0 );
-+    n = isExplain ? 10 : p->nOp;
-+    p->aStack = sqliteMalloc(
-+      n*(sizeof(p->aStack[0]) + 2*sizeof(char*))     /* aStack and zArgv */
-+        + p->nVar*(sizeof(char*)+sizeof(int)+1)    /* azVar, anVar, abVar */
-+    );
-+    p->zArgv = (char**)&p->aStack[n];
-+    p->azColName = (char**)&p->zArgv[n];
-+    p->azVar = (char**)&p->azColName[n];
-+    p->anVar = (int*)&p->azVar[p->nVar];
-+    p->abVar = (u8*)&p->anVar[p->nVar];
-+  }
-+
-+  sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
-+  p->agg.pSearch = 0;
-+#ifdef MEMORY_DEBUG
-+  if( sqliteOsFileExists("vdbe_trace") ){
-+    p->trace = stdout;
-+  }
-+#endif
-+  p->pTos = &p->aStack[-1];
-+  p->pc = 0;
-+  p->rc = SQLITE_OK;
-+  p->uniqueCnt = 0;
-+  p->returnDepth = 0;
-+  p->errorAction = OE_Abort;
-+  p->undoTransOnError = 0;
-+  p->popStack =  0;
-+  p->explain |= isExplain;
-+  p->magic = VDBE_MAGIC_RUN;
-+#ifdef VDBE_PROFILE
-+  {
-+    int i;
-+    for(i=0; i<p->nOp; i++){
-+      p->aOp[i].cnt = 0;
-+      p->aOp[i].cycles = 0;
-+    }
-+  }
-+#endif
-+}
-+
-+
-+/*
-+** Remove any elements that remain on the sorter for the VDBE given.
-+*/
-+void sqliteVdbeSorterReset(Vdbe *p){
-+  while( p->pSort ){
-+    Sorter *pSorter = p->pSort;
-+    p->pSort = pSorter->pNext;
-+    sqliteFree(pSorter->zKey);
-+    sqliteFree(pSorter->pData);
-+    sqliteFree(pSorter);
-+  }
-+}
-+
-+/*
-+** Reset an Agg structure.  Delete all its contents. 
-+**
-+** For installable aggregate functions, if the step function has been
-+** called, make sure the finalizer function has also been called.  The
-+** finalizer might need to free memory that was allocated as part of its
-+** private context.  If the finalizer has not been called yet, call it
-+** now.
-+*/
-+void sqliteVdbeAggReset(Agg *pAgg){
-+  int i;
-+  HashElem *p;
-+  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
-+    AggElem *pElem = sqliteHashData(p);
-+    assert( pAgg->apFunc!=0 );
-+    for(i=0; i<pAgg->nMem; i++){
-+      Mem *pMem = &pElem->aMem[i];
-+      if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
-+        sqlite_func ctx;
-+        ctx.pFunc = pAgg->apFunc[i];
-+        ctx.s.flags = MEM_Null;
-+        ctx.pAgg = pMem->z;
-+        ctx.cnt = pMem->i;
-+        ctx.isStep = 0;
-+        ctx.isError = 0;
-+        (*pAgg->apFunc[i]->xFinalize)(&ctx);
-+        if( pMem->z!=0 && pMem->z!=pMem->zShort ){
-+          sqliteFree(pMem->z);
-+        }
-+        if( ctx.s.flags & MEM_Dyn ){
-+          sqliteFree(ctx.s.z);
-+        }
-+      }else if( pMem->flags & MEM_Dyn ){
-+        sqliteFree(pMem->z);
-+      }
-+    }
-+    sqliteFree(pElem);
-+  }
-+  sqliteHashClear(&pAgg->hash);
-+  sqliteFree(pAgg->apFunc);
-+  pAgg->apFunc = 0;
-+  pAgg->pCurrent = 0;
-+  pAgg->pSearch = 0;
-+  pAgg->nMem = 0;
-+}
-+
-+/*
-+** Delete a keylist
-+*/
-+void sqliteVdbeKeylistFree(Keylist *p){
-+  while( p ){
-+    Keylist *pNext = p->pNext;
-+    sqliteFree(p);
-+    p = pNext;
-+  }
-+}
-+
-+/*
-+** Close a cursor and release all the resources that cursor happens
-+** to hold.
-+*/
-+void sqliteVdbeCleanupCursor(Cursor *pCx){
-+  if( pCx->pCursor ){
-+    sqliteBtreeCloseCursor(pCx->pCursor);
-+  }
-+  if( pCx->pBt ){
-+    sqliteBtreeClose(pCx->pBt);
-+  }
-+  sqliteFree(pCx->pData);
-+  memset(pCx, 0, sizeof(Cursor));
-+}
-+
-+/*
-+** Close all cursors
-+*/
-+static void closeAllCursors(Vdbe *p){
-+  int i;
-+  for(i=0; i<p->nCursor; i++){
-+    sqliteVdbeCleanupCursor(&p->aCsr[i]);
-+  }
-+  sqliteFree(p->aCsr);
-+  p->aCsr = 0;
-+  p->nCursor = 0;
-+}
-+
-+/*
-+** 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 azVariable[] array.
-+*/
-+static void Cleanup(Vdbe *p){
-+  int i;
-+  if( p->aStack ){
-+    Mem *pTos = p->pTos;
-+    while( pTos>=p->aStack ){
-+      if( pTos->flags & MEM_Dyn ){
-+        sqliteFree(pTos->z);
-+      }
-+      pTos--;
-+    }
-+    p->pTos = pTos;
-+  }
-+  closeAllCursors(p);
-+  if( p->aMem ){
-+    for(i=0; i<p->nMem; i++){
-+      if( p->aMem[i].flags & MEM_Dyn ){
-+        sqliteFree(p->aMem[i].z);
-+      }
-+    }
-+  }
-+  sqliteFree(p->aMem);
-+  p->aMem = 0;
-+  p->nMem = 0;
-+  if( p->pList ){
-+    sqliteVdbeKeylistFree(p->pList);
-+    p->pList = 0;
-+  }
-+  sqliteVdbeSorterReset(p);
-+  if( p->pFile ){
-+    if( p->pFile!=stdin ) fclose(p->pFile);
-+    p->pFile = 0;
-+  }
-+  if( p->azField ){
-+    sqliteFree(p->azField);
-+    p->azField = 0;
-+  }
-+  p->nField = 0;
-+  if( p->zLine ){
-+    sqliteFree(p->zLine);
-+    p->zLine = 0;
-+  }
-+  p->nLineAlloc = 0;
-+  sqliteVdbeAggReset(&p->agg);
-+  if( p->aSet ){
-+    for(i=0; i<p->nSet; i++){
-+      sqliteHashClear(&p->aSet[i].hash);
-+    }
-+  }
-+  sqliteFree(p->aSet);
-+  p->aSet = 0;
-+  p->nSet = 0;
-+  if( p->keylistStack ){
-+    int ii;
-+    for(ii = 0; ii < p->keylistStackDepth; ii++){
-+      sqliteVdbeKeylistFree(p->keylistStack[ii]);
-+    }
-+    sqliteFree(p->keylistStack);
-+    p->keylistStackDepth = 0;
-+    p->keylistStack = 0;
-+  }
-+  sqliteFree(p->contextStack);
-+  p->contextStack = 0;
-+  sqliteFree(p->zErrMsg);
-+  p->zErrMsg = 0;
-+}
-+
-+/*
-+** 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.
-+*/
-+int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
-+  sqlite *db = p->db;
-+  int i;
-+
-+  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
-+    return SQLITE_MISUSE;
-+  }
-+  if( p->zErrMsg ){
-+    if( pzErrMsg && *pzErrMsg==0 ){
-+      *pzErrMsg = p->zErrMsg;
-+    }else{
-+      sqliteFree(p->zErrMsg);
-+    }
-+    p->zErrMsg = 0;
-+  }else if( p->rc ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0);
-+  }
-+  Cleanup(p);
-+  if( p->rc!=SQLITE_OK ){
-+    switch( p->errorAction ){
-+      case OE_Abort: {
-+        if( !p->undoTransOnError ){
-+          for(i=0; i<db->nDb; i++){
-+            if( db->aDb[i].pBt ){
-+              sqliteBtreeRollbackCkpt(db->aDb[i].pBt);
-+            }
-+          }
-+          break;
-+        }
-+        /* Fall through to ROLLBACK */
-+      }
-+      case OE_Rollback: {
-+        sqliteRollbackAll(db);
-+        db->flags &= ~SQLITE_InTrans;
-+        db->onError = OE_Default;
-+        break;
-+      }
-+      default: {
-+        if( p->undoTransOnError ){
-+          sqliteRollbackAll(db);
-+          db->flags &= ~SQLITE_InTrans;
-+          db->onError = OE_Default;
-+        }
-+        break;
-+      }
-+    }
-+    sqliteRollbackInternalChanges(db);
-+  }
-+  for(i=0; i<db->nDb; i++){
-+    if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
-+      sqliteBtreeCommitCkpt(db->aDb[i].pBt);
-+      db->aDb[i].inTrans = 1;
-+    }
-+  }
-+  assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 );
-+#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
-+        );
-+        sqliteVdbePrintOp(out, i, &p->aOp[i]);
-+      }
-+      fclose(out);
-+    }
-+  }
-+#endif
-+  p->magic = VDBE_MAGIC_INIT;
-+  return p->rc;
-+}
-+
-+/*
-+** Clean up and delete a VDBE after execution.  Return an integer which is
-+** the result code.  Write any error message text into *pzErrMsg.
-+*/
-+int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
-+  int rc;
-+  sqlite *db;
-+
-+  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
-+    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
-+    return SQLITE_MISUSE;
-+  }
-+  db = p->db;
-+  rc = sqliteVdbeReset(p, pzErrMsg);
-+  sqliteVdbeDelete(p);
-+  if( db->want_to_close && db->pVdbe==0 ){
-+    sqlite_close(db);
-+  }
-+  if( rc==SQLITE_SCHEMA ){
-+    sqliteResetInternalSchema(db, 0);
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Set the values of all variables.  Variable $1 in the original SQL will
-+** be the string azValue[0].  $2 will have the value azValue[1].  And
-+** so forth.  If a value is out of range (for example $3 when nValue==2)
-+** then its value will be NULL.
-+**
-+** This routine overrides any prior call.
-+*/
-+int sqlite_bind(sqlite_vm *pVm, int i, const char *zVal, int len, int copy){
-+  Vdbe *p = (Vdbe*)pVm;
-+  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
-+    return SQLITE_MISUSE;
-+  }
-+  if( i<1 || i>p->nVar ){
-+    return SQLITE_RANGE;
-+  }
-+  i--;
-+  if( p->abVar[i] ){
-+    sqliteFree(p->azVar[i]);
-+  }
-+  if( zVal==0 ){
-+    copy = 0;
-+    len = 0;
-+  }
-+  if( len<0 ){
-+    len = strlen(zVal)+1;
-+  }
-+  if( copy ){
-+    p->azVar[i] = sqliteMalloc( len );
-+    if( p->azVar[i] ) memcpy(p->azVar[i], zVal, len);
-+  }else{
-+    p->azVar[i] = (char*)zVal;
-+  }
-+  p->abVar[i] = copy;
-+  p->anVar[i] = len;
-+  return SQLITE_OK;
-+}
-+
-+
-+/*
-+** Delete an entire VDBE.
-+*/
-+void sqliteVdbeDelete(Vdbe *p){
-+  int i;
-+  if( p==0 ) return;
-+  Cleanup(p);
-+  if( p->pPrev ){
-+    p->pPrev->pNext = p->pNext;
-+  }else{
-+    assert( p->db->pVdbe==p );
-+    p->db->pVdbe = p->pNext;
-+  }
-+  if( p->pNext ){
-+    p->pNext->pPrev = p->pPrev;
-+  }
-+  p->pPrev = p->pNext = 0;
-+  if( p->nOpAlloc==0 ){
-+    p->aOp = 0;
-+    p->nOp = 0;
-+  }
-+  for(i=0; i<p->nOp; i++){
-+    if( p->aOp[i].p3type==P3_DYNAMIC ){
-+      sqliteFree(p->aOp[i].p3);
-+    }
-+  }
-+  for(i=0; i<p->nVar; i++){
-+    if( p->abVar[i] ) sqliteFree(p->azVar[i]);
-+  }
-+  sqliteFree(p->aOp);
-+  sqliteFree(p->aLabel);
-+  sqliteFree(p->aStack);
-+  p->magic = VDBE_MAGIC_DEAD;
-+  sqliteFree(p);
-+}
-+
-+/*
-+** Convert an integer in between the native integer format and
-+** the bigEndian format used as the record number for tables.
-+**
-+** The bigEndian format (most significant byte first) is used for
-+** record numbers so that records will sort into the correct order
-+** even though memcmp() is used to compare the keys.  On machines
-+** whose native integer format is little endian (ex: i486) the
-+** order of bytes is reversed.  On native big-endian machines
-+** (ex: Alpha, Sparc, Motorola) the byte order is the same.
-+**
-+** This function is its own inverse.  In other words
-+**
-+**         X == byteSwap(byteSwap(X))
-+*/
-+int sqliteVdbeByteSwap(int x){
-+  union {
-+     char zBuf[sizeof(int)];
-+     int i;
-+  } ux;
-+  ux.zBuf[3] = x&0xff;
-+  ux.zBuf[2] = (x>>8)&0xff;
-+  ux.zBuf[1] = (x>>16)&0xff;
-+  ux.zBuf[0] = (x>>24)&0xff;
-+  return ux.i;
-+}
-+
-+/*
-+** If a MoveTo operation is pending on the given cursor, then do that
-+** MoveTo now.  Return an error code.  If no MoveTo is pending, this
-+** routine does nothing and returns SQLITE_OK.
-+*/
-+int sqliteVdbeCursorMoveto(Cursor *p){
-+  if( p->deferredMoveto ){
-+    int res;
-+    extern int sqlite_search_count;
-+    sqliteBtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);
-+    p->lastRecno = keyToInt(p->movetoTarget);
-+    p->recnoIsValid = res==0;
-+    if( res<0 ){
-+      sqliteBtreeNext(p->pCursor, &res);
-+    }
-+    sqlite_search_count++;
-+    p->deferredMoveto = 0;
-+  }
-+  return SQLITE_OK;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/vdbe.c
-@@ -0,0 +1,4921 @@
-+/*
-+** 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 "sqlite_vm*" 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 3 operands.  Operands P1 and P2 are integers.  Operand P3 
-+** is a null-terminated string.   The P2 operand must be non-negative.
-+** Opcodes will typically ignore one or more operands.  Many opcodes
-+** ignore all three operands.
-+**
-+** Computation results are stored on a stack.  Each entry on the
-+** stack is either an integer, a null-terminated string, a floating point
-+** number, or the SQL "NULL" value.  An inplicit conversion from one
-+** type to the other occurs as necessary.
-+** 
-+** Most of the code in this file is taken up by the sqliteVdbeExec()
-+** 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$
-+*/
-+#include "sqliteInt.h"
-+#include "os.h"
-+#include <ctype.h>
-+#include "vdbeInt.h"
-+
-+/*
-+** The following global variable is incremented every time a cursor
-+** moves, either by the OP_MoveTo or the OP_Next opcode.  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.
-+*/
-+int sqlite_search_count = 0;
-+
-+/*
-+** When this global variable is positive, it gets decremented once before
-+** each instruction in the VDBE.  When reaches zero, the SQLITE_Interrupt
-+** of the db.flags field is set in order to simulate an interrupt.
-+**
-+** This facility is used for testing purposes only.  It does not function
-+** in an ordinary build.
-+*/
-+int sqlite_interrupt_count = 0;
-+
-+/*
-+** Advance the virtual machine to the next output row.
-+**
-+** The return vale will be either SQLITE_BUSY, SQLITE_DONE, 
-+** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
-+**
-+** SQLITE_BUSY means that the virtual machine attempted to open
-+** a locked database and there is no busy callback registered.
-+** Call sqlite_step() again to retry the open.  *pN is set to 0
-+** and *pazColName and *pazValue are both set to NULL.
-+**
-+** SQLITE_DONE means that the virtual machine has finished
-+** executing.  sqlite_step() should not be called again on this
-+** virtual machine.  *pN and *pazColName are set appropriately
-+** but *pazValue is set to NULL.
-+**
-+** SQLITE_ROW means that the virtual machine has generated another
-+** row of the result set.  *pN is set to the number of columns in
-+** the row.  *pazColName is set to the names of the columns followed
-+** by the column datatypes.  *pazValue is set to the values of each
-+** column in the row.  The value of the i-th column is (*pazValue)[i].
-+** The name of the i-th column is (*pazColName)[i] and the datatype
-+** of the i-th column is (*pazColName)[i+*pN].
-+**
-+** SQLITE_ERROR means that a run-time error (such as a constraint
-+** violation) has occurred.  The details of the error will be returned
-+** by the next call to sqlite_finalize().  sqlite_step() should not
-+** be called again on the VM.
-+**
-+** SQLITE_MISUSE means that the this routine was called inappropriately.
-+** Perhaps it was called on a virtual machine that had already been
-+** finalized or on one that had previously returned SQLITE_ERROR or
-+** SQLITE_DONE.  Or it could be the case the the same database connection
-+** is being used simulataneously by two or more threads.
-+*/
-+int sqlite_step(
-+  sqlite_vm *pVm,              /* The virtual machine to execute */
-+  int *pN,                     /* OUT: Number of columns in result */
-+  const char ***pazValue,      /* OUT: Column data */
-+  const char ***pazColName     /* OUT: Column names and datatypes */
-+){
-+  Vdbe *p = (Vdbe*)pVm;
-+  sqlite *db;
-+  int rc;
-+
-+  if( !p || p->magic!=VDBE_MAGIC_RUN ){
-+    return SQLITE_MISUSE;
-+  }
-+  db = p->db;
-+  if( sqliteSafetyOn(db) ){
-+    p->rc = SQLITE_MISUSE;
-+    return SQLITE_MISUSE;
-+  }
-+  if( p->explain ){
-+    rc = sqliteVdbeList(p);
-+  }else{
-+    rc = sqliteVdbeExec(p);
-+  }
-+  if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
-+    if( pazColName ) *pazColName = (const char**)p->azColName;
-+    if( pN ) *pN = p->nResColumn;
-+  }else{
-+    if( pazColName) *pazColName = 0;
-+    if( pN ) *pN = 0;
-+  }
-+  if( pazValue ){
-+    if( rc==SQLITE_ROW ){
-+      *pazValue = (const char**)p->azResColumn;
-+    }else{
-+      *pazValue = 0;
-+    }
-+  }
-+  if( sqliteSafetyOff(db) ){
-+    return SQLITE_MISUSE;
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Insert a new aggregate element and make it the element that
-+** has focus.
-+**
-+** Return 0 on success and 1 if memory is exhausted.
-+*/
-+static int AggInsert(Agg *p, char *zKey, int nKey){
-+  AggElem *pElem, *pOld;
-+  int i;
-+  Mem *pMem;
-+  pElem = sqliteMalloc( sizeof(AggElem) + nKey +
-+                        (p->nMem-1)*sizeof(pElem->aMem[0]) );
-+  if( pElem==0 ) return 1;
-+  pElem->zKey = (char*)&pElem->aMem[p->nMem];
-+  memcpy(pElem->zKey, zKey, nKey);
-+  pElem->nKey = nKey;
-+  pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
-+  if( pOld!=0 ){
-+    assert( pOld==pElem );  /* Malloc failed on insert */
-+    sqliteFree(pOld);
-+    return 0;
-+  }
-+  for(i=0, pMem=pElem->aMem; i<p->nMem; i++, pMem++){
-+    pMem->flags = MEM_Null;
-+  }
-+  p->pCurrent = pElem;
-+  return 0;
-+}
-+
-+/*
-+** Get the AggElem currently in focus
-+*/
-+#define AggInFocus(P)   ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P)))
-+static AggElem *_AggInFocus(Agg *p){
-+  HashElem *pElem = sqliteHashFirst(&p->hash);
-+  if( pElem==0 ){
-+    AggInsert(p,"",1);
-+    pElem = sqliteHashFirst(&p->hash);
-+  }
-+  return pElem ? sqliteHashData(pElem) : 0;
-+}
-+
-+/*
-+** Convert the given stack entity into a string if it isn't one
-+** already.
-+*/
-+#define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);}
-+static int hardStringify(Mem *pStack){
-+  int fg = pStack->flags;
-+  if( fg & MEM_Real ){
-+    sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
-+  }else if( fg & MEM_Int ){
-+    sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%d",pStack->i);
-+  }else{
-+    pStack->zShort[0] = 0;
-+  }
-+  pStack->z = pStack->zShort;
-+  pStack->n = strlen(pStack->zShort)+1;
-+  pStack->flags = MEM_Str | MEM_Short;
-+  return 0;
-+}
-+
-+/*
-+** Convert the given stack entity into a string that has been obtained
-+** from sqliteMalloc().  This is different from Stringify() above in that
-+** Stringify() will use the NBFS bytes of static string space if the string
-+** will fit but this routine always mallocs for space.
-+** Return non-zero if we run out of memory.
-+*/
-+#define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0)
-+static int hardDynamicify(Mem *pStack){
-+  int fg = pStack->flags;
-+  char *z;
-+  if( (fg & MEM_Str)==0 ){
-+    hardStringify(pStack);
-+  }
-+  assert( (fg & MEM_Dyn)==0 );
-+  z = sqliteMallocRaw( pStack->n );
-+  if( z==0 ) return 1;
-+  memcpy(z, pStack->z, pStack->n);
-+  pStack->z = z;
-+  pStack->flags |= MEM_Dyn;
-+  return 0;
-+}
-+
-+/*
-+** 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 stack entry
-+** does not control the string, it might be deleted without the stack
-+** entry knowing it.
-+**
-+** This routine converts an ephemeral string into a dynamically allocated
-+** string that the stack entry 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 && hardDeephem(P) ){ goto no_mem;}
-+static int hardDeephem(Mem *pStack){
-+  char *z;
-+  assert( (pStack->flags & MEM_Ephem)!=0 );
-+  z = sqliteMallocRaw( pStack->n );
-+  if( z==0 ) return 1;
-+  memcpy(z, pStack->z, pStack->n);
-+  pStack->z = z;
-+  pStack->flags &= ~MEM_Ephem;
-+  pStack->flags |= MEM_Dyn;
-+  return 0;
-+}
-+
-+/*
-+** Release the memory associated with the given stack level.  This
-+** leaves the Mem.flags field in an inconsistent state.
-+*/
-+#define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
-+
-+/*
-+** Pop the stack N times.
-+*/
-+static void popStack(Mem **ppTos, int N){
-+  Mem *pTos = *ppTos;
-+  while( N>0 ){
-+    N--;
-+    Release(pTos);
-+    pTos--;
-+  }
-+  *ppTos = pTos;
-+}
-+
-+/*
-+** Return TRUE if zNum is a 32-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 just 32
-+** bits, then return false.
-+**
-+** Under Linux (RedHat 7.2) this routine is much faster than atoi()
-+** for converting strings into integers.
-+*/
-+static int toInt(const char *zNum, int *pNum){
-+  int v = 0;
-+  int neg;
-+  int i, c;
-+  if( *zNum=='-' ){
-+    neg = 1;
-+    zNum++;
-+  }else if( *zNum=='+' ){
-+    neg = 0;
-+    zNum++;
-+  }else{
-+    neg = 0;
-+  }
-+  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
-+    v = v*10 + c - '0';
-+  }
-+  *pNum = neg ? -v : v;
-+  return c==0 && i>0 && (i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0));
-+}
-+
-+/*
-+** Convert the given stack entity into a integer if it isn't one
-+** already.
-+**
-+** Any prior string or real representation is invalidated.  
-+** NULLs are converted into 0.
-+*/
-+#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
-+static void hardIntegerify(Mem *pStack){
-+  if( pStack->flags & MEM_Real ){
-+    pStack->i = (int)pStack->r;
-+    Release(pStack);
-+  }else if( pStack->flags & MEM_Str ){
-+    toInt(pStack->z, &pStack->i);
-+    Release(pStack);
-+  }else{
-+    pStack->i = 0;
-+  }
-+  pStack->flags = MEM_Int;
-+}
-+
-+/*
-+** Get a valid Real representation for the given stack element.
-+**
-+** Any prior string or integer representation is retained.
-+** NULLs are converted into 0.0.
-+*/
-+#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
-+static void hardRealify(Mem *pStack){
-+  if( pStack->flags & MEM_Str ){
-+    pStack->r = sqliteAtoF(pStack->z, 0);
-+  }else if( pStack->flags & MEM_Int ){
-+    pStack->r = pStack->i;
-+  }else{
-+    pStack->r = 0.0;
-+  }
-+  pStack->flags |= MEM_Real;
-+}
-+
-+/*
-+** The parameters are pointers to the head of two sorted lists
-+** of Sorter structures.  Merge these two lists together and return
-+** a single sorted list.  This routine forms the core of the merge-sort
-+** algorithm.
-+**
-+** In the case of a tie, left sorts in front of right.
-+*/
-+static Sorter *Merge(Sorter *pLeft, Sorter *pRight){
-+  Sorter sHead;
-+  Sorter *pTail;
-+  pTail = &sHead;
-+  pTail->pNext = 0;
-+  while( pLeft && pRight ){
-+    int c = sqliteSortCompare(pLeft->zKey, pRight->zKey);
-+    if( c<=0 ){
-+      pTail->pNext = pLeft;
-+      pLeft = pLeft->pNext;
-+    }else{
-+      pTail->pNext = pRight;
-+      pRight = pRight->pNext;
-+    }
-+    pTail = pTail->pNext;
-+  }
-+  if( pLeft ){
-+    pTail->pNext = pLeft;
-+  }else if( pRight ){
-+    pTail->pNext = pRight;
-+  }
-+  return sHead.pNext;
-+}
-+
-+/*
-+** The following routine works like a replacement for the standard
-+** library routine fgets().  The difference is in how end-of-line (EOL)
-+** is handled.  Standard fgets() uses LF for EOL under unix, CRLF
-+** under windows, and CR under mac.  This routine accepts any of these
-+** character sequences as an EOL mark.  The EOL mark is replaced by
-+** a single LF character in zBuf.
-+*/
-+static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){
-+  int i, c;
-+  for(i=0; i<nBuf-1 && (c=getc(in))!=EOF; i++){
-+    zBuf[i] = c;
-+    if( c=='\r' || c=='\n' ){
-+      if( c=='\r' ){
-+        zBuf[i] = '\n';
-+        c = getc(in);
-+        if( c!=EOF && c!='\n' ) ungetc(c, in);
-+      }
-+      i++;
-+      break;
-+    }
-+  }
-+  zBuf[i]  = 0;
-+  return i>0 ? zBuf : 0;
-+}
-+
-+/*
-+** Make sure there is space in the Vdbe structure to hold at least
-+** mxCursor cursors.  If there is not currently enough space, then
-+** allocate more.
-+**
-+** If a memory allocation error occurs, return 1.  Return 0 if
-+** everything works.
-+*/
-+static int expandCursorArraySize(Vdbe *p, int mxCursor){
-+  if( mxCursor>=p->nCursor ){
-+    Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) );
-+    if( aCsr==0 ) return 1;
-+    p->aCsr = aCsr;
-+    memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor));
-+    p->nCursor = mxCursor+1;
-+  }
-+  return 0;
-+}
-+
-+#ifdef VDBE_PROFILE
-+/*
-+** The following routine only works on pentium-class processors.
-+** It uses the RDTSC opcode to read cycle count value out of the
-+** processor and returns that value.  This can be used for high-res
-+** profiling.
-+*/
-+__inline__ unsigned long long int hwtime(void){
-+  unsigned long long int x;
-+  __asm__("rdtsc\n\t"
-+          "mov %%edx, %%ecx\n\t"
-+          :"=A" (x));
-+  return x;
-+}
-+#endif
-+
-+/*
-+** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
-+** sqlite_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->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;
-+
-+
-+/*
-+** Execute as much of a VDBE program as we can then return.
-+**
-+** sqliteVdbeMakeReady() 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 sqliteMalloc() 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, sqliteVdbeFinalize() should be
-+** used to clean up the mess that was left behind.
-+*/
-+int sqliteVdbeExec(
-+  Vdbe *p                    /* The VDBE */
-+){
-+  int pc;                    /* The program counter */
-+  Op *pOp;                   /* Current operation */
-+  int rc = SQLITE_OK;        /* Value to return */
-+  sqlite *db = p->db;        /* The database */
-+  Mem *pTos;                 /* Top entry in the operand stack */
-+  char zBuf[100];            /* Space to sprintf() an integer */
-+#ifdef VDBE_PROFILE
-+  unsigned long long 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
-+
-+  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
-+  assert( db->magic==SQLITE_MAGIC_BUSY );
-+  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
-+  p->rc = SQLITE_OK;
-+  assert( p->explain==0 );
-+  if( sqlite_malloc_failed ) goto no_mem;
-+  pTos = p->pTos;
-+  if( p->popStack ){
-+    popStack(&pTos, p->popStack);
-+    p->popStack = 0;
-+  }
-+  CHECK_FOR_INTERRUPT;
-+  for(pc=p->pc; rc==SQLITE_OK; pc++){
-+    assert( pc>=0 && pc<p->nOp );
-+    assert( pTos<=&p->aStack[pc] );
-+#ifdef VDBE_PROFILE
-+    origPc = pc;
-+    start = hwtime();
-+#endif
-+    pOp = &p->aOp[pc];
-+
-+    /* Only allow tracing if NDEBUG is not defined.
-+    */
-+#ifndef NDEBUG
-+    if( p->trace ){
-+      sqliteVdbePrintOp(p->trace, pc, pOp);
-+    }
-+#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( sqlite_interrupt_count>0 ){
-+      sqlite_interrupt_count--;
-+      if( sqlite_interrupt_count==0 ){
-+        sqlite_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
-+    ** sqliteVdbeExec() 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 ){
-+        if( db->xProgress(db->pProgressArg)!=0 ){
-+          rc = SQLITE_ABORT;
-+          continue; /* skip to the next iteration of the for loop */
-+        }
-+        nProgressOps = 0;
-+      }
-+      nProgressOps++;
-+    }
-+#endif
-+
-+    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.
-+**
-+** 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: {
-+  CHECK_FOR_INTERRUPT;
-+  pc = pOp->p2 - 1;
-+  break;
-+}
-+
-+/* Opcode:  Gosub * P2 *
-+**
-+** Push the current address plus 1 onto the return address stack
-+** and then jump to address P2.
-+**
-+** The return address stack is of limited depth.  If too many
-+** OP_Gosub operations occur without intervening OP_Returns, then
-+** the return address stack will fill up and processing will abort
-+** with a fatal error.
-+*/
-+case OP_Gosub: {
-+  if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){
-+    sqliteSetString(&p->zErrMsg, "return address stack overflow", (char*)0);
-+    p->rc = SQLITE_INTERNAL;
-+    return SQLITE_ERROR;
-+  }
-+  p->returnStack[p->returnDepth++] = pc+1;
-+  pc = pOp->p2 - 1;
-+  break;
-+}
-+
-+/* Opcode:  Return * * *
-+**
-+** Jump immediately to the next instruction after the last unreturned
-+** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
-+** processing aborts with a fatal error.
-+*/
-+case OP_Return: {
-+  if( p->returnDepth<=0 ){
-+    sqliteSetString(&p->zErrMsg, "return address stack underflow", (char*)0);
-+    p->rc = SQLITE_INTERNAL;
-+    return SQLITE_ERROR;
-+  }
-+  p->returnDepth--;
-+  pc = p->returnStack[p->returnDepth] - 1;
-+  break;
-+}
-+
-+/* Opcode:  Halt P1 P2 *
-+**
-+** Exit immediately.  All open cursors, Lists, Sorts, etc are closed
-+** automatically.
-+**
-+** P1 is the result code returned by sqlite_exec().  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. 
-+**
-+** 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: {
-+  p->magic = VDBE_MAGIC_HALT;
-+  p->pTos = pTos;
-+  if( pOp->p1!=SQLITE_OK ){
-+    p->rc = pOp->p1;
-+    p->errorAction = pOp->p2;
-+    if( pOp->p3 ){
-+      sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
-+    }
-+    return SQLITE_ERROR;
-+  }else{
-+    p->rc = SQLITE_OK;
-+    return SQLITE_DONE;
-+  }
-+}
-+
-+/* Opcode: Integer P1 * P3
-+**
-+** The integer value P1 is pushed onto the stack.  If P3 is not zero
-+** then it is assumed to be a string representation of the same integer.
-+*/
-+case OP_Integer: {
-+  pTos++;
-+  pTos->i = pOp->p1;
-+  pTos->flags = MEM_Int;
-+  if( pOp->p3 ){
-+    pTos->z = pOp->p3;
-+    pTos->flags |= MEM_Str | MEM_Static;
-+    pTos->n = strlen(pOp->p3)+1;
-+  }
-+  break;
-+}
-+
-+/* Opcode: String * * P3
-+**
-+** The string value P3 is pushed onto the stack.  If P3==0 then a
-+** NULL is pushed onto the stack.
-+*/
-+case OP_String: {
-+  char *z = pOp->p3;
-+  pTos++;
-+  if( z==0 ){
-+    pTos->flags = MEM_Null;
-+  }else{
-+    pTos->z = z;
-+    pTos->n = strlen(z) + 1;
-+    pTos->flags = MEM_Str | MEM_Static;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Variable P1 * *
-+**
-+** Push the value of variable P1 onto the stack.  A variable is
-+** an unknown in the original SQL string as handed to sqlite_compile().
-+** Any occurance of the '?' character in the original SQL is considered
-+** a variable.  Variables in the SQL string are number from left to
-+** right beginning with 1.  The values of variables are set using the
-+** sqlite_bind() API.
-+*/
-+case OP_Variable: {
-+  int j = pOp->p1 - 1;
-+  pTos++;
-+  if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){
-+    pTos->z = p->azVar[j];
-+    pTos->n = p->anVar[j];
-+    pTos->flags = MEM_Str | MEM_Static;
-+  }else{
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Pop P1 * *
-+**
-+** P1 elements are popped off of the top of stack and discarded.
-+*/
-+case OP_Pop: {
-+  assert( pOp->p1>=0 );
-+  popStack(&pTos, pOp->p1);
-+  assert( pTos>=&p->aStack[-1] );
-+  break;
-+}
-+
-+/* Opcode: Dup P1 P2 *
-+**
-+** A copy of the P1-th element of the stack 
-+** is made and pushed onto the top of the stack.
-+** The top of the stack is element 0.  So the
-+** instruction "Dup 0 0 0" will make a copy of the
-+** top of the stack.
-+**
-+** If the content of the P1-th element is a dynamically
-+** allocated string, then a new copy of that string
-+** is made if P2==0.  If P2!=0, then just a pointer
-+** to the string is copied.
-+**
-+** Also see the Pull instruction.
-+*/
-+case OP_Dup: {
-+  Mem *pFrom = &pTos[-pOp->p1];
-+  assert( pFrom<=pTos && pFrom>=p->aStack );
-+  pTos++;
-+  memcpy(pTos, pFrom, sizeof(*pFrom)-NBFS);
-+  if( pTos->flags & MEM_Str ){
-+    if( pOp->p2 && (pTos->flags & (MEM_Dyn|MEM_Ephem)) ){
-+      pTos->flags &= ~MEM_Dyn;
-+      pTos->flags |= MEM_Ephem;
-+    }else if( pTos->flags & MEM_Short ){
-+      memcpy(pTos->zShort, pFrom->zShort, pTos->n);
-+      pTos->z = pTos->zShort;
-+    }else if( (pTos->flags & MEM_Static)==0 ){
-+      pTos->z = sqliteMallocRaw(pFrom->n);
-+      if( sqlite_malloc_failed ) goto no_mem;
-+      memcpy(pTos->z, pFrom->z, pFrom->n);
-+      pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
-+      pTos->flags |= MEM_Dyn;
-+    }
-+  }
-+  break;
-+}
-+
-+/* Opcode: Pull P1 * *
-+**
-+** The P1-th element is removed from its current location on 
-+** the stack and pushed back on top of the stack.  The
-+** top of the stack is element 0, so "Pull 0 0 0" is
-+** a no-op.  "Pull 1 0 0" swaps the top two elements of
-+** the stack.
-+**
-+** See also the Dup instruction.
-+*/
-+case OP_Pull: {
-+  Mem *pFrom = &pTos[-pOp->p1];
-+  int i;
-+  Mem ts;
-+
-+  ts = *pFrom;
-+  Deephemeralize(pTos);
-+  for(i=0; i<pOp->p1; i++, pFrom++){
-+    Deephemeralize(&pFrom[1]);
-+    *pFrom = pFrom[1];
-+    assert( (pFrom->flags & MEM_Ephem)==0 );
-+    if( pFrom->flags & MEM_Short ){
-+      assert( pFrom->flags & MEM_Str );
-+      assert( pFrom->z==pFrom[1].zShort );
-+      pFrom->z = pFrom->zShort;
-+    }
-+  }
-+  *pTos = ts;
-+  if( pTos->flags & MEM_Short ){
-+    assert( pTos->flags & MEM_Str );
-+    assert( pTos->z==pTos[-pOp->p1].zShort );
-+    pTos->z = pTos->zShort;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Push P1 * *
-+**
-+** Overwrite the value of the P1-th element down on the
-+** stack (P1==0 is the top of the stack) with the value
-+** of the top of the stack.  Then pop the top of the stack.
-+*/
-+case OP_Push: {
-+  Mem *pTo = &pTos[-pOp->p1];
-+
-+  assert( pTo>=p->aStack );
-+  Deephemeralize(pTos);
-+  Release(pTo);
-+  *pTo = *pTos;
-+  if( pTo->flags & MEM_Short ){
-+    assert( pTo->z==pTos->zShort );
-+    pTo->z = pTo->zShort;
-+  }
-+  pTos--;
-+  break;
-+}
-+
-+
-+/* Opcode: ColumnName P1 P2 P3
-+**
-+** P3 becomes the P1-th column name (first is 0).  An array of pointers
-+** to all column names is passed as the 4th parameter to the callback.
-+** If P2==1 then this is the last column in the result set and thus the
-+** number of columns in the result set will be P1.  There must be at least
-+** one OP_ColumnName with a P2==1 before invoking OP_Callback and the
-+** number of columns specified in OP_Callback must one more than the P1
-+** value of the OP_ColumnName that has P2==1.
-+*/
-+case OP_ColumnName: {
-+  assert( pOp->p1>=0 && pOp->p1<p->nOp );
-+  p->azColName[pOp->p1] = pOp->p3;
-+  p->nCallback = 0;
-+  if( pOp->p2 ) p->nResColumn = pOp->p1+1;
-+  break;
-+}
-+
-+/* Opcode: Callback P1 * *
-+**
-+** Pop P1 values off the stack and form them into an array.  Then
-+** invoke the callback function using the newly formed array as the
-+** 3rd parameter.
-+*/
-+case OP_Callback: {
-+  int i;
-+  char **azArgv = p->zArgv;
-+  Mem *pCol;
-+
-+  pCol = &pTos[1-pOp->p1];
-+  assert( pCol>=p->aStack );
-+  for(i=0; i<pOp->p1; i++, pCol++){
-+    if( pCol->flags & MEM_Null ){
-+      azArgv[i] = 0;
-+    }else{
-+      Stringify(pCol);
-+      azArgv[i] = pCol->z;
-+    }
-+  }
-+  azArgv[i] = 0;
-+  p->nCallback++;
-+  p->azResColumn = azArgv;
-+  assert( p->nResColumn==pOp->p1 );
-+  p->popStack = pOp->p1;
-+  p->pc = pc + 1;
-+  p->pTos = pTos;
-+  return SQLITE_ROW;
-+}
-+
-+/* Opcode: Concat P1 P2 P3
-+**
-+** Look at the first P1 elements of the stack.  Append them all 
-+** together with the lowest element first.  Use P3 as a separator.  
-+** Put the result on the top of the stack.  The original P1 elements
-+** are popped from the stack if P2==0 and retained if P2==1.  If
-+** any element of the stack is NULL, then the result is NULL.
-+**
-+** If P3 is NULL, then use no separator.  When P1==1, this routine
-+** makes a copy of the top stack element into memory obtained
-+** from sqliteMalloc().
-+*/
-+case OP_Concat: {
-+  char *zNew;
-+  int nByte;
-+  int nField;
-+  int i, j;
-+  char *zSep;
-+  int nSep;
-+  Mem *pTerm;
-+
-+  nField = pOp->p1;
-+  zSep = pOp->p3;
-+  if( zSep==0 ) zSep = "";
-+  nSep = strlen(zSep);
-+  assert( &pTos[1-nField] >= p->aStack );
-+  nByte = 1 - nSep;
-+  pTerm = &pTos[1-nField];
-+  for(i=0; i<nField; i++, pTerm++){
-+    if( pTerm->flags & MEM_Null ){
-+      nByte = -1;
-+      break;
-+    }else{
-+      Stringify(pTerm);
-+      nByte += pTerm->n - 1 + nSep;
-+    }
-+  }
-+  if( nByte<0 ){
-+    if( pOp->p2==0 ){
-+      popStack(&pTos, nField);
-+    }
-+    pTos++;
-+    pTos->flags = MEM_Null;
-+    break;
-+  }
-+  zNew = sqliteMallocRaw( nByte );
-+  if( zNew==0 ) goto no_mem;
-+  j = 0;
-+  pTerm = &pTos[1-nField];
-+  for(i=j=0; i<nField; i++, pTerm++){
-+    assert( pTerm->flags & MEM_Str );
-+    memcpy(&zNew[j], pTerm->z, pTerm->n-1);
-+    j += pTerm->n-1;
-+    if( nSep>0 && i<nField-1 ){
-+      memcpy(&zNew[j], zSep, nSep);
-+      j += nSep;
-+    }
-+  }
-+  zNew[j] = 0;
-+  if( pOp->p2==0 ){
-+    popStack(&pTos, nField);
-+  }
-+  pTos++;
-+  pTos->n = nByte;
-+  pTos->flags = MEM_Str|MEM_Dyn;
-+  pTos->z = zNew;
-+  break;
-+}
-+
-+/* Opcode: Add * * *
-+**
-+** Pop the top two elements from the stack, add them together,
-+** and push the result back onto the stack.  If either element
-+** is a string then it is converted to a double using the atof()
-+** function before the addition.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: Multiply * * *
-+**
-+** Pop the top two elements from the stack, multiply them together,
-+** and push the result back onto the stack.  If either element
-+** is a string then it is converted to a double using the atof()
-+** function before the multiplication.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: Subtract * * *
-+**
-+** Pop the top two elements from the stack, subtract the
-+** first (what was on top of the stack) from the second (the
-+** next on stack)
-+** and push the result back onto the stack.  If either element
-+** is a string then it is converted to a double using the atof()
-+** function before the subtraction.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: Divide * * *
-+**
-+** Pop the top two elements from the stack, divide the
-+** first (what was on top of the stack) from the second (the
-+** next on stack)
-+** and push the result back onto the stack.  If either element
-+** is a string then it is converted to a double using the atof()
-+** function before the division.  Division by zero returns NULL.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: Remainder * * *
-+**
-+** Pop the top two elements from the stack, divide the
-+** first (what was on top of the stack) from the second (the
-+** next on stack)
-+** and push the remainder after division onto the stack.  If either element
-+** is a string then it is converted to a double using the atof()
-+** function before the division.  Division by zero returns NULL.
-+** If either operand is NULL, the result is NULL.
-+*/
-+case OP_Add:
-+case OP_Subtract:
-+case OP_Multiply:
-+case OP_Divide:
-+case OP_Remainder: {
-+  Mem *pNos = &pTos[-1];
-+  assert( pNos>=p->aStack );
-+  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
-+    Release(pTos);
-+    pTos--;
-+    Release(pTos);
-+    pTos->flags = MEM_Null;
-+  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
-+    int a, b;
-+    a = pTos->i;
-+    b = pNos->i;
-+    switch( pOp->opcode ){
-+      case OP_Add:         b += a;       break;
-+      case OP_Subtract:    b -= a;       break;
-+      case OP_Multiply:    b *= a;       break;
-+      case OP_Divide: {
-+        if( a==0 ) goto divide_by_zero;
-+        b /= a;
-+        break;
-+      }
-+      default: {
-+        if( a==0 ) goto divide_by_zero;
-+        b %= a;
-+        break;
-+      }
-+    }
-+    Release(pTos);
-+    pTos--;
-+    Release(pTos);
-+    pTos->i = b;
-+    pTos->flags = MEM_Int;
-+  }else{
-+    double a, b;
-+    Realify(pTos);
-+    Realify(pNos);
-+    a = pTos->r;
-+    b = pNos->r;
-+    switch( pOp->opcode ){
-+      case OP_Add:         b += a;       break;
-+      case OP_Subtract:    b -= a;       break;
-+      case OP_Multiply:    b *= a;       break;
-+      case OP_Divide: {
-+        if( a==0.0 ) goto divide_by_zero;
-+        b /= a;
-+        break;
-+      }
-+      default: {
-+        int ia = (int)a;
-+        int ib = (int)b;
-+        if( ia==0.0 ) goto divide_by_zero;
-+        b = ib % ia;
-+        break;
-+      }
-+    }
-+    Release(pTos);
-+    pTos--;
-+    Release(pTos);
-+    pTos->r = b;
-+    pTos->flags = MEM_Real;
-+  }
-+  break;
-+
-+divide_by_zero:
-+  Release(pTos);
-+  pTos--;
-+  Release(pTos);
-+  pTos->flags = MEM_Null;
-+  break;
-+}
-+
-+/* Opcode: Function P1 * P3
-+**
-+** Invoke a user function (P3 is a pointer to a Function structure that
-+** defines the function) with P1 string arguments taken from the stack.
-+** Pop all arguments from the stack and push back the result.
-+**
-+** See also: AggFunc
-+*/
-+case OP_Function: {
-+  int n, i;
-+  Mem *pArg;
-+  char **azArgv;
-+  sqlite_func ctx;
-+
-+  n = pOp->p1;
-+  pArg = &pTos[1-n];
-+  azArgv = p->zArgv;
-+  for(i=0; i<n; i++, pArg++){
-+    if( pArg->flags & MEM_Null ){
-+      azArgv[i] = 0;
-+    }else{
-+      Stringify(pArg);
-+      azArgv[i] = pArg->z;
-+    }
-+  }
-+  ctx.pFunc = (FuncDef*)pOp->p3;
-+  ctx.s.flags = MEM_Null;
-+  ctx.s.z = 0;
-+  ctx.isError = 0;
-+  ctx.isStep = 0;
-+  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
-+  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);
-+  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
-+  popStack(&pTos, n);
-+  pTos++;
-+  *pTos = ctx.s;
-+  if( pTos->flags & MEM_Short ){
-+    pTos->z = pTos->zShort;
-+  }
-+  if( ctx.isError ){
-+    sqliteSetString(&p->zErrMsg, 
-+       (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
-+    rc = SQLITE_ERROR;
-+  }
-+  break;
-+}
-+
-+/* Opcode: BitAnd * * *
-+**
-+** Pop the top two elements from the stack.  Convert both elements
-+** to integers.  Push back onto the stack the bit-wise AND of the
-+** two elements.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: BitOr * * *
-+**
-+** Pop the top two elements from the stack.  Convert both elements
-+** to integers.  Push back onto the stack the bit-wise OR of the
-+** two elements.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: ShiftLeft * * *
-+**
-+** Pop the top two elements from the stack.  Convert both elements
-+** to integers.  Push back onto the stack the top element shifted
-+** left by N bits where N is the second element on the stack.
-+** If either operand is NULL, the result is NULL.
-+*/
-+/* Opcode: ShiftRight * * *
-+**
-+** Pop the top two elements from the stack.  Convert both elements
-+** to integers.  Push back onto the stack the top element shifted
-+** right by N bits where N is the second element on the stack.
-+** If either operand is NULL, the result is NULL.
-+*/
-+case OP_BitAnd:
-+case OP_BitOr:
-+case OP_ShiftLeft:
-+case OP_ShiftRight: {
-+  Mem *pNos = &pTos[-1];
-+  int a, b;
-+
-+  assert( pNos>=p->aStack );
-+  if( (pTos->flags | pNos->flags) & MEM_Null ){
-+    popStack(&pTos, 2);
-+    pTos++;
-+    pTos->flags = MEM_Null;
-+    break;
-+  }
-+  Integerify(pTos);
-+  Integerify(pNos);
-+  a = pTos->i;
-+  b = pNos->i;
-+  switch( pOp->opcode ){
-+    case OP_BitAnd:      a &= b;     break;
-+    case OP_BitOr:       a |= b;     break;
-+    case OP_ShiftLeft:   a <<= b;    break;
-+    case OP_ShiftRight:  a >>= b;    break;
-+    default:   /* CANT HAPPEN */     break;
-+  }
-+  assert( (pTos->flags & MEM_Dyn)==0 );
-+  assert( (pNos->flags & MEM_Dyn)==0 );
-+  pTos--;
-+  Release(pTos);
-+  pTos->i = a;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: AddImm  P1 * *
-+** 
-+** Add the value P1 to whatever is on top of the stack.  The result
-+** is always an integer.
-+**
-+** To force the top of the stack to be an integer, just add 0.
-+*/
-+case OP_AddImm: {
-+  assert( pTos>=p->aStack );
-+  Integerify(pTos);
-+  pTos->i += pOp->p1;
-+  break;
-+}
-+
-+/* Opcode: ForceInt P1 P2 *
-+**
-+** Convert the top of the stack into an integer.  If the current top of
-+** the stack is not numeric (meaning that is is a NULL or a string that
-+** does not look like an integer or floating point number) then pop the
-+** stack and jump to P2.  If the top of the stack is numeric then
-+** convert it into the least integer that is greater than or equal to its
-+** current value if P1==0, or to the least integer that is strictly
-+** greater than its current value if P1==1.
-+*/
-+case OP_ForceInt: {
-+  int v;
-+  assert( pTos>=p->aStack );
-+  if( (pTos->flags & (MEM_Int|MEM_Real))==0
-+         && ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){
-+    Release(pTos);
-+    pTos--;
-+    pc = pOp->p2 - 1;
-+    break;
-+  }
-+  if( pTos->flags & MEM_Int ){
-+    v = pTos->i + (pOp->p1!=0);
-+  }else{
-+    Realify(pTos);
-+    v = (int)pTos->r;
-+    if( pTos->r>(double)v ) v++;
-+    if( pOp->p1 && pTos->r==(double)v ) v++;
-+  }
-+  Release(pTos);
-+  pTos->i = v;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: MustBeInt P1 P2 *
-+** 
-+** Force the top of the stack to be an integer.  If the top of the
-+** stack is not an integer and cannot be converted into an integer
-+** with out data loss, then jump immediately to P2, or if P2==0
-+** raise an SQLITE_MISMATCH exception.
-+**
-+** If the top of the stack is not an integer and P2 is not zero and
-+** P1 is 1, then the stack is popped.  In all other cases, the depth
-+** of the stack is unchanged.
-+*/
-+case OP_MustBeInt: {
-+  assert( pTos>=p->aStack );
-+  if( pTos->flags & MEM_Int ){
-+    /* Do nothing */
-+  }else if( pTos->flags & MEM_Real ){
-+    int i = (int)pTos->r;
-+    double r = (double)i;
-+    if( r!=pTos->r ){
-+      goto mismatch;
-+    }
-+    pTos->i = i;
-+  }else if( pTos->flags & MEM_Str ){
-+    int v;
-+    if( !toInt(pTos->z, &v) ){
-+      double r;
-+      if( !sqliteIsNumber(pTos->z) ){
-+        goto mismatch;
-+      }
-+      Realify(pTos);
-+      v = (int)pTos->r;
-+      r = (double)v;
-+      if( r!=pTos->r ){
-+        goto mismatch;
-+      }
-+    }
-+    pTos->i = v;
-+  }else{
-+    goto mismatch;
-+  }
-+  Release(pTos);
-+  pTos->flags = MEM_Int;
-+  break;
-+
-+mismatch:
-+  if( pOp->p2==0 ){
-+    rc = SQLITE_MISMATCH;
-+    goto abort_due_to_error;
-+  }else{
-+    if( pOp->p1 ) popStack(&pTos, 1);
-+    pc = pOp->p2 - 1;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Eq P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If they are equal, then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared for equality that way.  Otherwise the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrEq.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: Ne P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If they are not equal, then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared in that format.  Otherwise the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrNe.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: Lt P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is less than the first (the top of stack), then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+** In other words, jump if NOS<TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared in that format.  Numeric values are always less than
-+** non-numeric values.  If both operands are non-numeric, the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrLt.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: Le P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is less than or equal to the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS<=TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared in that format.  Numeric values are always less than
-+** non-numeric values.  If both operands are non-numeric, the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrLe.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: Gt P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is greater than the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS>TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared in that format.  Numeric values are always less than
-+** non-numeric values.  If both operands are non-numeric, the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrGt.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: Ge P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the next
-+** on stack) is greater than or equal to the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS>=TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** If both values are numeric, they are converted to doubles using atof()
-+** and compared in that format.  Numeric values are always less than
-+** non-numeric values.  If both operands are non-numeric, the strcmp() library
-+** routine is used for the comparison.  For a pure text comparison
-+** use OP_StrGe.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+case OP_Eq:
-+case OP_Ne:
-+case OP_Lt:
-+case OP_Le:
-+case OP_Gt:
-+case OP_Ge: {
-+  Mem *pNos = &pTos[-1];
-+  int c, v;
-+  int ft, fn;
-+  assert( pNos>=p->aStack );
-+  ft = pTos->flags;
-+  fn = pNos->flags;
-+  if( (ft | fn) & MEM_Null ){
-+    popStack(&pTos, 2);
-+    if( pOp->p2 ){
-+      if( pOp->p1 ) pc = pOp->p2-1;
-+    }else{
-+      pTos++;
-+      pTos->flags = MEM_Null;
-+    }
-+    break;
-+  }else if( (ft & fn & MEM_Int)==MEM_Int ){
-+    c = pNos->i - pTos->i;
-+  }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(pNos->z,&v) ){
-+    c = v - pTos->i;
-+  }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(pTos->z,&v) ){
-+    c = pNos->i - v;
-+  }else{
-+    Stringify(pTos);
-+    Stringify(pNos);
-+    c = sqliteCompare(pNos->z, pTos->z);
-+  }
-+  switch( pOp->opcode ){
-+    case OP_Eq:    c = c==0;     break;
-+    case OP_Ne:    c = c!=0;     break;
-+    case OP_Lt:    c = c<0;      break;
-+    case OP_Le:    c = c<=0;     break;
-+    case OP_Gt:    c = c>0;      break;
-+    default:       c = c>=0;     break;
-+  }
-+  popStack(&pTos, 2);
-+  if( pOp->p2 ){
-+    if( c ) pc = pOp->p2-1;
-+  }else{
-+    pTos++;
-+    pTos->i = c;
-+    pTos->flags = MEM_Int;
-+  }
-+  break;
-+}
-+/* INSERT NO CODE HERE!
-+**
-+** The opcode numbers are extracted from this source file by doing
-+**
-+**    grep '^case OP_' vdbe.c | ... >opcodes.h
-+**
-+** The opcodes are numbered in the order that they appear in this file.
-+** But in order for the expression generating code to work right, the
-+** string comparison operators that follow must be numbered exactly 6
-+** greater than the numeric comparison opcodes above.  So no other
-+** cases can appear between the two.
-+*/
-+/* Opcode: StrEq P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If they are equal, then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Eq.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: StrNe P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If they are not equal, then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Ne.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: StrLt P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is less than the first (the top of stack), then
-+** jump to instruction P2.  Otherwise, continue to the next instruction.
-+** In other words, jump if NOS<TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Lt.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: StrLe P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is less than or equal to the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS<=TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Le.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: StrGt P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the
-+** next on stack) is greater than the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS>TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Gt.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+/* Opcode: StrGe P1 P2 *
-+**
-+** Pop the top two elements from the stack.  If second element (the next
-+** on stack) is greater than or equal to the first (the top of stack),
-+** then jump to instruction P2. In other words, jump if NOS>=TOS.
-+**
-+** If either operand is NULL (and thus if the result is unknown) then
-+** take the jump if P1 is true.
-+**
-+** The strcmp() library routine is used for the comparison.  For a
-+** numeric comparison, use OP_Ge.
-+**
-+** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
-+** stack if the jump would have been taken, or a 0 if not.  Push a
-+** NULL if either operand was NULL.
-+*/
-+case OP_StrEq:
-+case OP_StrNe:
-+case OP_StrLt:
-+case OP_StrLe:
-+case OP_StrGt:
-+case OP_StrGe: {
-+  Mem *pNos = &pTos[-1];
-+  int c;
-+  assert( pNos>=p->aStack );
-+  if( (pNos->flags | pTos->flags) & MEM_Null ){
-+    popStack(&pTos, 2);
-+    if( pOp->p2 ){
-+      if( pOp->p1 ) pc = pOp->p2-1;
-+    }else{
-+      pTos++;
-+      pTos->flags = MEM_Null;
-+    }
-+    break;
-+  }else{
-+    Stringify(pTos);
-+    Stringify(pNos);
-+    c = strcmp(pNos->z, pTos->z);
-+  }
-+  /* The asserts on each case of the following switch are there to verify
-+  ** that string comparison opcodes are always exactly 6 greater than the
-+  ** corresponding numeric comparison opcodes.  The code generator depends
-+  ** on this fact.
-+  */
-+  switch( pOp->opcode ){
-+    case OP_StrEq:    c = c==0;    assert( pOp->opcode-6==OP_Eq );   break;
-+    case OP_StrNe:    c = c!=0;    assert( pOp->opcode-6==OP_Ne );   break;
-+    case OP_StrLt:    c = c<0;     assert( pOp->opcode-6==OP_Lt );   break;
-+    case OP_StrLe:    c = c<=0;    assert( pOp->opcode-6==OP_Le );   break;
-+    case OP_StrGt:    c = c>0;     assert( pOp->opcode-6==OP_Gt );   break;
-+    default:          c = c>=0;    assert( pOp->opcode-6==OP_Ge );   break;
-+  }
-+  popStack(&pTos, 2);
-+  if( pOp->p2 ){
-+    if( c ) pc = pOp->p2-1;
-+  }else{
-+    pTos++;
-+    pTos->flags = MEM_Int;
-+    pTos->i = c;
-+  }
-+  break;
-+}
-+
-+/* Opcode: And * * *
-+**
-+** Pop two values off the stack.  Take the logical AND of the
-+** two values and push the resulting boolean value back onto the
-+** stack. 
-+*/
-+/* Opcode: Or * * *
-+**
-+** Pop two values off the stack.  Take the logical OR of the
-+** two values and push the resulting boolean value back onto the
-+** stack. 
-+*/
-+case OP_And:
-+case OP_Or: {
-+  Mem *pNos = &pTos[-1];
-+  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
-+
-+  assert( pNos>=p->aStack );
-+  if( pTos->flags & MEM_Null ){
-+    v1 = 2;
-+  }else{
-+    Integerify(pTos);
-+    v1 = pTos->i==0;
-+  }
-+  if( pNos->flags & MEM_Null ){
-+    v2 = 2;
-+  }else{
-+    Integerify(pNos);
-+    v2 = pNos->i==0;
-+  }
-+  if( pOp->opcode==OP_And ){
-+    static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
-+    v1 = and_logic[v1*3+v2];
-+  }else{
-+    static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
-+    v1 = or_logic[v1*3+v2];
-+  }
-+  popStack(&pTos, 2);
-+  pTos++;
-+  if( v1==2 ){
-+    pTos->flags = MEM_Null;
-+  }else{
-+    pTos->i = v1==0;
-+    pTos->flags = MEM_Int;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Negative * * *
-+**
-+** Treat the top of the stack as a numeric quantity.  Replace it
-+** with its additive inverse.  If the top of the stack is NULL
-+** its value is unchanged.
-+*/
-+/* Opcode: AbsValue * * *
-+**
-+** Treat the top of the stack as a numeric quantity.  Replace it
-+** with its absolute value. If the top of the stack is NULL
-+** its value is unchanged.
-+*/
-+case OP_Negative:
-+case OP_AbsValue: {
-+  assert( pTos>=p->aStack );
-+  if( pTos->flags & MEM_Real ){
-+    Release(pTos);
-+    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
-+      pTos->r = -pTos->r;
-+    }
-+    pTos->flags = MEM_Real;
-+  }else if( pTos->flags & MEM_Int ){
-+    Release(pTos);
-+    if( pOp->opcode==OP_Negative || pTos->i<0 ){
-+      pTos->i = -pTos->i;
-+    }
-+    pTos->flags = MEM_Int;
-+  }else if( pTos->flags & MEM_Null ){
-+    /* Do nothing */
-+  }else{
-+    Realify(pTos);
-+    Release(pTos);
-+    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
-+      pTos->r = -pTos->r;
-+    }
-+    pTos->flags = MEM_Real;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Not * * *
-+**
-+** Interpret the top of the stack as a boolean value.  Replace it
-+** with its complement.  If the top of the stack is NULL its value
-+** is unchanged.
-+*/
-+case OP_Not: {
-+  assert( pTos>=p->aStack );
-+  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-+  Integerify(pTos);
-+  Release(pTos);
-+  pTos->i = !pTos->i;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: BitNot * * *
-+**
-+** Interpret the top of the stack as an value.  Replace it
-+** with its ones-complement.  If the top of the stack is NULL its
-+** value is unchanged.
-+*/
-+case OP_BitNot: {
-+  assert( pTos>=p->aStack );
-+  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
-+  Integerify(pTos);
-+  Release(pTos);
-+  pTos->i = ~pTos->i;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: Noop * * *
-+**
-+** Do nothing.  This instruction is often useful as a jump
-+** destination.
-+*/
-+case OP_Noop: {
-+  break;
-+}
-+
-+/* Opcode: If P1 P2 *
-+**
-+** Pop a single boolean from the stack.  If the boolean popped is
-+** true, then jump to p2.  Otherwise continue to the next instruction.
-+** An integer is false if zero and true otherwise.  A string is
-+** false if it has zero length and true otherwise.
-+**
-+** If the value popped of the stack is NULL, then take the jump if P1
-+** is true and fall through if P1 is false.
-+*/
-+/* Opcode: IfNot P1 P2 *
-+**
-+** Pop a single boolean from the stack.  If the boolean popped is
-+** false, then jump to p2.  Otherwise continue to the next instruction.
-+** An integer is false if zero and true otherwise.  A string is
-+** false if it has zero length and true otherwise.
-+**
-+** If the value popped of the stack is NULL, then take the jump if P1
-+** is true and fall through if P1 is false.
-+*/
-+case OP_If:
-+case OP_IfNot: {
-+  int c;
-+  assert( pTos>=p->aStack );
-+  if( pTos->flags & MEM_Null ){
-+    c = pOp->p1;
-+  }else{
-+    Integerify(pTos);
-+    c = pTos->i;
-+    if( pOp->opcode==OP_IfNot ) c = !c;
-+  }
-+  assert( (pTos->flags & MEM_Dyn)==0 );
-+  pTos--;
-+  if( c ) pc = pOp->p2-1;
-+  break;
-+}
-+
-+/* Opcode: IsNull P1 P2 *
-+**
-+** If any of the top abs(P1) values on the stack are NULL, then jump
-+** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
-+** unchanged.
-+*/
-+case OP_IsNull: {
-+  int i, cnt;
-+  Mem *pTerm;
-+  cnt = pOp->p1;
-+  if( cnt<0 ) cnt = -cnt;
-+  pTerm = &pTos[1-cnt];
-+  assert( pTerm>=p->aStack );
-+  for(i=0; i<cnt; i++, pTerm++){
-+    if( pTerm->flags & MEM_Null ){
-+      pc = pOp->p2-1;
-+      break;
-+    }
-+  }
-+  if( pOp->p1>0 ) popStack(&pTos, cnt);
-+  break;
-+}
-+
-+/* Opcode: NotNull P1 P2 *
-+**
-+** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
-+** stack if P1 times if P1 is greater than zero.  If P1 is less than
-+** zero then leave the stack unchanged.
-+*/
-+case OP_NotNull: {
-+  int i, cnt;
-+  cnt = pOp->p1;
-+  if( cnt<0 ) cnt = -cnt;
-+  assert( &pTos[1-cnt] >= p->aStack );
-+  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
-+  if( i>=cnt ) pc = pOp->p2-1;
-+  if( pOp->p1>0 ) popStack(&pTos, cnt);
-+  break;
-+}
-+
-+/* Opcode: MakeRecord P1 P2 *
-+**
-+** Convert the top P1 entries of the stack into a single entry
-+** suitable for use as a data record in a database table.  The
-+** details of the format are irrelavant as long as the OP_Column
-+** opcode can decode the record later.  Refer to source code
-+** comments for the details of the record format.
-+**
-+** If P2 is true (non-zero) and one or more of the P1 entries
-+** that go into building the record is NULL, then add some extra
-+** bytes to the record to make it distinct for other entries created
-+** during the same run of the VDBE.  The extra bytes added are a
-+** counter that is reset with each run of the VDBE, so records
-+** created this way will not necessarily be distinct across runs.
-+** But they should be distinct for transient tables (created using
-+** OP_OpenTemp) which is what they are intended for.
-+**
-+** (Later:) The P2==1 option was intended to make NULLs distinct
-+** for the UNION operator.  But I have since discovered that NULLs
-+** are indistinct for UNION.  So this option is never used.
-+*/
-+case OP_MakeRecord: {
-+  char *zNewRecord;
-+  int nByte;
-+  int nField;
-+  int i, j;
-+  int idxWidth;
-+  u32 addr;
-+  Mem *pRec;
-+  int addUnique = 0;   /* True to cause bytes to be added to make the
-+                       ** generated record distinct */
-+  char zTemp[NBFS];    /* Temp space for small records */
-+
-+  /* Assuming the record contains N fields, the record format looks
-+  ** like this:
-+  **
-+  **   -------------------------------------------------------------------
-+  **   | idx0 | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
-+  **   -------------------------------------------------------------------
-+  **
-+  ** All data fields are converted to strings before being stored and
-+  ** are stored with their null terminators.  NULL entries omit the
-+  ** null terminator.  Thus an empty string uses 1 byte and a NULL uses
-+  ** zero bytes.  Data(0) is taken from the lowest element of the stack
-+  ** and data(N-1) is the top of the stack.
-+  **
-+  ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
-+  ** how big the total record is.  Idx(0) contains the offset to the start
-+  ** of data(0).  Idx(k) contains the offset to the start of data(k).
-+  ** Idx(N) contains the total number of bytes in the record.
-+  */
-+  nField = pOp->p1;
-+  pRec = &pTos[1-nField];
-+  assert( pRec>=p->aStack );
-+  nByte = 0;
-+  for(i=0; i<nField; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      addUnique = pOp->p2;
-+    }else{
-+      Stringify(pRec);
-+      nByte += pRec->n;
-+    }
-+  }
-+  if( addUnique ) nByte += sizeof(p->uniqueCnt);
-+  if( nByte + nField + 1 < 256 ){
-+    idxWidth = 1;
-+  }else if( nByte + 2*nField + 2 < 65536 ){
-+    idxWidth = 2;
-+  }else{
-+    idxWidth = 3;
-+  }
-+  nByte += idxWidth*(nField + 1);
-+  if( nByte>MAX_BYTES_PER_ROW ){
-+    rc = SQLITE_TOOBIG;
-+    goto abort_due_to_error;
-+  }
-+  if( nByte<=NBFS ){
-+    zNewRecord = zTemp;
-+  }else{
-+    zNewRecord = sqliteMallocRaw( nByte );
-+    if( zNewRecord==0 ) goto no_mem;
-+  }
-+  j = 0;
-+  addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt);
-+  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
-+    zNewRecord[j++] = addr & 0xff;
-+    if( idxWidth>1 ){
-+      zNewRecord[j++] = (addr>>8)&0xff;
-+      if( idxWidth>2 ){
-+        zNewRecord[j++] = (addr>>16)&0xff;
-+      }
-+    }
-+    if( (pRec->flags & MEM_Null)==0 ){
-+      addr += pRec->n;
-+    }
-+  }
-+  zNewRecord[j++] = addr & 0xff;
-+  if( idxWidth>1 ){
-+    zNewRecord[j++] = (addr>>8)&0xff;
-+    if( idxWidth>2 ){
-+      zNewRecord[j++] = (addr>>16)&0xff;
-+    }
-+  }
-+  if( addUnique ){
-+    memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt));
-+    p->uniqueCnt++;
-+    j += sizeof(p->uniqueCnt);
-+  }
-+  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
-+    if( (pRec->flags & MEM_Null)==0 ){
-+      memcpy(&zNewRecord[j], pRec->z, pRec->n);
-+      j += pRec->n;
-+    }
-+  }
-+  popStack(&pTos, nField);
-+  pTos++;
-+  pTos->n = nByte;
-+  if( nByte<=NBFS ){
-+    assert( zNewRecord==zTemp );
-+    memcpy(pTos->zShort, zTemp, nByte);
-+    pTos->z = pTos->zShort;
-+    pTos->flags = MEM_Str | MEM_Short;
-+  }else{
-+    assert( zNewRecord!=zTemp );
-+    pTos->z = zNewRecord;
-+    pTos->flags = MEM_Str | MEM_Dyn;
-+  }
-+  break;
-+}
-+
-+/* Opcode: MakeKey P1 P2 P3
-+**
-+** Convert the top P1 entries of the stack into a single entry suitable
-+** for use as the key in an index.  The top P1 records are
-+** converted to strings and merged.  The null-terminators 
-+** are retained and used as separators.
-+** The lowest entry in the stack is the first field and the top of the
-+** stack becomes the last.
-+**
-+** If P2 is not zero, then the original entries remain on the stack
-+** and the new key is pushed on top.  If P2 is zero, the original
-+** data is popped off the stack first then the new key is pushed
-+** back in its place.
-+**
-+** P3 is a string that is P1 characters long.  Each character is either
-+** an 'n' or a 't' to indicates if the argument should be intepreted as
-+** numeric or text type.  The first character of P3 corresponds to the
-+** lowest element on the stack.  If P3 is NULL then all arguments are
-+** assumed to be of the numeric type.
-+**
-+** The type makes a difference in that text-type fields may not be 
-+** introduced by 'b' (as described in the next paragraph).  The
-+** first character of a text-type field must be either 'a' (if it is NULL)
-+** or 'c'.  Numeric fields will be introduced by 'b' if their content
-+** looks like a well-formed number.  Otherwise the 'a' or 'c' will be
-+** used.
-+**
-+** The key is a concatenation of fields.  Each field is terminated by
-+** a single 0x00 character.  A NULL field is introduced by an 'a' and
-+** is followed immediately by its 0x00 terminator.  A numeric field is
-+** introduced by a single character 'b' and is followed by a sequence
-+** of characters that represent the number such that a comparison of
-+** the character string using memcpy() sorts the numbers in numerical
-+** order.  The character strings for numbers are generated using the
-+** sqliteRealToSortable() function.  A text field is introduced by a
-+** 'c' character and is followed by the exact text of the field.  The
-+** use of an 'a', 'b', or 'c' character at the beginning of each field
-+** guarantees that NULLs sort before numbers and that numbers sort
-+** before text.  0x00 characters do not occur except as separators
-+** between fields.
-+**
-+** See also: MakeIdxKey, SortMakeKey
-+*/
-+/* Opcode: MakeIdxKey P1 P2 P3
-+**
-+** Convert the top P1 entries of the stack into a single entry suitable
-+** for use as the key in an index.  In addition, take one additional integer
-+** off of the stack, treat that integer as a four-byte record number, and
-+** append the four bytes to the key.  Thus a total of P1+1 entries are
-+** popped from the stack for this instruction and a single entry is pushed
-+** back.  The first P1 entries that are popped are strings and the last
-+** entry (the lowest on the stack) is an integer record number.
-+**
-+** The converstion of the first P1 string entries occurs just like in
-+** MakeKey.  Each entry is separated from the others by a null.
-+** The entire concatenation is null-terminated.  The lowest entry
-+** in the stack is the first field and the top of the stack becomes the
-+** last.
-+**
-+** If P2 is not zero and one or more of the P1 entries that go into the
-+** generated key is NULL, then jump to P2 after the new key has been
-+** pushed on the stack.  In other words, jump to P2 if the key is
-+** guaranteed to be unique.  This jump can be used to skip a subsequent
-+** uniqueness test.
-+**
-+** P3 is a string that is P1 characters long.  Each character is either
-+** an 'n' or a 't' to indicates if the argument should be numeric or
-+** text.  The first character corresponds to the lowest element on the
-+** stack.  If P3 is null then all arguments are assumed to be numeric.
-+**
-+** See also:  MakeKey, SortMakeKey
-+*/
-+case OP_MakeIdxKey:
-+case OP_MakeKey: {
-+  char *zNewKey;
-+  int nByte;
-+  int nField;
-+  int addRowid;
-+  int i, j;
-+  int containsNull = 0;
-+  Mem *pRec;
-+  char zTemp[NBFS];
-+
-+  addRowid = pOp->opcode==OP_MakeIdxKey;
-+  nField = pOp->p1;
-+  pRec = &pTos[1-nField];
-+  assert( pRec>=p->aStack );
-+  nByte = 0;
-+  for(j=0, i=0; i<nField; i++, j++, pRec++){
-+    int flags = pRec->flags;
-+    int len;
-+    char *z;
-+    if( flags & MEM_Null ){
-+      nByte += 2;
-+      containsNull = 1;
-+    }else if( pOp->p3 && pOp->p3[j]=='t' ){
-+      Stringify(pRec);
-+      pRec->flags &= ~(MEM_Int|MEM_Real);
-+      nByte += pRec->n+1;
-+    }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
-+      if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
-+        pRec->r = pRec->i;
-+      }else if( (flags & (MEM_Real|MEM_Int))==0 ){
-+        pRec->r = sqliteAtoF(pRec->z, 0);
-+      }
-+      Release(pRec);
-+      z = pRec->zShort;
-+      sqliteRealToSortable(pRec->r, z);
-+      len = strlen(z);
-+      pRec->z = 0;
-+      pRec->flags = MEM_Real;
-+      pRec->n = len+1;
-+      nByte += pRec->n+1;
-+    }else{
-+      nByte += pRec->n+1;
-+    }
-+  }
-+  if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
-+    rc = SQLITE_TOOBIG;
-+    goto abort_due_to_error;
-+  }
-+  if( addRowid ) nByte += sizeof(u32);
-+  if( nByte<=NBFS ){
-+    zNewKey = zTemp;
-+  }else{
-+    zNewKey = sqliteMallocRaw( nByte );
-+    if( zNewKey==0 ) goto no_mem;
-+  }
-+  j = 0;
-+  pRec = &pTos[1-nField];
-+  for(i=0; i<nField; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      zNewKey[j++] = 'a';
-+      zNewKey[j++] = 0;
-+    }else if( pRec->flags==MEM_Real ){
-+      zNewKey[j++] = 'b';
-+      memcpy(&zNewKey[j], pRec->zShort, pRec->n);
-+      j += pRec->n;
-+    }else{
-+      assert( pRec->flags & MEM_Str );
-+      zNewKey[j++] = 'c';
-+      memcpy(&zNewKey[j], pRec->z, pRec->n);
-+      j += pRec->n;
-+    }
-+  }
-+  if( addRowid ){
-+    u32 iKey;
-+    pRec = &pTos[-nField];
-+    assert( pRec>=p->aStack );
-+    Integerify(pRec);
-+    iKey = intToKey(pRec->i);
-+    memcpy(&zNewKey[j], &iKey, sizeof(u32));
-+    popStack(&pTos, nField+1);
-+    if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
-+  }else{
-+    if( pOp->p2==0 ) popStack(&pTos, nField);
-+  }
-+  pTos++;
-+  pTos->n = nByte;
-+  if( nByte<=NBFS ){
-+    assert( zNewKey==zTemp );
-+    pTos->z = pTos->zShort;
-+    memcpy(pTos->zShort, zTemp, nByte);
-+    pTos->flags = MEM_Str | MEM_Short;
-+  }else{
-+    pTos->z = zNewKey;
-+    pTos->flags = MEM_Str | MEM_Dyn;
-+  }
-+  break;
-+}
-+
-+/* Opcode: IncrKey * * *
-+**
-+** The top of the stack should contain an index key generated by
-+** The MakeKey opcode.  This routine increases the least significant
-+** byte of that key by one.  This is used so that the MoveTo opcode
-+** will move to the first entry greater than the key rather than to
-+** the key itself.
-+*/
-+case OP_IncrKey: {
-+  assert( pTos>=p->aStack );
-+  /* The IncrKey opcode is only applied to keys generated by
-+  ** MakeKey or MakeIdxKey and the results of those operands
-+  ** are always dynamic strings or zShort[] strings.  So we
-+  ** are always free to modify the string in place.
-+  */
-+  assert( pTos->flags & (MEM_Dyn|MEM_Short) );
-+  pTos->z[pTos->n-1]++;
-+  break;
-+}
-+
-+/* Opcode: Checkpoint P1 * *
-+**
-+** Begin a checkpoint.  A checkpoint is the beginning of a operation that
-+** is part of a larger transaction but which might need to be rolled back
-+** itself without effecting the containing transaction.  A checkpoint will
-+** be automatically committed or rollback when the VDBE halts.
-+**
-+** The checkpoint is begun on the database file with index P1.  The main
-+** database file has an index of 0 and the file used for temporary tables
-+** has an index of 1.
-+*/
-+case OP_Checkpoint: {
-+  int i = pOp->p1;
-+  if( i>=0 && i<db->nDb && db->aDb[i].pBt && db->aDb[i].inTrans==1 ){
-+    rc = sqliteBtreeBeginCkpt(db->aDb[i].pBt);
-+    if( rc==SQLITE_OK ) db->aDb[i].inTrans = 2;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Transaction P1 * *
-+**
-+** 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.
-+**
-+** A write lock is obtained on the database file when a transaction is
-+** started.  No other process can read or write the file while the
-+** transaction is underway.  Starting a transaction also creates a
-+** rollback journal.  A transaction must be started before any changes
-+** can be made to the database.
-+*/
-+case OP_Transaction: {
-+  int busy = 1;
-+  int i = pOp->p1;
-+  assert( i>=0 && i<db->nDb );
-+  if( db->aDb[i].inTrans ) break;
-+  while( db->aDb[i].pBt!=0 && busy ){
-+    rc = sqliteBtreeBeginTrans(db->aDb[i].pBt);
-+    switch( rc ){
-+      case SQLITE_BUSY: {
-+        if( db->xBusyCallback==0 ){
-+          p->pc = pc;
-+          p->undoTransOnError = 1;
-+          p->rc = SQLITE_BUSY;
-+          p->pTos = pTos;
-+          return SQLITE_BUSY;
-+        }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
-+          sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
-+          busy = 0;
-+        }
-+        break;
-+      }
-+      case SQLITE_READONLY: {
-+        rc = SQLITE_OK;
-+        /* Fall thru into the next case */
-+      }
-+      case SQLITE_OK: {
-+        p->inTempTrans = 0;
-+        busy = 0;
-+        break;
-+      }
-+      default: {
-+        goto abort_due_to_error;
-+      }
-+    }
-+  }
-+  db->aDb[i].inTrans = 1;
-+  p->undoTransOnError = 1;
-+  break;
-+}
-+
-+/* Opcode: Commit * * *
-+**
-+** Cause all modifications to the database that have been made since the
-+** last Transaction to actually take effect.  No additional modifications
-+** are allowed until another transaction is started.  The Commit instruction
-+** deletes the journal file and releases the write lock on the database.
-+** A read lock continues to be held if there are still cursors open.
-+*/
-+case OP_Commit: {
-+  int i;
-+  if( db->xCommitCallback!=0 ){
-+    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
-+    if( db->xCommitCallback(db->pCommitArg)!=0 ){
-+      rc = SQLITE_CONSTRAINT;
-+    }
-+    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
-+  }
-+  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
-+    if( db->aDb[i].inTrans ){
-+      rc = sqliteBtreeCommit(db->aDb[i].pBt);
-+      db->aDb[i].inTrans = 0;
-+    }
-+  }
-+  if( rc==SQLITE_OK ){
-+    sqliteCommitInternalChanges(db);
-+  }else{
-+    sqliteRollbackAll(db);
-+  }
-+  break;
-+}
-+
-+/* Opcode: Rollback P1 * *
-+**
-+** Cause all modifications to the database that have been made since the
-+** last Transaction to be undone. The database is restored to its state
-+** before the Transaction opcode was executed.  No additional modifications
-+** are allowed until another transaction is started.
-+**
-+** P1 is the index of the database file that is committed.  An index of 0
-+** is used for the main database and an index of 1 is used for the file used
-+** to hold temporary tables.
-+**
-+** This instruction automatically closes all cursors and releases both
-+** the read and write locks on the indicated database.
-+*/
-+case OP_Rollback: {
-+  sqliteRollbackAll(db);
-+  break;
-+}
-+
-+/* Opcode: ReadCookie P1 P2 *
-+**
-+** Read cookie number P2 from database P1 and push it onto the stack.
-+** P2==0 is the schema version.  P2==1 is the database format.
-+** P2==2 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: {
-+  int aMeta[SQLITE_N_BTREE_META];
-+  assert( pOp->p2<SQLITE_N_BTREE_META );
-+  assert( pOp->p1>=0 && pOp->p1<db->nDb );
-+  assert( db->aDb[pOp->p1].pBt!=0 );
-+  rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
-+  pTos++;
-+  pTos->i = aMeta[1+pOp->p2];
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: SetCookie P1 P2 *
-+**
-+** Write the top of the stack into cookie number P2 of database P1.
-+** P2==0 is the schema version.  P2==1 is the database format.
-+** P2==2 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: {
-+  int aMeta[SQLITE_N_BTREE_META];
-+  assert( pOp->p2<SQLITE_N_BTREE_META );
-+  assert( pOp->p1>=0 && pOp->p1<db->nDb );
-+  assert( db->aDb[pOp->p1].pBt!=0 );
-+  assert( pTos>=p->aStack );
-+  Integerify(pTos)
-+  rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
-+  if( rc==SQLITE_OK ){
-+    aMeta[1+pOp->p2] = pTos->i;
-+    rc = sqliteBtreeUpdateMeta(db->aDb[pOp->p1].pBt, aMeta);
-+  }
-+  Release(pTos);
-+  pTos--;
-+  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: {
-+  int aMeta[SQLITE_N_BTREE_META];
-+  assert( pOp->p1>=0 && pOp->p1<db->nDb );
-+  rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
-+  if( rc==SQLITE_OK && aMeta[1]!=pOp->p2 ){
-+    sqliteSetString(&p->zErrMsg, "database schema has changed", (char*)0);
-+    rc = SQLITE_SCHEMA;
-+  }
-+  break;
-+}
-+
-+/* Opcode: OpenRead P1 P2 P3
-+**
-+** Open a read-only cursor for the database table whose root page is
-+** P2 in a database file.  The database file is determined by an 
-+** integer from the top of the stack.  0 means the main database and
-+** 1 means the database used for temporary tables.  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 P2==0 then take the root page number from the next of the stack.
-+**
-+** 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 P3 value is the name of the table or index being opened.
-+** The P3 value is not actually used by this opcode and may be
-+** omitted.  But the code generator usually inserts the index or
-+** table name into P3 to make the code easier to read.
-+**
-+** See also OpenWrite.
-+*/
-+/* Opcode: OpenWrite P1 P2 P3
-+**
-+** Open a read/write cursor named P1 on the table or index whose root
-+** page is P2.  If P2==0 then take the root page number from the stack.
-+**
-+** The P3 value is the name of the table or index being opened.
-+** The P3 value is not actually used by this opcode and may be
-+** omitted.  But the code generator usually inserts the index or
-+** table name into P3 to make the code easier to read.
-+**
-+** 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: {
-+  int busy = 0;
-+  int i = pOp->p1;
-+  int p2 = pOp->p2;
-+  int wrFlag;
-+  Btree *pX;
-+  int iDb;
-+  
-+  assert( pTos>=p->aStack );
-+  Integerify(pTos);
-+  iDb = pTos->i;
-+  pTos--;
-+  assert( iDb>=0 && iDb<db->nDb );
-+  pX = db->aDb[iDb].pBt;
-+  assert( pX!=0 );
-+  wrFlag = pOp->opcode==OP_OpenWrite;
-+  if( p2<=0 ){
-+    assert( pTos>=p->aStack );
-+    Integerify(pTos);
-+    p2 = pTos->i;
-+    pTos--;
-+    if( p2<2 ){
-+      sqliteSetString(&p->zErrMsg, "root page number less than 2", (char*)0);
-+      rc = SQLITE_INTERNAL;
-+      break;
-+    }
-+  }
-+  assert( i>=0 );
-+  if( expandCursorArraySize(p, i) ) goto no_mem;
-+  sqliteVdbeCleanupCursor(&p->aCsr[i]);
-+  memset(&p->aCsr[i], 0, sizeof(Cursor));
-+  p->aCsr[i].nullRow = 1;
-+  if( pX==0 ) break;
-+  do{
-+    rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
-+    switch( rc ){
-+      case SQLITE_BUSY: {
-+        if( db->xBusyCallback==0 ){
-+          p->pc = pc;
-+          p->rc = SQLITE_BUSY;
-+          p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
-+          return SQLITE_BUSY;
-+        }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
-+          sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
-+          busy = 0;
-+        }
-+        break;
-+      }
-+      case SQLITE_OK: {
-+        busy = 0;
-+        break;
-+      }
-+      default: {
-+        goto abort_due_to_error;
-+      }
-+    }
-+  }while( busy );
-+  break;
-+}
-+
-+/* Opcode: OpenTemp P1 P2 *
-+**
-+** Open a new cursor to a transient table.
-+** The transient cursor is always opened read/write even if 
-+** the main database is read-only.  The transient table is deleted
-+** automatically when the cursor is closed.
-+**
-+** The cursor points to a BTree table if P2==0 and to a BTree index
-+** if P2==1.  A BTree table must have an integer key and can have arbitrary
-+** data.  A BTree index has no data but can have an arbitrary key.
-+**
-+** This opcode is used for tables that exist for the duration of a single
-+** SQL statement only.  Tables created using CREATE TEMPORARY TABLE
-+** are opened using OP_OpenRead or OP_OpenWrite.  "Temporary" in the
-+** context of this opcode means for the duration of a single SQL statement
-+** whereas "Temporary" in the context of CREATE TABLE means for the duration
-+** of the connection to the database.  Same word; different meanings.
-+*/
-+case OP_OpenTemp: {
-+  int i = pOp->p1;
-+  Cursor *pCx;
-+  assert( i>=0 );
-+  if( expandCursorArraySize(p, i) ) goto no_mem;
-+  pCx = &p->aCsr[i];
-+  sqliteVdbeCleanupCursor(pCx);
-+  memset(pCx, 0, sizeof(*pCx));
-+  pCx->nullRow = 1;
-+  rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
-+
-+  if( rc==SQLITE_OK ){
-+    rc = sqliteBtreeBeginTrans(pCx->pBt);
-+  }
-+  if( rc==SQLITE_OK ){
-+    if( pOp->p2 ){
-+      int pgno;
-+      rc = sqliteBtreeCreateIndex(pCx->pBt, &pgno);
-+      if( rc==SQLITE_OK ){
-+        rc = sqliteBtreeCursor(pCx->pBt, pgno, 1, &pCx->pCursor);
-+      }
-+    }else{
-+      rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor);
-+    }
-+  }
-+  break;
-+}
-+
-+/* Opcode: OpenPseudo P1 * *
-+**
-+** Open a new cursor that points to a fake table that contains a single
-+** row of data.  Any attempt to write a second row of data causes the
-+** first row to be deleted.  All data is deleted when the cursor is
-+** closed.
-+**
-+** A pseudo-table created by this opcode is useful for holding the
-+** NEW or OLD tables in a trigger.
-+*/
-+case OP_OpenPseudo: {
-+  int i = pOp->p1;
-+  Cursor *pCx;
-+  assert( i>=0 );
-+  if( expandCursorArraySize(p, i) ) goto no_mem;
-+  pCx = &p->aCsr[i];
-+  sqliteVdbeCleanupCursor(pCx);
-+  memset(pCx, 0, sizeof(*pCx));
-+  pCx->nullRow = 1;
-+  pCx->pseudoTable = 1;
-+  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: {
-+  int i = pOp->p1;
-+  if( i>=0 && i<p->nCursor ){
-+    sqliteVdbeCleanupCursor(&p->aCsr[i]);
-+  }
-+  break;
-+}
-+
-+/* Opcode: MoveTo P1 P2 *
-+**
-+** Pop the top of the stack and use its value as a key.  Reposition
-+** cursor P1 so that it points to an entry with a matching key.  If
-+** the table contains no record with a matching key, then the cursor
-+** is left pointing at the first record that is greater than the key.
-+** If there are no records greater than the key and P2 is not zero,
-+** then an immediate jump to P2 is made.
-+**
-+** See also: Found, NotFound, Distinct, MoveLt
-+*/
-+/* Opcode: MoveLt P1 P2 *
-+**
-+** Pop the top of the stack and use its value as a key.  Reposition
-+** cursor P1 so that it points to the entry with the largest key that is
-+** less than the key popped from the stack.
-+** If there are no records less than than the key and P2
-+** is not zero then an immediate jump to P2 is made.
-+**
-+** See also: MoveTo
-+*/
-+case OP_MoveLt:
-+case OP_MoveTo: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+
-+  assert( pTos>=p->aStack );
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  if( pC->pCursor!=0 ){
-+    int res, oc;
-+    pC->nullRow = 0;
-+    if( pTos->flags & MEM_Int ){
-+      int iKey = intToKey(pTos->i);
-+      if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
-+        pC->movetoTarget = iKey;
-+        pC->deferredMoveto = 1;
-+        Release(pTos);
-+        pTos--;
-+        break;
-+      }
-+      sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
-+      pC->lastRecno = pTos->i;
-+      pC->recnoIsValid = res==0;
-+    }else{
-+      Stringify(pTos);
-+      sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
-+      pC->recnoIsValid = 0;
-+    }
-+    pC->deferredMoveto = 0;
-+    sqlite_search_count++;
-+    oc = pOp->opcode;
-+    if( oc==OP_MoveTo && res<0 ){
-+      sqliteBtreeNext(pC->pCursor, &res);
-+      pC->recnoIsValid = 0;
-+      if( res && pOp->p2>0 ){
-+        pc = pOp->p2 - 1;
-+      }
-+    }else if( oc==OP_MoveLt ){
-+      if( res>=0 ){
-+        sqliteBtreePrevious(pC->pCursor, &res);
-+        pC->recnoIsValid = 0;
-+      }else{
-+        /* res might be negative because the table is empty.  Check to
-+        ** see if this is the case.
-+        */
-+        int keysize;
-+        res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
-+      }
-+      if( res && pOp->p2>0 ){
-+        pc = pOp->p2 - 1;
-+      }
-+    }
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: Distinct P1 P2 *
-+**
-+** Use the top of the stack as a string key.  If a record with that key does
-+** not exist in the table of cursor P1, then jump to P2.  If the record
-+** does already exist, then fall thru.  The cursor is left pointing
-+** at the record if it exists. The key is not popped from the stack.
-+**
-+** This operation is similar to NotFound except that this operation
-+** does not pop the key from the stack.
-+**
-+** See also: Found, NotFound, MoveTo, IsUnique, NotExists
-+*/
-+/* Opcode: Found P1 P2 *
-+**
-+** Use the top of the stack as a string key.  If a record with that key
-+** does exist in table of P1, then jump to P2.  If the record
-+** does not exist, then fall thru.  The cursor is left pointing
-+** to the record if it exists.  The key is popped from the stack.
-+**
-+** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
-+*/
-+/* Opcode: NotFound P1 P2 *
-+**
-+** Use the top of the stack as a string 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 key is popped from the stack.
-+**
-+** The difference between this operation and Distinct is that
-+** Distinct does not pop the key from the stack.
-+**
-+** See also: Distinct, Found, MoveTo, NotExists, IsUnique
-+*/
-+case OP_Distinct:
-+case OP_NotFound:
-+case OP_Found: {
-+  int i = pOp->p1;
-+  int alreadyExists = 0;
-+  Cursor *pC;
-+  assert( pTos>=p->aStack );
-+  assert( i>=0 && i<p->nCursor );
-+  if( (pC = &p->aCsr[i])->pCursor!=0 ){
-+    int res, rx;
-+    Stringify(pTos);
-+    rx = sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
-+    alreadyExists = rx==SQLITE_OK && res==0;
-+    pC->deferredMoveto = 0;
-+  }
-+  if( pOp->opcode==OP_Found ){
-+    if( alreadyExists ) pc = pOp->p2 - 1;
-+  }else{
-+    if( !alreadyExists ) pc = pOp->p2 - 1;
-+  }
-+  if( pOp->opcode!=OP_Distinct ){
-+    Release(pTos);
-+    pTos--;
-+  }
-+  break;
-+}
-+
-+/* Opcode: IsUnique P1 P2 *
-+**
-+** The top of the stack is an integer record number.  Call this
-+** record number R.  The next on the stack is an index key created
-+** using MakeIdxKey.  Call it K.  This instruction pops R from the
-+** stack but it leaves K unchanged.
-+**
-+** P1 is an index.  So all but the last four bytes of K are an
-+** index string.  The last four bytes of K are a record number.
-+**
-+** This instruction asks if there is an entry in P1 where the
-+** index string matches K but the record number is different
-+** from R.  If there is no such entry, then there is an immediate
-+** jump to P2.  If any entry does exist where the index string
-+** matches K but the record number is not R, then the record
-+** number for that entry is pushed onto the stack and control
-+** falls through to the next instruction.
-+**
-+** See also: Distinct, NotFound, NotExists, Found
-+*/
-+case OP_IsUnique: {
-+  int i = pOp->p1;
-+  Mem *pNos = &pTos[-1];
-+  BtCursor *pCrsr;
-+  int R;
-+
-+  /* Pop the value R off the top of the stack
-+  */
-+  assert( pNos>=p->aStack );
-+  Integerify(pTos);
-+  R = pTos->i;
-+  pTos--;
-+  assert( i>=0 && i<=p->nCursor );
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int res, rc;
-+    int v;         /* The record number on the P1 entry that matches K */
-+    char *zKey;    /* The value of K */
-+    int nKey;      /* Number of bytes in K */
-+
-+    /* Make sure K is a string and make zKey point to K
-+    */
-+    Stringify(pNos);
-+    zKey = pNos->z;
-+    nKey = pNos->n;
-+    assert( nKey >= 4 );
-+
-+    /* Search for an entry in P1 where all but the last four bytes match K.
-+    ** If there is no such entry, jump immediately to P2.
-+    */
-+    assert( p->aCsr[i].deferredMoveto==0 );
-+    rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
-+    if( rc!=SQLITE_OK ) goto abort_due_to_error;
-+    if( res<0 ){
-+      rc = sqliteBtreeNext(pCrsr, &res);
-+      if( res ){
-+        pc = pOp->p2 - 1;
-+        break;
-+      }
-+    }
-+    rc = sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res);
-+    if( rc!=SQLITE_OK ) goto abort_due_to_error;
-+    if( res>0 ){
-+      pc = pOp->p2 - 1;
-+      break;
-+    }
-+
-+    /* At this point, pCrsr is pointing to an entry in P1 where all but
-+    ** the last for bytes of the key match K.  Check to see if the last
-+    ** four bytes of the key are different from R.  If the last four
-+    ** bytes equal R then jump immediately to P2.
-+    */
-+    sqliteBtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
-+    v = keyToInt(v);
-+    if( v==R ){
-+      pc = pOp->p2 - 1;
-+      break;
-+    }
-+
-+    /* The last four bytes of the key are different from R.  Convert the
-+    ** last four bytes of the key into an integer and push it onto the
-+    ** stack.  (These bytes are the record number of an entry that
-+    ** violates a UNIQUE constraint.)
-+    */
-+    pTos++;
-+    pTos->i = v;
-+    pTos->flags = MEM_Int;
-+  }
-+  break;
-+}
-+
-+/* Opcode: NotExists P1 P2 *
-+**
-+** Use the top of the stack 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 integer key is popped from the stack.
-+**
-+** The difference between this operation and NotFound is that this
-+** operation assumes the key is an integer and NotFound assumes it
-+** is a string.
-+**
-+** See also: Distinct, Found, MoveTo, NotFound, IsUnique
-+*/
-+case OP_NotExists: {
-+  int i = pOp->p1;
-+  BtCursor *pCrsr;
-+  assert( pTos>=p->aStack );
-+  assert( i>=0 && i<p->nCursor );
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int res, rx, iKey;
-+    assert( pTos->flags & MEM_Int );
-+    iKey = intToKey(pTos->i);
-+    rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
-+    p->aCsr[i].lastRecno = pTos->i;
-+    p->aCsr[i].recnoIsValid = res==0;
-+    p->aCsr[i].nullRow = 0;
-+    if( rx!=SQLITE_OK || res!=0 ){
-+      pc = pOp->p2 - 1;
-+      p->aCsr[i].recnoIsValid = 0;
-+    }
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: NewRecno P1 * *
-+**
-+** Get a new integer record number 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 pushed 
-+** onto the stack.
-+*/
-+case OP_NewRecno: {
-+  int i = pOp->p1;
-+  int v = 0;
-+  Cursor *pC;
-+  assert( i>=0 && i<p->nCursor );
-+  if( (pC = &p->aCsr[i])->pCursor==0 ){
-+    v = 0;
-+  }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 1000 times.
-+    **
-+    ** For a table with less than 2 billion entries, the probability
-+    ** of not finding a unused rowid is about 1.0e-300.  This is a 
-+    ** non-zero probability, but it is still vanishingly small and should
-+    ** never cause a problem.  You are much, much more likely to have a
-+    ** hardware failure than for this algorithm to fail.
-+    **
-+    ** The analysis in the previous paragraph assumes that you have a good
-+    ** source of random numbers.  Is a library function like lrand48()
-+    ** good enough?  Maybe. Maybe not. It's hard to know whether there
-+    ** might be subtle bugs is some implementations of lrand48() that
-+    ** could cause problems. To avoid uncertainty, SQLite uses its own 
-+    ** random number generator based on the RC4 algorithm.
-+    **
-+    ** To promote locality of reference for repetitive inserts, the
-+    ** first few attempts at chosing a random rowid pick values just a little
-+    ** larger than the previous rowid.  This has been shown experimentally
-+    ** to double the speed of the COPY operation.
-+    */
-+    int res, rx, cnt, x;
-+    cnt = 0;
-+    if( !pC->useRandomRowid ){
-+      if( pC->nextRowidValid ){
-+        v = pC->nextRowid;
-+      }else{
-+        rx = sqliteBtreeLast(pC->pCursor, &res);
-+        if( res ){
-+          v = 1;
-+        }else{
-+          sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
-+          v = keyToInt(v);
-+          if( v==0x7fffffff ){
-+            pC->useRandomRowid = 1;
-+          }else{
-+            v++;
-+          }
-+        }
-+      }
-+      if( v<0x7fffffff ){
-+        pC->nextRowidValid = 1;
-+        pC->nextRowid = v+1;
-+      }else{
-+        pC->nextRowidValid = 0;
-+      }
-+    }
-+    if( pC->useRandomRowid ){
-+      v = db->priorNewRowid;
-+      cnt = 0;
-+      do{
-+        if( v==0 || cnt>2 ){
-+          sqliteRandomness(sizeof(v), &v);
-+          if( cnt<5 ) v &= 0xffffff;
-+        }else{
-+          unsigned char r;
-+          sqliteRandomness(1, &r);
-+          v += r + 1;
-+        }
-+        if( v==0 ) continue;
-+        x = intToKey(v);
-+        rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
-+        cnt++;
-+      }while( cnt<1000 && rx==SQLITE_OK && res==0 );
-+      db->priorNewRowid = v;
-+      if( rx==SQLITE_OK && res==0 ){
-+        rc = SQLITE_FULL;
-+        goto abort_due_to_error;
-+      }
-+    }
-+    pC->recnoIsValid = 0;
-+    pC->deferredMoveto = 0;
-+  }
-+  pTos++;
-+  pTos->i = v;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: PutIntKey P1 P2 *
-+**
-+** 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 on the top of the
-+** stack.  The key is the next value down on the stack.  The key must
-+** be an integer.  The stack is popped twice by this instruction.
-+**
-+** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-+** incremented (otherwise not).  If the OPFLAG_CSCHANGE flag is set,
-+** then the current statement change count is incremented (otherwise not).
-+** If the OPFLAG_LASTROWID flag of P2 is set, then rowid is
-+** stored for subsequent return by the sqlite_last_insert_rowid() function
-+** (otherwise it's unmodified).
-+*/
-+/* Opcode: PutStrKey P1 * *
-+**
-+** 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 on the top of the
-+** stack.  The key is the next value down on the stack.  The key must
-+** be a string.  The stack is popped twice by this instruction.
-+**
-+** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
-+*/
-+case OP_PutIntKey:
-+case OP_PutStrKey: {
-+  Mem *pNos = &pTos[-1];
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  assert( pNos>=p->aStack );
-+  assert( i>=0 && i<p->nCursor );
-+  if( ((pC = &p->aCsr[i])->pCursor!=0 || pC->pseudoTable) ){
-+    char *zKey;
-+    int nKey, iKey;
-+    if( pOp->opcode==OP_PutStrKey ){
-+      Stringify(pNos);
-+      nKey = pNos->n;
-+      zKey = pNos->z;
-+    }else{
-+      assert( pNos->flags & MEM_Int );
-+      nKey = sizeof(int);
-+      iKey = intToKey(pNos->i);
-+      zKey = (char*)&iKey;
-+      if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
-+      if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
-+      if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
-+      if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
-+        pC->nextRowidValid = 0;
-+      }
-+    }
-+    if( pTos->flags & MEM_Null ){
-+      pTos->z = 0;
-+      pTos->n = 0;
-+    }else{
-+      assert( pTos->flags & MEM_Str );
-+    }
-+    if( pC->pseudoTable ){
-+      /* PutStrKey does not work for pseudo-tables.
-+      ** The following assert makes sure we are not trying to use
-+      ** PutStrKey on a pseudo-table
-+      */
-+      assert( pOp->opcode==OP_PutIntKey );
-+      sqliteFree(pC->pData);
-+      pC->iKey = iKey;
-+      pC->nData = pTos->n;
-+      if( pTos->flags & MEM_Dyn ){
-+        pC->pData = pTos->z;
-+        pTos->flags = MEM_Null;
-+      }else{
-+        pC->pData = sqliteMallocRaw( pC->nData );
-+        if( pC->pData ){
-+          memcpy(pC->pData, pTos->z, pC->nData);
-+        }
-+      }
-+      pC->nullRow = 0;
-+    }else{
-+      rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
-+    }
-+    pC->recnoIsValid = 0;
-+    pC->deferredMoveto = 0;
-+  }
-+  popStack(&pTos, 2);
-+  break;
-+}
-+
-+/* Opcode: Delete P1 P2 *
-+**
-+** 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).  If OPFLAG_CSCHANGE flag is set,
-+** then the current statement change count is incremented (otherwise not).
-+**
-+** If P1 is a pseudo-table, then this instruction is a no-op.
-+*/
-+case OP_Delete: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  if( pC->pCursor!=0 ){
-+    sqliteVdbeCursorMoveto(pC);
-+    rc = sqliteBtreeDelete(pC->pCursor);
-+    pC->nextRowidValid = 0;
-+  }
-+  if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
-+  if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
-+  break;
-+}
-+
-+/* Opcode: SetCounts * * *
-+**
-+** Called at end of statement.  Updates lsChange (last statement change count)
-+** and resets csChange (current statement change count) to 0.
-+*/
-+case OP_SetCounts: {
-+  db->lsChange=db->csChange;
-+  db->csChange=0;
-+  break;
-+}
-+
-+/* Opcode: KeyAsData P1 P2 *
-+**
-+** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
-+** off (if P2==0).  In key-as-data mode, the OP_Column opcode pulls
-+** data off of the key rather than the data.  This is used for
-+** processing compound selects.
-+*/
-+case OP_KeyAsData: {
-+  int i = pOp->p1;
-+  assert( i>=0 && i<p->nCursor );
-+  p->aCsr[i].keyAsData = pOp->p2;
-+  break;
-+}
-+
-+/* Opcode: RowData P1 * *
-+**
-+** Push onto the stack the complete row data for cursor P1.
-+** There is no interpretation of the data.  It is just copied
-+** onto the stack exactly as it is found in the database file.
-+**
-+** If the cursor is not pointing to a valid row, a NULL is pushed
-+** onto the stack.
-+*/
-+/* Opcode: RowKey P1 * *
-+**
-+** Push onto the stack the complete row key for cursor P1.
-+** There is no interpretation of the key.  It is just copied
-+** onto the stack exactly as it is found in the database file.
-+**
-+** If the cursor is not pointing to a valid row, a NULL is pushed
-+** onto the stack.
-+*/
-+case OP_RowKey:
-+case OP_RowData: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  int n;
-+
-+  pTos++;
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  if( pC->nullRow ){
-+    pTos->flags = MEM_Null;
-+  }else if( pC->pCursor!=0 ){
-+    BtCursor *pCrsr = pC->pCursor;
-+    sqliteVdbeCursorMoveto(pC);
-+    if( pC->nullRow ){
-+      pTos->flags = MEM_Null;
-+      break;
-+    }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
-+      sqliteBtreeKeySize(pCrsr, &n);
-+    }else{
-+      sqliteBtreeDataSize(pCrsr, &n);
-+    }
-+    pTos->n = n;
-+    if( n<=NBFS ){
-+      pTos->flags = MEM_Str | MEM_Short;
-+      pTos->z = pTos->zShort;
-+    }else{
-+      char *z = sqliteMallocRaw( n );
-+      if( z==0 ) goto no_mem;
-+      pTos->flags = MEM_Str | MEM_Dyn;
-+      pTos->z = z;
-+    }
-+    if( pC->keyAsData || pOp->opcode==OP_RowKey ){
-+      sqliteBtreeKey(pCrsr, 0, n, pTos->z);
-+    }else{
-+      sqliteBtreeData(pCrsr, 0, n, pTos->z);
-+    }
-+  }else if( pC->pseudoTable ){
-+    pTos->n = pC->nData;
-+    pTos->z = pC->pData;
-+    pTos->flags = MEM_Str|MEM_Ephem;
-+  }else{
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Column P1 P2 *
-+**
-+** 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.)
-+** Push onto the stack the value of the P2-th column contained
-+** in the data.
-+**
-+** If the KeyAsData opcode has previously executed on this cursor,
-+** then the field might be extracted from the key rather than the
-+** data.
-+**
-+** If P1 is negative, then the record is stored on the stack rather
-+** than in a table.  For P1==-1, the top of the stack is used.
-+** For P1==-2, the next on the stack is used.  And so forth.  The
-+** value pushed is always just a pointer into the record which is
-+** stored further down on the stack.  The column value is not copied.
-+*/
-+case OP_Column: {
-+  int amt, offset, end, payloadSize;
-+  int i = pOp->p1;
-+  int p2 = pOp->p2;
-+  Cursor *pC;
-+  char *zRec;
-+  BtCursor *pCrsr;
-+  int idxWidth;
-+  unsigned char aHdr[10];
-+
-+  assert( i<p->nCursor );
-+  pTos++;
-+  if( i<0 ){
-+    assert( &pTos[i]>=p->aStack );
-+    assert( pTos[i].flags & MEM_Str );
-+    zRec = pTos[i].z;
-+    payloadSize = pTos[i].n;
-+  }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
-+    sqliteVdbeCursorMoveto(pC);
-+    zRec = 0;
-+    pCrsr = pC->pCursor;
-+    if( pC->nullRow ){
-+      payloadSize = 0;
-+    }else if( pC->keyAsData ){
-+      sqliteBtreeKeySize(pCrsr, &payloadSize);
-+    }else{
-+      sqliteBtreeDataSize(pCrsr, &payloadSize);
-+    }
-+  }else if( pC->pseudoTable ){
-+    payloadSize = pC->nData;
-+    zRec = pC->pData;
-+    assert( payloadSize==0 || zRec!=0 );
-+  }else{
-+    payloadSize = 0;
-+  }
-+
-+  /* Figure out how many bytes in the column data and where the column
-+  ** data begins.
-+  */
-+  if( payloadSize==0 ){
-+    pTos->flags = MEM_Null;
-+    break;
-+  }else if( payloadSize<256 ){
-+    idxWidth = 1;
-+  }else if( payloadSize<65536 ){
-+    idxWidth = 2;
-+  }else{
-+    idxWidth = 3;
-+  }
-+
-+  /* Figure out where the requested column is stored and how big it is.
-+  */
-+  if( payloadSize < idxWidth*(p2+1) ){
-+    rc = SQLITE_CORRUPT;
-+    goto abort_due_to_error;
-+  }
-+  if( zRec ){
-+    memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
-+  }else if( pC->keyAsData ){
-+    sqliteBtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
-+  }else{
-+    sqliteBtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
-+  }
-+  offset = aHdr[0];
-+  end = aHdr[idxWidth];
-+  if( idxWidth>1 ){
-+    offset |= aHdr[1]<<8;
-+    end |= aHdr[idxWidth+1]<<8;
-+    if( idxWidth>2 ){
-+      offset |= aHdr[2]<<16;
-+      end |= aHdr[idxWidth+2]<<16;
-+    }
-+  }
-+  amt = end - offset;
-+  if( amt<0 || offset<0 || end>payloadSize ){
-+    rc = SQLITE_CORRUPT;
-+    goto abort_due_to_error;
-+  }
-+
-+  /* amt and offset now hold the offset to the start of data and the
-+  ** amount of data.  Go get the data and put it on the stack.
-+  */
-+  pTos->n = amt;
-+  if( amt==0 ){
-+    pTos->flags = MEM_Null;
-+  }else if( zRec ){
-+    pTos->flags = MEM_Str | MEM_Ephem;
-+    pTos->z = &zRec[offset];
-+  }else{
-+    if( amt<=NBFS ){
-+      pTos->flags = MEM_Str | MEM_Short;
-+      pTos->z = pTos->zShort;
-+    }else{
-+      char *z = sqliteMallocRaw( amt );
-+      if( z==0 ) goto no_mem;
-+      pTos->flags = MEM_Str | MEM_Dyn;
-+      pTos->z = z;
-+    }
-+    if( pC->keyAsData ){
-+      sqliteBtreeKey(pCrsr, offset, amt, pTos->z);
-+    }else{
-+      sqliteBtreeData(pCrsr, offset, amt, pTos->z);
-+    }
-+  }
-+  break;
-+}
-+
-+/* Opcode: Recno P1 * *
-+**
-+** Push onto the stack an integer which is the first 4 bytes of the
-+** the key to the current entry in a sequential scan of the database
-+** file P1.  The sequential scan should have been started using the 
-+** Next opcode.
-+*/
-+case OP_Recno: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  int v;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  sqliteVdbeCursorMoveto(pC);
-+  pTos++;
-+  if( pC->recnoIsValid ){
-+    v = pC->lastRecno;
-+  }else if( pC->pseudoTable ){
-+    v = keyToInt(pC->iKey);
-+  }else if( pC->nullRow || pC->pCursor==0 ){
-+    pTos->flags = MEM_Null;
-+    break;
-+  }else{
-+    assert( pC->pCursor!=0 );
-+    sqliteBtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
-+    v = keyToInt(v);
-+  }
-+  pTos->i = v;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: FullKey P1 * *
-+**
-+** Extract the complete key from the record that cursor P1 is currently
-+** pointing to and push the key onto the stack as a string.
-+**
-+** Compare this opcode to Recno.  The Recno opcode extracts the first
-+** 4 bytes of the key and pushes those bytes onto the stack as an
-+** integer.  This instruction pushes the entire key as a string.
-+**
-+** This opcode may not be used on a pseudo-table.
-+*/
-+case OP_FullKey: {
-+  int i = pOp->p1;
-+  BtCursor *pCrsr;
-+
-+  assert( p->aCsr[i].keyAsData );
-+  assert( !p->aCsr[i].pseudoTable );
-+  assert( i>=0 && i<p->nCursor );
-+  pTos++;
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int amt;
-+    char *z;
-+
-+    sqliteVdbeCursorMoveto(&p->aCsr[i]);
-+    sqliteBtreeKeySize(pCrsr, &amt);
-+    if( amt<=0 ){
-+      rc = SQLITE_CORRUPT;
-+      goto abort_due_to_error;
-+    }
-+    if( amt>NBFS ){
-+      z = sqliteMallocRaw( amt );
-+      if( z==0 ) goto no_mem;
-+      pTos->flags = MEM_Str | MEM_Dyn;
-+    }else{
-+      z = pTos->zShort;
-+      pTos->flags = MEM_Str | MEM_Short;
-+    }
-+    sqliteBtreeKey(pCrsr, 0, amt, z);
-+    pTos->z = z;
-+    pTos->n = amt;
-+  }
-+  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 push 
-+** a NULL onto the stack.
-+*/
-+case OP_NullRow: {
-+  int i = pOp->p1;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  p->aCsr[i].nullRow = 1;
-+  p->aCsr[i].recnoIsValid = 0;
-+  break;
-+}
-+
-+/* Opcode: Last P1 P2 *
-+**
-+** The next use of the Recno 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: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  BtCursor *pCrsr;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  if( (pCrsr = pC->pCursor)!=0 ){
-+    int res;
-+    rc = sqliteBtreeLast(pCrsr, &res);
-+    pC->nullRow = res;
-+    pC->deferredMoveto = 0;
-+    if( res && pOp->p2>0 ){
-+      pc = pOp->p2 - 1;
-+    }
-+  }else{
-+    pC->nullRow = 0;
-+  }
-+  break;
-+}
-+
-+/* Opcode: Rewind P1 P2 *
-+**
-+** The next use of the Recno 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: {
-+  int i = pOp->p1;
-+  Cursor *pC;
-+  BtCursor *pCrsr;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  pC = &p->aCsr[i];
-+  if( (pCrsr = pC->pCursor)!=0 ){
-+    int res;
-+    rc = sqliteBtreeFirst(pCrsr, &res);
-+    pC->atFirst = res==0;
-+    pC->nullRow = res;
-+    pC->deferredMoveto = 0;
-+    if( res && pOp->p2>0 ){
-+      pc = pOp->p2 - 1;
-+    }
-+  }else{
-+    pC->nullRow = 0;
-+  }
-+  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.
-+**
-+** 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.
-+*/
-+case OP_Prev:
-+case OP_Next: {
-+  Cursor *pC;
-+  BtCursor *pCrsr;
-+
-+  CHECK_FOR_INTERRUPT;
-+  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-+  pC = &p->aCsr[pOp->p1];
-+  if( (pCrsr = pC->pCursor)!=0 ){
-+    int res;
-+    if( pC->nullRow ){
-+      res = 1;
-+    }else{
-+      assert( pC->deferredMoveto==0 );
-+      rc = pOp->opcode==OP_Next ? sqliteBtreeNext(pCrsr, &res) :
-+                                  sqliteBtreePrevious(pCrsr, &res);
-+      pC->nullRow = res;
-+    }
-+    if( res==0 ){
-+      pc = pOp->p2 - 1;
-+      sqlite_search_count++;
-+    }
-+  }else{
-+    pC->nullRow = 1;
-+  }
-+  pC->recnoIsValid = 0;
-+  break;
-+}
-+
-+/* Opcode: IdxPut P1 P2 P3
-+**
-+** The top of the stack holds a SQL index key made using the
-+** MakeIdxKey instruction.  This opcode writes that key into the
-+** index P1.  Data for the entry is nil.
-+**
-+** If P2==1, then the key must be unique.  If the key is not unique,
-+** the program aborts with a SQLITE_CONSTRAINT error and the database
-+** is rolled back.  If P3 is not null, then it becomes part of the
-+** error message returned with the SQLITE_CONSTRAINT.
-+*/
-+case OP_IdxPut: {
-+  int i = pOp->p1;
-+  BtCursor *pCrsr;
-+  assert( pTos>=p->aStack );
-+  assert( i>=0 && i<p->nCursor );
-+  assert( pTos->flags & MEM_Str );
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int nKey = pTos->n;
-+    const char *zKey = pTos->z;
-+    if( pOp->p2 ){
-+      int res, n;
-+      assert( nKey >= 4 );
-+      rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
-+      if( rc!=SQLITE_OK ) goto abort_due_to_error;
-+      while( res!=0 ){
-+        int c;
-+        sqliteBtreeKeySize(pCrsr, &n);
-+        if( n==nKey
-+           && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
-+           && c==0
-+        ){
-+          rc = SQLITE_CONSTRAINT;
-+          if( pOp->p3 && pOp->p3[0] ){
-+            sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
-+          }
-+          goto abort_due_to_error;
-+        }
-+        if( res<0 ){
-+          sqliteBtreeNext(pCrsr, &res);
-+          res = +1;
-+        }else{
-+          break;
-+        }
-+      }
-+    }
-+    rc = sqliteBtreeInsert(pCrsr, zKey, nKey, "", 0);
-+    assert( p->aCsr[i].deferredMoveto==0 );
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: IdxDelete P1 * *
-+**
-+** The top of the stack is an index key built using the MakeIdxKey opcode.
-+** This opcode removes that entry from the index.
-+*/
-+case OP_IdxDelete: {
-+  int i = pOp->p1;
-+  BtCursor *pCrsr;
-+  assert( pTos>=p->aStack );
-+  assert( pTos->flags & MEM_Str );
-+  assert( i>=0 && i<p->nCursor );
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int rx, res;
-+    rx = sqliteBtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
-+    if( rx==SQLITE_OK && res==0 ){
-+      rc = sqliteBtreeDelete(pCrsr);
-+    }
-+    assert( p->aCsr[i].deferredMoveto==0 );
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: IdxRecno P1 * *
-+**
-+** Push onto the stack an integer which is the last 4 bytes of the
-+** the key to the current entry in index P1.  These 4 bytes should
-+** be the record number of the table entry to which this index entry
-+** points.
-+**
-+** See also: Recno, MakeIdxKey.
-+*/
-+case OP_IdxRecno: {
-+  int i = pOp->p1;
-+  BtCursor *pCrsr;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  pTos++;
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int v;
-+    int sz;
-+    assert( p->aCsr[i].deferredMoveto==0 );
-+    sqliteBtreeKeySize(pCrsr, &sz);
-+    if( sz<sizeof(u32) ){
-+      pTos->flags = MEM_Null;
-+    }else{
-+      sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
-+      v = keyToInt(v);
-+      pTos->i = v;
-+      pTos->flags = MEM_Int;
-+    }
-+  }else{
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: IdxGT P1 P2 *
-+**
-+** Compare the top of the stack against the key on the index entry that
-+** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
-+** index entry.  If the index entry is greater than the top of the stack
-+** then jump to P2.  Otherwise fall through to the next instruction.
-+** In either case, the stack is popped once.
-+*/
-+/* Opcode: IdxGE P1 P2 *
-+**
-+** Compare the top of the stack against the key on the index entry that
-+** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
-+** index entry.  If the index entry is greater than or equal to 
-+** the top of the stack
-+** then jump to P2.  Otherwise fall through to the next instruction.
-+** In either case, the stack is popped once.
-+*/
-+/* Opcode: IdxLT P1 P2 *
-+**
-+** Compare the top of the stack against the key on the index entry that
-+** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
-+** index entry.  If the index entry is less than the top of the stack
-+** then jump to P2.  Otherwise fall through to the next instruction.
-+** In either case, the stack is popped once.
-+*/
-+case OP_IdxLT:
-+case OP_IdxGT:
-+case OP_IdxGE: {
-+  int i= pOp->p1;
-+  BtCursor *pCrsr;
-+
-+  assert( i>=0 && i<p->nCursor );
-+  assert( pTos>=p->aStack );
-+  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
-+    int res, rc;
-+ 
-+    Stringify(pTos);
-+    assert( p->aCsr[i].deferredMoveto==0 );
-+    rc = sqliteBtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
-+    if( rc!=SQLITE_OK ){
-+      break;
-+    }
-+    if( pOp->opcode==OP_IdxLT ){
-+      res = -res;
-+    }else if( pOp->opcode==OP_IdxGE ){
-+      res++;
-+    }
-+    if( res>0 ){
-+      pc = pOp->p2 - 1 ;
-+    }
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: IdxIsNull P1 P2 *
-+**
-+** The top of the stack contains an index entry such as might be generated
-+** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
-+** that key.  If any of the first P1 fields are NULL, then a jump is made
-+** to address P2.  Otherwise we fall straight through.
-+**
-+** The index entry is always popped from the stack.
-+*/
-+case OP_IdxIsNull: {
-+  int i = pOp->p1;
-+  int k, n;
-+  const char *z;
-+
-+  assert( pTos>=p->aStack );
-+  assert( pTos->flags & MEM_Str );
-+  z = pTos->z;
-+  n = pTos->n;
-+  for(k=0; k<n && i>0; i--){
-+    if( z[k]=='a' ){
-+      pc = pOp->p2-1;
-+      break;
-+    }
-+    while( k<n && z[k] ){ k++; }
-+    k++;
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: Destroy P1 P2 *
-+**
-+** 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 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.
-+**
-+** See also: Clear
-+*/
-+case OP_Destroy: {
-+  rc = sqliteBtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1);
-+  break;
-+}
-+
-+/* Opcode: Clear P1 P2 *
-+**
-+** 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.
-+**
-+** See also: Destroy
-+*/
-+case OP_Clear: {
-+  rc = sqliteBtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
-+  break;
-+}
-+
-+/* Opcode: CreateTable * P2 P3
-+**
-+** Allocate a new table in the main database file if P2==0 or in the
-+** auxiliary database file if P2==1.  Push the page number
-+** for the root page of the new table onto the stack.
-+**
-+** The root page number is also written to a memory location that P3
-+** points to.  This is the mechanism is used to write the root page
-+** number into the parser's internal data structures that describe the
-+** new table.
-+**
-+** 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 * P2 P3
-+**
-+** Allocate a new index in the main database file if P2==0 or in the
-+** auxiliary database file if P2==1.  Push the page number of the
-+** root page of the new index onto the stack.
-+**
-+** See documentation on OP_CreateTable for additional information.
-+*/
-+case OP_CreateIndex:
-+case OP_CreateTable: {
-+  int pgno;
-+  assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
-+  assert( pOp->p2>=0 && pOp->p2<db->nDb );
-+  assert( db->aDb[pOp->p2].pBt!=0 );
-+  if( pOp->opcode==OP_CreateTable ){
-+    rc = sqliteBtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno);
-+  }else{
-+    rc = sqliteBtreeCreateIndex(db->aDb[pOp->p2].pBt, &pgno);
-+  }
-+  pTos++;
-+  if( rc==SQLITE_OK ){
-+    pTos->i = pgno;
-+    pTos->flags = MEM_Int;
-+    *(u32*)pOp->p3 = pgno;
-+    pOp->p3 = 0;
-+  }else{
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: IntegrityCk P1 P2 *
-+**
-+** Do an analysis of the currently open database.  Push onto the
-+** stack the text of an error message describing any problems.
-+** If there are no errors, push a "ok" onto the stack.
-+**
-+** P1 is the index of a set that contains the root page numbers
-+** for all tables and indices in the main database file.  The set
-+** is cleared by this opcode.  In other words, after this opcode
-+** has executed, the set will be empty.
-+**
-+** If P2 is not zero, the check is done on the auxiliary database
-+** file, not the main database file.
-+**
-+** This opcode is used for testing purposes only.
-+*/
-+case OP_IntegrityCk: {
-+  int nRoot;
-+  int *aRoot;
-+  int iSet = pOp->p1;
-+  Set *pSet;
-+  int j;
-+  HashElem *i;
-+  char *z;
-+
-+  assert( iSet>=0 && iSet<p->nSet );
-+  pTos++;
-+  pSet = &p->aSet[iSet];
-+  nRoot = sqliteHashCount(&pSet->hash);
-+  aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
-+  if( aRoot==0 ) goto no_mem;
-+  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
-+    toInt((char*)sqliteHashKey(i), &aRoot[j]);
-+  }
-+  aRoot[j] = 0;
-+  sqliteHashClear(&pSet->hash);
-+  pSet->prev = 0;
-+  z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
-+  if( z==0 || z[0]==0 ){
-+    if( z ) sqliteFree(z);
-+    pTos->z = "ok";
-+    pTos->n = 3;
-+    pTos->flags = MEM_Str | MEM_Static;
-+  }else{
-+    pTos->z = z;
-+    pTos->n = strlen(z) + 1;
-+    pTos->flags = MEM_Str | MEM_Dyn;
-+  }
-+  sqliteFree(aRoot);
-+  break;
-+}
-+
-+/* Opcode: ListWrite * * *
-+**
-+** Write the integer on the top of the stack
-+** into the temporary storage list.
-+*/
-+case OP_ListWrite: {
-+  Keylist *pKeylist;
-+  assert( pTos>=p->aStack );
-+  pKeylist = p->pList;
-+  if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
-+    pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
-+    if( pKeylist==0 ) goto no_mem;
-+    pKeylist->nKey = 1000;
-+    pKeylist->nRead = 0;
-+    pKeylist->nUsed = 0;
-+    pKeylist->pNext = p->pList;
-+    p->pList = pKeylist;
-+  }
-+  Integerify(pTos);
-+  pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: ListRewind * * *
-+**
-+** Rewind the temporary buffer back to the beginning.
-+*/
-+case OP_ListRewind: {
-+  /* What this opcode codes, really, is reverse the order of the
-+  ** linked list of Keylist structures so that they are read out
-+  ** in the same order that they were read in. */
-+  Keylist *pRev, *pTop;
-+  pRev = 0;
-+  while( p->pList ){
-+    pTop = p->pList;
-+    p->pList = pTop->pNext;
-+    pTop->pNext = pRev;
-+    pRev = pTop;
-+  }
-+  p->pList = pRev;
-+  break;
-+}
-+
-+/* Opcode: ListRead * P2 *
-+**
-+** Attempt to read an integer from the temporary storage buffer
-+** and push it onto the stack.  If the storage buffer is empty, 
-+** push nothing but instead jump to P2.
-+*/
-+case OP_ListRead: {
-+  Keylist *pKeylist;
-+  CHECK_FOR_INTERRUPT;
-+  pKeylist = p->pList;
-+  if( pKeylist!=0 ){
-+    assert( pKeylist->nRead>=0 );
-+    assert( pKeylist->nRead<pKeylist->nUsed );
-+    assert( pKeylist->nRead<pKeylist->nKey );
-+    pTos++;
-+    pTos->i = pKeylist->aKey[pKeylist->nRead++];
-+    pTos->flags = MEM_Int;
-+    if( pKeylist->nRead>=pKeylist->nUsed ){
-+      p->pList = pKeylist->pNext;
-+      sqliteFree(pKeylist);
-+    }
-+  }else{
-+    pc = pOp->p2 - 1;
-+  }
-+  break;
-+}
-+
-+/* Opcode: ListReset * * *
-+**
-+** Reset the temporary storage buffer so that it holds nothing.
-+*/
-+case OP_ListReset: {
-+  if( p->pList ){
-+    sqliteVdbeKeylistFree(p->pList);
-+    p->pList = 0;
-+  }
-+  break;
-+}
-+
-+/* Opcode: ListPush * * * 
-+**
-+** Save the current Vdbe list such that it can be restored by a ListPop
-+** opcode. The list is empty after this is executed.
-+*/
-+case OP_ListPush: {
-+  p->keylistStackDepth++;
-+  assert(p->keylistStackDepth > 0);
-+  p->keylistStack = sqliteRealloc(p->keylistStack, 
-+          sizeof(Keylist *) * p->keylistStackDepth);
-+  if( p->keylistStack==0 ) goto no_mem;
-+  p->keylistStack[p->keylistStackDepth - 1] = p->pList;
-+  p->pList = 0;
-+  break;
-+}
-+
-+/* Opcode: ListPop * * * 
-+**
-+** Restore the Vdbe list to the state it was in when ListPush was last
-+** executed.
-+*/
-+case OP_ListPop: {
-+  assert(p->keylistStackDepth > 0);
-+  p->keylistStackDepth--;
-+  sqliteVdbeKeylistFree(p->pList);
-+  p->pList = p->keylistStack[p->keylistStackDepth];
-+  p->keylistStack[p->keylistStackDepth] = 0;
-+  if( p->keylistStackDepth == 0 ){
-+    sqliteFree(p->keylistStack);
-+    p->keylistStack = 0;
-+  }
-+  break;
-+}
-+
-+/* Opcode: ContextPush * * * 
-+**
-+** Save the current Vdbe context such that it can be restored by a ContextPop
-+** opcode. The context stores the last insert row id, the last statement change
-+** count, and the current statement change count.
-+*/
-+case OP_ContextPush: {
-+  p->contextStackDepth++;
-+  assert(p->contextStackDepth > 0);
-+  p->contextStack = sqliteRealloc(p->contextStack, 
-+          sizeof(Context) * p->contextStackDepth);
-+  if( p->contextStack==0 ) goto no_mem;
-+  p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid;
-+  p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
-+  p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
-+  break;
-+}
-+
-+/* Opcode: ContextPop * * * 
-+**
-+** Restore the Vdbe context to the state it was in when contextPush was last
-+** executed. The context stores the last insert row id, the last statement
-+** change count, and the current statement change count.
-+*/
-+case OP_ContextPop: {
-+  assert(p->contextStackDepth > 0);
-+  p->contextStackDepth--;
-+  p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid;
-+  p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange;
-+  p->db->csChange = p->contextStack[p->contextStackDepth].csChange;
-+  if( p->contextStackDepth == 0 ){
-+    sqliteFree(p->contextStack);
-+    p->contextStack = 0;
-+  }
-+  break;
-+}
-+
-+/* Opcode: SortPut * * *
-+**
-+** The TOS is the key and the NOS is the data.  Pop both from the stack
-+** and put them on the sorter.  The key and data should have been
-+** made using SortMakeKey and SortMakeRec, respectively.
-+*/
-+case OP_SortPut: {
-+  Mem *pNos = &pTos[-1];
-+  Sorter *pSorter;
-+  assert( pNos>=p->aStack );
-+  if( Dynamicify(pTos) || Dynamicify(pNos) ) goto no_mem;
-+  pSorter = sqliteMallocRaw( sizeof(Sorter) );
-+  if( pSorter==0 ) goto no_mem;
-+  pSorter->pNext = p->pSort;
-+  p->pSort = pSorter;
-+  assert( pTos->flags & MEM_Dyn );
-+  pSorter->nKey = pTos->n;
-+  pSorter->zKey = pTos->z;
-+  assert( pNos->flags & MEM_Dyn );
-+  pSorter->nData = pNos->n;
-+  pSorter->pData = pNos->z;
-+  pTos -= 2;
-+  break;
-+}
-+
-+/* Opcode: SortMakeRec P1 * *
-+**
-+** The top P1 elements are the arguments to a callback.  Form these
-+** elements into a single data entry that can be stored on a sorter
-+** using SortPut and later fed to a callback using SortCallback.
-+*/
-+case OP_SortMakeRec: {
-+  char *z;
-+  char **azArg;
-+  int nByte;
-+  int nField;
-+  int i;
-+  Mem *pRec;
-+
-+  nField = pOp->p1;
-+  pRec = &pTos[1-nField];
-+  assert( pRec>=p->aStack );
-+  nByte = 0;
-+  for(i=0; i<nField; i++, pRec++){
-+    if( (pRec->flags & MEM_Null)==0 ){
-+      Stringify(pRec);
-+      nByte += pRec->n;
-+    }
-+  }
-+  nByte += sizeof(char*)*(nField+1);
-+  azArg = sqliteMallocRaw( nByte );
-+  if( azArg==0 ) goto no_mem;
-+  z = (char*)&azArg[nField+1];
-+  for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      azArg[i] = 0;
-+    }else{
-+      azArg[i] = z;
-+      memcpy(z, pRec->z, pRec->n);
-+      z += pRec->n;
-+    }
-+  }
-+  popStack(&pTos, nField);
-+  pTos++;
-+  pTos->n = nByte;
-+  pTos->z = (char*)azArg;
-+  pTos->flags = MEM_Str | MEM_Dyn;
-+  break;
-+}
-+
-+/* Opcode: SortMakeKey * * P3
-+**
-+** Convert the top few entries of the stack into a sort key.  The
-+** number of stack entries consumed is the number of characters in 
-+** the string P3.  One character from P3 is prepended to each entry.
-+** The first character of P3 is prepended to the element lowest in
-+** the stack and the last character of P3 is prepended to the top of
-+** the stack.  All stack entries are separated by a \000 character
-+** in the result.  The whole key is terminated by two \000 characters
-+** in a row.
-+**
-+** "N" is substituted in place of the P3 character for NULL values.
-+**
-+** See also the MakeKey and MakeIdxKey opcodes.
-+*/
-+case OP_SortMakeKey: {
-+  char *zNewKey;
-+  int nByte;
-+  int nField;
-+  int i, j, k;
-+  Mem *pRec;
-+
-+  nField = strlen(pOp->p3);
-+  pRec = &pTos[1-nField];
-+  nByte = 1;
-+  for(i=0; i<nField; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      nByte += 2;
-+    }else{
-+      Stringify(pRec);
-+      nByte += pRec->n+2;
-+    }
-+  }
-+  zNewKey = sqliteMallocRaw( nByte );
-+  if( zNewKey==0 ) goto no_mem;
-+  j = 0;
-+  k = 0;
-+  for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      zNewKey[j++] = 'N';
-+      zNewKey[j++] = 0;
-+      k++;
-+    }else{
-+      zNewKey[j++] = pOp->p3[k++];
-+      memcpy(&zNewKey[j], pRec->z, pRec->n-1);
-+      j += pRec->n-1;
-+      zNewKey[j++] = 0;
-+    }
-+  }
-+  zNewKey[j] = 0;
-+  assert( j<nByte );
-+  popStack(&pTos, nField);
-+  pTos++;
-+  pTos->n = nByte;
-+  pTos->flags = MEM_Str|MEM_Dyn;
-+  pTos->z = zNewKey;
-+  break;
-+}
-+
-+/* Opcode: Sort * * *
-+**
-+** Sort all elements on the sorter.  The algorithm is a
-+** mergesort.
-+*/
-+case OP_Sort: {
-+  int i;
-+  Sorter *pElem;
-+  Sorter *apSorter[NSORT];
-+  for(i=0; i<NSORT; i++){
-+    apSorter[i] = 0;
-+  }
-+  while( p->pSort ){
-+    pElem = p->pSort;
-+    p->pSort = pElem->pNext;
-+    pElem->pNext = 0;
-+    for(i=0; i<NSORT-1; i++){
-+    if( apSorter[i]==0 ){
-+        apSorter[i] = pElem;
-+        break;
-+      }else{
-+        pElem = Merge(apSorter[i], pElem);
-+        apSorter[i] = 0;
-+      }
-+    }
-+    if( i>=NSORT-1 ){
-+      apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
-+    }
-+  }
-+  pElem = 0;
-+  for(i=0; i<NSORT; i++){
-+    pElem = Merge(apSorter[i], pElem);
-+  }
-+  p->pSort = pElem;
-+  break;
-+}
-+
-+/* Opcode: SortNext * P2 *
-+**
-+** Push the data for the topmost element in the sorter onto the
-+** stack, then remove the element from the sorter.  If the sorter
-+** is empty, push nothing on the stack and instead jump immediately 
-+** to instruction P2.
-+*/
-+case OP_SortNext: {
-+  Sorter *pSorter = p->pSort;
-+  CHECK_FOR_INTERRUPT;
-+  if( pSorter!=0 ){
-+    p->pSort = pSorter->pNext;
-+    pTos++;
-+    pTos->z = pSorter->pData;
-+    pTos->n = pSorter->nData;
-+    pTos->flags = MEM_Str|MEM_Dyn;
-+    sqliteFree(pSorter->zKey);
-+    sqliteFree(pSorter);
-+  }else{
-+    pc = pOp->p2 - 1;
-+  }
-+  break;
-+}
-+
-+/* Opcode: SortCallback P1 * *
-+**
-+** The top of the stack contains a callback record built using
-+** the SortMakeRec operation with the same P1 value as this
-+** instruction.  Pop this record from the stack and invoke the
-+** callback on it.
-+*/
-+case OP_SortCallback: {
-+  assert( pTos>=p->aStack );
-+  assert( pTos->flags & MEM_Str );
-+  p->nCallback++;
-+  p->pc = pc+1;
-+  p->azResColumn = (char**)pTos->z;
-+  assert( p->nResColumn==pOp->p1 );
-+  p->popStack = 1;
-+  p->pTos = pTos;
-+  return SQLITE_ROW;
-+}
-+
-+/* Opcode: SortReset * * *
-+**
-+** Remove any elements that remain on the sorter.
-+*/
-+case OP_SortReset: {
-+  sqliteVdbeSorterReset(p);
-+  break;
-+}
-+
-+/* Opcode: FileOpen * * P3
-+**
-+** Open the file named by P3 for reading using the FileRead opcode.
-+** If P3 is "stdin" then open standard input for reading.
-+*/
-+case OP_FileOpen: {
-+  assert( pOp->p3!=0 );
-+  if( p->pFile ){
-+    if( p->pFile!=stdin ) fclose(p->pFile);
-+    p->pFile = 0;
-+  }
-+  if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
-+    p->pFile = stdin;
-+  }else{
-+    p->pFile = fopen(pOp->p3, "r");
-+  }
-+  if( p->pFile==0 ){
-+    sqliteSetString(&p->zErrMsg,"unable to open file: ", pOp->p3, (char*)0);
-+    rc = SQLITE_ERROR;
-+  }
-+  break;
-+}
-+
-+/* Opcode: FileRead P1 P2 P3
-+**
-+** Read a single line of input from the open file (the file opened using
-+** FileOpen).  If we reach end-of-file, jump immediately to P2.  If
-+** we are able to get another line, split the line apart using P3 as
-+** a delimiter.  There should be P1 fields.  If the input line contains
-+** more than P1 fields, ignore the excess.  If the input line contains
-+** fewer than P1 fields, assume the remaining fields contain NULLs.
-+**
-+** Input ends if a line consists of just "\.".  A field containing only
-+** "\N" is a null field.  The backslash \ character can be used be used
-+** to escape newlines or the delimiter.
-+*/
-+case OP_FileRead: {
-+  int n, eol, nField, i, c, nDelim;
-+  char *zDelim, *z;
-+  CHECK_FOR_INTERRUPT;
-+  if( p->pFile==0 ) goto fileread_jump;
-+  nField = pOp->p1;
-+  if( nField<=0 ) goto fileread_jump;
-+  if( nField!=p->nField || p->azField==0 ){
-+    char **azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
-+    if( azField==0 ){ goto no_mem; }
-+    p->azField = azField;
-+    p->nField = nField;
-+  }
-+  n = 0;
-+  eol = 0;
-+  while( eol==0 ){
-+    if( p->zLine==0 || n+200>p->nLineAlloc ){
-+      char *zLine;
-+      p->nLineAlloc = p->nLineAlloc*2 + 300;
-+      zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
-+      if( zLine==0 ){
-+        p->nLineAlloc = 0;
-+        sqliteFree(p->zLine);
-+        p->zLine = 0;
-+        goto no_mem;
-+      }
-+      p->zLine = zLine;
-+    }
-+    if( vdbe_fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
-+      eol = 1;
-+      p->zLine[n] = 0;
-+    }else{
-+      int c;
-+      while( (c = p->zLine[n])!=0 ){
-+        if( c=='\\' ){
-+          if( p->zLine[n+1]==0 ) break;
-+          n += 2;
-+        }else if( c=='\n' ){
-+          p->zLine[n] = 0;
-+          eol = 1;
-+          break;
-+        }else{
-+          n++;
-+        }
-+      }
-+    }
-+  }
-+  if( n==0 ) goto fileread_jump;
-+  z = p->zLine;
-+  if( z[0]=='\\' && z[1]=='.' && z[2]==0 ){
-+    goto fileread_jump;
-+  }
-+  zDelim = pOp->p3;
-+  if( zDelim==0 ) zDelim = "\t";
-+  c = zDelim[0];
-+  nDelim = strlen(zDelim);
-+  p->azField[0] = z;
-+  for(i=1; *z!=0 && i<=nField; i++){
-+    int from, to;
-+    from = to = 0;
-+    if( z[0]=='\\' && z[1]=='N' 
-+       && (z[2]==0 || strncmp(&z[2],zDelim,nDelim)==0) ){
-+      if( i<=nField ) p->azField[i-1] = 0;
-+      z += 2 + nDelim;
-+      if( i<nField ) p->azField[i] = z;
-+      continue;
-+    }
-+    while( z[from] ){
-+      if( z[from]=='\\' && z[from+1]!=0 ){
-+        int tx = z[from+1];
-+        switch( tx ){
-+          case 'b':  tx = '\b'; break;
-+          case 'f':  tx = '\f'; break;
-+          case 'n':  tx = '\n'; break;
-+          case 'r':  tx = '\r'; break;
-+          case 't':  tx = '\t'; break;
-+          case 'v':  tx = '\v'; break;
-+          default:   break;
-+        }
-+        z[to++] = tx;
-+        from += 2;
-+        continue;
-+      }
-+      if( z[from]==c && strncmp(&z[from],zDelim,nDelim)==0 ) break;
-+      z[to++] = z[from++];
-+    }
-+    if( z[from] ){
-+      z[to] = 0;
-+      z += from + nDelim;
-+      if( i<nField ) p->azField[i] = z;
-+    }else{
-+      z[to] = 0;
-+      z = "";
-+    }
-+  }
-+  while( i<nField ){
-+    p->azField[i++] = 0;
-+  }
-+  break;
-+
-+  /* If we reach end-of-file, or if anything goes wrong, jump here.
-+  ** This code will cause a jump to P2 */
-+fileread_jump:
-+  pc = pOp->p2 - 1;
-+  break;
-+}
-+
-+/* Opcode: FileColumn P1 * *
-+**
-+** Push onto the stack the P1-th column of the most recently read line
-+** from the input file.
-+*/
-+case OP_FileColumn: {
-+  int i = pOp->p1;
-+  char *z;
-+  assert( i>=0 && i<p->nField );
-+  if( p->azField ){
-+    z = p->azField[i];
-+  }else{
-+    z = 0;
-+  }
-+  pTos++;
-+  if( z ){
-+    pTos->n = strlen(z) + 1;
-+    pTos->z = z;
-+    pTos->flags = MEM_Str | MEM_Ephem;
-+  }else{
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: MemStore P1 P2 *
-+**
-+** Write the top of the stack into memory location P1.
-+** P1 should be a small integer since space is allocated
-+** for all memory locations between 0 and P1 inclusive.
-+**
-+** After the data is stored in the memory location, the
-+** stack is popped once if P2 is 1.  If P2 is zero, then
-+** the original data remains on the stack.
-+*/
-+case OP_MemStore: {
-+  int i = pOp->p1;
-+  Mem *pMem;
-+  assert( pTos>=p->aStack );
-+  if( i>=p->nMem ){
-+    int nOld = p->nMem;
-+    Mem *aMem;
-+    p->nMem = i + 5;
-+    aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
-+    if( aMem==0 ) goto no_mem;
-+    if( aMem!=p->aMem ){
-+      int j;
-+      for(j=0; j<nOld; j++){
-+        if( aMem[j].flags & MEM_Short ){
-+          aMem[j].z = aMem[j].zShort;
-+        }
-+      }
-+    }
-+    p->aMem = aMem;
-+    if( nOld<p->nMem ){
-+      memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
-+    }
-+  }
-+  Deephemeralize(pTos);
-+  pMem = &p->aMem[i];
-+  Release(pMem);
-+  *pMem = *pTos;
-+  if( pMem->flags & MEM_Dyn ){
-+    if( pOp->p2 ){
-+      pTos->flags = MEM_Null;
-+    }else{
-+      pMem->z = sqliteMallocRaw( pMem->n );
-+      if( pMem->z==0 ) goto no_mem;
-+      memcpy(pMem->z, pTos->z, pMem->n);
-+    }
-+  }else if( pMem->flags & MEM_Short ){
-+    pMem->z = pMem->zShort;
-+  }
-+  if( pOp->p2 ){
-+    Release(pTos);
-+    pTos--;
-+  }
-+  break;
-+}
-+
-+/* Opcode: MemLoad P1 * *
-+**
-+** Push a copy of the value in memory location P1 onto the stack.
-+**
-+** If the value is a string, then the value pushed is a pointer to
-+** the string that is stored in the memory location.  If the memory
-+** location is subsequently changed (using OP_MemStore) then the
-+** value pushed onto the stack will change too.
-+*/
-+case OP_MemLoad: {
-+  int i = pOp->p1;
-+  assert( i>=0 && i<p->nMem );
-+  pTos++;
-+  memcpy(pTos, &p->aMem[i], sizeof(pTos[0])-NBFS);;
-+  if( pTos->flags & MEM_Str ){
-+    pTos->flags |= MEM_Ephem;
-+    pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
-+  }
-+  break;
-+}
-+
-+/* Opcode: MemIncr P1 P2 *
-+**
-+** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
-+** and the result after the increment is greater than zero, then jump
-+** to P2.
-+**
-+** This instruction throws an error if the memory cell is not initially
-+** an integer.
-+*/
-+case OP_MemIncr: {
-+  int i = pOp->p1;
-+  Mem *pMem;
-+  assert( i>=0 && i<p->nMem );
-+  pMem = &p->aMem[i];
-+  assert( pMem->flags==MEM_Int );
-+  pMem->i++;
-+  if( pOp->p2>0 && pMem->i>0 ){
-+     pc = pOp->p2 - 1;
-+  }
-+  break;
-+}
-+
-+/* Opcode: AggReset * P2 *
-+**
-+** Reset the aggregator so that it no longer contains any data.
-+** Future aggregator elements will contain P2 values each.
-+*/
-+case OP_AggReset: {
-+  sqliteVdbeAggReset(&p->agg);
-+  p->agg.nMem = pOp->p2;
-+  p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
-+  if( p->agg.apFunc==0 ) goto no_mem;
-+  break;
-+}
-+
-+/* Opcode: AggInit * P2 P3
-+**
-+** Initialize the function parameters for an aggregate function.
-+** The aggregate will operate out of aggregate column P2.
-+** P3 is a pointer to the FuncDef structure for the function.
-+*/
-+case OP_AggInit: {
-+  int i = pOp->p2;
-+  assert( i>=0 && i<p->agg.nMem );
-+  p->agg.apFunc[i] = (FuncDef*)pOp->p3;
-+  break;
-+}
-+
-+/* Opcode: AggFunc * P2 P3
-+**
-+** Execute the step function for an aggregate.  The
-+** function has P2 arguments.  P3 is a pointer to the FuncDef
-+** structure that specifies the function.
-+**
-+** The top of the stack must be an integer which is the index of
-+** the aggregate column that corresponds to this aggregate function.
-+** Ideally, this index would be another parameter, but there are
-+** no free parameters left.  The integer is popped from the stack.
-+*/
-+case OP_AggFunc: {
-+  int n = pOp->p2;
-+  int i;
-+  Mem *pMem, *pRec;
-+  char **azArgv = p->zArgv;
-+  sqlite_func ctx;
-+
-+  assert( n>=0 );
-+  assert( pTos->flags==MEM_Int );
-+  pRec = &pTos[-n];
-+  assert( pRec>=p->aStack );
-+  for(i=0; i<n; i++, pRec++){
-+    if( pRec->flags & MEM_Null ){
-+      azArgv[i] = 0;
-+    }else{
-+      Stringify(pRec);
-+      azArgv[i] = pRec->z;
-+    }
-+  }
-+  i = pTos->i;
-+  assert( i>=0 && i<p->agg.nMem );
-+  ctx.pFunc = (FuncDef*)pOp->p3;
-+  pMem = &p->agg.pCurrent->aMem[i];
-+  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
-+  ctx.pAgg = pMem->z;
-+  ctx.cnt = ++pMem->i;
-+  ctx.isError = 0;
-+  ctx.isStep = 1;
-+  (ctx.pFunc->xStep)(&ctx, n, (const char**)azArgv);
-+  pMem->z = ctx.pAgg;
-+  pMem->flags = MEM_AggCtx;
-+  popStack(&pTos, n+1);
-+  if( ctx.isError ){
-+    rc = SQLITE_ERROR;
-+  }
-+  break;
-+}
-+
-+/* Opcode: AggFocus * P2 *
-+**
-+** Pop the top of the stack and use that as an aggregator key.  If
-+** an aggregator with that same key already exists, then make the
-+** aggregator the current aggregator and jump to P2.  If no aggregator
-+** with the given key exists, create one and make it current but
-+** do not jump.
-+**
-+** The order of aggregator opcodes is important.  The order is:
-+** AggReset AggFocus AggNext.  In other words, you must execute
-+** AggReset first, then zero or more AggFocus operations, then
-+** zero or more AggNext operations.  You must not execute an AggFocus
-+** in between an AggNext and an AggReset.
-+*/
-+case OP_AggFocus: {
-+  AggElem *pElem;
-+  char *zKey;
-+  int nKey;
-+
-+  assert( pTos>=p->aStack );
-+  Stringify(pTos);
-+  zKey = pTos->z;
-+  nKey = pTos->n;
-+  pElem = sqliteHashFind(&p->agg.hash, zKey, nKey);
-+  if( pElem ){
-+    p->agg.pCurrent = pElem;
-+    pc = pOp->p2 - 1;
-+  }else{
-+    AggInsert(&p->agg, zKey, nKey);
-+    if( sqlite_malloc_failed ) goto no_mem;
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break; 
-+}
-+
-+/* Opcode: AggSet * P2 *
-+**
-+** Move the top of the stack into the P2-th field of the current
-+** aggregate.  String values are duplicated into new memory.
-+*/
-+case OP_AggSet: {
-+  AggElem *pFocus = AggInFocus(p->agg);
-+  Mem *pMem;
-+  int i = pOp->p2;
-+  assert( pTos>=p->aStack );
-+  if( pFocus==0 ) goto no_mem;
-+  assert( i>=0 && i<p->agg.nMem );
-+  Deephemeralize(pTos);
-+  pMem = &pFocus->aMem[i];
-+  Release(pMem);
-+  *pMem = *pTos;
-+  if( pMem->flags & MEM_Dyn ){
-+    pTos->flags = MEM_Null;
-+  }else if( pMem->flags & MEM_Short ){
-+    pMem->z = pMem->zShort;
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: AggGet * P2 *
-+**
-+** Push a new entry onto the stack which is a copy of the P2-th field
-+** of the current aggregate.  Strings are not duplicated so
-+** string values will be ephemeral.
-+*/
-+case OP_AggGet: {
-+  AggElem *pFocus = AggInFocus(p->agg);
-+  Mem *pMem;
-+  int i = pOp->p2;
-+  if( pFocus==0 ) goto no_mem;
-+  assert( i>=0 && i<p->agg.nMem );
-+  pTos++;
-+  pMem = &pFocus->aMem[i];
-+  *pTos = *pMem;
-+  if( pTos->flags & MEM_Str ){
-+    pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
-+    pTos->flags |= MEM_Ephem;
-+  }
-+  if( pTos->flags & MEM_AggCtx ){
-+    Release(pTos);
-+    pTos->flags = MEM_Null;
-+  }
-+  break;
-+}
-+
-+/* Opcode: AggNext * P2 *
-+**
-+** Make the next aggregate value the current aggregate.  The prior
-+** aggregate is deleted.  If all aggregate values have been consumed,
-+** jump to P2.
-+**
-+** The order of aggregator opcodes is important.  The order is:
-+** AggReset AggFocus AggNext.  In other words, you must execute
-+** AggReset first, then zero or more AggFocus operations, then
-+** zero or more AggNext operations.  You must not execute an AggFocus
-+** in between an AggNext and an AggReset.
-+*/
-+case OP_AggNext: {
-+  CHECK_FOR_INTERRUPT;
-+  if( p->agg.pSearch==0 ){
-+    p->agg.pSearch = sqliteHashFirst(&p->agg.hash);
-+  }else{
-+    p->agg.pSearch = sqliteHashNext(p->agg.pSearch);
-+  }
-+  if( p->agg.pSearch==0 ){
-+    pc = pOp->p2 - 1;
-+  } else {
-+    int i;
-+    sqlite_func ctx;
-+    Mem *aMem;
-+    p->agg.pCurrent = sqliteHashData(p->agg.pSearch);
-+    aMem = p->agg.pCurrent->aMem;
-+    for(i=0; i<p->agg.nMem; i++){
-+      int freeCtx;
-+      if( p->agg.apFunc[i]==0 ) continue;
-+      if( p->agg.apFunc[i]->xFinalize==0 ) continue;
-+      ctx.s.flags = MEM_Null;
-+      ctx.s.z = aMem[i].zShort;
-+      ctx.pAgg = (void*)aMem[i].z;
-+      freeCtx = aMem[i].z && aMem[i].z!=aMem[i].zShort;
-+      ctx.cnt = aMem[i].i;
-+      ctx.isStep = 0;
-+      ctx.pFunc = p->agg.apFunc[i];
-+      (*p->agg.apFunc[i]->xFinalize)(&ctx);
-+      if( freeCtx ){
-+        sqliteFree( aMem[i].z );
-+      }
-+      aMem[i] = ctx.s;
-+      if( aMem[i].flags & MEM_Short ){
-+        aMem[i].z = aMem[i].zShort;
-+      }
-+    }
-+  }
-+  break;
-+}
-+
-+/* Opcode: SetInsert P1 * P3
-+**
-+** If Set P1 does not exist then create it.  Then insert value
-+** P3 into that set.  If P3 is NULL, then insert the top of the
-+** stack into the set.
-+*/
-+case OP_SetInsert: {
-+  int i = pOp->p1;
-+  if( p->nSet<=i ){
-+    int k;
-+    Set *aSet = sqliteRealloc(p->aSet, (i+1)*sizeof(p->aSet[0]) );
-+    if( aSet==0 ) goto no_mem;
-+    p->aSet = aSet;
-+    for(k=p->nSet; k<=i; k++){
-+      sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
-+    }
-+    p->nSet = i+1;
-+  }
-+  if( pOp->p3 ){
-+    sqliteHashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
-+  }else{
-+    assert( pTos>=p->aStack );
-+    Stringify(pTos);
-+    sqliteHashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
-+    Release(pTos);
-+    pTos--;
-+  }
-+  if( sqlite_malloc_failed ) goto no_mem;
-+  break;
-+}
-+
-+/* Opcode: SetFound P1 P2 *
-+**
-+** Pop the stack once and compare the value popped off with the
-+** contents of set P1.  If the element popped exists in set P1,
-+** then jump to P2.  Otherwise fall through.
-+*/
-+case OP_SetFound: {
-+  int i = pOp->p1;
-+  assert( pTos>=p->aStack );
-+  Stringify(pTos);
-+  if( i>=0 && i<p->nSet && sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
-+    pc = pOp->p2 - 1;
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: SetNotFound P1 P2 *
-+**
-+** Pop the stack once and compare the value popped off with the
-+** contents of set P1.  If the element popped does not exists in 
-+** set P1, then jump to P2.  Otherwise fall through.
-+*/
-+case OP_SetNotFound: {
-+  int i = pOp->p1;
-+  assert( pTos>=p->aStack );
-+  Stringify(pTos);
-+  if( i<0 || i>=p->nSet ||
-+       sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
-+    pc = pOp->p2 - 1;
-+  }
-+  Release(pTos);
-+  pTos--;
-+  break;
-+}
-+
-+/* Opcode: SetFirst P1 P2 *
-+**
-+** Read the first element from set P1 and push it onto the stack.  If the
-+** set is empty, push nothing and jump immediately to P2.  This opcode is
-+** used in combination with OP_SetNext to loop over all elements of a set.
-+*/
-+/* Opcode: SetNext P1 P2 *
-+**
-+** Read the next element from set P1 and push it onto the stack.  If there
-+** are no more elements in the set, do not do the push and fall through.
-+** Otherwise, jump to P2 after pushing the next set element.
-+*/
-+case OP_SetFirst: 
-+case OP_SetNext: {
-+  Set *pSet;
-+  CHECK_FOR_INTERRUPT;
-+  if( pOp->p1<0 || pOp->p1>=p->nSet ){
-+    if( pOp->opcode==OP_SetFirst ) pc = pOp->p2 - 1;
-+    break;
-+  }
-+  pSet = &p->aSet[pOp->p1];
-+  if( pOp->opcode==OP_SetFirst ){
-+    pSet->prev = sqliteHashFirst(&pSet->hash);
-+    if( pSet->prev==0 ){
-+      pc = pOp->p2 - 1;
-+      break;
-+    }
-+  }else{
-+    if( pSet->prev ){
-+      pSet->prev = sqliteHashNext(pSet->prev);
-+    }
-+    if( pSet->prev==0 ){
-+      break;
-+    }else{
-+      pc = pOp->p2 - 1;
-+    }
-+  }
-+  pTos++;
-+  pTos->z = sqliteHashKey(pSet->prev);
-+  pTos->n = sqliteHashKeysize(pSet->prev);
-+  pTos->flags = MEM_Str | MEM_Ephem;
-+  break;
-+}
-+
-+/* 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( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
-+  rc = sqliteRunVacuum(&p->zErrMsg, db);
-+  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
-+  break;
-+}
-+
-+/* Opcode: StackDepth * * *
-+**
-+** Push an integer onto the stack which is the depth of the stack prior
-+** to that integer being pushed.
-+*/
-+case OP_StackDepth: {
-+  int depth = (&pTos[1]) - p->aStack;
-+  pTos++;
-+  pTos->i = depth;
-+  pTos->flags = MEM_Int;
-+  break;
-+}
-+
-+/* Opcode: StackReset * * *
-+**
-+** Pop a single integer off of the stack.  Then pop the stack
-+** as many times as necessary to get the depth of the stack down
-+** to the value of the integer that was popped.
-+*/
-+case OP_StackReset: {
-+  int depth, goal;
-+  assert( pTos>=p->aStack );
-+  Integerify(pTos);
-+  goal = pTos->i;
-+  depth = (&pTos[1]) - p->aStack;
-+  assert( goal<depth );
-+  popStack(&pTos, depth-goal);
-+  break;
-+}
-+
-+/* An other opcode is illegal...
-+*/
-+default: {
-+  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
-+  sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
-+  rc = SQLITE_INTERNAL;
-+  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
-+    {
-+      long long elapse = hwtime() - start;
-+      pOp->cycles += elapse;
-+      pOp->cnt++;
-+#if 0
-+        fprintf(stdout, "%10lld ", elapse);
-+        sqliteVdbePrintOp(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
-+    /* Sanity checking on the top element of the stack */
-+    if( pTos>=p->aStack ){
-+      assert( pTos->flags!=0 );  /* Must define some type */
-+      if( pTos->flags & MEM_Str ){
-+        int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
-+        assert( x!=0 );            /* Strings must define a string subtype */
-+        assert( (x & (x-1))==0 );  /* Only one string subtype can be defined */
-+        assert( pTos->z!=0 );      /* Strings must have a value */
-+        /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
-+        assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
-+        assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );
-+      }else{
-+        /* Cannot define a string subtype for non-string objects */
-+        assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
-+      }
-+      /* MEM_Null excludes all other types */
-+      assert( pTos->flags==MEM_Null || (pTos->flags&MEM_Null)==0 );
-+    }
-+    if( pc<-1 || pc>=p->nOp ){
-+      sqliteSetString(&p->zErrMsg, "jump destination out of range", (char*)0);
-+      rc = SQLITE_INTERNAL;
-+    }
-+    if( p->trace && pTos>=p->aStack ){
-+      int i;
-+      fprintf(p->trace, "Stack:");
-+      for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
-+        if( pTos[i].flags & MEM_Null ){
-+          fprintf(p->trace, " NULL");
-+        }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
-+          fprintf(p->trace, " si:%d", pTos[i].i);
-+        }else if( pTos[i].flags & MEM_Int ){
-+          fprintf(p->trace, " i:%d", pTos[i].i);
-+        }else if( pTos[i].flags & MEM_Real ){
-+          fprintf(p->trace, " r:%g", pTos[i].r);
-+        }else if( pTos[i].flags & MEM_Str ){
-+          int j, k;
-+          char zBuf[100];
-+          zBuf[0] = ' ';
-+          if( pTos[i].flags & MEM_Dyn ){
-+            zBuf[1] = 'z';
-+            assert( (pTos[i].flags & (MEM_Static|MEM_Ephem))==0 );
-+          }else if( pTos[i].flags & MEM_Static ){
-+            zBuf[1] = 't';
-+            assert( (pTos[i].flags & (MEM_Dyn|MEM_Ephem))==0 );
-+          }else if( pTos[i].flags & MEM_Ephem ){
-+            zBuf[1] = 'e';
-+            assert( (pTos[i].flags & (MEM_Static|MEM_Dyn))==0 );
-+          }else{
-+            zBuf[1] = 's';
-+          }
-+          zBuf[2] = '[';
-+          k = 3;
-+          for(j=0; j<20 && j<pTos[i].n; j++){
-+            int c = pTos[i].z[j];
-+            if( c==0 && j==pTos[i].n-1 ) break;
-+            if( isprint(c) && !isspace(c) ){
-+              zBuf[k++] = c;
-+            }else{
-+              zBuf[k++] = '.';
-+            }
-+          }
-+          zBuf[k++] = ']';
-+          zBuf[k++] = 0;
-+          fprintf(p->trace, "%s", zBuf);
-+        }else{
-+          fprintf(p->trace, " ???");
-+        }
-+      }
-+      if( rc!=0 ) fprintf(p->trace," rc=%d",rc);
-+      fprintf(p->trace,"\n");
-+    }
-+#endif
-+  }  /* The end of the for(;;) loop the loops through opcodes */
-+
-+  /* If we reach this point, it means that execution is finished.
-+  */
-+vdbe_halt:
-+  CHECK_FOR_INTERRUPT
-+  if( rc ){
-+    p->rc = rc;
-+    rc = SQLITE_ERROR;
-+  }else{
-+    rc = SQLITE_DONE;
-+  }
-+  p->magic = VDBE_MAGIC_HALT;
-+  p->pTos = pTos;
-+  return rc;
-+
-+  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
-+  ** to fail on a modern VM computer, so this code is untested.
-+  */
-+no_mem:
-+  sqliteSetString(&p->zErrMsg, "out of memory", (char*)0);
-+  rc = SQLITE_NOMEM;
-+  goto vdbe_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:
-+  if( p->zErrMsg==0 ){
-+    if( sqlite_malloc_failed ) rc = SQLITE_NOMEM;
-+    sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
-+  }
-+  goto vdbe_halt;
-+
-+  /* Jump to here if the sqlite_interrupt() API sets the interrupt
-+  ** flag.
-+  */
-+abort_due_to_interrupt:
-+  assert( db->flags & SQLITE_Interrupt );
-+  db->flags &= ~SQLITE_Interrupt;
-+  if( db->magic!=SQLITE_MAGIC_BUSY ){
-+    rc = SQLITE_MISUSE;
-+  }else{
-+    rc = SQLITE_INTERRUPT;
-+  }
-+  sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
-+  goto vdbe_halt;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/vdbe.h
-@@ -0,0 +1,112 @@
-+/*
-+** 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$
-+*/
-+#ifndef _SQLITE_VDBE_H_
-+#define _SQLITE_VDBE_H_
-+#include <stdio.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;
-+
-+/*
-+** 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 */
-+  int p1;             /* First operand */
-+  int p2;             /* Second parameter (often the jump destination) */
-+  char *p3;           /* Third parameter */
-+  int p3type;         /* P3_STATIC, P3_DYNAMIC or P3_POINTER */
-+#ifdef VDBE_PROFILE
-+  int cnt;            /* Number of times this instruction was executed */
-+  long long cycles;   /* Total time spend executing this instruction */
-+#endif
-+};
-+typedef struct VdbeOp VdbeOp;
-+
-+/*
-+** 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 */
-+  short int p2;       /* Second parameter (often the jump destination) */
-+  char *p3;           /* Third parameter */
-+};
-+typedef struct VdbeOpList VdbeOpList;
-+
-+/*
-+** Allowed values of VdbeOp.p3type
-+*/
-+#define P3_NOTUSED    0   /* The P3 parameter is not used */
-+#define P3_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
-+#define P3_STATIC   (-2)  /* Pointer to a static string */
-+#define P3_POINTER  (-3)  /* P3 is a pointer to some structure or object */
-+
-+/*
-+** The following macro converts a relative address in the p2 field
-+** of a VdbeOp structure into a negative number so that 
-+** sqliteVdbeAddOpList() 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"
-+
-+/*
-+** Prototypes for the VDBE interface.  See comments on the implementation
-+** for a description of what each of these routines does.
-+*/
-+Vdbe *sqliteVdbeCreate(sqlite*);
-+void sqliteVdbeCreateCallback(Vdbe*, int*);
-+int sqliteVdbeAddOp(Vdbe*,int,int,int);
-+int sqliteVdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
-+int sqliteVdbeCode(Vdbe*,...);
-+int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
-+void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
-+void sqliteVdbeChangeP2(Vdbe*, int addr, int P2);
-+void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
-+void sqliteVdbeDequoteP3(Vdbe*, int addr);
-+int sqliteVdbeFindOp(Vdbe*, int, int);
-+VdbeOp *sqliteVdbeGetOp(Vdbe*, int);
-+int sqliteVdbeMakeLabel(Vdbe*);
-+void sqliteVdbeDelete(Vdbe*);
-+void sqliteVdbeMakeReady(Vdbe*,int,int);
-+int sqliteVdbeExec(Vdbe*);
-+int sqliteVdbeList(Vdbe*);
-+int sqliteVdbeFinalize(Vdbe*,char**);
-+void sqliteVdbeResolveLabel(Vdbe*, int);
-+int sqliteVdbeCurrentAddr(Vdbe*);
-+void sqliteVdbeTrace(Vdbe*,FILE*);
-+void sqliteVdbeCompressSpace(Vdbe*,int);
-+int sqliteVdbeReset(Vdbe*,char **);
-+int sqliteVdbeSetVariables(Vdbe*,int,const char**);
-+
-+#endif
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/vdbeInt.h
-@@ -0,0 +1,303 @@
-+/*
-+** 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.
-+*/
-+
-+/*
-+** When converting from the native format to the key format and back
-+** again, in addition to changing the byte order we invert the high-order
-+** bit of the most significant byte.  This causes negative numbers to
-+** sort before positive numbers in the memcmp() function.
-+*/
-+#define keyToInt(X)   (sqliteVdbeByteSwap(X) ^ 0x80000000)
-+#define intToKey(X)   (sqliteVdbeByteSwap((X) ^ 0x80000000))
-+
-+/*
-+** The makefile scans this source file and creates the following
-+** array of string constants which are the names of all VDBE opcodes.
-+** This array is defined in a separate source code file named opcode.c
-+** which is automatically generated by the makefile.
-+*/
-+extern char *sqliteOpcodeNames[];
-+
-+/*
-+** 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 Cursor.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 Cursor.pData and
-+** the rowid is in Cursor.iKey.
-+*/
-+struct Cursor {
-+  BtCursor *pCursor;    /* The cursor structure of the backend */
-+  int lastRecno;        /* Last recno from a Next or NextIdx operation */
-+  int nextRowid;        /* Next rowid returned by OP_NewRowid */
-+  Bool recnoIsValid;    /* True if lastRecno is valid */
-+  Bool keyAsData;       /* The OP_Column command works on key instead of data */
-+  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 nextRowidValid;  /* True if the nextRowid field is valid */
-+  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
-+  Bool deferredMoveto;  /* A call to sqliteBtreeMoveto() is needed */
-+  int movetoTarget;     /* Argument to the deferred sqliteBtreeMoveto() */
-+  Btree *pBt;           /* Separate file holding temporary table */
-+  int nData;            /* Number of bytes in pData */
-+  char *pData;          /* Data for a NEW or OLD pseudo-table */
-+  int iKey;             /* Key for the NEW or OLD pseudo-table row */
-+};
-+typedef struct Cursor Cursor;
-+
-+/*
-+** A sorter builds a list of elements to be sorted.  Each element of
-+** the list is an instance of the following structure.
-+*/
-+typedef struct Sorter Sorter;
-+struct Sorter {
-+  int nKey;           /* Number of bytes in the key */
-+  char *zKey;         /* The key by which we will sort */
-+  int nData;          /* Number of bytes in the data */
-+  char *pData;        /* The data associated with this key */
-+  Sorter *pNext;      /* Next in the list */
-+};
-+
-+/* 
-+** Number of buckets used for merge-sort.  
-+*/
-+#define NSORT 30
-+
-+/*
-+** Number of bytes of string storage space available to each stack
-+** layer without having to malloc.  NBFS is short for Number of Bytes
-+** For Strings.
-+*/
-+#define NBFS 32
-+
-+/*
-+** A single level of the stack or a single memory cell
-+** is an instance of the following structure. 
-+*/
-+struct Mem {
-+  int i;              /* Integer value */
-+  int n;              /* Number of characters in string value, including '\0' */
-+  int flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
-+  double r;           /* Real value */
-+  char *z;            /* String value */
-+  char zShort[NBFS];  /* Space for short strings */
-+};
-+typedef struct Mem Mem;
-+
-+/*
-+** Allowed values for Mem.flags
-+*/
-+#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_Dyn       0x0010   /* Need to call sqliteFree() on Mem.z */
-+#define MEM_Static    0x0020   /* Mem.z points to a static string */
-+#define MEM_Ephem     0x0040   /* Mem.z points to an ephemeral string */
-+#define MEM_Short     0x0080   /* Mem.z points to Mem.zShort */
-+
-+/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
-+** It indicates that the corresponding AggElem.aMem.z points to a
-+** aggregate function context that needs to be finalized.
-+*/
-+#define MEM_AggCtx    0x0100   /* Mem.z points to an agg function context */
-+
-+/*
-+** 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 vdbe.c because it uses substructures
-+** (Mem) which are only defined there.
-+*/
-+struct sqlite_func {
-+  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
-+  Mem s;            /* The return value is stored here */
-+  void *pAgg;       /* Aggregate context */
-+  u8 isError;       /* Set to true for an error */
-+  u8 isStep;        /* Current in the step function */
-+  int cnt;          /* Number of times that the step function has been called */
-+};
-+
-+/*
-+** An Agg structure describes an Aggregator.  Each Agg consists of
-+** zero or more Aggregator elements (AggElem).  Each AggElem contains
-+** a key and one or more values.  The values are used in processing
-+** aggregate functions in a SELECT.  The key is used to implement
-+** the GROUP BY clause of a select.
-+*/
-+typedef struct Agg Agg;
-+typedef struct AggElem AggElem;
-+struct Agg {
-+  int nMem;            /* Number of values stored in each AggElem */
-+  AggElem *pCurrent;   /* The AggElem currently in focus */
-+  HashElem *pSearch;   /* The hash element for pCurrent */
-+  Hash hash;           /* Hash table of all aggregate elements */
-+  FuncDef **apFunc;    /* Information about aggregate functions */
-+};
-+struct AggElem {
-+  char *zKey;          /* The key to this AggElem */
-+  int nKey;            /* Number of bytes in the key, including '\0' at end */
-+  Mem aMem[1];         /* The values for this AggElem */
-+};
-+
-+/*
-+** 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 */
-+};
-+
-+/*
-+** A Keylist is a bunch of keys into a table.  The keylist can
-+** grow without bound.  The keylist stores the ROWIDs of database
-+** records that need to be deleted or updated.
-+*/
-+typedef struct Keylist Keylist;
-+struct Keylist {
-+  int nKey;         /* Number of slots in aKey[] */
-+  int nUsed;        /* Next unwritten slot in aKey[] */
-+  int nRead;        /* Next unread slot in aKey[] */
-+  Keylist *pNext;   /* Next block of keys */
-+  int aKey[1];      /* One or more keys.  Extra space allocated as needed */
-+};
-+
-+/*
-+** A Context stores the last insert rowid, the last statement change count,
-+** and the current statement change count (i.e. changes since last statement).
-+** Elements of Context structure type make up the ContextStack, which is
-+** updated by the ContextPush and ContextPop opcodes (used by triggers)
-+*/
-+typedef struct Context Context;
-+struct Context {
-+  int lastRowid;    /* Last insert rowid (from db->lastRowid) */
-+  int lsChange;     /* Last statement change count (from db->lsChange) */
-+  int csChange;     /* Current statement change count (from db->csChange) */
-+};
-+
-+/*
-+** An instance of the virtual machine.  This structure contains the complete
-+** state of the virtual machine.
-+**
-+** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
-+** is really a pointer to an instance of this structure.
-+*/
-+struct Vdbe {
-+  sqlite *db;         /* The whole database */
-+  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
-+  FILE *trace;        /* Write an execution trace here, if not NULL */
-+  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 *aStack;        /* The operand stack, except string values */
-+  Mem *pTos;          /* Top entry in the operand stack */
-+  char **zArgv;       /* Text values used by the callback */
-+  char **azColName;   /* Becomes the 4th parameter to callbacks */
-+  int nCursor;        /* Number of slots in aCsr[] */
-+  Cursor *aCsr;       /* One element of this array for each open cursor */
-+  Sorter *pSort;      /* A linked list of objects to be sorted */
-+  FILE *pFile;        /* At most one open file handler */
-+  int nField;         /* Number of file fields */
-+  char **azField;     /* Data for each file field */
-+  int nVar;           /* Number of entries in azVariable[] */
-+  char **azVar;       /* Values for the OP_Variable opcode */
-+  int *anVar;         /* Length of each value in azVariable[] */
-+  u8 *abVar;          /* TRUE if azVariable[i] needs to be sqliteFree()ed */
-+  char *zLine;            /* A single line from the input file */
-+  int nLineAlloc;         /* Number of spaces allocated for zLine */
-+  int magic;              /* Magic number for sanity checking */
-+  int nMem;               /* Number of memory locations currently allocated */
-+  Mem *aMem;              /* The memory locations */
-+  Agg agg;                /* Aggregate information */
-+  int nSet;               /* Number of sets allocated */
-+  Set *aSet;              /* An array of sets */
-+  int nCallback;          /* Number of callbacks invoked so far */
-+  Keylist *pList;         /* A list of ROWIDs */
-+  int keylistStackDepth;  /* The size of the "keylist" stack */
-+  Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */
-+  int contextStackDepth;  /* The size of the "context" stack */
-+  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
-+  int pc;                 /* The program counter */
-+  int rc;                 /* Value to return */
-+  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
-+  int errorAction;        /* Recovery action to do in case of an error */
-+  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
-+  int inTempTrans;        /* True if temp database is transactioned */
-+  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
-+  int returnDepth;        /* Next unused element in returnStack[] */
-+  int nResColumn;         /* Number of columns in one row of the result set */
-+  char **azResColumn;     /* Values for one row of result */ 
-+  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
-+  char *zErrMsg;          /* Error message written here */
-+  u8 explain;             /* True if EXPLAIN present on SQL command */
-+};
-+
-+/*
-+** 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
-+*/
-+void sqliteVdbeCleanupCursor(Cursor*);
-+void sqliteVdbeSorterReset(Vdbe*);
-+void sqliteVdbeAggReset(Agg*);
-+void sqliteVdbeKeylistFree(Keylist*);
-+void sqliteVdbePopStack(Vdbe*,int);
-+int sqliteVdbeCursorMoveto(Cursor*);
-+int sqliteVdbeByteSwap(int);
-+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
-+void sqliteVdbePrintOp(FILE*, int, Op*);
-+#endif
---- /dev/null
-+++ b/ext/sqlite/libsqlite/src/where.c
-@@ -0,0 +1,1235 @@
-+/*
-+** 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.
-+**
-+** $Id$
-+*/
-+#include "sqliteInt.h"
-+
-+/*
-+** 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 an AND operator.
-+*/
-+typedef struct ExprInfo ExprInfo;
-+struct ExprInfo {
-+  Expr *p;                /* Pointer to the subexpression */
-+  u8 indexable;           /* True if this subexprssion is usable by an index */
-+  short int idxLeft;      /* p->pLeft is a column in this table number. -1 if
-+                          ** p->pLeft is not the column of any table */
-+  short int idxRight;     /* p->pRight is a column in this table number. -1 if
-+                          ** p->pRight is not the column of any table */
-+  unsigned prereqLeft;    /* Bitmask of tables referenced by p->pLeft */
-+  unsigned prereqRight;   /* Bitmask of tables referenced by p->pRight */
-+  unsigned prereqAll;     /* Bitmask of tables referenced by p */
-+};
-+
-+/*
-+** An instance of the following structure keeps track of a mapping
-+** between VDBE cursor numbers and bitmasks.  The VDBE cursor numbers
-+** are small integers contained in SrcList_item.iCursor and Expr.iTable
-+** fields.  For any given WHERE clause, we want to track which cursors
-+** are being used, so we assign a single bit in a 32-bit word to track
-+** that cursor.  Then a 32-bit integer is able to show the set of all
-+** cursors being used.
-+*/
-+typedef struct ExprMaskSet ExprMaskSet;
-+struct ExprMaskSet {
-+  int n;          /* Number of assigned cursor values */
-+  int ix[31];     /* Cursor assigned to each bit */
-+};
-+
-+/*
-+** Determine the number of elements in an array.
-+*/
-+#define ARRAYSIZE(X)  (sizeof(X)/sizeof(X[0]))
-+
-+/*
-+** This routine is used to divide the WHERE expression into subexpressions
-+** separated by the AND operator.
-+**
-+** aSlot[] is an array of subexpressions structures.
-+** There are nSlot spaces left in this array.  This routine attempts to
-+** split pExpr into subexpressions and fills aSlot[] with those subexpressions.
-+** The return value is the number of slots filled.
-+*/
-+static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
-+  int cnt = 0;
-+  if( pExpr==0 || nSlot<1 ) return 0;
-+  if( nSlot==1 || pExpr->op!=TK_AND ){
-+    aSlot[0].p = pExpr;
-+    return 1;
-+  }
-+  if( pExpr->pLeft->op!=TK_AND ){
-+    aSlot[0].p = pExpr->pLeft;
-+    cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight);
-+  }else{
-+    cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
-+    cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
-+  }
-+  return cnt;
-+}
-+
-+/*
-+** Initialize an expression mask set
-+*/
-+#define initMaskSet(P)  memset(P, 0, sizeof(*P))
-+
-+/*
-+** Return the bitmask for the given cursor.  Assign a new bitmask
-+** if this is the first time the cursor has been seen.
-+*/
-+static int getMask(ExprMaskSet *pMaskSet, int iCursor){
-+  int i;
-+  for(i=0; i<pMaskSet->n; i++){
-+    if( pMaskSet->ix[i]==iCursor ) return 1<<i;
-+  }
-+  if( i==pMaskSet->n && i<ARRAYSIZE(pMaskSet->ix) ){
-+    pMaskSet->n++;
-+    pMaskSet->ix[i] = iCursor;
-+    return 1<<i;
-+  }
-+  return 0;
-+}
-+
-+/*
-+** Destroy an expression mask set
-+*/
-+#define freeMaskSet(P)   /* NO-OP */
-+
-+/*
-+** 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 sqliteExprResolveIds() on the expression.  See
-+** the header comment on that routine for additional information.
-+** The sqliteExprResolveIds() 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.
-+*/
-+static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
-+  unsigned int mask = 0;
-+  if( p==0 ) return 0;
-+  if( p->op==TK_COLUMN ){
-+    mask = getMask(pMaskSet, p->iTable);
-+    if( mask==0 ) mask = -1;
-+    return mask;
-+  }
-+  if( p->pRight ){
-+    mask = exprTableUsage(pMaskSet, p->pRight);
-+  }
-+  if( p->pLeft ){
-+    mask |= exprTableUsage(pMaskSet, p->pLeft);
-+  }
-+  if( p->pList ){
-+    int i;
-+    for(i=0; i<p->pList->nExpr; i++){
-+      mask |= exprTableUsage(pMaskSet, p->pList->a[i].pExpr);
-+    }
-+  }
-+  return mask;
-+}
-+
-+/*
-+** Return TRUE if the given operator is one of the operators that is
-+** allowed for an indexable WHERE clause.  The allowed operators are
-+** "=", "<", ">", "<=", ">=", and "IN".
-+*/
-+static int allowedOp(int op){
-+  switch( op ){
-+    case TK_LT:
-+    case TK_LE:
-+    case TK_GT:
-+    case TK_GE:
-+    case TK_EQ:
-+    case TK_IN:
-+      return 1;
-+    default:
-+      return 0;
-+  }
-+}
-+
-+/*
-+** The input to this routine is an ExprInfo structure with only the
-+** "p" field filled in.  The job of this routine is to analyze the
-+** subexpression and populate all the other fields of the ExprInfo
-+** structure.
-+*/
-+static void exprAnalyze(ExprMaskSet *pMaskSet, ExprInfo *pInfo){
-+  Expr *pExpr = pInfo->p;
-+  pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
-+  pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
-+  pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr);
-+  pInfo->indexable = 0;
-+  pInfo->idxLeft = -1;
-+  pInfo->idxRight = -1;
-+  if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
-+    if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){
-+      pInfo->idxRight = pExpr->pRight->iTable;
-+      pInfo->indexable = 1;
-+    }
-+    if( pExpr->pLeft->op==TK_COLUMN ){
-+      pInfo->idxLeft = pExpr->pLeft->iTable;
-+      pInfo->indexable = 1;
-+    }
-+  }
-+}
-+
-+/*
-+** 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".
-+**
-+** This routine attempts to find an index for pTab that generates the
-+** correct record sequence for the given ORDER BY clause.  The return value
-+** is a pointer to an index that does the job.  NULL is returned if the
-+** table has no index that will generate the correct sort order.
-+**
-+** If there are two or more indices that generate the correct sort order
-+** and pPreferredIdx is one of those indices, then return pPreferredIdx.
-+**
-+** nEqCol is the number of columns of pPreferredIdx that are used as
-+** equality constraints.  Any index returned must have exactly this same
-+** set of columns.  The ORDER BY clause only matches index columns beyond the
-+** the first nEqCol columns.
-+**
-+** All terms of the ORDER BY clause must be either ASC or DESC.  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 Index *findSortingIndex(
-+  Table *pTab,            /* The table to be sorted */
-+  int base,               /* Cursor number for pTab */
-+  ExprList *pOrderBy,     /* The ORDER BY clause */
-+  Index *pPreferredIdx,   /* Use this index, if possible and not NULL */
-+  int nEqCol,             /* Number of index columns used with == constraints */
-+  int *pbRev              /* Set to 1 if ORDER BY is DESC */
-+){
-+  int i, j;
-+  Index *pMatch;
-+  Index *pIdx;
-+  int sortOrder;
-+
-+  assert( pOrderBy!=0 );
-+  assert( pOrderBy->nExpr>0 );
-+  sortOrder = pOrderBy->a[0].sortOrder & SQLITE_SO_DIRMASK;
-+  for(i=0; i<pOrderBy->nExpr; i++){
-+    Expr *p;
-+    if( (pOrderBy->a[i].sortOrder & SQLITE_SO_DIRMASK)!=sortOrder ){
-+      /* Indices can only be used if all ORDER BY terms are either
-+      ** DESC or ASC.  Indices cannot be used on a mixture. */
-+      return 0;
-+    }
-+    if( (pOrderBy->a[i].sortOrder & SQLITE_SO_TYPEMASK)!=SQLITE_SO_UNK ){
-+      /* Do not sort by index if there is a COLLATE clause */
-+      return 0;
-+    }
-+    p = pOrderBy->a[i].pExpr;
-+    if( p->op!=TK_COLUMN || p->iTable!=base ){
-+      /* Can not use an index sort on anything that is not a column in the
-+      ** left-most table of the FROM clause */
-+      return 0;
-+    }
-+  }
-+  
-+  /* If we get this far, it means the ORDER BY clause consists only of
-+  ** ascending columns in the left-most table of the FROM clause.  Now
-+  ** check for a matching index.
-+  */
-+  pMatch = 0;
-+  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-+    int nExpr = pOrderBy->nExpr;
-+    if( pIdx->nColumn < nEqCol || pIdx->nColumn < nExpr ) continue;
-+    for(i=j=0; i<nEqCol; i++){
-+      if( pPreferredIdx->aiColumn[i]!=pIdx->aiColumn[i] ) break;
-+      if( j<nExpr && pOrderBy->a[j].pExpr->iColumn==pIdx->aiColumn[i] ){ j++; }
-+    }
-+    if( i<nEqCol ) continue;
-+    for(i=0; i+j<nExpr; i++){
-+      if( pOrderBy->a[i+j].pExpr->iColumn!=pIdx->aiColumn[i+nEqCol] ) break;
-+    }
-+    if( i+j>=nExpr ){
-+      pMatch = pIdx;
-+      if( pIdx==pPreferredIdx ) break;
-+    }
-+  }
-+  if( pMatch && pbRev ){
-+    *pbRev = sortOrder==SQLITE_SO_DESC;
-+  }
-+  return pMatch;
-+}
-+
-+/*
-+** 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 did not originate
-+** 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.  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, Expr **ppExpr){
-+  Expr *pExpr = *ppExpr;
-+  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
-+    *ppExpr = 0;
-+  }
-+}
-+
-+/*
-+** 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 sqliteWhereEnd() 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 sqliteWhereBegin()
-+**          foreach row3 in t3 do   /
-+**            ...
-+**          end                     \    Code generated
-+**        end                        |-- by sqliteWhereEnd()
-+**      end                         /
-+**
-+** 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 sqliteWhereEnd() generates the code to close them.
-+**
-+** 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.
-+*/
-+WhereInfo *sqliteWhereBegin(
-+  Parse *pParse,       /* The parser context */
-+  SrcList *pTabList,   /* A list of all tables to be scanned */
-+  Expr *pWhere,        /* The WHERE clause */
-+  int pushKey,         /* If TRUE, leave the table key on the stack */
-+  ExprList **ppOrderBy /* An ORDER BY clause, or NULL */
-+){
-+  int i;                     /* Loop counter */
-+  WhereInfo *pWInfo;         /* Will become the return value of this function */
-+  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
-+  int brk, cont = 0;         /* Addresses used during code generation */
-+  int nExpr;           /* Number of subexpressions in the WHERE clause */
-+  int loopMask;        /* One bit set for each outer loop */
-+  int haveKey;         /* True if KEY is on the stack */
-+  ExprMaskSet maskSet; /* The expression mask set */
-+  int iDirectEq[32];   /* Term of the form ROWID==X for the N-th table */
-+  int iDirectLt[32];   /* Term of the form ROWID<X or ROWID<=X */
-+  int iDirectGt[32];   /* Term of the form ROWID>X or ROWID>=X */
-+  ExprInfo aExpr[101]; /* The WHERE clause is divided into these expressions */
-+
-+  /* pushKey is only allowed if there is a single table (as in an INSERT or
-+  ** UPDATE statement)
-+  */
-+  assert( pushKey==0 || pTabList->nSrc==1 );
-+
-+  /* Split the WHERE clause into separate subexpressions where each
-+  ** subexpression is separated by an AND operator.  If the aExpr[]
-+  ** array fills up, the last entry might point to an expression which
-+  ** contains additional unfactored AND operators.
-+  */
-+  initMaskSet(&maskSet);
-+  memset(aExpr, 0, sizeof(aExpr));
-+  nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
-+  if( nExpr==ARRAYSIZE(aExpr) ){
-+    sqliteErrorMsg(pParse, "WHERE clause too complex - no more "
-+       "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
-+    return 0;
-+  }
-+  
-+  /* Allocate and initialize the WhereInfo structure that will become the
-+  ** return value.
-+  */
-+  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
-+  if( sqlite_malloc_failed ){
-+    sqliteFree(pWInfo);
-+    return 0;
-+  }
-+  pWInfo->pParse = pParse;
-+  pWInfo->pTabList = pTabList;
-+  pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;
-+  pWInfo->iBreak = sqliteVdbeMakeLabel(v);
-+
-+  /* 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 || sqliteExprIsConstant(pWhere)) ){
-+    sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
-+    pWhere = 0;
-+  }
-+
-+  /* Analyze all of the subexpressions.
-+  */
-+  for(i=0; i<nExpr; i++){
-+    exprAnalyze(&maskSet, &aExpr[i]);
-+
-+    /* If we are executing a trigger body, remove all references to
-+    ** new.* and old.* tables from the prerequisite masks.
-+    */
-+    if( pParse->trigStack ){
-+      int x;
-+      if( (x = pParse->trigStack->newIdx) >= 0 ){
-+        int mask = ~getMask(&maskSet, x);
-+        aExpr[i].prereqRight &= mask;
-+        aExpr[i].prereqLeft &= mask;
-+        aExpr[i].prereqAll &= mask;
-+      }
-+      if( (x = pParse->trigStack->oldIdx) >= 0 ){
-+        int mask = ~getMask(&maskSet, x);
-+        aExpr[i].prereqRight &= mask;
-+        aExpr[i].prereqLeft &= mask;
-+        aExpr[i].prereqAll &= mask;
-+      }
-+    }
-+  }
-+
-+  /* Figure out what index to use (if any) for each nested loop.
-+  ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested
-+  ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner
-+  ** loop. 
-+  **
-+  ** If terms exist that use the ROWID of any table, then set the
-+  ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table
-+  ** to the index of the term containing the ROWID.  We always prefer
-+  ** to use a ROWID which can directly access a table rather than an
-+  ** index which requires reading an index first to get the rowid then
-+  ** doing a second read of the actual database table.
-+  **
-+  ** Actually, if there are more than 32 tables in the join, only the
-+  ** first 32 tables are candidates for indices.  This is (again) due
-+  ** to the limit of 32 bits in an integer bitmask.
-+  */
-+  loopMask = 0;
-+  for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){
-+    int j;
-+    int iCur = pTabList->a[i].iCursor;    /* The cursor for this table */
-+    int mask = getMask(&maskSet, iCur);   /* Cursor mask for this table */
-+    Table *pTab = pTabList->a[i].pTab;
-+    Index *pIdx;
-+    Index *pBestIdx = 0;
-+    int bestScore = 0;
-+
-+    /* Check to see if there is an expression that uses only the
-+    ** ROWID field of this table.  For terms of the form ROWID==expr
-+    ** set iDirectEq[i] to the index of the term.  For terms of the
-+    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
-+    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
-+    **
-+    ** (Added:) Treat ROWID IN expr like ROWID=expr.
-+    */
-+    pWInfo->a[i].iCur = -1;
-+    iDirectEq[i] = -1;
-+    iDirectLt[i] = -1;
-+    iDirectGt[i] = -1;
-+    for(j=0; j<nExpr; j++){
-+      if( aExpr[j].idxLeft==iCur && aExpr[j].p->pLeft->iColumn<0
-+            && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
-+        switch( aExpr[j].p->op ){
-+          case TK_IN:
-+          case TK_EQ: iDirectEq[i] = j; break;
-+          case TK_LE:
-+          case TK_LT: iDirectLt[i] = j; break;
-+          case TK_GE:
-+          case TK_GT: iDirectGt[i] = j;  break;
-+        }
-+      }
-+      if( aExpr[j].idxRight==iCur && aExpr[j].p->pRight->iColumn<0
-+            && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
-+        switch( aExpr[j].p->op ){
-+          case TK_EQ: iDirectEq[i] = j;  break;
-+          case TK_LE:
-+          case TK_LT: iDirectGt[i] = j;  break;
-+          case TK_GE:
-+          case TK_GT: iDirectLt[i] = j;  break;
-+        }
-+      }
-+    }
-+    if( iDirectEq[i]>=0 ){
-+      loopMask |= mask;
-+      pWInfo->a[i].pIdx = 0;
-+      continue;
-+    }
-+
-+    /* Do a search for usable indices.  Leave pBestIdx pointing to
-+    ** the "best" index.  pBestIdx is left set to NULL if no indices
-+    ** are usable.
-+    **
-+    ** The best index is determined as follows.  For each of the
-+    ** left-most terms that is fixed by an equality operator, add
-+    ** 8 to the score.  The right-most term of the index may be
-+    ** constrained by an inequality.  Add 1 if for an "x<..." constraint
-+    ** and add 2 for an "x>..." constraint.  Chose the index that
-+    ** gives the best score.
-+    **
-+    ** This scoring system is designed so that the score can later be
-+    ** used to determine how the index is used.  If the score&7 is 0
-+    ** then all constraints are equalities.  If score&1 is not 0 then
-+    ** there is an inequality used as a termination key.  (ex: "x<...")
-+    ** If score&2 is not 0 then there is an inequality used as the
-+    ** start key.  (ex: "x>...").  A score or 4 is the special case
-+    ** of an IN operator constraint.  (ex:  "x IN ...").
-+    **
-+    ** The IN operator (as in "<expr> IN (...)") is treated the same as
-+    ** an equality comparison except that it can only be used on the
-+    ** left-most column of an index and other terms of the WHERE clause
-+    ** cannot be used in conjunction with the IN operator to help satisfy
-+    ** other columns of the index.
-+    */
-+    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-+      int eqMask = 0;  /* Index columns covered by an x=... term */
-+      int ltMask = 0;  /* Index columns covered by an x<... term */
-+      int gtMask = 0;  /* Index columns covered by an x>... term */
-+      int inMask = 0;  /* Index columns covered by an x IN .. term */
-+      int nEq, m, score;
-+
-+      if( pIdx->nColumn>32 ) continue;  /* Ignore indices too many columns */
-+      for(j=0; j<nExpr; j++){
-+        if( aExpr[j].idxLeft==iCur 
-+             && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
-+          int iColumn = aExpr[j].p->pLeft->iColumn;
-+          int k;
-+          for(k=0; k<pIdx->nColumn; k++){
-+            if( pIdx->aiColumn[k]==iColumn ){
-+              switch( aExpr[j].p->op ){
-+                case TK_IN: {
-+                  if( k==0 ) inMask |= 1;
-+                  break;
-+                }
-+                case TK_EQ: {
-+                  eqMask |= 1<<k;
-+                  break;
-+                }
-+                case TK_LE:
-+                case TK_LT: {
-+                  ltMask |= 1<<k;
-+                  break;
-+                }
-+                case TK_GE:
-+                case TK_GT: {
-+                  gtMask |= 1<<k;
-+                  break;
-+                }
-+                default: {
-+                  /* CANT_HAPPEN */
-+                  assert( 0 );
-+                  break;
-+                }
-+              }
-+              break;
-+            }
-+          }
-+        }
-+        if( aExpr[j].idxRight==iCur 
-+             && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
-+          int iColumn = aExpr[j].p->pRight->iColumn;
-+          int k;
-+          for(k=0; k<pIdx->nColumn; k++){
-+            if( pIdx->aiColumn[k]==iColumn ){
-+              switch( aExpr[j].p->op ){
-+                case TK_EQ: {
-+                  eqMask |= 1<<k;
-+                  break;
-+                }
-+                case TK_LE:
-+                case TK_LT: {
-+                  gtMask |= 1<<k;
-+                  break;
-+                }
-+                case TK_GE:
-+                case TK_GT: {
-+                  ltMask |= 1<<k;
-+                  break;
-+                }
-+                default: {
-+                  /* CANT_HAPPEN */
-+                  assert( 0 );
-+                  break;
-+                }
-+              }
-+              break;
-+            }
-+          }
-+        }
-+      }
-+
-+      /* The following loop ends with nEq set to the number of columns
-+      ** on the left of the index with == constraints.
-+      */
-+      for(nEq=0; nEq<pIdx->nColumn; nEq++){
-+        m = (1<<(nEq+1))-1;
-+        if( (m & eqMask)!=m ) break;
-+      }
-+      score = nEq*8;   /* Base score is 8 times number of == constraints */
-+      m = 1<<nEq;
-+      if( m & ltMask ) score++;    /* Increase score for a < constraint */
-+      if( m & gtMask ) score+=2;   /* Increase score for a > constraint */
-+      if( score==0 && inMask ) score = 4;  /* Default score for IN constraint */
-+      if( score>bestScore ){
-+        pBestIdx = pIdx;
-+        bestScore = score;
-+      }
-+    }
-+    pWInfo->a[i].pIdx = pBestIdx;
-+    pWInfo->a[i].score = bestScore;
-+    pWInfo->a[i].bRev = 0;
-+    loopMask |= mask;
-+    if( pBestIdx ){
-+      pWInfo->a[i].iCur = pParse->nTab++;
-+      pWInfo->peakNTab = pParse->nTab;
-+    }
-+  }
-+
-+  /* Check to see if the ORDER BY clause is or can be satisfied by the
-+  ** use of an index on the first table.
-+  */
-+  if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){
-+     Index *pSortIdx;
-+     Index *pIdx;
-+     Table *pTab;
-+     int bRev = 0;
-+
-+     pTab = pTabList->a[0].pTab;
-+     pIdx = pWInfo->a[0].pIdx;
-+     if( pIdx && pWInfo->a[0].score==4 ){
-+       /* If there is already an IN index on the left-most table,
-+       ** it will not give the correct sort order.
-+       ** So, pretend that no suitable index is found.
-+       */
-+       pSortIdx = 0;
-+     }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){
-+       /* If the left-most column is accessed using its ROWID, then do
-+       ** not try to sort by index.
-+       */
-+       pSortIdx = 0;
-+     }else{
-+       int nEqCol = (pWInfo->a[0].score+4)/8;
-+       pSortIdx = findSortingIndex(pTab, pTabList->a[0].iCursor, 
-+                                   *ppOrderBy, pIdx, nEqCol, &bRev);
-+     }
-+     if( pSortIdx && (pIdx==0 || pIdx==pSortIdx) ){
-+       if( pIdx==0 ){
-+         pWInfo->a[0].pIdx = pSortIdx;
-+         pWInfo->a[0].iCur = pParse->nTab++;
-+         pWInfo->peakNTab = pParse->nTab;
-+       }
-+       pWInfo->a[0].bRev = bRev;
-+       *ppOrderBy = 0;
-+     }
-+  }
-+
-+  /* Open all tables in the pTabList and all indices used by those tables.
-+  */
-+  for(i=0; i<pTabList->nSrc; i++){
-+    Table *pTab;
-+    Index *pIx;
-+
-+    pTab = pTabList->a[i].pTab;
-+    if( pTab->isTransient || pTab->pSelect ) continue;
-+    sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
-+    sqliteVdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
-+                     pTab->zName, P3_STATIC);
-+    sqliteCodeVerifySchema(pParse, pTab->iDb);
-+    if( (pIx = pWInfo->a[i].pIdx)!=0 ){
-+      sqliteVdbeAddOp(v, OP_Integer, pIx->iDb, 0);
-+      sqliteVdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
-+    }
-+  }
-+
-+  /* Generate the code to do the search
-+  */
-+  loopMask = 0;
-+  for(i=0; i<pTabList->nSrc; i++){
-+    int j, k;
-+    int iCur = pTabList->a[i].iCursor;
-+    Index *pIdx;
-+    WhereLevel *pLevel = &pWInfo->a[i];
-+
-+    /* 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( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
-+      if( !pParse->nMem ) pParse->nMem++;
-+      pLevel->iLeftJoin = pParse->nMem++;
-+      sqliteVdbeAddOp(v, OP_String, 0, 0);
-+      sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
-+    }
-+
-+    pIdx = pLevel->pIdx;
-+    pLevel->inOp = OP_Noop;
-+    if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
-+      /* 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.
-+      */
-+      k = iDirectEq[i];
-+      assert( k<nExpr );
-+      assert( aExpr[k].p!=0 );
-+      assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
-+      brk = pLevel->brk = sqliteVdbeMakeLabel(v);
-+      if( aExpr[k].idxLeft==iCur ){
-+        Expr *pX = aExpr[k].p;
-+        if( pX->op!=TK_IN ){
-+          sqliteExprCode(pParse, aExpr[k].p->pRight);
-+        }else if( pX->pList ){
-+          sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
-+          pLevel->inOp = OP_SetNext;
-+          pLevel->inP1 = pX->iTable;
-+          pLevel->inP2 = sqliteVdbeCurrentAddr(v);
-+        }else{
-+          assert( pX->pSelect );
-+          sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
-+          sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
-+          pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
-+          pLevel->inOp = OP_Next;
-+          pLevel->inP1 = pX->iTable;
-+        }
-+      }else{
-+        sqliteExprCode(pParse, aExpr[k].p->pLeft);
-+      }
-+      disableTerm(pLevel, &aExpr[k].p);
-+      cont = pLevel->cont = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
-+      haveKey = 0;
-+      sqliteVdbeAddOp(v, OP_NotExists, iCur, brk);
-+      pLevel->op = OP_Noop;
-+    }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
-+      /* Case 2:  There is an index and all terms of the WHERE clause that
-+      **          refer to the index use the "==" or "IN" operators.
-+      */
-+      int start;
-+      int testOp;
-+      int nColumn = (pLevel->score+4)/8;
-+      brk = pLevel->brk = sqliteVdbeMakeLabel(v);
-+      for(j=0; j<nColumn; j++){
-+        for(k=0; k<nExpr; k++){
-+          Expr *pX = aExpr[k].p;
-+          if( pX==0 ) continue;
-+          if( aExpr[k].idxLeft==iCur
-+             && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
-+             && pX->pLeft->iColumn==pIdx->aiColumn[j]
-+          ){
-+            if( pX->op==TK_EQ ){
-+              sqliteExprCode(pParse, pX->pRight);
-+              disableTerm(pLevel, &aExpr[k].p);
-+              break;
-+            }
-+            if( pX->op==TK_IN && nColumn==1 ){
-+              if( pX->pList ){
-+                sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
-+                pLevel->inOp = OP_SetNext;
-+                pLevel->inP1 = pX->iTable;
-+                pLevel->inP2 = sqliteVdbeCurrentAddr(v);
-+              }else{
-+                assert( pX->pSelect );
-+                sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
-+                sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
-+                pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
-+                pLevel->inOp = OP_Next;
-+                pLevel->inP1 = pX->iTable;
-+              }
-+              disableTerm(pLevel, &aExpr[k].p);
-+              break;
-+            }
-+          }
-+          if( aExpr[k].idxRight==iCur
-+             && aExpr[k].p->op==TK_EQ
-+             && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
-+             && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, aExpr[k].p->pLeft);
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+        }
-+      }
-+      pLevel->iMem = pParse->nMem++;
-+      cont = pLevel->cont = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_NotNull, -nColumn, sqliteVdbeCurrentAddr(v)+3);
-+      sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
-+      sqliteVdbeAddOp(v, OP_Goto, 0, brk);
-+      sqliteVdbeAddOp(v, OP_MakeKey, nColumn, 0);
-+      sqliteAddIdxKeyType(v, pIdx);
-+      if( nColumn==pIdx->nColumn || pLevel->bRev ){
-+        sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
-+        testOp = OP_IdxGT;
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Dup, 0, 0);
-+        sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
-+        sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
-+        testOp = OP_IdxGE;
-+      }
-+      if( pLevel->bRev ){
-+        /* Scan in reverse order */
-+        sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
-+        sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
-+        start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-+        sqliteVdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
-+        pLevel->op = OP_Prev;
-+      }else{
-+        /* Scan in the forward order */
-+        sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
-+        start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-+        sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
-+        pLevel->op = OP_Next;
-+      }
-+      sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
-+      sqliteVdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
-+      sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
-+      if( i==pTabList->nSrc-1 && pushKey ){
-+        haveKey = 1;
-+      }else{
-+        sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+        haveKey = 0;
-+      }
-+      pLevel->p1 = pLevel->iCur;
-+      pLevel->p2 = start;
-+    }else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
-+      /* Case 3:  We have an inequality comparison against the ROWID field.
-+      */
-+      int testOp = OP_Noop;
-+      int start;
-+
-+      brk = pLevel->brk = sqliteVdbeMakeLabel(v);
-+      cont = pLevel->cont = sqliteVdbeMakeLabel(v);
-+      if( iDirectGt[i]>=0 ){
-+        k = iDirectGt[i];
-+        assert( k<nExpr );
-+        assert( aExpr[k].p!=0 );
-+        assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
-+        if( aExpr[k].idxLeft==iCur ){
-+          sqliteExprCode(pParse, aExpr[k].p->pRight);
-+        }else{
-+          sqliteExprCode(pParse, aExpr[k].p->pLeft);
-+        }
-+        sqliteVdbeAddOp(v, OP_ForceInt,
-+          aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
-+        sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
-+        disableTerm(pLevel, &aExpr[k].p);
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
-+      }
-+      if( iDirectLt[i]>=0 ){
-+        k = iDirectLt[i];
-+        assert( k<nExpr );
-+        assert( aExpr[k].p!=0 );
-+        assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
-+        if( aExpr[k].idxLeft==iCur ){
-+          sqliteExprCode(pParse, aExpr[k].p->pRight);
-+        }else{
-+          sqliteExprCode(pParse, aExpr[k].p->pLeft);
-+        }
-+        /* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */
-+        pLevel->iMem = pParse->nMem++;
-+        sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
-+        if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
-+          testOp = OP_Ge;
-+        }else{
-+          testOp = OP_Gt;
-+        }
-+        disableTerm(pLevel, &aExpr[k].p);
-+      }
-+      start = sqliteVdbeCurrentAddr(v);
-+      pLevel->op = OP_Next;
-+      pLevel->p1 = iCur;
-+      pLevel->p2 = start;
-+      if( testOp!=OP_Noop ){
-+        sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
-+        sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-+        sqliteVdbeAddOp(v, testOp, 0, brk);
-+      }
-+      haveKey = 0;
-+    }else if( pIdx==0 ){
-+      /* Case 4:  There is no usable index.  We must do a complete
-+      **          scan of the entire database table.
-+      */
-+      int start;
-+
-+      brk = pLevel->brk = sqliteVdbeMakeLabel(v);
-+      cont = pLevel->cont = sqliteVdbeMakeLabel(v);
-+      sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
-+      start = sqliteVdbeCurrentAddr(v);
-+      pLevel->op = OP_Next;
-+      pLevel->p1 = iCur;
-+      pLevel->p2 = start;
-+      haveKey = 0;
-+    }else{
-+      /* Case 5: The WHERE clause term that refers to the right-most
-+      **         column of the index is an inequality.  For example, if
-+      **         the index is on (x,y,z) and the WHERE clause is of the
-+      **         form "x=5 AND y<10" then this case is used.  Only the
-+      **         right-most column can be an inequality - the rest must
-+      **         use the "==" operator.
-+      **
-+      **         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 score = pLevel->score;
-+      int nEqColumn = score/8;
-+      int start;
-+      int leFlag, geFlag;
-+      int testOp;
-+
-+      /* Evaluate the equality constraints
-+      */
-+      for(j=0; j<nEqColumn; j++){
-+        for(k=0; k<nExpr; k++){
-+          if( aExpr[k].p==0 ) continue;
-+          if( aExpr[k].idxLeft==iCur
-+             && aExpr[k].p->op==TK_EQ
-+             && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
-+             && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, aExpr[k].p->pRight);
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+          if( aExpr[k].idxRight==iCur
-+             && aExpr[k].p->op==TK_EQ
-+             && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
-+             && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, aExpr[k].p->pLeft);
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+        }
-+      }
-+
-+      /* Duplicate the equality term values because they will all be
-+      ** used twice: once to make the termination key and once to make the
-+      ** start key.
-+      */
-+      for(j=0; j<nEqColumn; j++){
-+        sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
-+      }
-+
-+      /* Labels for the beginning and end of the loop
-+      */
-+      cont = pLevel->cont = sqliteVdbeMakeLabel(v);
-+      brk = pLevel->brk = sqliteVdbeMakeLabel(v);
-+
-+      /* Generate the termination key.  This is the key value that
-+      ** will end the search.  There is no termination key if there
-+      ** are no equality terms and no "X<..." term.
-+      **
-+      ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
-+      ** key computed here really ends up being the start key.
-+      */
-+      if( (score & 1)!=0 ){
-+        for(k=0; k<nExpr; k++){
-+          Expr *pExpr = aExpr[k].p;
-+          if( pExpr==0 ) continue;
-+          if( aExpr[k].idxLeft==iCur
-+             && (pExpr->op==TK_LT || pExpr->op==TK_LE)
-+             && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
-+             && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, pExpr->pRight);
-+            leFlag = pExpr->op==TK_LE;
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+          if( aExpr[k].idxRight==iCur
-+             && (pExpr->op==TK_GT || pExpr->op==TK_GE)
-+             && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
-+             && pExpr->pRight->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, pExpr->pLeft);
-+            leFlag = pExpr->op==TK_GE;
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+        }
-+        testOp = OP_IdxGE;
-+      }else{
-+        testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
-+        leFlag = 1;
-+      }
-+      if( testOp!=OP_Noop ){
-+        int nCol = nEqColumn + (score & 1);
-+        pLevel->iMem = pParse->nMem++;
-+        sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
-+        sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, brk);
-+        sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
-+        sqliteAddIdxKeyType(v, pIdx);
-+        if( leFlag ){
-+          sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
-+        }
-+        if( pLevel->bRev ){
-+          sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
-+        }else{
-+          sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
-+        }
-+      }else if( pLevel->bRev ){
-+        sqliteVdbeAddOp(v, OP_Last, pLevel->iCur, brk);
-+      }
-+
-+      /* Generate the start key.  This is the key that defines the lower
-+      ** bound on the search.  There is no start key if there are no
-+      ** equality terms and if there is no "X>..." term.  In
-+      ** that case, generate a "Rewind" instruction in place of the
-+      ** start key search.
-+      **
-+      ** 2002-Dec-04: In the case of a reverse-order search, the so-called
-+      ** "start" key really ends up being used as the termination key.
-+      */
-+      if( (score & 2)!=0 ){
-+        for(k=0; k<nExpr; k++){
-+          Expr *pExpr = aExpr[k].p;
-+          if( pExpr==0 ) continue;
-+          if( aExpr[k].idxLeft==iCur
-+             && (pExpr->op==TK_GT || pExpr->op==TK_GE)
-+             && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
-+             && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, pExpr->pRight);
-+            geFlag = pExpr->op==TK_GE;
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+          if( aExpr[k].idxRight==iCur
-+             && (pExpr->op==TK_LT || pExpr->op==TK_LE)
-+             && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
-+             && pExpr->pRight->iColumn==pIdx->aiColumn[j]
-+          ){
-+            sqliteExprCode(pParse, pExpr->pLeft);
-+            geFlag = pExpr->op==TK_LE;
-+            disableTerm(pLevel, &aExpr[k].p);
-+            break;
-+          }
-+        }
-+      }else{
-+        geFlag = 1;
-+      }
-+      if( nEqColumn>0 || (score&2)!=0 ){
-+        int nCol = nEqColumn + ((score&2)!=0);
-+        sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
-+        sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
-+        sqliteVdbeAddOp(v, OP_Goto, 0, brk);
-+        sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
-+        sqliteAddIdxKeyType(v, pIdx);
-+        if( !geFlag ){
-+          sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
-+        }
-+        if( pLevel->bRev ){
-+          pLevel->iMem = pParse->nMem++;
-+          sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
-+          testOp = OP_IdxLT;
-+        }else{
-+          sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
-+        }
-+      }else if( pLevel->bRev ){
-+        testOp = OP_Noop;
-+      }else{
-+        sqliteVdbeAddOp(v, OP_Rewind, pLevel->iCur, brk);
-+      }
-+
-+      /* Generate the the top of the loop.  If there is a termination
-+      ** key we have to test for that key and abort at the top of the
-+      ** loop.
-+      */
-+      start = sqliteVdbeCurrentAddr(v);
-+      if( testOp!=OP_Noop ){
-+        sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-+        sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
-+      }
-+      sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
-+      sqliteVdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
-+      sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
-+      if( i==pTabList->nSrc-1 && pushKey ){
-+        haveKey = 1;
-+      }else{
-+        sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+        haveKey = 0;
-+      }
-+
-+      /* Record the instruction used to terminate the loop.
-+      */
-+      pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
-+      pLevel->p1 = pLevel->iCur;
-+      pLevel->p2 = start;
-+    }
-+    loopMask |= getMask(&maskSet, iCur);
-+
-+    /* Insert code to test every subexpression that can be completely
-+    ** computed using the current set of tables.
-+    */
-+    for(j=0; j<nExpr; j++){
-+      if( aExpr[j].p==0 ) continue;
-+      if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
-+      if( pLevel->iLeftJoin && !ExprHasProperty(aExpr[j].p,EP_FromJoin) ){
-+        continue;
-+      }
-+      if( haveKey ){
-+        haveKey = 0;
-+        sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+      }
-+      sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
-+      aExpr[j].p = 0;
-+    }
-+    brk = cont;
-+
-+    /* 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->top = sqliteVdbeCurrentAddr(v);
-+      sqliteVdbeAddOp(v, OP_Integer, 1, 0);
-+      sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
-+      for(j=0; j<nExpr; j++){
-+        if( aExpr[j].p==0 ) continue;
-+        if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
-+        if( haveKey ){
-+          /* Cannot happen.  "haveKey" can only be true if pushKey is true
-+          ** an pushKey can only be true for DELETE and UPDATE and there are
-+          ** no outer joins with DELETE and UPDATE.
-+          */
-+          haveKey = 0;
-+          sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
-+        }
-+        sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
-+        aExpr[j].p = 0;
-+      }
-+    }
-+  }
-+  pWInfo->iContinue = cont;
-+  if( pushKey && !haveKey ){
-+    sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0);
-+  }
-+  freeMaskSet(&maskSet);
-+  return pWInfo;
-+}
-+
-+/*
-+** Generate the end of the WHERE loop.  See comments on 
-+** sqliteWhereBegin() for additional information.
-+*/
-+void sqliteWhereEnd(WhereInfo *pWInfo){
-+  Vdbe *v = pWInfo->pParse->pVdbe;
-+  int i;
-+  WhereLevel *pLevel;
-+  SrcList *pTabList = pWInfo->pTabList;
-+
-+  for(i=pTabList->nSrc-1; i>=0; i--){
-+    pLevel = &pWInfo->a[i];
-+    sqliteVdbeResolveLabel(v, pLevel->cont);
-+    if( pLevel->op!=OP_Noop ){
-+      sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
-+    }
-+    sqliteVdbeResolveLabel(v, pLevel->brk);
-+    if( pLevel->inOp!=OP_Noop ){
-+      sqliteVdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
-+    }
-+    if( pLevel->iLeftJoin ){
-+      int addr;
-+      addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
-+      sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0));
-+      sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
-+      if( pLevel->iCur>=0 ){
-+        sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0);
-+      }
-+      sqliteVdbeAddOp(v, OP_Goto, 0, pLevel->top);
-+    }
-+  }
-+  sqliteVdbeResolveLabel(v, pWInfo->iBreak);
-+  for(i=0; i<pTabList->nSrc; i++){
-+    Table *pTab = pTabList->a[i].pTab;
-+    assert( pTab!=0 );
-+    if( pTab->isTransient || pTab->pSelect ) continue;
-+    pLevel = &pWInfo->a[i];
-+    sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0);
-+    if( pLevel->pIdx!=0 ){
-+      sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0);
-+    }
-+  }
-+#if 0  /* Never reuse a cursor */
-+  if( pWInfo->pParse->nTab==pWInfo->peakNTab ){
-+    pWInfo->pParse->nTab = pWInfo->savedNTab;
-+  }
-+#endif
-+  sqliteFree(pWInfo);
-+  return;
-+}
---- /dev/null
-+++ b/ext/sqlite/libsqlite/VERSION
-@@ -0,0 +1 @@
-+2.8.17
---- /dev/null
-+++ b/ext/sqlite/Makefile.frag
-@@ -0,0 +1,2 @@
-+$(srcdir)/libsqlite/src/parse.c: $(srcdir)/libsqlite/src/parse.y
-+      @$(LEMON) $(srcdir)/libsqlite/src/parse.y 
---- /dev/null
-+++ b/ext/sqlite/package.xml
-@@ -0,0 +1,136 @@
-+<?xml version="1.0" encoding="ISO-8859-1" ?>
-+<!DOCTYPE package SYSTEM "../pear/package.dtd">
-+<package>
-+ <name>SQLite</name>
-+ <summary>SQLite database bindings</summary>
-+ <maintainers>
-+  <maintainer>
-+   <user>wez</user>
-+   <name>Wez Furlong</name>
-+   <email>wez@php.net</email>
-+   <role>lead</role>
-+  </maintainer>
-+  <maintainer>
-+   <user>tal</user>
-+   <name>Tal Peer</name>
-+   <email>tal@php.net</email>
-+   <role>developer</role>
-+  </maintainer>
-+  <maintainer>
-+   <user>helly</user>
-+   <name>Marcus Börger</name>
-+   <email>helly@php.net</email>
-+   <role>lead</role>
-+  </maintainer>
-+  <maintainer>
-+   <user>iliaa</user>
-+   <name>Ilia Alshanetsky</name>
-+   <email>ilia@php.net</email>
-+   <role>developer</role>
-+  </maintainer>
-+ </maintainers>
-+ <description>
-+SQLite is a C library that implements an embeddable SQL database engine.
-+Programs that link with the SQLite library can have SQL database access
-+without running a separate RDBMS process.
-+This extension allows you to access SQLite databases from within PHP.
-+
-+Windows binary available from:
-+http://snaps.php.net/win32/PECL_STABLE/php_sqlite.dll
-+ </description>
-+ <license>PHP</license>
-+ <release>
-+  <state>stable</state>
-+  <version>2.0-dev</version>
-+  <date>TBA</date>
-+  <notes>
-+   Added:
-+   OO API (Marcus).
-+  </notes>
-+  <filelist>
-+   <file role="src" name="config.m4"/>
-+   <file role="src" name="config.w32"/>
-+   <file role="src" name="sqlite.c"/>
-+   <file role="src" name="sqlite.dsp"/>
-+   <file role="src" name="php_sqlite.h"/>
-+   <file role="src" name="php_sqlite.def"/>
-+   <file role="doc" name="CREDITS"/>
-+   <file role="doc" name="README"/>
-+   <file role="doc" name="TODO"/>
-+   <file role="doc" name="sqlite.php"/>
-+   <file role="test" name="tests/sqlite_001.phpt"/>
-+   <file role="test" name="tests/sqlite_002.phpt"/>
-+   <file role="test" name="tests/sqlite_003.phpt"/>
-+   <file role="test" name="tests/sqlite_004.phpt"/>
-+   <file role="test" name="tests/sqlite_005.phpt"/>
-+   <file role="test" name="tests/sqlite_006.phpt"/>
-+   <file role="test" name="tests/sqlite_007.phpt"/>
-+   <file role="test" name="tests/sqlite_008.phpt"/>
-+   <file role="test" name="tests/sqlite_009.phpt"/>
-+   <file role="test" name="tests/sqlite_010.phpt"/>
-+   <file role="test" name="tests/sqlite_011.phpt"/>
-+   <file role="test" name="tests/sqlite_012.phpt"/>
-+   <file role="test" name="tests/sqlite_013.phpt"/>
-+   <file role="test" name="tests/sqlite_014.phpt"/>
-+   <file role="test" name="tests/sqlite_015.phpt"/>
-+   <file role="test" name="tests/sqlite_016.phpt"/>
-+   <file role="test" name="tests/sqlite_017.phpt"/>
-+   <file role="test" name="tests/blankdb.inc"/>
-+
-+   <dir name="libsqlite">
-+    <file role="doc" name="README"/>
-+    <file role="src" name="VERSION"/>
-+
-+    <dir name="src">
-+     <file role="src" name="attach.c"/>
-+     <file role="src" name="auth.c"/>
-+     <file role="src" name="btree.c"/>
-+     <file role="src" name="btree_rb.c"/>
-+     <file role="src" name="build.c"/>
-+     <file role="src" name="copy.c"/>
-+     <file role="src" name="delete.c"/>
-+     <file role="src" name="encode.c"/>
-+     <file role="src" name="expr.c"/>
-+     <file role="src" name="func.c"/>
-+     <file role="src" name="hash.c"/>
-+     <file role="src" name="insert.c"/>
-+     <file role="src" name="main.c"/>
-+     <file role="src" name="opcodes.c"/>
-+     <file role="src" name="os.c"/>
-+     <file role="src" name="pager.c"/>
-+     <file role="src" name="parse.c"/>
-+     <file role="src" name="parse.y"/>
-+     <file role="src" name="pragma.c"/>
-+     <file role="src" name="printf.c"/>
-+     <file role="src" name="random.c"/>
-+     <file role="src" name="select.c"/>
-+     <file role="src" name="table.c"/>
-+     <file role="src" name="tokenize.c"/>
-+     <file role="src" name="trigger.c"/>
-+     <file role="src" name="update.c"/>
-+     <file role="src" name="util.c"/>
-+     <file role="src" name="vacuum.c"/>
-+     <file role="src" name="vdbe.c"/>
-+     <file role="src" name="where.c"/>
-+     <file role="src" name="btree.h"/>
-+     <file role="src" name="hash.h"/>
-+     <file role="src" name="opcodes.h"/>
-+     <file role="src" name="os.h"/>
-+     <file role="src" name="pager.h"/>
-+     <file role="src" name="parse.h"/>
-+     <file role="src" name="sqlite_config.w32.h"/>
-+     <file role="src" name="sqlite.h.in"/>
-+     <file role="src" name="sqliteInt.h"/>
-+     <file role="src" name="sqlite.w32.h"/>
-+     <file role="src" name="vdbe.h"/>
-+    </dir>
-+   </dir>
-+  </filelist>
-+  <deps>
-+   <dep type="php" rel="ge" version="5" />
-+  </deps>
-+ </release>
-+</package>
-+<!--
-+vim:et:ts=1:sw=1
-+-->
---- /dev/null
-+++ b/ext/sqlite/pdo_sqlite2.c
-@@ -0,0 +1,638 @@
-+/*
-+  +----------------------------------------------------------------------+
-+  | PHP Version 5                                                        |
-+  +----------------------------------------------------------------------+
-+  | Copyright (c) 1997-2012 The PHP Group                                |
-+  +----------------------------------------------------------------------+
-+  | This source file is subject to version 3.01 of the PHP license,      |
-+  | that is bundled with this package in the file LICENSE, and is        |
-+  | available through the world-wide-web at the following url:           |
-+  | http://www.php.net/license/3_01.txt                                  |
-+  | If you did not receive a copy of the PHP license and are unable to   |
-+  | obtain it through the world-wide-web, please send a note to          |
-+  | license@php.net so we can mail you a copy immediately.               |
-+  +----------------------------------------------------------------------+
-+  | Author: Wez Furlong <wez@php.net>                                    |
-+  +----------------------------------------------------------------------+
-+*/
-+
-+/* $Id$ */
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+#include "php.h"
-+
-+#ifdef PHP_SQLITE2_HAVE_PDO
-+#include "sqlite.h"
-+#include "pdo/php_pdo.h"
-+#include "pdo/php_pdo_driver.h"
-+#include "zend_exceptions.h"
-+
-+#define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
-+#define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
-+
-+
-+typedef struct {
-+      const char *file;
-+      int line;
-+      unsigned int errcode;
-+      char *errmsg;
-+} pdo_sqlite2_error_info;
-+
-+typedef struct {
-+      sqlite *db;
-+      pdo_sqlite2_error_info einfo;
-+} pdo_sqlite2_db_handle;
-+
-+typedef struct {
-+      pdo_sqlite2_db_handle   *H;
-+      sqlite_vm *vm;
-+      const char **rowdata, **colnames;
-+      int ncols;
-+      unsigned pre_fetched:1;
-+      unsigned done:1;
-+      pdo_sqlite2_error_info einfo;
-+} pdo_sqlite2_stmt;
-+
-+extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
-+#define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
-+#define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
-+
-+extern struct pdo_stmt_methods sqlite2_stmt_methods;
-+
-+static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
-+{
-+      pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
-+
-+      if (S->vm) {
-+              char *errmsg = NULL;
-+              sqlite_finalize(S->vm, &errmsg);
-+              if (errmsg) {
-+                      sqlite_freemem(errmsg);
-+              }
-+              S->vm = NULL;
-+      }
-+      if (S->einfo.errmsg) {
-+              pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
-+      }
-+      efree(S);
-+      return 1;
-+}
-+
-+static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
-+{
-+      pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
-+      char *errmsg = NULL;
-+      const char *tail;
-+
-+      if (stmt->executed && !S->done) {
-+              sqlite_finalize(S->vm, &errmsg);
-+              pdo_sqlite2_error_stmt(errmsg, stmt);
-+              errmsg = NULL;
-+              S->vm = NULL;
-+      }
-+
-+      S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
-+      if (S->einfo.errcode != SQLITE_OK) {
-+              pdo_sqlite2_error_stmt(errmsg, stmt);
-+              return 0;
-+      }
-+
-+      S->done = 0;
-+      S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
-+      switch (S->einfo.errcode) {
-+              case SQLITE_ROW:
-+                      S->pre_fetched = 1;
-+                      stmt->column_count = S->ncols;
-+                      return 1;
-+
-+              case SQLITE_DONE:
-+                      stmt->column_count = S->ncols;
-+                      stmt->row_count = sqlite_changes(S->H->db);
-+                      S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
-+                      if (S->einfo.errcode != SQLITE_OK) {
-+                              pdo_sqlite2_error_stmt(errmsg, stmt);
-+                      }
-+                      S->done = 1;
-+                      return 1;
-+
-+              case SQLITE_ERROR:
-+              case SQLITE_MISUSE:
-+              case SQLITE_BUSY:
-+              default:
-+                      pdo_sqlite2_error_stmt(errmsg, stmt);
-+                      return 0;
-+      }
-+}
-+
-+static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
-+              enum pdo_param_event event_type TSRMLS_DC)
-+{
-+      return 1;
-+}
-+
-+static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
-+      enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
-+{
-+      pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
-+      char *errmsg = NULL;
-+
-+      if (!S->vm) {
-+              return 0;       
-+      }
-+      if (S->pre_fetched) {
-+              S->pre_fetched = 0;
-+              return 1;
-+      }
-+      if (S->done) {
-+              return 0;
-+      }
-+
-+      S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
-+      switch (S->einfo.errcode) {
-+              case SQLITE_ROW:
-+                      return 1;
-+
-+              case SQLITE_DONE:
-+                      S->done = 1;
-+                      S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
-+                      if (S->einfo.errcode != SQLITE_OK) {
-+                              pdo_sqlite2_error_stmt(errmsg, stmt);
-+                              errmsg = NULL;
-+                      }
-+                      return 0;
-+
-+              default:
-+                      pdo_sqlite2_error_stmt(errmsg, stmt);
-+                      return 0;
-+      }
-+}
-+
-+static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
-+{
-+      pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
-+
-+      if(colno >= S->ncols) {
-+              /* error invalid column */
-+              pdo_sqlite2_error_stmt(NULL, stmt);
-+              return 0;
-+      }
-+
-+      stmt->columns[colno].name = estrdup(S->colnames[colno]);
-+      stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
-+      stmt->columns[colno].maxlen = 0xffffffff;
-+      stmt->columns[colno].precision = 0;
-+      stmt->columns[colno].param_type = PDO_PARAM_STR;
-+
-+      return 1;
-+}
-+
-+static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
-+{
-+      pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
-+      if (!S->vm) {
-+              return 0;
-+      }
-+      if(colno >= S->ncols) {
-+              /* error invalid column */
-+              pdo_sqlite2_error_stmt(NULL, stmt);
-+              return 0;
-+      }
-+      if (S->rowdata[colno]) {
-+              if (S->rowdata[colno][0] == '\x01') {
-+                      /* encoded */
-+                      *caller_frees = 1;
-+                      *ptr = emalloc(strlen(S->rowdata[colno]));
-+                      *len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
-+                      (*(char**)ptr)[*len] = '\0';
-+              } else {
-+                      *ptr = (char*)S->rowdata[colno];
-+                      *len = strlen(*ptr);
-+              }
-+      } else {
-+              *ptr = NULL;
-+              *len = 0;
-+      }
-+      return 1;
-+}
-+
-+struct pdo_stmt_methods sqlite2_stmt_methods = {
-+      pdo_sqlite2_stmt_dtor,
-+      pdo_sqlite2_stmt_execute,
-+      pdo_sqlite2_stmt_fetch,
-+      pdo_sqlite2_stmt_describe,
-+      pdo_sqlite2_stmt_get_col,
-+      pdo_sqlite2_stmt_param_hook,
-+      NULL, /* set_attr */
-+      NULL, /* get_attr */
-+      NULL
-+};
-+
-+
-+int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
-+      pdo_sqlite2_error_info *einfo = &H->einfo;
-+      pdo_sqlite2_stmt *S;
-+
-+      if (stmt) {
-+              S = stmt->driver_data;
-+              einfo = &S->einfo;
-+      }
-+
-+      einfo->file = file;
-+      einfo->line = line;
-+
-+      if (einfo->errmsg) {
-+              pefree(einfo->errmsg, dbh->is_persistent);
-+              einfo->errmsg = NULL;
-+      }
-+
-+      if (einfo->errcode != SQLITE_OK) {
-+              if (errmsg) {
-+                      einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
-+                      sqlite_freemem(errmsg);
-+              } else {
-+                      einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
-+              }
-+      } else { /* no error */
-+              strcpy(*pdo_err, PDO_ERR_NONE);
-+              return 0;
-+      }
-+      switch (einfo->errcode) {
-+              case SQLITE_NOTFOUND:
-+                      strcpy(*pdo_err, "42S02");
-+                      break;  
-+
-+              case SQLITE_INTERRUPT:
-+                      strcpy(*pdo_err, "01002");
-+                      break;
-+
-+              case SQLITE_NOLFS:
-+                      strcpy(*pdo_err, "HYC00");
-+                      break;
-+
-+              case SQLITE_TOOBIG:
-+                      strcpy(*pdo_err, "22001");
-+                      break;
-+
-+              case SQLITE_CONSTRAINT:
-+                      strcpy(*pdo_err, "23000");
-+                      break;
-+
-+              case SQLITE_ERROR:
-+              default:
-+                      strcpy(*pdo_err, "HY000");
-+                      break;
-+      }
-+
-+      if (!dbh->methods) {
-+              zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
-+                              *pdo_err, einfo->errcode, einfo->errmsg);
-+      }
-+
-+      return einfo->errcode;
-+}
-+/* }}} */
-+
-+static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      pdo_sqlite2_error_info *einfo = &H->einfo;
-+      pdo_sqlite2_stmt *S;
-+
-+      if (stmt) {
-+              S = stmt->driver_data;
-+              einfo = &S->einfo;
-+      }
-+
-+      if (einfo->errcode) {
-+              add_next_index_long(info, einfo->errcode);
-+              if (einfo->errmsg) {
-+                      add_next_index_string(info, einfo->errmsg, 1);
-+              }
-+      }
-+
-+      return 1;
-+}
-+
-+static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      
-+      if (H) {
-+              if (H->db) {
-+                      sqlite_close(H->db);
-+                      H->db = NULL;
-+              }
-+              if (H->einfo.errmsg) {
-+                      pefree(H->einfo.errmsg, dbh->is_persistent);
-+                      H->einfo.errmsg = NULL;
-+              }
-+              pefree(H, dbh->is_persistent);
-+              dbh->driver_data = NULL;
-+      }
-+      return 0;
-+}
-+/* }}} */
-+
-+static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
-+
-+      S->H = H;
-+      stmt->driver_data = S;
-+      stmt->methods = &sqlite2_stmt_methods;
-+      stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
-+
-+      if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
-+              H->einfo.errcode = SQLITE_ERROR;
-+              pdo_sqlite2_error(NULL, dbh);
-+              return 0;
-+      }
-+
-+      return 1;
-+}
-+
-+static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      char *errmsg = NULL;
-+
-+      if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
-+              pdo_sqlite2_error(errmsg, dbh);
-+              return -1;
-+      } else {
-+              return sqlite_changes(H->db);
-+      }
-+}
-+
-+static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      char *id;
-+      
-+      id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
-+      *len = strlen(id);
-+      return id;
-+}
-+
-+static int sqlite2_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
-+{
-+      char *ret;
-+
-+      if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
-+              /* binary string */
-+              int len;
-+              ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
-+              ret[0] = '\'';
-+              ret[1] = '\x01';
-+              len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
-+              ret[len + 2] = '\'';
-+              ret[len + 3] = '\0';
-+              *quoted = ret;
-+              *quotedlen = len + 3;
-+              /* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
-+              return 1;
-+      } else if (unquotedlen) {
-+              ret = sqlite_mprintf("'%q'", unquoted);
-+              if (ret) {
-+                      *quoted = estrdup(ret);
-+                      *quotedlen = strlen(ret);
-+                      sqlite_freemem(ret);
-+                      return 1;
-+              }
-+              return 0;
-+      } else {
-+              *quoted = estrdup("''");
-+              *quotedlen = 2;
-+              return 1;
-+      }
-+}
-+
-+static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      char *errmsg = NULL;
-+
-+      if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
-+              pdo_sqlite2_error(errmsg, dbh);
-+              return 0;
-+      }
-+      return 1;
-+}
-+
-+static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      char *errmsg = NULL;
-+
-+      if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
-+              pdo_sqlite2_error(errmsg, dbh);
-+              return 0;
-+      }
-+      return 1;
-+}
-+
-+static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+      char *errmsg = NULL;
-+
-+      if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
-+              pdo_sqlite2_error(errmsg, dbh);
-+              return 0;
-+      }
-+      return 1;
-+}
-+
-+static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
-+{
-+      switch (attr) {
-+              case PDO_ATTR_CLIENT_VERSION:
-+              case PDO_ATTR_SERVER_VERSION:
-+                      ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
-+                      break;
-+              
-+              default:
-+                      return 0;       
-+      }
-+
-+      return 1;
-+}
-+
-+static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
-+{
-+      pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
-+
-+      switch (attr) {
-+              case PDO_ATTR_TIMEOUT:
-+                      convert_to_long(val);
-+                      sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static PHP_FUNCTION(sqlite2_create_function)
-+{
-+      /* TODO: implement this stuff */
-+}
-+
-+static const zend_function_entry dbh_methods[] = {
-+      PHP_FE(sqlite2_create_function, NULL)
-+      {NULL, NULL, NULL}
-+};
-+
-+static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
-+{
-+      switch (kind) {
-+              case PDO_DBH_DRIVER_METHOD_KIND_DBH:
-+                      return dbh_methods;
-+
-+              default:
-+                      return NULL;
-+      }
-+}
-+
-+static struct pdo_dbh_methods sqlite2_methods = {
-+      sqlite2_handle_closer,
-+      sqlite2_handle_preparer,
-+      sqlite2_handle_doer,
-+      sqlite2_handle_quoter,
-+      sqlite2_handle_begin,
-+      sqlite2_handle_commit,
-+      sqlite2_handle_rollback,
-+      pdo_sqlite2_set_attr,
-+      pdo_sqlite2_last_insert_id,
-+      pdo_sqlite2_fetch_error_func,
-+      pdo_sqlite2_get_attribute,
-+      NULL,   /* check_liveness: not needed */
-+      get_driver_methods
-+};
-+
-+static char *make_filename_safe(const char *filename TSRMLS_DC)
-+{
-+      if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
-+              char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
-+
-+              if (!fullpath) {
-+                      return NULL;
-+              }
-+
-+              if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
-+                      efree(fullpath);
-+                      return NULL;
-+              }
-+
-+              if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-+                      efree(fullpath);
-+                      return NULL;
-+              }
-+              return fullpath;
-+      }
-+      return estrdup(filename);
-+}
-+
-+static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
-+              const char *arg5, const char *arg6)
-+{
-+      char *filename;
-+      switch (access_type) {
-+              case SQLITE_COPY: {
-+                      TSRMLS_FETCH();
-+                      filename = make_filename_safe(arg4 TSRMLS_CC);
-+                      if (!filename) {
-+                              return SQLITE_DENY;
-+                      }
-+                      efree(filename);
-+                      return SQLITE_OK;
-+              }
-+
-+              case SQLITE_ATTACH: {
-+                      TSRMLS_FETCH();
-+                      filename = make_filename_safe(arg3 TSRMLS_CC);
-+                      if (!filename) {
-+                              return SQLITE_DENY;
-+                      }
-+                      efree(filename);
-+                      return SQLITE_OK;
-+              }
-+
-+              default:
-+                      /* access allowed */
-+                      return SQLITE_OK;
-+      }
-+}
-+
-+static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
-+{
-+      pdo_sqlite2_db_handle *H;
-+      int ret = 0;
-+      long timeout = 60;
-+      char *filename;
-+      char *errmsg = NULL;
-+
-+      H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
-+
-+      H->einfo.errcode = 0;
-+      H->einfo.errmsg = NULL;
-+      dbh->driver_data = H;
-+
-+      filename = make_filename_safe(dbh->data_source TSRMLS_CC);
-+
-+      if (!filename) {
-+              zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
-+                              "safe_mode/open_basedir prohibits opening %s",
-+                              dbh->data_source);
-+              goto cleanup;
-+      }
-+
-+      H->db = sqlite_open(filename, 0666, &errmsg);
-+      efree(filename);
-+
-+      if (!H->db) {
-+              H->einfo.errcode = SQLITE_ERROR;
-+              pdo_sqlite2_error(errmsg, dbh);
-+              goto cleanup;
-+      }
-+
-+      sqlite_set_authorizer(H->db, authorizer, NULL);
-+
-+      if (driver_options) {
-+              timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
-+      }
-+      sqlite_busy_timeout(H->db, timeout * 1000);
-+
-+      dbh->alloc_own_columns = 1;
-+      dbh->max_escaped_char_length = 2;
-+
-+      ret = 1;
-+
-+cleanup:
-+      dbh->methods = &sqlite2_methods;
-+
-+      return ret;
-+}
-+/* }}} */
-+
-+pdo_driver_t pdo_sqlite2_driver = {
-+      PDO_DRIVER_HEADER(sqlite2),
-+      pdo_sqlite2_handle_factory
-+};
-+
-+
-+
-+#endif
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: noet sw=4 ts=4 fdm=marker
-+ * vim<600: noet sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/sqlite/php_sqlite.def
-@@ -0,0 +1,43 @@
-+EXPORTS
-+sqlite_open
-+sqlite_close
-+sqlite_exec
-+sqlite_last_insert_rowid
-+sqlite_changes
-+sqlite_error_string
-+sqlite_interrupt
-+sqlite_complete
-+sqlite_busy_handler
-+sqlite_busy_timeout
-+sqlite_get_table
-+sqlite_free_table
-+sqlite_exec_printf
-+sqlite_exec_vprintf
-+sqlite_get_table_printf
-+sqlite_get_table_vprintf
-+sqlite_mprintf
-+sqlite_vmprintf
-+sqlite_freemem
-+sqlite_libversion
-+sqlite_libencoding
-+sqlite_create_function
-+sqlite_create_aggregate
-+sqlite_function_type
-+sqlite_set_result_string
-+sqlite_set_result_int
-+sqlite_set_result_double
-+sqlite_set_result_error
-+sqlite_user_data
-+sqlite_aggregate_context
-+sqlite_aggregate_count
-+sqlite_set_authorizer
-+sqlite_trace
-+sqlite_compile
-+sqlite_step
-+sqlite_finalize
-+; some experimental stuff
-+sqlite_last_statement_changes
-+sqlite_reset
-+sqlite_bind
-+sqlite_progress_handler
-+sqlite_commit_hook
---- /dev/null
-+++ b/ext/sqlite/php_sqlite.h
-@@ -0,0 +1,107 @@
-+/*
-+   +----------------------------------------------------------------------+
-+   | PHP Version 5                                                        |
-+   +----------------------------------------------------------------------+
-+   | Copyright (c) 1997-2012 The PHP Group                                |
-+   +----------------------------------------------------------------------+
-+   | This source file is subject to version 3.01 of the PHP license,      |
-+   | that is bundled with this package in the file LICENSE, and is        |
-+   | available through the world-wide-web at the following url:           |
-+   | http://www.php.net/license/3_01.txt                                  |
-+   | If you did not receive a copy of the PHP license and are unable to   |
-+   | obtain it through the world-wide-web, please send a note to          |
-+   | license@php.net so we can mail you a copy immediately.               |
-+   +----------------------------------------------------------------------+
-+   | Authors: Wez Furlong <wez@thebrainroom.com>                          |
-+   |          Tal Peer <tal@php.net>                                      |
-+   |          Marcus Boerger <helly@php.net>                              |
-+   +----------------------------------------------------------------------+
-+
-+   $Id$ 
-+*/
-+
-+#ifndef PHP_SQLITE_H
-+#define PHP_SQLITE_H
-+
-+extern zend_module_entry sqlite_module_entry;
-+#define phpext_sqlite_ptr &sqlite_module_entry
-+
-+#ifdef ZTS
-+#include "TSRM.h"
-+#endif
-+
-+PHP_MINIT_FUNCTION(sqlite);
-+PHP_MSHUTDOWN_FUNCTION(sqlite);
-+PHP_RSHUTDOWN_FUNCTION(sqlite);
-+PHP_MINFO_FUNCTION(sqlite);
-+
-+PHP_FUNCTION(sqlite_open);
-+PHP_FUNCTION(sqlite_popen);
-+PHP_FUNCTION(sqlite_close);
-+PHP_FUNCTION(sqlite_query);
-+PHP_FUNCTION(sqlite_exec);
-+PHP_FUNCTION(sqlite_unbuffered_query);
-+PHP_FUNCTION(sqlite_array_query);
-+PHP_FUNCTION(sqlite_single_query);
-+
-+PHP_FUNCTION(sqlite_fetch_array);
-+PHP_FUNCTION(sqlite_fetch_object);
-+PHP_FUNCTION(sqlite_fetch_single);
-+PHP_FUNCTION(sqlite_fetch_all);
-+PHP_FUNCTION(sqlite_current);
-+PHP_FUNCTION(sqlite_column);
-+
-+PHP_FUNCTION(sqlite_num_rows);
-+PHP_FUNCTION(sqlite_num_fields);
-+PHP_FUNCTION(sqlite_field_name);
-+PHP_FUNCTION(sqlite_seek);
-+PHP_FUNCTION(sqlite_rewind);
-+PHP_FUNCTION(sqlite_next);
-+PHP_FUNCTION(sqlite_prev);
-+PHP_FUNCTION(sqlite_key);
-+
-+PHP_FUNCTION(sqlite_valid);
-+PHP_FUNCTION(sqlite_has_prev);
-+
-+PHP_FUNCTION(sqlite_libversion);
-+PHP_FUNCTION(sqlite_libencoding);
-+
-+PHP_FUNCTION(sqlite_changes);
-+PHP_FUNCTION(sqlite_last_insert_rowid);
-+
-+PHP_FUNCTION(sqlite_escape_string);
-+
-+PHP_FUNCTION(sqlite_busy_timeout);
-+
-+PHP_FUNCTION(sqlite_last_error);
-+PHP_FUNCTION(sqlite_error_string);
-+
-+PHP_FUNCTION(sqlite_create_aggregate);
-+PHP_FUNCTION(sqlite_create_function);
-+PHP_FUNCTION(sqlite_udf_decode_binary);
-+PHP_FUNCTION(sqlite_udf_encode_binary);
-+
-+PHP_FUNCTION(sqlite_factory);
-+
-+PHP_FUNCTION(sqlite_fetch_column_types);
-+
-+ZEND_BEGIN_MODULE_GLOBALS(sqlite)
-+       long assoc_case;
-+ZEND_END_MODULE_GLOBALS(sqlite)
-+
-+#ifdef ZTS
-+#define SQLITE_G(v) TSRMG(sqlite_globals_id, zend_sqlite_globals *, v)
-+#else
-+#define SQLITE_G(v) (sqlite_globals.v)
-+#endif
-+
-+#endif
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * indent-tabs-mode: t
-+ * End:
-+ */
---- /dev/null
-+++ b/ext/sqlite/README
-@@ -0,0 +1,14 @@
-+This is an extension for the SQLite Embeddable SQL Database Engine.
-+http://www.sqlite.org/
-+
-+SQLite is a C library that implements an embeddable SQL database engine.
-+Programs that link with the SQLite library can have SQL database access
-+without running a separate RDBMS process.
-+
-+SQLite is not a client library used to connect to a big database server.
-+SQLite is the server. The SQLite library reads and writes directly to and from
-+the database files on disk
-+
-+
-+
-+vim:tw=78:et
---- /dev/null
-+++ b/ext/sqlite/sess_sqlite.c
-@@ -0,0 +1,201 @@
-+/* 
-+   +----------------------------------------------------------------------+
-+   | PHP Version 5                                                        |
-+   +----------------------------------------------------------------------+
-+   | Copyright (c) 1997-2012 The PHP Group                                |
-+   +----------------------------------------------------------------------+
-+   | This source file is subject to version 3.01 of the PHP license,      |
-+   | that is bundled with this package in the file LICENSE, and is        |
-+   | available through the world-wide-web at the following url:           |
-+   | http://www.php.net/license/3_01.txt                                  |
-+   | If you did not receive a copy of the PHP license and are unable to   |
-+   | obtain it through the world-wide-web, please send a note to          |
-+   | license@php.net so we can mail you a copy immediately.               |
-+   +----------------------------------------------------------------------+
-+   | Authors: John Coggeshall <john@php.net>                              |
-+   |          Wez Furlong <wez@thebrainroom.com>                          |
-+   +----------------------------------------------------------------------+
-+ */
-+
-+/* $Id$ */
-+
-+#include "php.h"
-+
-+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
-+
-+#include "ext/session/php_session.h"
-+#include "ext/standard/php_lcg.h"
-+#include <sqlite.h>
-+#define SQLITE_RETVAL(__r) ((__r) == SQLITE_OK ? SUCCESS : FAILURE)
-+#define PS_SQLITE_DATA sqlite *db = (sqlite*)PS_GET_MOD_DATA()
-+extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
-+extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
-+
-+PS_FUNCS(sqlite);
-+
-+ps_module ps_mod_sqlite = {
-+      PS_MOD(sqlite)
-+};
-+
-+PS_OPEN_FUNC(sqlite) 
-+{
-+      char *errmsg = NULL;
-+      sqlite *db;
-+
-+      /* TODO: do we need a safe_mode check here? */
-+      db = sqlite_open(save_path, 0666, &errmsg);
-+      if (db == NULL) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, 
-+                              "SQLite: failed to open/create session database `%s' - %s", save_path, errmsg);
-+              sqlite_freemem(errmsg);
-+              return FAILURE;
-+      }
-+
-+      /* allow up to 1 minute when busy */
-+      sqlite_busy_timeout(db, 60000);
-+
-+      sqlite_exec(db, "PRAGMA default_synchronous = OFF", NULL, NULL, NULL);
-+      sqlite_exec(db, "PRAGMA count_changes = OFF", NULL, NULL, NULL);
-+
-+      /* This will fail if the table already exists, but that's not a big problem. I'm
-+         unclear as to how to check for a table's existence in SQLite -- that would be better here. */
-+      sqlite_exec(db, 
-+          "CREATE TABLE session_data ("
-+          "    sess_id PRIMARY KEY," 
-+          "    value TEXT, "
-+          "    updated INTEGER "
-+          ")", NULL, NULL, NULL);
-+
-+      PS_SET_MOD_DATA(db);
-+
-+      return SUCCESS;
-+}
-+
-+PS_CLOSE_FUNC(sqlite) 
-+{
-+      PS_SQLITE_DATA;
-+
-+      sqlite_close(db);
-+
-+      return SUCCESS;
-+}
-+
-+PS_READ_FUNC(sqlite) 
-+{
-+      PS_SQLITE_DATA;
-+      char *query;
-+      const char *tail;
-+      sqlite_vm *vm;
-+      int colcount, result;
-+      const char **rowdata, **colnames;
-+      char *error;
-+
-+      *val = NULL;
-+      *vallen = 0;
-+      
-+      query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
-+      if (query == NULL) {
-+              /* no memory */
-+              return FAILURE;
-+      }
-+
-+      if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session read query: %s", error);
-+              sqlite_freemem(error);
-+              sqlite_freemem(query);
-+              return FAILURE;
-+      }
-+
-+      switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
-+              case SQLITE_ROW:
-+                      if (rowdata[0] != NULL) {
-+                              *vallen = strlen(rowdata[0]);
-+                              if (*vallen) {
-+                                      *val = emalloc(*vallen);
-+                                      *vallen = sqlite_decode_binary(rowdata[0], *val);
-+                                      (*val)[*vallen] = '\0';
-+                              } else {
-+                                      *val = STR_EMPTY_ALLOC();
-+                              }
-+                      }
-+                      break;
-+              default:
-+                      sqlite_freemem(error);
-+                      error = NULL;
-+      }
-+      
-+      if (SQLITE_OK != sqlite_finalize(vm, &error)) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session read: error %s", error);
-+              sqlite_freemem(error);
-+              error = NULL;
-+      }
-+
-+      sqlite_freemem(query);
-+      
-+      return *val == NULL ? FAILURE : SUCCESS;
-+}
-+
-+PS_WRITE_FUNC(sqlite) 
-+{
-+      PS_SQLITE_DATA;
-+      char *error;
-+      time_t t;
-+      char *binary;
-+      int binlen;
-+      int rv;
-+      
-+      t = time(NULL);
-+
-+      binary = safe_emalloc(1 + vallen / 254, 257, 3);
-+      binlen = sqlite_encode_binary((const unsigned char*)val, vallen, binary);
-+      
-+      rv = sqlite_exec_printf(db, "REPLACE INTO session_data VALUES('%q', '%q', %d)", NULL, NULL, &error, key, binary, t);
-+      if (rv != SQLITE_OK) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session write query failed: %s", error);
-+              sqlite_freemem(error);
-+      }
-+      efree(binary);
-+
-+      return SQLITE_RETVAL(rv);
-+}
-+
-+PS_DESTROY_FUNC(sqlite) 
-+{
-+      int rv;
-+      PS_SQLITE_DATA;
-+
-+      rv = sqlite_exec_printf(db, "DELETE FROM session_data WHERE sess_id='%q'", NULL, NULL, NULL, key);
-+      
-+      return SQLITE_RETVAL(rv);
-+}
-+
-+PS_GC_FUNC(sqlite) 
-+{
-+      PS_SQLITE_DATA;
-+      int rv;
-+      time_t t = time(NULL);
-+
-+      rv = sqlite_exec_printf(db, 
-+                      "DELETE FROM session_data WHERE (%d - updated) > %d", 
-+                      NULL, NULL, NULL, t, maxlifetime);
-+
-+      /* because SQLite does not actually clear the deleted data from the database 
-+       * we need to occassionaly do so manually to prevent the sessions database 
-+       * from growing endlessly.
-+       */
-+      if ((int) ((float) PS(gc_divisor) * PS(gc_divisor) * php_combined_lcg(TSRMLS_C)) < PS(gc_probability)) {
-+              rv = sqlite_exec_printf(db, "VACUUM", NULL, NULL, NULL);
-+      }
-+      return SQLITE_RETVAL(rv);
-+}
-+
-+#endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/sqlite/sqlite.c
-@@ -0,0 +1,3448 @@
-+/*
-+   +----------------------------------------------------------------------+
-+   | PHP Version 5                                                        |
-+   +----------------------------------------------------------------------+
-+   | Copyright (c) 1997-2012 The PHP Group                                |
-+   +----------------------------------------------------------------------+
-+   | This source file is subject to version 3.01 of the PHP license,      |
-+   | that is bundled with this package in the file LICENSE, and is        |
-+   | available through the world-wide-web at the following url:           |
-+   | http://www.php.net/license/3_01.txt                                  |
-+   | If you did not receive a copy of the PHP license and are unable to   |
-+   | obtain it through the world-wide-web, please send a note to          |
-+   | license@php.net so we can mail you a copy immediately.               |
-+   +----------------------------------------------------------------------+
-+   | Authors: Wez Furlong <wez@thebrainroom.com>                          |
-+   |          Tal Peer <tal@php.net>                                      |
-+   |          Marcus Boerger <helly@php.net>                              |
-+   +----------------------------------------------------------------------+
-+
-+   $Id$
-+*/
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#define PHP_SQLITE_MODULE_VERSION     "2.0-dev"
-+
-+#include "php.h"
-+#include "php_ini.h"
-+#include "ext/standard/info.h"
-+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
-+#include "ext/session/php_session.h"
-+#endif
-+#include "php_sqlite.h"
-+
-+#if HAVE_TIME_H
-+# include <time.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include <sqlite.h>
-+
-+#include "zend_exceptions.h"
-+#include "zend_interfaces.h"
-+
-+#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
-+extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
-+extern PHPAPI zend_class_entry *spl_ce_Countable;
-+#endif
-+
-+#if PHP_SQLITE2_HAVE_PDO
-+# include "pdo/php_pdo.h"
-+# include "pdo/php_pdo_driver.h"
-+extern pdo_driver_t pdo_sqlite2_driver;
-+#endif
-+
-+#ifndef safe_emalloc
-+# define safe_emalloc(a,b,c) emalloc((a)*(b)+(c))
-+#endif
-+
-+ZEND_DECLARE_MODULE_GLOBALS(sqlite)
-+static PHP_GINIT_FUNCTION(sqlite);
-+
-+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
-+extern ps_module ps_mod_sqlite;
-+#define ps_sqlite_ptr &ps_mod_sqlite
-+#endif
-+
-+extern int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
-+extern int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
-+
-+#define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
-+#define php_sqlite_decode_binary(in, out) in && *in ? sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out) : 0
-+
-+static int sqlite_count_elements(zval *object, long *count TSRMLS_DC);
-+
-+static int le_sqlite_db, le_sqlite_result, le_sqlite_pdb;
-+
-+static inline void php_sqlite_strtoupper(char *s)
-+{
-+      while (*s!='\0') {
-+              *s = toupper(*s);
-+              s++;
-+      }
-+}
-+
-+static inline void php_sqlite_strtolower(char *s)
-+{
-+      while (*s!='\0') {
-+              *s = tolower(*s);
-+              s++;
-+      }
-+}
-+
-+/* {{{ PHP_INI
-+ */
-+PHP_INI_BEGIN()
-+STD_PHP_INI_ENTRY_EX("sqlite.assoc_case", "0", PHP_INI_ALL, OnUpdateLong, assoc_case, zend_sqlite_globals, sqlite_globals, display_link_numbers)
-+PHP_INI_END()
-+/* }}} */
-+
-+#define DB_FROM_ZVAL(db, zv)  ZEND_FETCH_RESOURCE2(db, struct php_sqlite_db *, zv, -1, "sqlite database", le_sqlite_db, le_sqlite_pdb)
-+
-+#define DB_FROM_OBJECT(db, object) \
-+      { \
-+              sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
-+              db = obj->u.db; \
-+              if (!db) { \
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "The database wasn't opened"); \
-+                      RETURN_NULL(); \
-+              } \
-+      }
-+
-+#define RES_FROM_OBJECT_RESTORE_ERH(res, object, error_handling) \
-+      { \
-+              sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC); \
-+              res = obj->u.res; \
-+              if (!res) { \
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "No result set available"); \
-+                      if (error_handling) \
-+                              zend_restore_error_handling(error_handling TSRMLS_CC); \
-+                      RETURN_NULL(); \
-+              } \
-+      }
-+
-+#define RES_FROM_OBJECT(res, object) RES_FROM_OBJECT_RESTORE_ERH(res, object, NULL)
-+
-+#define PHP_SQLITE_EMPTY_QUERY \
-+      if (!sql_len || !*sql) { \
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute empty query."); \
-+              RETURN_FALSE; \
-+      }
-+
-+struct php_sqlite_result {
-+      struct php_sqlite_db *db;
-+      sqlite_vm *vm;
-+      int buffered;
-+      int ncolumns;
-+      int nrows;
-+      int curr_row;
-+      char **col_names;
-+      int alloc_rows;
-+      int mode;
-+      char **table;
-+};
-+
-+struct php_sqlite_db {
-+      sqlite *db;
-+      int last_err_code;
-+      zend_bool is_persistent;
-+      long rsrc_id;
-+
-+      HashTable callbacks;
-+};
-+
-+struct php_sqlite_agg_functions {
-+      struct php_sqlite_db *db;
-+      int is_valid;
-+      zval *step;
-+      zval *fini;
-+};
-+
-+static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC);
-+static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC);
-+
-+enum { PHPSQLITE_ASSOC = 1, PHPSQLITE_NUM = 2, PHPSQLITE_BOTH = PHPSQLITE_ASSOC|PHPSQLITE_NUM };
-+
-+/* {{{ arginfo */
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_popen, 0, 0, 1)
-+      ZEND_ARG_INFO(0, filename)
-+      ZEND_ARG_INFO(0, mode)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_open, 0, 0, 1)
-+      ZEND_ARG_INFO(0, filename)
-+      ZEND_ARG_INFO(0, mode)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_factory, 0, 0, 1)
-+      ZEND_ARG_INFO(0, filename)
-+      ZEND_ARG_INFO(0, mode)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_busy_timeout, 0, 0, 2)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, ms)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_busy_timeout, 0, 0, 1)
-+      ZEND_ARG_INFO(0, ms)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_close, 0, 0, 1)
-+      ZEND_ARG_INFO(0, db)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_unbuffered_query, 0, 0, 2)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_unbuffered_query, 0, 0, 1)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_column_types, 0, 0, 2)
-+      ZEND_ARG_INFO(0, table_name)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, result_type)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_column_types, 0, 0, 1)
-+      ZEND_ARG_INFO(0, table_name)
-+      ZEND_ARG_INFO(0, result_type)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_query, 0, 0, 2)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_query, 0, 0, 1)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_exec, 0, 0, 2)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_exec, 0, 0, 1)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(1, error_message)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_all, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_all, 0, 0, 0)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_array, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_array, 0, 0, 0)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_object, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, class_name)
-+      ZEND_ARG_INFO(0, ctor_params)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_object, 0, 0, 0)
-+      ZEND_ARG_INFO(0, class_name)
-+      ZEND_ARG_INFO(0, ctor_params)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_array_query, 0, 0, 2)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_array_query, 0, 0, 1)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_single_query, 0, 0, 2)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, first_row_only)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_single_query, 0, 0, 1)
-+      ZEND_ARG_INFO(0, query)
-+      ZEND_ARG_INFO(0, first_row_only)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_fetch_single, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_fetch_single, 0, 0, 0)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_current, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_current, 0, 0, 0)
-+      ZEND_ARG_INFO(0, result_type)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_column, 0, 0, 2)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, index_or_name)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_column, 0, 0, 1)
-+      ZEND_ARG_INFO(0, index_or_name)
-+      ZEND_ARG_INFO(0, decode_binary)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libversion, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_libencoding, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_changes, 0, 0, 1)
-+      ZEND_ARG_INFO(0, db)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_changes, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_insert_rowid, 0, 0, 1)
-+      ZEND_ARG_INFO(0, db)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_insert_rowid, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_rows, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_rows, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_valid, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_valid, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_has_prev, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_has_prev, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_num_fields, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_num_fields, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_field_name, 0, 0, 2)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, field_index)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_field_name, 0, 0, 1)
-+      ZEND_ARG_INFO(0, field_index)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_seek, 0, 0, 2)
-+      ZEND_ARG_INFO(0, result)
-+      ZEND_ARG_INFO(0, row)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_seek, 0, 0, 1)
-+      ZEND_ARG_INFO(0, row)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_rewind, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_rewind, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_next, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_next, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_key, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_key, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_prev, 0, 0, 1)
-+      ZEND_ARG_INFO(0, result)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_prev, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_escape_string, 0, 0, 1)
-+      ZEND_ARG_INFO(0, item)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_last_error, 0, 0, 1)
-+      ZEND_ARG_INFO(0, db)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO(arginfo_sqlite_method_last_error, 0)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_error_string, 0, 0, 1)
-+      ZEND_ARG_INFO(0, error_code)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_aggregate, 0, 0, 4)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, funcname)
-+      ZEND_ARG_INFO(0, step_func)
-+      ZEND_ARG_INFO(0, finalize_func)
-+      ZEND_ARG_INFO(0, num_args)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_aggregate, 0, 0, 3)
-+      ZEND_ARG_INFO(0, funcname)
-+      ZEND_ARG_INFO(0, step_func)
-+      ZEND_ARG_INFO(0, finalize_func)
-+      ZEND_ARG_INFO(0, num_args)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_create_function, 0, 0, 3)
-+      ZEND_ARG_INFO(0, db)
-+      ZEND_ARG_INFO(0, funcname)
-+      ZEND_ARG_INFO(0, callback)
-+      ZEND_ARG_INFO(0, num_args)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_method_create_function, 0, 0, 2)
-+      ZEND_ARG_INFO(0, funcname)
-+      ZEND_ARG_INFO(0, callback)
-+      ZEND_ARG_INFO(0, num_args)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_encode_binary, 0, 0, 1)
-+      ZEND_ARG_INFO(0, data)
-+ZEND_END_ARG_INFO()
-+
-+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite_udf_decode_binary, 0, 0, 1)
-+      ZEND_ARG_INFO(0, data)
-+ZEND_END_ARG_INFO()
-+/* }}} */
-+
-+const zend_function_entry sqlite_functions[] = {
-+      PHP_FE(sqlite_open,                             arginfo_sqlite_open)
-+      PHP_FE(sqlite_popen,                            arginfo_sqlite_popen)
-+      PHP_FE(sqlite_close,                            arginfo_sqlite_close)
-+      PHP_FE(sqlite_query,                            arginfo_sqlite_query)
-+      PHP_FE(sqlite_exec,                             arginfo_sqlite_exec)
-+      PHP_FE(sqlite_array_query,                      arginfo_sqlite_array_query)
-+      PHP_FE(sqlite_single_query,             arginfo_sqlite_single_query)
-+      PHP_FE(sqlite_fetch_array,                      arginfo_sqlite_fetch_array)
-+      PHP_FE(sqlite_fetch_object,             arginfo_sqlite_fetch_object)
-+      PHP_FE(sqlite_fetch_single,             arginfo_sqlite_fetch_single)
-+      PHP_FALIAS(sqlite_fetch_string, sqlite_fetch_single, arginfo_sqlite_fetch_single)
-+      PHP_FE(sqlite_fetch_all,                        arginfo_sqlite_fetch_all)
-+      PHP_FE(sqlite_current,                          arginfo_sqlite_current)
-+      PHP_FE(sqlite_column,                           arginfo_sqlite_column)
-+      PHP_FE(sqlite_libversion,                       arginfo_sqlite_libversion)
-+      PHP_FE(sqlite_libencoding,                      arginfo_sqlite_libencoding)
-+      PHP_FE(sqlite_changes,                          arginfo_sqlite_changes)
-+      PHP_FE(sqlite_last_insert_rowid,        arginfo_sqlite_last_insert_rowid)
-+      PHP_FE(sqlite_num_rows,                         arginfo_sqlite_num_rows)
-+      PHP_FE(sqlite_num_fields,                       arginfo_sqlite_num_fields)
-+      PHP_FE(sqlite_field_name,                       arginfo_sqlite_field_name)
-+      PHP_FE(sqlite_seek,                             arginfo_sqlite_seek)
-+      PHP_FE(sqlite_rewind,                           arginfo_sqlite_rewind)
-+      PHP_FE(sqlite_next,                             arginfo_sqlite_next)
-+      PHP_FE(sqlite_prev,                             arginfo_sqlite_prev)
-+      PHP_FE(sqlite_valid,                            arginfo_sqlite_valid)
-+      PHP_FALIAS(sqlite_has_more, sqlite_valid, arginfo_sqlite_valid)
-+      PHP_FE(sqlite_has_prev,                         arginfo_sqlite_has_prev)
-+      PHP_FE(sqlite_escape_string,            arginfo_sqlite_escape_string)
-+      PHP_FE(sqlite_busy_timeout,             arginfo_sqlite_busy_timeout)
-+      PHP_FE(sqlite_last_error,                       arginfo_sqlite_last_error)
-+      PHP_FE(sqlite_error_string,             arginfo_sqlite_error_string)
-+      PHP_FE(sqlite_unbuffered_query,         arginfo_sqlite_unbuffered_query)
-+      PHP_FE(sqlite_create_aggregate,         arginfo_sqlite_create_aggregate)
-+      PHP_FE(sqlite_create_function,          arginfo_sqlite_create_function)
-+      PHP_FE(sqlite_factory,                          arginfo_sqlite_factory)
-+      PHP_FE(sqlite_udf_encode_binary,        arginfo_sqlite_udf_encode_binary)
-+      PHP_FE(sqlite_udf_decode_binary,        arginfo_sqlite_udf_decode_binary)
-+      PHP_FE(sqlite_fetch_column_types,       arginfo_sqlite_fetch_column_types)
-+      {NULL, NULL, NULL}
-+};
-+
-+const zend_function_entry sqlite_funcs_db[] = {
-+      PHP_ME_MAPPING(__construct, sqlite_open, arginfo_sqlite_open, 0)
-+/*    PHP_ME_MAPPING(close, sqlite_close, NULL, 0)*/
-+      PHP_ME_MAPPING(query, sqlite_query, arginfo_sqlite_method_query, 0)
-+      PHP_ME_MAPPING(queryExec, sqlite_exec, arginfo_sqlite_method_exec, 0)
-+      PHP_ME_MAPPING(arrayQuery, sqlite_array_query, arginfo_sqlite_method_array_query, 0)
-+      PHP_ME_MAPPING(singleQuery, sqlite_single_query, arginfo_sqlite_method_single_query, 0)
-+      PHP_ME_MAPPING(unbufferedQuery, sqlite_unbuffered_query, arginfo_sqlite_method_unbuffered_query, 0)
-+      PHP_ME_MAPPING(lastInsertRowid, sqlite_last_insert_rowid, arginfo_sqlite_method_last_insert_rowid, 0)
-+      PHP_ME_MAPPING(changes, sqlite_changes, arginfo_sqlite_method_changes, 0)
-+      PHP_ME_MAPPING(createAggregate, sqlite_create_aggregate, arginfo_sqlite_method_create_aggregate, 0)
-+      PHP_ME_MAPPING(createFunction, sqlite_create_function, arginfo_sqlite_method_create_function, 0)
-+      PHP_ME_MAPPING(busyTimeout, sqlite_busy_timeout, arginfo_sqlite_method_busy_timeout, 0)
-+      PHP_ME_MAPPING(lastError, sqlite_last_error, arginfo_sqlite_method_last_error, 0)
-+      PHP_ME_MAPPING(fetchColumnTypes, sqlite_fetch_column_types, arginfo_sqlite_method_fetch_column_types, 0)
-+/*    PHP_ME_MAPPING(error_string, sqlite_error_string, NULL, 0) static */
-+/*    PHP_ME_MAPPING(escape_string, sqlite_escape_string, NULL, 0) static */
-+      {NULL, NULL, NULL}
-+};
-+
-+const zend_function_entry sqlite_funcs_query[] = {
-+      PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
-+      PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
-+      PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
-+      PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
-+      PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
-+      PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
-+      PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
-+      /* iterator */
-+      PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
-+      PHP_ME_MAPPING(key, sqlite_key, arginfo_sqlite_method_key, 0)
-+      PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
-+      PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
-+      PHP_ME_MAPPING(rewind, sqlite_rewind, arginfo_sqlite_method_rewind, 0)
-+      /* countable */
-+      PHP_ME_MAPPING(count, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
-+      /* additional */
-+      PHP_ME_MAPPING(prev, sqlite_prev, arginfo_sqlite_method_prev, 0)
-+      PHP_ME_MAPPING(hasPrev, sqlite_has_prev, arginfo_sqlite_method_has_prev, 0)
-+      PHP_ME_MAPPING(numRows, sqlite_num_rows, arginfo_sqlite_method_num_rows, 0)
-+      PHP_ME_MAPPING(seek, sqlite_seek, arginfo_sqlite_method_seek, 0)
-+      {NULL, NULL, NULL}
-+};
-+
-+const zend_function_entry sqlite_funcs_ub_query[] = {
-+      PHP_ME_MAPPING(fetch, sqlite_fetch_array, arginfo_sqlite_method_fetch_array, 0)
-+      PHP_ME_MAPPING(fetchObject, sqlite_fetch_object, arginfo_sqlite_method_fetch_object, 0)
-+      PHP_ME_MAPPING(fetchSingle, sqlite_fetch_single, arginfo_sqlite_method_fetch_single, 0)
-+      PHP_ME_MAPPING(fetchAll, sqlite_fetch_all, arginfo_sqlite_method_fetch_all, 0)
-+      PHP_ME_MAPPING(column, sqlite_column, arginfo_sqlite_method_column, 0)
-+      PHP_ME_MAPPING(numFields, sqlite_num_fields, arginfo_sqlite_method_num_fields, 0)
-+      PHP_ME_MAPPING(fieldName, sqlite_field_name, arginfo_sqlite_method_field_name, 0)
-+      /* iterator */
-+      PHP_ME_MAPPING(current, sqlite_current, arginfo_sqlite_method_current, 0)
-+      PHP_ME_MAPPING(next, sqlite_next, arginfo_sqlite_method_next, 0)
-+      PHP_ME_MAPPING(valid, sqlite_valid, arginfo_sqlite_method_valid, 0)
-+      {NULL, NULL, NULL}
-+};
-+
-+const zend_function_entry sqlite_funcs_exception[] = {
-+      {NULL, NULL, NULL}
-+};
-+
-+/* Dependancies */
-+static const zend_module_dep sqlite_deps[] = {
-+#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
-+      ZEND_MOD_REQUIRED("spl")
-+#endif
-+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
-+      ZEND_MOD_REQUIRED("session")
-+#endif
-+#ifdef PHP_SQLITE2_HAVE_PDO
-+      ZEND_MOD_REQUIRED("pdo")
-+#endif
-+      {NULL, NULL, NULL}
-+};
-+
-+zend_module_entry sqlite_module_entry = {
-+#if ZEND_MODULE_API_NO >= 20050922
-+      STANDARD_MODULE_HEADER_EX, NULL,
-+      sqlite_deps,
-+#elif ZEND_MODULE_API_NO >= 20010901
-+      STANDARD_MODULE_HEADER,
-+#endif
-+      "SQLite",
-+      sqlite_functions,
-+      PHP_MINIT(sqlite),
-+      PHP_MSHUTDOWN(sqlite),
-+      NULL,
-+      PHP_RSHUTDOWN(sqlite),
-+      PHP_MINFO(sqlite),
-+#if ZEND_MODULE_API_NO >= 20010901
-+      PHP_SQLITE_MODULE_VERSION,
-+#endif
-+#if ZEND_MODULE_API_NO >= 20060613
-+      PHP_MODULE_GLOBALS(sqlite),
-+      PHP_GINIT(sqlite),
-+      NULL,
-+      NULL,
-+      STANDARD_MODULE_PROPERTIES_EX
-+#else
-+      STANDARD_MODULE_PROPERTIES
-+#endif
-+};
-+
-+
-+#ifdef COMPILE_DL_SQLITE
-+ZEND_GET_MODULE(sqlite)
-+#endif
-+
-+static int php_sqlite_callback_invalidator(struct php_sqlite_agg_functions *funcs TSRMLS_DC)
-+{
-+      if (!funcs->is_valid) {
-+              return 0;
-+      }
-+
-+      if (funcs->step) {
-+              zval_ptr_dtor(&funcs->step);
-+              funcs->step = NULL;
-+      }
-+
-+      if (funcs->fini) {
-+              zval_ptr_dtor(&funcs->fini);
-+              funcs->fini = NULL;
-+      }
-+
-+      funcs->is_valid = 0;
-+
-+      return 0;
-+}
-+
-+
-+static void php_sqlite_callback_dtor(void *pDest)
-+{
-+      struct php_sqlite_agg_functions *funcs = (struct php_sqlite_agg_functions*)pDest;
-+
-+      if (funcs->is_valid) {
-+              TSRMLS_FETCH();
-+
-+              php_sqlite_callback_invalidator(funcs TSRMLS_CC);
-+      }
-+}
-+
-+static ZEND_RSRC_DTOR_FUNC(php_sqlite_db_dtor)
-+{
-+      if (rsrc->ptr) {
-+              struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
-+
-+              sqlite_close(db->db);
-+
-+              zend_hash_destroy(&db->callbacks);
-+
-+              pefree(db, db->is_persistent);
-+
-+              rsrc->ptr = NULL;
-+      }
-+}
-+
-+static void real_result_dtor(struct php_sqlite_result *res TSRMLS_DC)
-+{
-+      int i, j, base;
-+
-+      if (res->vm) {
-+              sqlite_finalize(res->vm, NULL);
-+      }
-+
-+      if (res->table) {
-+              if (!res->buffered && res->nrows) {
-+                      res->nrows = 1; /* only one row is stored */
-+              }
-+              for (i = 0; i < res->nrows; i++) {
-+                      base = i * res->ncolumns;
-+                      for (j = 0; j < res->ncolumns; j++) {
-+                              if (res->table[base + j] != NULL) {
-+                                      efree(res->table[base + j]);
-+                              }
-+                      }
-+              }
-+              efree(res->table);
-+      }
-+      if (res->col_names) {
-+              for (j = 0; j < res->ncolumns; j++) {
-+                      efree(res->col_names[j]);
-+              }
-+              efree(res->col_names);
-+      }
-+
-+      if (res->db) {
-+              zend_list_delete(res->db->rsrc_id);
-+      }
-+      efree(res);
-+}
-+
-+static int _clean_unfinished_results(zend_rsrc_list_entry *le, void *db TSRMLS_DC)
-+{
-+      if (Z_TYPE_P(le) == le_sqlite_result) {
-+              struct php_sqlite_result *res = (struct php_sqlite_result *)le->ptr;
-+              if (res->db->rsrc_id == ((struct php_sqlite_db*)db)->rsrc_id) {
-+                      return ZEND_HASH_APPLY_REMOVE;
-+              }
-+      }
-+      return ZEND_HASH_APPLY_KEEP;
-+}
-+
-+static ZEND_RSRC_DTOR_FUNC(php_sqlite_result_dtor)
-+{
-+      struct php_sqlite_result *res = (struct php_sqlite_result *)rsrc->ptr;
-+      real_result_dtor(res TSRMLS_CC);
-+}
-+
-+static int php_sqlite_forget_persistent_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-+{
-+      struct php_sqlite_db *db = (struct php_sqlite_db*)rsrc->ptr;
-+
-+      if (Z_TYPE_P(rsrc) != le_sqlite_pdb) {
-+              return 0;
-+      }
-+
-+      /* prevent bad mojo if someone tries to use a previously registered function in the next request */
-+      zend_hash_apply(&db->callbacks, (apply_func_t)php_sqlite_callback_invalidator TSRMLS_CC);
-+
-+      db->rsrc_id = FAILURE;
-+
-+      /* don't leave pending commits hanging around */
-+      sqlite_exec(db->db, "ROLLBACK", NULL, NULL, NULL);
-+
-+      return 0;
-+}
-+
-+PHP_RSHUTDOWN_FUNCTION(sqlite)
-+{
-+      zend_hash_apply(&EG(persistent_list), (apply_func_t)php_sqlite_forget_persistent_id_numbers TSRMLS_CC);
-+      return SUCCESS;
-+}
-+
-+/* {{{ PHP Function interface */
-+static void php_sqlite_generic_function_callback(sqlite_func *func, int argc, const char **argv)
-+{
-+      zval *retval = NULL;
-+      zval ***zargs = NULL;
-+      zval funcname;
-+      int i, res;
-+      char *callable = NULL, *errbuf=NULL;
-+      TSRMLS_FETCH();
-+
-+      /* sanity check the args */
-+      if (argc == 0) {
-+              sqlite_set_result_error(func, "not enough parameters", -1);
-+              return;
-+      }
-+
-+      ZVAL_STRING(&funcname, (char*)argv[0], 1);
-+
-+      if (!zend_make_callable(&funcname, &callable TSRMLS_CC)) {
-+              spprintf(&errbuf, 0, "function `%s' is not a function name", callable);
-+              sqlite_set_result_error(func, errbuf, -1);
-+              efree(errbuf);
-+              efree(callable);
-+              zval_dtor(&funcname);
-+              return;
-+      }
-+
-+      if (argc > 1) {
-+              zargs = (zval ***)safe_emalloc((argc - 1), sizeof(zval **), 0);
-+
-+              for (i = 0; i < argc-1; i++) {
-+                      zargs[i] = emalloc(sizeof(zval *));
-+                      MAKE_STD_ZVAL(*zargs[i]);
-+                      ZVAL_STRING(*zargs[i], (char*)argv[i+1], 1);
-+              }
-+      }
-+
-+      res = call_user_function_ex(EG(function_table),
-+                      NULL,
-+                      &funcname,
-+                      &retval,
-+                      argc-1,
-+                      zargs,
-+                      0, NULL TSRMLS_CC);
-+
-+      zval_dtor(&funcname);
-+
-+      if (res == SUCCESS) {
-+              if (retval == NULL) {
-+                      sqlite_set_result_string(func, NULL, 0);
-+              } else {
-+                      switch (Z_TYPE_P(retval)) {
-+                              case IS_STRING:
-+                                      sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-+                                      break;
-+                              case IS_LONG:
-+                              case IS_BOOL:
-+                                      sqlite_set_result_int(func, Z_LVAL_P(retval));
-+                                      break;
-+                              case IS_DOUBLE:
-+                                      sqlite_set_result_double(func, Z_DVAL_P(retval));
-+                                      break;
-+                              case IS_NULL:
-+                              default:
-+                                      sqlite_set_result_string(func, NULL, 0);
-+                      }
-+              }
-+      } else {
-+              char *errbuf;
-+              spprintf(&errbuf, 0, "call_user_function_ex failed for function %s()", callable);
-+              sqlite_set_result_error(func, errbuf, -1);
-+              efree(errbuf);
-+      }
-+
-+      efree(callable);
-+
-+      if (retval) {
-+              zval_ptr_dtor(&retval);
-+      }
-+
-+      if (zargs) {
-+              for (i = 0; i < argc-1; i++) {
-+                      zval_ptr_dtor(zargs[i]);
-+                      efree(zargs[i]);
-+              }
-+              efree(zargs);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ callback for sqlite_create_function */
-+static void php_sqlite_function_callback(sqlite_func *func, int argc, const char **argv)
-+{
-+      zval *retval = NULL;
-+      zval ***zargs = NULL;
-+      int i, res;
-+      struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
-+      TSRMLS_FETCH();
-+
-+      if (!funcs->is_valid) {
-+              sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
-+              return;
-+      }
-+
-+      if (argc > 0) {
-+              zargs = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
-+
-+              for (i = 0; i < argc; i++) {
-+                      zargs[i] = emalloc(sizeof(zval *));
-+                      MAKE_STD_ZVAL(*zargs[i]);
-+
-+                      if (argv[i] == NULL) {
-+                              ZVAL_NULL(*zargs[i]);
-+                      } else {
-+                              ZVAL_STRING(*zargs[i], (char*)argv[i], 1);
-+                      }
-+              }
-+      }
-+
-+      res = call_user_function_ex(EG(function_table),
-+                      NULL,
-+                      funcs->step,
-+                      &retval,
-+                      argc,
-+                      zargs,
-+                      0, NULL TSRMLS_CC);
-+
-+      if (res == SUCCESS) {
-+              if (retval == NULL) {
-+                      sqlite_set_result_string(func, NULL, 0);
-+              } else {
-+                      switch (Z_TYPE_P(retval)) {
-+                              case IS_STRING:
-+                                      /* TODO: for binary results, need to encode the string */
-+                                      sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-+                                      break;
-+                              case IS_LONG:
-+                              case IS_BOOL:
-+                                      sqlite_set_result_int(func, Z_LVAL_P(retval));
-+                                      break;
-+                              case IS_DOUBLE:
-+                                      sqlite_set_result_double(func, Z_DVAL_P(retval));
-+                                      break;
-+                              case IS_NULL:
-+                              default:
-+                                      sqlite_set_result_string(func, NULL, 0);
-+                      }
-+              }
-+      } else {
-+              sqlite_set_result_error(func, "call_user_function_ex failed", -1);
-+      }
-+
-+      if (retval) {
-+              zval_ptr_dtor(&retval);
-+      }
-+
-+      if (zargs) {
-+              for (i = 0; i < argc; i++) {
-+                      zval_ptr_dtor(zargs[i]);
-+                      efree(zargs[i]);
-+              }
-+              efree(zargs);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ callback for sqlite_create_aggregate: step function */
-+static void php_sqlite_agg_step_function_callback(sqlite_func *func, int argc, const char **argv)
-+{
-+      zval *retval = NULL;
-+      zval ***zargs;
-+      zval **context_p;
-+      int i, res, zargc;
-+      struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
-+      TSRMLS_FETCH();
-+
-+      if (!funcs->is_valid) {
-+              sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
-+              return;
-+      }
-+
-+      /* sanity check the args */
-+      if (argc < 1) {
-+              return;
-+      }
-+
-+      zargc = argc + 1;
-+      zargs = (zval ***)safe_emalloc(zargc, sizeof(zval **), 0);
-+
-+      /* first arg is always the context zval */
-+      context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
-+
-+      if (*context_p == NULL) {
-+              MAKE_STD_ZVAL(*context_p);
-+              Z_SET_ISREF_PP(context_p);
-+              Z_TYPE_PP(context_p) = IS_NULL;
-+      }
-+
-+      zargs[0] = context_p;
-+
-+      /* copy the other args */
-+      for (i = 0; i < argc; i++) {
-+              zargs[i+1] = emalloc(sizeof(zval *));
-+              MAKE_STD_ZVAL(*zargs[i+1]);
-+              if (argv[i] == NULL) {
-+                      ZVAL_NULL(*zargs[i+1]);
-+              } else {
-+                      ZVAL_STRING(*zargs[i+1], (char*)argv[i], 1);
-+              }
-+      }
-+
-+      res = call_user_function_ex(EG(function_table),
-+                      NULL,
-+                      funcs->step,
-+                      &retval,
-+                      zargc,
-+                      zargs,
-+                      0, NULL TSRMLS_CC);
-+
-+      if (res != SUCCESS) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "call_user_function_ex failed");
-+      }
-+
-+      if (retval) {
-+              zval_ptr_dtor(&retval);
-+      }
-+
-+      if (zargs) {
-+              for (i = 1; i < zargc; i++) {
-+                      zval_ptr_dtor(zargs[i]);
-+                      efree(zargs[i]);
-+              }
-+              efree(zargs);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ callback for sqlite_create_aggregate: finalize function */
-+static void php_sqlite_agg_fini_function_callback(sqlite_func *func)
-+{
-+      zval *retval = NULL;
-+      int res;
-+      struct php_sqlite_agg_functions *funcs = sqlite_user_data(func);
-+      zval **context_p;
-+      TSRMLS_FETCH();
-+
-+      if (!funcs->is_valid) {
-+              sqlite_set_result_error(func, "this function has not been correctly defined for this request", -1);
-+              return;
-+      }
-+
-+      context_p = (zval **)sqlite_aggregate_context(func, sizeof(*context_p));
-+
-+      res = call_user_function_ex(EG(function_table),
-+                      NULL,
-+                      funcs->fini,
-+                      &retval,
-+                      1,
-+                      &context_p,
-+                      0, NULL TSRMLS_CC);
-+
-+      if (res == SUCCESS) {
-+              if (retval == NULL) {
-+                      sqlite_set_result_string(func, NULL, 0);
-+              } else {
-+                      switch (Z_TYPE_P(retval)) {
-+                              case IS_STRING:
-+                                      /* TODO: for binary results, need to encode the string */
-+                                      sqlite_set_result_string(func, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-+                                      break;
-+                              case IS_LONG:
-+                              case IS_BOOL:
-+                                      sqlite_set_result_int(func, Z_LVAL_P(retval));
-+                                      break;
-+                              case IS_DOUBLE:
-+                                      sqlite_set_result_double(func, Z_DVAL_P(retval));
-+                                      break;
-+                              case IS_NULL:
-+                              default:
-+                                      sqlite_set_result_string(func, NULL, 0);
-+                      }
-+              }
-+      } else {
-+              sqlite_set_result_error(func, "call_user_function_ex failed", -1);
-+      }
-+
-+      if (retval) {
-+              zval_ptr_dtor(&retval);
-+      }
-+
-+      zval_ptr_dtor(context_p);
-+}
-+/* }}} */
-+
-+/* {{{ Authorization Callback */
-+static int php_sqlite_authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
-+              const char *arg5, const char *arg6)
-+{
-+      switch (access_type) {
-+              case SQLITE_COPY:
-+                      if (strncmp(arg4, ":memory:", sizeof(":memory:") - 1)) {
-+                              TSRMLS_FETCH();
-+                              if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
-+                                      return SQLITE_DENY;
-+                              }
-+
-+                              if (php_check_open_basedir(arg4 TSRMLS_CC)) {
-+                                      return SQLITE_DENY;
-+                              }
-+                      }
-+                      return SQLITE_OK;
-+#ifdef SQLITE_ATTACH
-+              case SQLITE_ATTACH:
-+                      if (strncmp(arg3, ":memory:", sizeof(":memory:") - 1)) {
-+                              TSRMLS_FETCH();
-+                              if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
-+                                      return SQLITE_DENY;
-+                              }
-+
-+                              if (php_check_open_basedir(arg3 TSRMLS_CC)) {
-+                                      return SQLITE_DENY;
-+                              }
-+                      }
-+                      return SQLITE_OK;
-+#endif
-+
-+              default:
-+                      /* access allowed */
-+                      return SQLITE_OK;
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ OO init/structure stuff */
-+#define REGISTER_SQLITE_CLASS(name, c_name, parent) \
-+      { \
-+              zend_class_entry ce; \
-+              INIT_CLASS_ENTRY(ce, "SQLite" # name, sqlite_funcs_ ## c_name); \
-+              ce.create_object = sqlite_object_new_ ## c_name; \
-+              sqlite_ce_ ## c_name = zend_register_internal_class_ex(&ce, parent, NULL TSRMLS_CC); \
-+              memcpy(&sqlite_object_handlers_ ## c_name, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); \
-+              sqlite_object_handlers_ ## c_name.clone_obj = NULL; \
-+              sqlite_ce_ ## c_name->ce_flags |= ZEND_ACC_FINAL_CLASS; \
-+      }
-+
-+zend_class_entry *sqlite_ce_db, *sqlite_ce_exception;
-+zend_class_entry *sqlite_ce_query, *sqlite_ce_ub_query;
-+
-+static zend_object_handlers sqlite_object_handlers_db;
-+static zend_object_handlers sqlite_object_handlers_query;
-+static zend_object_handlers sqlite_object_handlers_ub_query;
-+static zend_object_handlers sqlite_object_handlers_exception;
-+
-+typedef enum {
-+      is_db,
-+      is_result
-+} sqlite_obj_type;
-+
-+typedef struct _sqlite_object {
-+      zend_object       std;
-+      sqlite_obj_type   type;
-+      union {
-+              struct php_sqlite_db     *db;
-+              struct php_sqlite_result *res;
-+              void *ptr;
-+      } u;
-+} sqlite_object;
-+
-+static int sqlite_free_persistent(zend_rsrc_list_entry *le, void *ptr TSRMLS_DC)
-+{
-+      return le->ptr == ptr ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
-+}
-+
-+static void sqlite_object_free_storage(void *object TSRMLS_DC)
-+{
-+      sqlite_object *intern = (sqlite_object *)object;
-+
-+      zend_object_std_dtor(&intern->std TSRMLS_CC);
-+
-+      if (intern->u.ptr) {
-+              if (intern->type == is_db) {
-+                      if (intern->u.db->rsrc_id) {
-+                              zend_list_delete(intern->u.db->rsrc_id);
-+                              zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) sqlite_free_persistent, &intern->u.ptr TSRMLS_CC);
-+                      }
-+              } else {
-+                      real_result_dtor(intern->u.res TSRMLS_CC);
-+              }
-+      }
-+
-+      efree(object);
-+}
-+
-+static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
-+{
-+      sqlite_object *intern;
-+      zval *tmp;
-+
-+      intern = emalloc(sizeof(sqlite_object));
-+      memset(intern, 0, sizeof(sqlite_object));
-+
-+      zend_object_std_init(&intern->std, class_type TSRMLS_CC);
-+      zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-+
-+      retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) sqlite_object_free_storage, NULL TSRMLS_CC);
-+      retval->handlers = handlers;
-+}
-+
-+static zend_object_value sqlite_object_new_db(zend_class_entry *class_type TSRMLS_DC)
-+{
-+      zend_object_value retval;
-+
-+      sqlite_object_new(class_type, &sqlite_object_handlers_db, &retval TSRMLS_CC);
-+      return retval;
-+}
-+
-+static zend_object_value sqlite_object_new_query(zend_class_entry *class_type TSRMLS_DC)
-+{
-+      zend_object_value retval;
-+
-+      sqlite_object_new(class_type, &sqlite_object_handlers_query, &retval TSRMLS_CC);
-+      return retval;
-+}
-+
-+static zend_object_value sqlite_object_new_ub_query(zend_class_entry *class_type TSRMLS_DC)
-+{
-+      zend_object_value retval;
-+
-+      sqlite_object_new(class_type, &sqlite_object_handlers_ub_query, &retval TSRMLS_CC);
-+      return retval;
-+}
-+
-+static zend_object_value sqlite_object_new_exception(zend_class_entry *class_type TSRMLS_DC)
-+{
-+      zend_object_value retval;
-+
-+      sqlite_object_new(class_type, &sqlite_object_handlers_exception, &retval TSRMLS_CC);
-+      return retval;
-+}
-+
-+#define SQLITE_REGISTER_OBJECT(_type, _object, _ptr) \
-+      { \
-+              sqlite_object *obj; \
-+              obj = (sqlite_object*)zend_object_store_get_object(_object TSRMLS_CC); \
-+              obj->type = is_ ## _type; \
-+              obj->u._type = _ptr; \
-+      }
-+
-+static zend_class_entry *sqlite_get_ce_query(const zval *object TSRMLS_DC)
-+{
-+      return sqlite_ce_query;
-+}
-+
-+static zend_class_entry *sqlite_get_ce_ub_query(const zval *object TSRMLS_DC)
-+{
-+      return sqlite_ce_ub_query;
-+}
-+
-+static zval * sqlite_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC)
-+{
-+      if (!object) {
-+              ALLOC_ZVAL(object);
-+      }
-+      Z_TYPE_P(object) = IS_OBJECT;
-+      object_init_ex(object, pce);
-+      Z_SET_REFCOUNT_P(object, 1);
-+      Z_SET_ISREF_P(object);
-+      return object;
-+}
-+
-+typedef struct _sqlite_object_iterator {
-+      zend_object_iterator     it;
-+      struct php_sqlite_result *res;
-+      zval *value;
-+} sqlite_object_iterator;
-+
-+void sqlite_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
-+{
-+      zval *object = (zval*)((sqlite_object_iterator*)iter)->it.data;
-+
-+      if (((sqlite_object_iterator*)iter)->value) {
-+              zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
-+              ((sqlite_object_iterator*)iter)->value = NULL;
-+      }
-+      zval_ptr_dtor(&object);
-+      efree(iter);
-+}
-+
-+void sqlite_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
-+{
-+      struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
-+
-+      if (((sqlite_object_iterator*)iter)->value) {
-+              zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
-+              ((sqlite_object_iterator*)iter)->value = NULL;
-+      }
-+      if (res) {
-+              res->curr_row = 0;
-+      }
-+}
-+
-+int sqlite_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
-+{
-+      struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
-+
-+      if (res && res->curr_row < res->nrows && res->nrows) { /* curr_row may be -1 */
-+              return SUCCESS;
-+      } else {
-+              return FAILURE;
-+      }
-+}
-+
-+void sqlite_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
-+{
-+      struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
-+
-+      *data = &((sqlite_object_iterator*)iter)->value;
-+      if (res && !**data) {
-+              MAKE_STD_ZVAL(**data);
-+              php_sqlite_fetch_array(res, res->mode, 1, 0, **data TSRMLS_CC);
-+      }
-+
-+}
-+
-+int sqlite_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
-+{
-+      struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
-+
-+      *str_key = NULL;
-+      *str_key_len = 0;
-+      *int_key = res ? res->curr_row : 0;
-+      return HASH_KEY_IS_LONG;
-+}
-+
-+void sqlite_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
-+{
-+      struct php_sqlite_result *res = ((sqlite_object_iterator*)iter)->res;
-+
-+      if (((sqlite_object_iterator*)iter)->value) {
-+              zval_ptr_dtor(&((sqlite_object_iterator*)iter)->value);
-+              ((sqlite_object_iterator*)iter)->value = NULL;
-+      }
-+      if (res) {
-+              if (!res->buffered && res->vm) {
-+                      php_sqlite_fetch(res TSRMLS_CC);
-+              }
-+              if (res->curr_row >= res->nrows) {
-+                      /* php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available"); */
-+                      return;
-+              }
-+
-+              res->curr_row++;
-+      }
-+}
-+
-+zend_object_iterator_funcs sqlite_ub_query_iterator_funcs = {
-+      sqlite_iterator_dtor,
-+      sqlite_iterator_valid,
-+      sqlite_iterator_get_current_data,
-+      sqlite_iterator_get_current_key,
-+      sqlite_iterator_move_forward,
-+      NULL
-+};
-+
-+zend_object_iterator_funcs sqlite_query_iterator_funcs = {
-+      sqlite_iterator_dtor,
-+      sqlite_iterator_valid,
-+      sqlite_iterator_get_current_data,
-+      sqlite_iterator_get_current_key,
-+      sqlite_iterator_move_forward,
-+      sqlite_iterator_rewind
-+};
-+
-+zend_object_iterator *sqlite_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
-+{
-+      sqlite_object_iterator *iterator = emalloc(sizeof(sqlite_object_iterator));
-+
-+      sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
-+
-+      if (by_ref) {
-+              zend_error(E_RECOVERABLE_ERROR, "An iterator cannot be used with foreach by reference");
-+      }
-+      Z_ADDREF_P(object);
-+      iterator->it.data = (void*)object;
-+      iterator->it.funcs = ce->iterator_funcs.funcs;
-+      iterator->res = obj->u.res;
-+      iterator->value = NULL;
-+      return (zend_object_iterator*)iterator;
-+}
-+/* }}} */
-+
-+static PHP_GINIT_FUNCTION(sqlite)
-+{
-+      sqlite_globals->assoc_case = 0;
-+}
-+
-+PHP_MINIT_FUNCTION(sqlite)
-+{
-+      REGISTER_SQLITE_CLASS(Database,   db,        NULL);
-+      REGISTER_SQLITE_CLASS(Result,     query,     NULL);
-+      REGISTER_SQLITE_CLASS(Unbuffered, ub_query,  NULL);
-+#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
-+      REGISTER_SQLITE_CLASS(Exception,  exception, spl_ce_RuntimeException);
-+#else
-+      REGISTER_SQLITE_CLASS(Exception,  exception, zend_exception_get_default(TSRMLS_C));
-+#endif
-+
-+      sqlite_ce_db->ce_flags &= ~ZEND_ACC_FINAL_CLASS;
-+      sqlite_ce_db->constructor->common.fn_flags |= ZEND_ACC_FINAL;
-+
-+      sqlite_object_handlers_query.get_class_entry = sqlite_get_ce_query;
-+      sqlite_object_handlers_ub_query.get_class_entry = sqlite_get_ce_ub_query;
-+      sqlite_object_handlers_ub_query.count_elements = sqlite_count_elements;
-+
-+      sqlite_ce_ub_query->get_iterator = sqlite_get_iterator;
-+      sqlite_ce_ub_query->iterator_funcs.funcs = &sqlite_ub_query_iterator_funcs;
-+
-+#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
-+      zend_class_implements(sqlite_ce_query TSRMLS_CC, 2, zend_ce_iterator, spl_ce_Countable);
-+#else
-+      zend_class_implements(sqlite_ce_query TSRMLS_CC, 1, zend_ce_iterator);
-+#endif
-+      sqlite_ce_query->get_iterator = sqlite_get_iterator;
-+      sqlite_ce_query->iterator_funcs.funcs = &sqlite_query_iterator_funcs;
-+
-+      REGISTER_INI_ENTRIES();
-+
-+#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
-+      php_session_register_module(ps_sqlite_ptr);
-+#endif
-+
-+      le_sqlite_db = zend_register_list_destructors_ex(php_sqlite_db_dtor, NULL, "sqlite database", module_number);
-+      le_sqlite_pdb = zend_register_list_destructors_ex(NULL, php_sqlite_db_dtor, "sqlite database (persistent)", module_number);
-+      le_sqlite_result = zend_register_list_destructors_ex(php_sqlite_result_dtor, NULL, "sqlite result", module_number);
-+
-+      REGISTER_LONG_CONSTANT("SQLITE_BOTH",   PHPSQLITE_BOTH, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_NUM",    PHPSQLITE_NUM, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_ASSOC",  PHPSQLITE_ASSOC, CONST_CS|CONST_PERSISTENT);
-+
-+      REGISTER_LONG_CONSTANT("SQLITE_OK",                             SQLITE_OK, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_ERROR",                  SQLITE_ERROR, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_INTERNAL",               SQLITE_INTERNAL, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_PERM",                   SQLITE_PERM, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_ABORT",                  SQLITE_ABORT, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_BUSY",                   SQLITE_BUSY, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_LOCKED",                 SQLITE_LOCKED, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_NOMEM",                  SQLITE_NOMEM, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_READONLY",               SQLITE_READONLY, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_INTERRUPT",              SQLITE_INTERRUPT, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_IOERR",                  SQLITE_IOERR, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_CORRUPT",                SQLITE_CORRUPT, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_NOTFOUND",               SQLITE_NOTFOUND, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_FULL",                   SQLITE_FULL, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_CANTOPEN",               SQLITE_CANTOPEN, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_PROTOCOL",               SQLITE_PROTOCOL, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_EMPTY",                  SQLITE_EMPTY, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_SCHEMA",                 SQLITE_SCHEMA, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_TOOBIG",                 SQLITE_TOOBIG, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_CONSTRAINT",             SQLITE_CONSTRAINT, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_MISMATCH",               SQLITE_MISMATCH, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_MISUSE",                 SQLITE_MISUSE, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_NOLFS",                  SQLITE_NOLFS, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_AUTH",                   SQLITE_AUTH, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_NOTADB",                 SQLITE_NOTADB, CONST_CS|CONST_PERSISTENT);
-+#ifdef SQLITE_FORMAT
-+      REGISTER_LONG_CONSTANT("SQLITE_FORMAT",                 SQLITE_FORMAT, CONST_CS|CONST_PERSISTENT);
-+#endif
-+      REGISTER_LONG_CONSTANT("SQLITE_ROW",                    SQLITE_ROW, CONST_CS|CONST_PERSISTENT);
-+      REGISTER_LONG_CONSTANT("SQLITE_DONE",                   SQLITE_DONE, CONST_CS|CONST_PERSISTENT);
-+
-+#ifdef PHP_SQLITE2_HAVE_PDO
-+    if (FAILURE == php_pdo_register_driver(&pdo_sqlite2_driver)) {
-+      return FAILURE;
-+    }
-+#endif
-+
-+      return SUCCESS;
-+}
-+
-+PHP_MSHUTDOWN_FUNCTION(sqlite)
-+{
-+      UNREGISTER_INI_ENTRIES();
-+
-+#ifdef PHP_SQLITE2_HAVE_PDO
-+    php_pdo_unregister_driver(&pdo_sqlite2_driver);
-+#endif
-+
-+      return SUCCESS;
-+}
-+
-+PHP_MINFO_FUNCTION(sqlite)
-+{
-+      php_info_print_table_start();
-+      php_info_print_table_header(2, "SQLite support", "enabled");
-+      php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id$");
-+      php_info_print_table_row(2, "SQLite Library", sqlite_libversion());
-+      php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding());
-+      php_info_print_table_end();
-+
-+      DISPLAY_INI_ENTRIES();
-+}
-+
-+static struct php_sqlite_db *php_sqlite_open(char *filename, int mode, char *persistent_id, zval *return_value, zval *errmsg, zval *object TSRMLS_DC)
-+{
-+      char *errtext = NULL;
-+      sqlite *sdb = NULL;
-+      struct php_sqlite_db *db = NULL;
-+
-+      sdb = sqlite_open(filename, mode, &errtext);
-+
-+      if (sdb == NULL) {
-+
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+
-+              if (errmsg) {
-+                      ZVAL_STRING(errmsg, errtext, 1);
-+              }
-+
-+              sqlite_freemem(errtext);
-+
-+              /* if object is not an object then we're called from the factory() function */
-+              if (object && Z_TYPE_P(object) != IS_OBJECT) {
-+                      RETVAL_NULL();
-+              } else {
-+                      RETVAL_FALSE;
-+              }
-+              return NULL;
-+      }
-+
-+      db = (struct php_sqlite_db *)pemalloc(sizeof(struct php_sqlite_db), persistent_id ? 1 : 0);
-+      db->is_persistent = persistent_id ? 1 : 0;
-+      db->last_err_code = SQLITE_OK;
-+      db->db = sdb;
-+
-+      zend_hash_init(&db->callbacks, 0, NULL, php_sqlite_callback_dtor, db->is_persistent);
-+
-+      /* register the PHP functions */
-+      sqlite_create_function(sdb, "php", -1, php_sqlite_generic_function_callback, 0);
-+
-+      /* set default busy handler; keep retrying up until 1 minute has passed,
-+       * then fail with a busy status code */
-+      sqlite_busy_timeout(sdb, 60000);
-+
-+      /* authorizer hook so we can enforce safe mode
-+       * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
-+       * and IS backwards binary compatible with earlier versions */
-+      if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
-+              sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
-+      }
-+
-+      db->rsrc_id = ZEND_REGISTER_RESOURCE(object ? NULL : return_value, db, persistent_id ? le_sqlite_pdb : le_sqlite_db);
-+      if (object) {
-+              /* if object is not an object then we're called from the factory() function */
-+              if (Z_TYPE_P(object) != IS_OBJECT) {
-+                      sqlite_instanciate(sqlite_ce_db, object TSRMLS_CC);
-+              }
-+              /* and now register the object */
-+              SQLITE_REGISTER_OBJECT(db, object, db)
-+      }
-+
-+      if (persistent_id) {
-+              zend_rsrc_list_entry le;
-+
-+              Z_TYPE(le) = le_sqlite_pdb;
-+              le.ptr = db;
-+
-+              if (FAILURE == zend_hash_update(&EG(persistent_list), persistent_id,
-+                                      strlen(persistent_id)+1,
-+                                      (void *)&le, sizeof(le), NULL)) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource");
-+              }
-+      }
-+
-+      return db;
-+}
-+
-+/* {{{ proto resource sqlite_popen(string filename [, int mode [, string &error_message]])
-+   Opens a persistent handle to a SQLite database. Will create the database if it does not exist. */
-+PHP_FUNCTION(sqlite_popen)
-+{
-+      long mode = 0666;
-+      char *filename, *fullpath, *hashkey;
-+      int filename_len, hashkeylen;
-+      zval *errmsg = NULL;
-+      struct php_sqlite_db *db = NULL;
-+      zend_rsrc_list_entry *le;
-+
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
-+                              &filename, &filename_len, &mode, &errmsg)) {
-+              return;
-+      }
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      if (strlen(filename) != filename_len) {
-+              RETURN_FALSE;
-+      }
-+      if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
-+              /* resolve the fully-qualified path name to use as the hash key */
-+              if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
-+                      RETURN_FALSE;
-+              }
-+
-+              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || 
-+                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+                      efree(fullpath);
-+                      RETURN_FALSE;
-+              }
-+      } else {
-+              fullpath = estrndup(filename, filename_len);
-+      }
-+
-+      hashkeylen = spprintf(&hashkey, 0, "sqlite_pdb_%s:%ld", fullpath, mode);
-+
-+      /* do we have an existing persistent connection ? */
-+      if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkeylen+1, (void*)&le)) {
-+              if (Z_TYPE_P(le) == le_sqlite_pdb) {
-+                      db = (struct php_sqlite_db*)le->ptr;
-+
-+                      if (db->rsrc_id == FAILURE) {
-+                              /* give it a valid resource id for this request */
-+                              db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
-+                      } else {
-+                              int type;
-+                              /* sanity check to ensure that the resource is still a valid regular resource
-+                               * number */
-+                              if (zend_list_find(db->rsrc_id, &type) == db) {
-+                                      /* already accessed this request; map it */
-+                                      zend_list_addref(db->rsrc_id);
-+                                      ZVAL_RESOURCE(return_value, db->rsrc_id);
-+                              } else {
-+                                      db->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, db, le_sqlite_pdb);
-+                              }
-+                      }
-+
-+                      /* all set */
-+                      goto done;
-+              }
-+
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Some other type of persistent resource is using this hash key!?");
-+              RETVAL_FALSE;
-+              goto done;
-+      }
-+
-+      /* now we need to open the database */
-+      php_sqlite_open(fullpath, (int)mode, hashkey, return_value, errmsg, NULL TSRMLS_CC);
-+done:
-+      efree(fullpath);
-+      efree(hashkey);
-+}
-+/* }}} */
-+
-+/* {{{ proto resource sqlite_open(string filename [, int mode [, string &error_message]])
-+   Opens a SQLite database. Will create the database if it does not exist. */
-+PHP_FUNCTION(sqlite_open)
-+{
-+      long mode = 0666;
-+      char *filename, *fullpath = NULL;
-+      int filename_len;
-+      zval *errmsg = NULL;
-+      zval *object = getThis();
-+      zend_error_handling error_handling;
-+
-+      zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
-+                              &filename, &filename_len, &mode, &errmsg)) {
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              return;
-+      }
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      if (strlen(filename) != filename_len) {
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              RETURN_FALSE;
-+      }
-+
-+      if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
-+              /* resolve the fully-qualified path name to use as the hash key */
-+              if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      if (object) {
-+                              RETURN_NULL();
-+                      } else {
-+                              RETURN_FALSE;
-+                      }
-+              }
-+
-+              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
-+                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+                      efree(fullpath);
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      if (object) {
-+                              RETURN_NULL();
-+                      } else {
-+                              RETURN_FALSE;
-+                      }
-+              }
-+      }
-+
-+      php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, object TSRMLS_CC);
-+
-+      if (fullpath) {
-+              efree(fullpath);
-+      }
-+      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto object sqlite_factory(string filename [, int mode [, string &error_message]])
-+   Opens a SQLite database and creates an object for it. Will create the database if it does not exist. */
-+PHP_FUNCTION(sqlite_factory)
-+{
-+      long mode = 0666;
-+      char *filename, *fullpath = NULL;
-+      int filename_len;
-+      zval *errmsg = NULL;
-+      zend_error_handling error_handling;
-+
-+      zend_replace_error_handling(EH_THROW, sqlite_ce_exception, &error_handling TSRMLS_CC);
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/",
-+                              &filename, &filename_len, &mode, &errmsg)) {
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              RETURN_NULL();
-+      }
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      if (strlen(filename) != filename_len) {
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              RETURN_FALSE;
-+      }
-+
-+      if (strncmp(filename, ":memory:", sizeof(":memory:") - 1)) {
-+              /* resolve the fully-qualified path name to use as the hash key */
-+              if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) {
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      RETURN_NULL();
-+              }
-+
-+              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
-+                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+                      efree(fullpath);
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      RETURN_NULL();
-+              }
-+      }
-+
-+      php_sqlite_open(fullpath ? fullpath : filename, (int)mode, NULL, return_value, errmsg, return_value TSRMLS_CC);
-+      if (fullpath) {
-+              efree(fullpath);
-+      }
-+      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto void sqlite_busy_timeout(resource db, int ms)
-+   Set busy timeout duration. If ms <= 0, all busy handlers are disabled. */
-+PHP_FUNCTION(sqlite_busy_timeout)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      long ms;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ms)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zdb, &ms)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      sqlite_busy_timeout(db->db, ms);
-+}
-+/* }}} */
-+
-+/* {{{ proto void sqlite_close(resource db)
-+   Closes an open sqlite database. */
-+PHP_FUNCTION(sqlite_close)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Ignored, you must destruct the object instead");
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      zend_hash_apply_with_argument(&EG(regular_list),
-+              (apply_func_arg_t) _clean_unfinished_results,
-+              db TSRMLS_CC);
-+
-+      zend_list_delete(Z_RESVAL_P(zdb));
-+}
-+/* }}} */
-+
-+/* {{{ php_sqlite_fetch */
-+static int php_sqlite_fetch(struct php_sqlite_result *rres TSRMLS_DC)
-+{
-+      const char **rowdata, **colnames;
-+      int ret, i, base;
-+      char *errtext = NULL;
-+
-+next_row:
-+      ret = sqlite_step(rres->vm, &rres->ncolumns, &rowdata, &colnames);
-+      if (!rres->nrows) {
-+              /* first row - lets copy the column names */
-+              rres->col_names = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
-+              for (i = 0; i < rres->ncolumns; i++) {
-+                      rres->col_names[i] = estrdup((char*)colnames[i]);
-+
-+                      if (SQLITE_G(assoc_case) == 1) {
-+                              php_sqlite_strtoupper(rres->col_names[i]);
-+                      } else if (SQLITE_G(assoc_case) == 2) {
-+                              php_sqlite_strtolower(rres->col_names[i]);
-+                      }
-+              }
-+              if (!rres->buffered) {
-+                      /* non buffered mode - also fetch memory for on single row */
-+                      rres->table = safe_emalloc(rres->ncolumns, sizeof(char *), 0);
-+              }
-+      }
-+
-+      switch (ret) {
-+              case SQLITE_ROW:
-+                      if (rres->buffered) {
-+                              /* add the row to our collection */
-+                              if (rres->nrows + 1 >= rres->alloc_rows) {
-+                                      rres->alloc_rows = rres->alloc_rows ? rres->alloc_rows * 2 : 16;
-+                                      rres->table = safe_erealloc(rres->table, rres->alloc_rows, rres->ncolumns*sizeof(char *), 0);
-+                              }
-+                              base = rres->nrows * rres->ncolumns;
-+                              for (i = 0; i < rres->ncolumns; i++) {
-+                                      if (rowdata[i]) {
-+                                              rres->table[base + i] = estrdup(rowdata[i]);
-+                                      } else {
-+                                              rres->table[base + i] = NULL;
-+                                      }
-+                              }
-+                              rres->nrows++;
-+                              goto next_row;
-+                      } else {
-+                              /* non buffered: only fetch one row but first free data if not first row */
-+                              if (rres->nrows++) {
-+                                      for (i = 0; i < rres->ncolumns; i++) {
-+                                              if (rres->table[i]) {
-+                                                      efree(rres->table[i]);
-+                                              }
-+                                      }
-+                              }
-+                              for (i = 0; i < rres->ncolumns; i++) {
-+                                      if (rowdata[i]) {
-+                                              rres->table[i] = estrdup(rowdata[i]);
-+                                      } else {
-+                                              rres->table[i] = NULL;
-+                                      }
-+                              }
-+                      }
-+                      ret = SQLITE_OK;
-+                      break;
-+
-+              case SQLITE_BUSY:
-+              case SQLITE_ERROR:
-+              case SQLITE_MISUSE:
-+              case SQLITE_DONE:
-+              default:
-+                      if (rres->vm) {
-+                              ret = sqlite_finalize(rres->vm, &errtext);
-+                      }
-+                      rres->vm = NULL;
-+                      if (ret != SQLITE_OK) {
-+                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+                              sqlite_freemem(errtext);
-+                      }
-+                      break;
-+      }
-+      rres->db->last_err_code = ret;
-+
-+      return ret;
-+}
-+/* }}} */
-+
-+/* {{{ sqlite_query */
-+void sqlite_query(zval *object, struct php_sqlite_db *db, char *sql, long sql_len, int mode, int buffered, zval *return_value, struct php_sqlite_result **prres, zval *errmsg TSRMLS_DC)
-+{
-+      struct php_sqlite_result res, *rres;
-+      int ret;
-+      char *errtext = NULL;
-+      const char *tail;
-+
-+      memset(&res, 0, sizeof(res));
-+      res.buffered = buffered;
-+      res.mode = mode;
-+
-+      ret = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
-+      db->last_err_code = ret;
-+
-+      if (ret != SQLITE_OK) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+              if (errmsg) {
-+                      ZVAL_STRING(errmsg, errtext, 1);
-+              }
-+              sqlite_freemem(errtext);
-+              goto terminate;
-+      } else if (!res.vm) { /* empty query */
-+terminate:
-+              if (return_value) {
-+                      RETURN_FALSE;
-+              } else {
-+                      return;
-+              }
-+      }
-+
-+      if (!prres) {
-+              rres = NULL;
-+              prres = &rres;
-+      }
-+      if (!*prres) {
-+              *prres = (struct php_sqlite_result*)emalloc(sizeof(**prres));
-+      }
-+      memcpy(*prres, &res, sizeof(**prres));
-+      (*prres)->db = db;
-+      zend_list_addref(db->rsrc_id);
-+
-+
-+      /* now the result set is ready for stepping: get first row */
-+      if (php_sqlite_fetch((*prres) TSRMLS_CC) != SQLITE_OK) {
-+              real_result_dtor((*prres) TSRMLS_CC);
-+              *prres = NULL;
-+              if (return_value) {
-+                      RETURN_FALSE;
-+              } else {
-+                      return;
-+              }
-+      }
-+
-+      (*prres)->curr_row = 0;
-+
-+      if (object) {
-+              sqlite_object *obj;
-+              if (buffered) {
-+                      sqlite_instanciate(sqlite_ce_query, return_value TSRMLS_CC);
-+              } else {
-+                      sqlite_instanciate(sqlite_ce_ub_query, return_value TSRMLS_CC);
-+              }
-+              obj = (sqlite_object *) zend_object_store_get_object(return_value TSRMLS_CC);
-+              obj->type = is_result;
-+              obj->u.res = (*prres);
-+      } else if (return_value) {
-+              ZEND_REGISTER_RESOURCE(object ? NULL : return_value, (*prres), le_sqlite_result);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto resource sqlite_unbuffered_query(string query, resource db [ , int result_type [, string &error_message]])
-+   Executes a query that does not prefetch and buffer all data. */
-+PHP_FUNCTION(sqlite_unbuffered_query)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      char *sql;
-+      int sql_len;
-+      long mode = PHPSQLITE_BOTH;
-+      char *errtext = NULL;
-+      zval *errmsg = NULL;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                              ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
-+                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      PHP_SQLITE_EMPTY_QUERY;
-+
-+      /* avoid doing work if we can */
-+      if (!return_value_used) {
-+              db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
-+
-+              if (db->last_err_code != SQLITE_OK) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+                      if (errmsg) {
-+                              ZVAL_STRING(errmsg, errtext, 1);
-+                      }
-+                      sqlite_freemem(errtext);
-+              }
-+              return;
-+      }
-+
-+      sqlite_query(object, db, sql, sql_len, (int)mode, 0, return_value, NULL, errmsg TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto resource sqlite_fetch_column_types(string table_name, resource db [, int result_type])
-+   Return an array of column types from a particular table. */
-+PHP_FUNCTION(sqlite_fetch_column_types)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      char *tbl, *sql;
-+      int tbl_len;
-+      char *errtext = NULL;
-+      zval *object = getThis();
-+      struct php_sqlite_result res;
-+      const char **rowdata, **colnames, *tail;
-+      int i, ncols;
-+      long result_type = PHPSQLITE_ASSOC;
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &tbl, &tbl_len, &result_type)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                              ZEND_NUM_ARGS() TSRMLS_CC, "sr|l", &tbl, &tbl_len, &zdb, &result_type) &&
-+                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &zdb, &tbl, &tbl_len, &result_type)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (!(sql = sqlite_mprintf("SELECT * FROM '%q' LIMIT 1", tbl))) {
-+              RETURN_FALSE;
-+      }
-+
-+      sqlite_exec(db->db, "PRAGMA show_datatypes = ON", NULL, NULL, NULL);
-+
-+      db->last_err_code = sqlite_compile(db->db, sql, &tail, &res.vm, &errtext);
-+
-+      sqlite_freemem(sql);
-+
-+      if (db->last_err_code != SQLITE_OK) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+              sqlite_freemem(errtext);
-+              RETVAL_FALSE;
-+              goto done;
-+      }
-+
-+      sqlite_step(res.vm, &ncols, &rowdata, &colnames);
-+
-+      array_init(return_value);
-+
-+      for (i = 0; i < ncols; i++) {
-+              if (result_type == PHPSQLITE_ASSOC) {
-+                      char *colname = estrdup((char *)colnames[i]);
-+
-+                      if (SQLITE_G(assoc_case) == 1) {
-+                              php_sqlite_strtoupper(colname);
-+                      } else if (SQLITE_G(assoc_case) == 2) {
-+                              php_sqlite_strtolower(colname);
-+                      }
-+
-+                      add_assoc_string(return_value, colname, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
-+                      efree(colname);
-+              }
-+              if (result_type == PHPSQLITE_NUM) {
-+                      add_index_string(return_value, i, colnames[ncols + i] ? (char *)colnames[ncols + i] : "", 1);
-+              }
-+      }
-+      if (res.vm) {
-+              sqlite_finalize(res.vm, NULL);
-+      }
-+done:
-+      sqlite_exec(db->db, "PRAGMA show_datatypes = OFF", NULL, NULL, NULL);
-+}
-+/* }}} */
-+
-+/* {{{ proto resource sqlite_query(string query, resource db [, int result_type [, string &error_message]])
-+   Executes a query against a given database and returns a result handle. */
-+PHP_FUNCTION(sqlite_query)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      char *sql;
-+      int sql_len;
-+      long mode = PHPSQLITE_BOTH;
-+      char *errtext = NULL;
-+      zval *errmsg = NULL;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz/", &sql, &sql_len, &mode, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                              ZEND_NUM_ARGS() TSRMLS_CC, "sr|lz/", &sql, &sql_len, &zdb, &mode, &errmsg) &&
-+                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lz/", &zdb, &sql, &sql_len, &mode, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      PHP_SQLITE_EMPTY_QUERY;
-+
-+      /* avoid doing work if we can */
-+      if (!return_value_used) {
-+              db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
-+
-+              if (db->last_err_code != SQLITE_OK) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+                      if (errmsg) {
-+                              ZVAL_STRING(errmsg, errtext, 1);
-+                      }
-+                      sqlite_freemem(errtext);
-+              }
-+              return;
-+      }
-+
-+      sqlite_query(object, db, sql, sql_len, (int)mode, 1, return_value, NULL, errmsg TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto boolean sqlite_exec(string query, resource db[, string &error_message])
-+   Executes a result-less query against a given database */
-+PHP_FUNCTION(sqlite_exec)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      char *sql;
-+      int sql_len;
-+      char *errtext = NULL;
-+      zval *errmsg = NULL;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &sql, &sql_len, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if(FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                      ZEND_NUM_ARGS() TSRMLS_CC, "sr", &sql, &sql_len, &zdb) &&
-+                 FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &zdb, &sql, &sql_len, &errmsg)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (errmsg) {
-+              zval_dtor(errmsg);
-+              ZVAL_NULL(errmsg);
-+      }
-+
-+      PHP_SQLITE_EMPTY_QUERY;
-+
-+      db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
-+
-+      if (db->last_err_code != SQLITE_OK) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+              if (errmsg) {
-+                      ZVAL_STRING(errmsg, errtext, 1);
-+              }
-+              sqlite_freemem(errtext);
-+              RETURN_FALSE;
-+      }
-+
-+      RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ php_sqlite_fetch_array */
-+static void php_sqlite_fetch_array(struct php_sqlite_result *res, int mode, zend_bool decode_binary, int move_next, zval *return_value TSRMLS_DC)
-+{
-+      int j, n = res->ncolumns, buffered = res->buffered;
-+      const char **rowdata, **colnames;
-+
-+      /* check range of the row */
-+      if (res->curr_row >= res->nrows) {
-+              /* no more */
-+              RETURN_FALSE;
-+      }
-+      colnames = (const char**)res->col_names;
-+      if (res->buffered) {
-+              rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
-+      } else {
-+              rowdata = (const char**)res->table;
-+      }
-+
-+      /* now populate the result */
-+      array_init(return_value);
-+
-+      for (j = 0; j < n; j++) {
-+              zval *decoded;
-+              MAKE_STD_ZVAL(decoded);
-+
-+              if (rowdata[j] == NULL) {
-+                      ZVAL_NULL(decoded);
-+              } else if (decode_binary && rowdata[j][0] == '\x01') {
-+                      Z_STRVAL_P(decoded) = emalloc(strlen(rowdata[j]));
-+                      Z_STRLEN_P(decoded) = php_sqlite_decode_binary(rowdata[j]+1, Z_STRVAL_P(decoded));
-+                      Z_STRVAL_P(decoded)[Z_STRLEN_P(decoded)] = '\0';
-+                      Z_TYPE_P(decoded) = IS_STRING;
-+                      if (!buffered) {
-+                              efree((char*)rowdata[j]);
-+                              rowdata[j] = NULL;
-+                      }
-+              } else {
-+                      ZVAL_STRING(decoded, (char*)rowdata[j], buffered);
-+                      if (!buffered) {
-+                              rowdata[j] = NULL;
-+                      }
-+              }
-+
-+              if (mode & PHPSQLITE_NUM) {
-+                      if (mode & PHPSQLITE_ASSOC) {
-+                              add_index_zval(return_value, j, decoded);
-+                              Z_ADDREF_P(decoded);
-+                              add_assoc_zval(return_value, (char*)colnames[j], decoded);
-+                      } else {
-+                              add_next_index_zval(return_value, decoded);
-+                      }
-+              } else {
-+                      add_assoc_zval(return_value, (char*)colnames[j], decoded);
-+              }
-+      }
-+
-+      if (move_next) {
-+              if (!res->buffered) {
-+                      /* non buffered: fetch next row */
-+                      php_sqlite_fetch(res TSRMLS_CC);
-+              }
-+              /* advance the row pointer */
-+              res->curr_row++;
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ php_sqlite_fetch_column */
-+static void php_sqlite_fetch_column(struct php_sqlite_result *res, zval *which, zend_bool decode_binary, zval *return_value TSRMLS_DC)
-+{
-+      int j;
-+      const char **rowdata, **colnames;
-+
-+      /* check range of the row */
-+      if (res->curr_row >= res->nrows) {
-+              /* no more */
-+              RETURN_FALSE;
-+      }
-+      colnames = (const char**)res->col_names;
-+
-+      if (Z_TYPE_P(which) == IS_LONG) {
-+              j = Z_LVAL_P(which);
-+      } else {
-+              convert_to_string_ex(&which);
-+              for (j = 0; j < res->ncolumns; j++) {
-+                      if (!strcasecmp((char*)colnames[j], Z_STRVAL_P(which))) {
-+                              break;
-+                      }
-+              }
-+      }
-+      if (j < 0 || j >= res->ncolumns) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such column %d", j);
-+              RETURN_FALSE;
-+      }
-+
-+      if (res->buffered) {
-+              rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
-+      } else {
-+              rowdata = (const char**)res->table;
-+      }
-+
-+      if (rowdata[j] == NULL) {
-+              RETURN_NULL();
-+      } else if (decode_binary && rowdata[j] != NULL && rowdata[j][0] == '\x01') {
-+              int l = strlen(rowdata[j]);
-+              char *decoded = emalloc(l);
-+              l = php_sqlite_decode_binary(rowdata[j]+1, decoded);
-+              decoded[l] = '\0';
-+              RETVAL_STRINGL(decoded, l, 0);
-+              if (!res->buffered) {
-+                      efree((char*)rowdata[j]);
-+                      rowdata[j] = NULL;
-+              }
-+      } else {
-+              RETVAL_STRING((char*)rowdata[j], res->buffered);
-+              if (!res->buffered) {
-+                      rowdata[j] = NULL;
-+              }
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto array sqlite_fetch_all(resource result [, int result_type [, bool decode_binary]])
-+   Fetches all rows from a result set as an array of arrays. */
-+PHP_FUNCTION(sqlite_fetch_all)
-+{
-+      zval *zres, *ent;
-+      long mode = PHPSQLITE_BOTH;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+              if (!ZEND_NUM_ARGS()) {
-+                      mode = res->mode;
-+              }
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+              if (ZEND_NUM_ARGS() < 2) {
-+                      mode = res->mode;
-+              }
-+      }
-+
-+      if (res->curr_row >= res->nrows && res->nrows) {
-+              if (!res->buffered) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "One or more rowsets were already returned; returning NULL this time");
-+              } else {
-+                      res->curr_row = 0;
-+              }
-+      }
-+
-+      array_init(return_value);
-+
-+      while (res->curr_row < res->nrows) {
-+              MAKE_STD_ZVAL(ent);
-+              php_sqlite_fetch_array(res, mode, decode_binary, 1, ent TSRMLS_CC);
-+              add_next_index_zval(return_value, ent);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto array sqlite_fetch_array(resource result [, int result_type [, bool decode_binary]])
-+   Fetches the next row from a result set as an array. */
-+PHP_FUNCTION(sqlite_fetch_array)
-+{
-+      zval *zres;
-+      long mode = PHPSQLITE_BOTH;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+              if (!ZEND_NUM_ARGS()) {
-+                      mode = res->mode;
-+              }
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+              if (ZEND_NUM_ARGS() < 2) {
-+                      mode = res->mode;
-+              }
-+      }
-+
-+      php_sqlite_fetch_array(res, mode, decode_binary, 1, return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto object sqlite_fetch_object(resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]])
-+   Fetches the next row from a result set as an object. */
-+   /* note that you can do array(&$val) for param ctor_params */
-+PHP_FUNCTION(sqlite_fetch_object)
-+{
-+      zval *zres;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+      char *class_name = NULL;
-+      int class_name_len;
-+      zend_class_entry *ce;
-+      zval dataset;
-+      zend_fcall_info fci;
-+      zend_fcall_info_cache fcc;
-+      zval *retval_ptr;
-+      zval *ctor_params = NULL;
-+      zend_error_handling error_handling;
-+
-+      zend_replace_error_handling(object ? EH_THROW : EH_NORMAL, sqlite_ce_exception, &error_handling TSRMLS_CC);
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szb", &class_name, &class_name_len, &ctor_params, &decode_binary)) {
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      return;
-+              }
-+              RES_FROM_OBJECT_RESTORE_ERH(res, object, &error_handling);
-+              if (!class_name) {
-+                      ce = zend_standard_class_def;
-+              } else {
-+                      ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
-+              }
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|szb", &zres, &class_name, &class_name_len, &ctor_params, &decode_binary)) {
-+                      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+              if (!class_name) {
-+                      ce = zend_standard_class_def;
-+              } else {
-+                      ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
-+              }
-+      }
-+
-+      if (!ce) {
-+              zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not find class '%s'", class_name);
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              return;
-+      }
-+
-+      if (res->curr_row < res->nrows) {
-+              php_sqlite_fetch_array(res, PHPSQLITE_ASSOC, decode_binary, 1, &dataset TSRMLS_CC);
-+      } else {
-+              zend_restore_error_handling(&error_handling TSRMLS_CC);
-+              RETURN_FALSE;
-+      }
-+
-+      object_and_properties_init(return_value, ce, NULL);
-+      zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
-+
-+      zend_restore_error_handling(&error_handling TSRMLS_CC);
-+
-+      if (ce->constructor) {
-+              fci.size = sizeof(fci);
-+              fci.function_table = &ce->function_table;
-+              fci.function_name = NULL;
-+              fci.symbol_table = NULL;
-+              fci.object_ptr = return_value;
-+              fci.retval_ptr_ptr = &retval_ptr;
-+              if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
-+                      if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
-+                              HashTable *ht = Z_ARRVAL_P(ctor_params);
-+                              Bucket *p;
-+
-+                              fci.param_count = 0;
-+                              fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
-+                              p = ht->pListHead;
-+                              while (p != NULL) {
-+                                      fci.params[fci.param_count++] = (zval**)p->pData;
-+                                      p = p->pListNext;
-+                              }
-+                      } else {
-+                              /* Two problems why we throw exceptions here: PHP is typeless
-+                               * and hence passing one argument that's not an array could be
-+                               * by mistake and the other way round is possible, too. The
-+                               * single value is an array. Also we'd have to make that one
-+                               * argument passed by reference.
-+                               */
-+                              zend_throw_exception(sqlite_ce_exception, "Parameter ctor_params must be an array", 0 TSRMLS_CC);
-+                              return;
-+                      }
-+              } else {
-+                      fci.param_count = 0;
-+                      fci.params = NULL;
-+              }
-+              fci.no_separation = 1;
-+
-+              fcc.initialized = 1;
-+              fcc.function_handler = ce->constructor;
-+              fcc.calling_scope = EG(scope);
-+              fcc.called_scope = Z_OBJCE_P(return_value);
-+              fcc.object_ptr = return_value;
-+
-+              if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
-+                      zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Could not execute %s::%s()", class_name, ce->constructor->common.function_name);
-+              } else {
-+                      if (retval_ptr) {
-+                              zval_ptr_dtor(&retval_ptr);
-+                      }
-+              }
-+              if (fci.params) {
-+                      efree(fci.params);
-+              }
-+      } else if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
-+              zend_throw_exception_ex(sqlite_ce_exception, 0 TSRMLS_CC, "Class %s does not have a constructor, use NULL for parameter ctor_params or omit it", class_name);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto array sqlite_array_query(resource db, string query [ , int result_type [, bool decode_binary]])
-+   Executes a query against a given database and returns an array of arrays. */
-+PHP_FUNCTION(sqlite_array_query)
-+{
-+      zval *zdb, *ent;
-+      struct php_sqlite_db *db;
-+      struct php_sqlite_result *rres;
-+      char *sql;
-+      int sql_len;
-+      long mode = PHPSQLITE_BOTH;
-+      char *errtext = NULL;
-+      zend_bool decode_binary = 1;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &sql, &sql_len, &mode, &decode_binary)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                              ZEND_NUM_ARGS() TSRMLS_CC, "sr|lb", &sql, &sql_len, &zdb, &mode, &decode_binary) &&
-+                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lb", &zdb, &sql, &sql_len, &mode, &decode_binary)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      PHP_SQLITE_EMPTY_QUERY;
-+
-+      /* avoid doing work if we can */
-+      if (!return_value_used) {
-+              db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
-+
-+              if (db->last_err_code != SQLITE_OK) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+                      sqlite_freemem(errtext);
-+              }
-+              return;
-+      }
-+
-+      rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
-+      sqlite_query(NULL, db, sql, sql_len, (int)mode, 0, NULL, &rres, NULL TSRMLS_CC);
-+      if (db->last_err_code != SQLITE_OK) {
-+              if (rres) {
-+                      efree(rres);
-+              }
-+              RETURN_FALSE;
-+      }
-+
-+      array_init(return_value);
-+
-+      while (rres->curr_row < rres->nrows) {
-+              MAKE_STD_ZVAL(ent);
-+              php_sqlite_fetch_array(rres, mode, decode_binary, 1, ent TSRMLS_CC);
-+              add_next_index_zval(return_value, ent);
-+      }
-+      real_result_dtor(rres TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ php_sqlite_fetch_single */
-+static void php_sqlite_fetch_single(struct php_sqlite_result *res, zend_bool decode_binary, zval *return_value TSRMLS_DC)
-+{
-+      const char **rowdata;
-+      char *decoded;
-+      int decoded_len;
-+
-+      /* check range of the row */
-+      if (res->curr_row >= res->nrows) {
-+              /* no more */
-+              RETURN_FALSE;
-+      }
-+
-+      if (res->buffered) {
-+              rowdata = (const char**)&res->table[res->curr_row * res->ncolumns];
-+      } else {
-+              rowdata = (const char**)res->table;
-+      }
-+
-+      if (decode_binary && rowdata[0] != NULL && rowdata[0][0] == '\x01') {
-+              decoded = emalloc(strlen(rowdata[0]));
-+              decoded_len = php_sqlite_decode_binary(rowdata[0]+1, decoded);
-+              if (!res->buffered) {
-+                      efree((char*)rowdata[0]);
-+                      rowdata[0] = NULL;
-+              }
-+      } else if (rowdata[0]) {
-+              decoded_len = strlen((char*)rowdata[0]);
-+              if (res->buffered) {
-+                      decoded = estrndup((char*)rowdata[0], decoded_len);
-+              } else {
-+                      decoded = (char*)rowdata[0];
-+                      rowdata[0] = NULL;
-+              }
-+      } else {
-+              decoded = NULL;
-+              decoded_len = 0;
-+      }
-+
-+      if (!res->buffered) {
-+              /* non buffered: fetch next row */
-+              php_sqlite_fetch(res TSRMLS_CC);
-+      }
-+      /* advance the row pointer */
-+      res->curr_row++;
-+
-+      if (decoded == NULL) {
-+              RETURN_NULL();
-+      } else {
-+              RETURN_STRINGL(decoded, decoded_len, 0);
-+      }
-+}
-+/* }}} */
-+
-+
-+/* {{{ proto array sqlite_single_query(resource db, string query [, bool first_row_only [, bool decode_binary]])
-+   Executes a query and returns either an array for one single column or the value of the first row. */
-+PHP_FUNCTION(sqlite_single_query)
-+{
-+      zval *zdb, *ent;
-+      struct php_sqlite_db *db;
-+      struct php_sqlite_result *rres;
-+      char *sql;
-+      int sql_len;
-+      char *errtext = NULL;
-+      zend_bool decode_binary = 1;
-+      zend_bool srow = 1;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb", &sql, &sql_len, &srow, &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
-+                              ZEND_NUM_ARGS() TSRMLS_CC, "sr|bb", &sql, &sql_len, &zdb, &srow, &decode_binary) &&
-+                      FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|bb", &zdb, &sql, &sql_len, &srow, &decode_binary)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      PHP_SQLITE_EMPTY_QUERY;
-+
-+      /* avoid doing work if we can */
-+      if (!return_value_used) {
-+              db->last_err_code = sqlite_exec(db->db, sql, NULL, NULL, &errtext);
-+
-+              if (db->last_err_code != SQLITE_OK) {
-+                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
-+                      sqlite_freemem(errtext);
-+              }
-+              return;
-+      }
-+
-+      rres = (struct php_sqlite_result *)ecalloc(1, sizeof(*rres));
-+      sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, &rres, NULL TSRMLS_CC);
-+      if (db->last_err_code != SQLITE_OK) {
-+              if (rres) {
-+                      efree(rres);
-+              }
-+              RETURN_FALSE;
-+      }
-+
-+      if (!srow) {
-+              array_init(return_value);
-+      }
-+
-+      while (rres->curr_row < rres->nrows) {
-+              MAKE_STD_ZVAL(ent);
-+              php_sqlite_fetch_single(rres, decode_binary, ent TSRMLS_CC);
-+
-+              /* if set and we only have 1 row in the result set, return the result as a string. */
-+              if (srow) {
-+                      if (rres->curr_row == 1 && rres->curr_row >= rres->nrows) {
-+                              *return_value = *ent;
-+                              zval_copy_ctor(return_value);
-+                              zval_dtor(ent);
-+                              FREE_ZVAL(ent);
-+                              break;
-+                      } else {
-+                              srow = 0;
-+                              array_init(return_value);
-+                      }
-+              }
-+              add_next_index_zval(return_value, ent);
-+      }
-+
-+      real_result_dtor(rres TSRMLS_CC);
-+}
-+/* }}} */
-+
-+
-+/* {{{ proto string sqlite_fetch_single(resource result [, bool decode_binary])
-+   Fetches the first column of a result set as a string. */
-+PHP_FUNCTION(sqlite_fetch_single)
-+{
-+      zval *zres;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zres, &decode_binary)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      php_sqlite_fetch_single(res, decode_binary, return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto array sqlite_current(resource result [, int result_type [, bool decode_binary]])
-+   Fetches the current row from a result set as an array. */
-+PHP_FUNCTION(sqlite_current)
-+{
-+      zval *zres;
-+      long mode = PHPSQLITE_BOTH;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (ZEND_NUM_ARGS() && FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &mode, &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+              if (!ZEND_NUM_ARGS()) {
-+                      mode = res->mode;
-+              }
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lb", &zres, &mode, &decode_binary)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+              if (ZEND_NUM_ARGS() < 2) {
-+                      mode = res->mode;
-+              }
-+      }
-+
-+      php_sqlite_fetch_array(res, mode, decode_binary, 0, return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto mixed sqlite_column(resource result, mixed index_or_name [, bool decode_binary])
-+   Fetches a column from the current row of a result set. */
-+PHP_FUNCTION(sqlite_column)
-+{
-+      zval *zres;
-+      zval *which;
-+      zend_bool decode_binary = 1;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &which, &decode_binary)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|b", &zres, &which, &decode_binary)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      php_sqlite_fetch_column(res, which, decode_binary, return_value TSRMLS_CC);
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_libversion()
-+   Returns the version of the linked SQLite library. */
-+PHP_FUNCTION(sqlite_libversion)
-+{
-+      if (zend_parse_parameters_none() == FAILURE) {
-+              return;
-+      }
-+      RETURN_STRING((char*)sqlite_libversion(), 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_libencoding()
-+   Returns the encoding (iso8859 or UTF-8) of the linked SQLite library. */
-+PHP_FUNCTION(sqlite_libencoding)
-+{
-+      if (zend_parse_parameters_none() == FAILURE) {
-+              return;
-+      }
-+      RETURN_STRING((char*)sqlite_libencoding(), 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto int sqlite_changes(resource db)
-+   Returns the number of rows that were changed by the most recent SQL statement. */
-+PHP_FUNCTION(sqlite_changes)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      RETURN_LONG(sqlite_changes(db->db));
-+}
-+/* }}} */
-+
-+/* {{{ proto int sqlite_last_insert_rowid(resource db)
-+   Returns the rowid of the most recently inserted row. */
-+PHP_FUNCTION(sqlite_last_insert_rowid)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      RETURN_LONG(sqlite_last_insert_rowid(db->db));
-+}
-+/* }}} */
-+
-+static int sqlite_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
-+{
-+      sqlite_object *obj = (sqlite_object*) zend_object_store_get_object(object TSRMLS_CC);
-+
-+      if (obj->u.res == NULL) {
-+              zend_throw_exception(sqlite_ce_exception, "Row count is not available for this query", 0 TSRMLS_CC);
-+              return FAILURE;
-+      }
-+
-+      if (obj->u.res->buffered) {
-+              * count = obj->u.res->nrows;
-+              return SUCCESS;
-+      } else {
-+              zend_throw_exception(sqlite_ce_exception, "Row count is not available for unbuffered queries", 0 TSRMLS_CC);
-+              return FAILURE;
-+      }
-+} /* }}} */
-+
-+/* {{{ proto int sqlite_num_rows(resource result)
-+   Returns the number of rows in a buffered result set. */
-+PHP_FUNCTION(sqlite_num_rows)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (res->buffered) {
-+              RETURN_LONG(res->nrows);
-+      } else {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Row count is not available for unbuffered queries");
-+              RETURN_FALSE;
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_valid(resource result)
-+   Returns whether more rows are available. */
-+PHP_FUNCTION(sqlite_valid)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      RETURN_BOOL(res->curr_row < res->nrows && res->nrows); /* curr_row may be -1 */
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_has_prev(resource result)
-+ * Returns whether a previous row is available. */
-+PHP_FUNCTION(sqlite_has_prev)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if(!res->buffered) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_has_prev on unbuffered querys");
-+              RETURN_FALSE;
-+      }
-+
-+      RETURN_BOOL(res->curr_row);
-+}
-+/* }}} */
-+
-+/* {{{ proto int sqlite_num_fields(resource result)
-+   Returns the number of fields in a result set. */
-+PHP_FUNCTION(sqlite_num_fields)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      RETURN_LONG(res->ncolumns);
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_field_name(resource result, int field_index)
-+   Returns the name of a particular field of a result set. */
-+PHP_FUNCTION(sqlite_field_name)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      long field;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &field)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &field)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (field < 0 || field >= res->ncolumns) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "field %ld out of range", field);
-+              RETURN_FALSE;
-+      }
-+
-+      RETURN_STRING(res->col_names[field], 1);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_seek(resource result, int row)
-+   Seek to a particular row number of a buffered result set. */
-+PHP_FUNCTION(sqlite_seek)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      long row;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &row)) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zres, &row)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (!res->buffered) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot seek an unbuffered result set");
-+              RETURN_FALSE;
-+      }
-+
-+      if (row < 0 || row >= res->nrows) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "row %ld out of range", row);
-+              RETURN_FALSE;
-+      }
-+
-+      res->curr_row = row;
-+      RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_rewind(resource result)
-+   Seek to the first row number of a buffered result set. */
-+PHP_FUNCTION(sqlite_rewind)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (!res->buffered) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot rewind an unbuffered result set");
-+              RETURN_FALSE;
-+      }
-+
-+      if (!res->nrows) {
-+              php_error_docref(NULL TSRMLS_CC, E_NOTICE, "no rows received");
-+              RETURN_FALSE;
-+      }
-+
-+      res->curr_row = 0;
-+      RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_next(resource result)
-+   Seek to the next row number of a result set. */
-+PHP_FUNCTION(sqlite_next)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (!res->buffered && res->vm) {
-+              php_sqlite_fetch(res TSRMLS_CC);
-+      }
-+
-+      if (res->curr_row >= res->nrows) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "no more rows available");
-+              RETURN_FALSE;
-+      }
-+
-+      res->curr_row++;
-+
-+      RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto int sqlite_key(resource result)
-+   Return the current row index of a buffered result. */
-+PHP_FUNCTION(sqlite_key)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      RETURN_LONG(res->curr_row);
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_prev(resource result)
-+ * Seek to the previous row number of a result set. */
-+PHP_FUNCTION(sqlite_prev)
-+{
-+      zval *zres;
-+      struct php_sqlite_result *res;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              RES_FROM_OBJECT(res, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zres)) {
-+                      return;
-+              }
-+              ZEND_FETCH_RESOURCE(res, struct php_sqlite_result *, &zres, -1, "sqlite result", le_sqlite_result);
-+      }
-+
-+      if (!res->buffered) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "you cannot use sqlite_prev on unbuffered querys");
-+              RETURN_FALSE;
-+      }
-+
-+      if (res->curr_row <= 0) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "no previous row available");
-+              RETURN_FALSE;
-+      }
-+
-+      res->curr_row--;
-+
-+      RETURN_TRUE;
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_escape_string(string item)
-+   Escapes a string for use as a query parameter. */
-+PHP_FUNCTION(sqlite_escape_string)
-+{
-+      char *string = NULL;
-+      int stringlen;
-+      char *ret;
-+
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &stringlen)) {
-+              return;
-+      }
-+
-+      if (stringlen && (string[0] == '\x01' || memchr(string, '\0', stringlen) != NULL)) {
-+              /* binary string */
-+              int enclen;
-+
-+              ret = safe_emalloc(1 + stringlen / 254, 257, 3);
-+              ret[0] = '\x01';
-+              enclen = php_sqlite_encode_binary(string, stringlen, ret+1);
-+              RETVAL_STRINGL(ret, enclen+1, 0);
-+
-+      } else if (stringlen) {
-+              ret = sqlite_mprintf("%q", string);
-+              if (ret) {
-+                      RETVAL_STRING(ret, 1);
-+                      sqlite_freemem(ret);
-+              }
-+      } else {
-+              RETURN_EMPTY_STRING();
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto int sqlite_last_error(resource db)
-+   Returns the error code of the last error for a database. */
-+PHP_FUNCTION(sqlite_last_error)
-+{
-+      zval *zdb;
-+      struct php_sqlite_db *db;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (zend_parse_parameters_none() == FAILURE) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zdb)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      RETURN_LONG(db->last_err_code);
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_error_string(int error_code)
-+   Returns the textual description of an error code. */
-+PHP_FUNCTION(sqlite_error_string)
-+{
-+      long code;
-+      const char *msg;
-+
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code)) {
-+              return;
-+      }
-+
-+      msg = sqlite_error_string(code);
-+
-+      if (msg) {
-+              RETURN_STRING((char*)msg, 1);
-+      } else {
-+              RETURN_NULL();
-+      }
-+}
-+/* }}} */
-+
-+/* manages duplicate registrations of a particular function, and
-+ * also handles the case where the db is using a persistent connection */
-+enum callback_prep_t { DO_REG, SKIP_REG, ERR };
-+
-+static enum callback_prep_t prep_callback_struct(struct php_sqlite_db *db, int is_agg,
-+              char *funcname,
-+              zval *step, zval *fini, struct php_sqlite_agg_functions **funcs)
-+{
-+      struct php_sqlite_agg_functions *alloc_funcs, func_tmp;
-+      char *hashkey;
-+      int hashkeylen;
-+      enum callback_prep_t ret;
-+
-+      hashkeylen = spprintf(&hashkey, 0, "%s-%s", is_agg ? "agg" : "reg", funcname);
-+
-+      /* is it already registered ? */
-+      if (SUCCESS == zend_hash_find(&db->callbacks, hashkey, hashkeylen+1, (void*)&alloc_funcs)) {
-+              /* override the previous definition */
-+
-+              if (alloc_funcs->is_valid) {
-+                      /* release these */
-+
-+                      if (alloc_funcs->step) {
-+                              zval_ptr_dtor(&alloc_funcs->step);
-+                              alloc_funcs->step = NULL;
-+                      }
-+
-+                      if (alloc_funcs->fini) {
-+                              zval_ptr_dtor(&alloc_funcs->fini);
-+                              alloc_funcs->fini = NULL;
-+                      }
-+              }
-+
-+              ret = SKIP_REG;
-+      } else {
-+              /* add a new one */
-+              func_tmp.db = db;
-+
-+              ret = SUCCESS == zend_hash_update(&db->callbacks, hashkey, hashkeylen+1,
-+                              (void*)&func_tmp, sizeof(func_tmp), (void**)&alloc_funcs) ? DO_REG : ERR;
-+      }
-+
-+      efree(hashkey);
-+
-+      MAKE_STD_ZVAL(alloc_funcs->step);
-+      *(alloc_funcs->step)  = *step;
-+      zval_copy_ctor(alloc_funcs->step);
-+      INIT_PZVAL(alloc_funcs->step);
-+
-+      if (is_agg) {
-+              MAKE_STD_ZVAL(alloc_funcs->fini);
-+              *(alloc_funcs->fini) = *fini;
-+              zval_copy_ctor(alloc_funcs->fini);
-+              INIT_PZVAL(alloc_funcs->fini);
-+      } else {
-+              alloc_funcs->fini = NULL;
-+      }
-+      alloc_funcs->is_valid = 1;
-+      *funcs = alloc_funcs;
-+
-+      return ret;
-+}
-+
-+
-+/* {{{ proto bool sqlite_create_aggregate(resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args])
-+    Registers an aggregate function for queries. */
-+PHP_FUNCTION(sqlite_create_aggregate)
-+{
-+      char *funcname = NULL;
-+      int funcname_len;
-+      zval *zstep, *zfinal, *zdb;
-+      struct php_sqlite_db *db;
-+      struct php_sqlite_agg_functions *funcs;
-+      char *callable = NULL;
-+      long num_args = -1;
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rszz|l", &zdb, &funcname, &funcname_len, &zstep, &zfinal, &num_args)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (!zend_is_callable(zstep, 0, &callable TSRMLS_CC)) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "step function `%s' is not callable", callable);
-+              efree(callable);
-+              return;
-+      }
-+      efree(callable);
-+
-+      if (!zend_is_callable(zfinal, 0, &callable TSRMLS_CC)) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "finalize function `%s' is not callable", callable);
-+              efree(callable);
-+              return;
-+      }
-+      efree(callable);
-+
-+
-+      if (prep_callback_struct(db, 1, funcname, zstep, zfinal, &funcs) == DO_REG) {
-+              sqlite_create_aggregate(db->db, funcname, num_args,
-+                              php_sqlite_agg_step_function_callback,
-+                              php_sqlite_agg_fini_function_callback, funcs);
-+      }
-+
-+
-+}
-+/* }}} */
-+
-+/* {{{ proto bool sqlite_create_function(resource db, string funcname, mixed callback[, long num_args])
-+    Registers a "regular" function for queries. */
-+PHP_FUNCTION(sqlite_create_function)
-+{
-+      char *funcname = NULL;
-+      int funcname_len;
-+      zval *zcall, *zdb;
-+      struct php_sqlite_db *db;
-+      struct php_sqlite_agg_functions *funcs;
-+      char *callable = NULL;
-+      long num_args = -1;
-+
-+      zval *object = getThis();
-+
-+      if (object) {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &funcname, &funcname_len, &zcall, &num_args)) {
-+                      return;
-+              }
-+              DB_FROM_OBJECT(db, object);
-+      } else {
-+              if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsz|l", &zdb, &funcname, &funcname_len, &zcall, &num_args)) {
-+                      return;
-+              }
-+              DB_FROM_ZVAL(db, &zdb);
-+      }
-+
-+      if (!zend_is_callable(zcall, 0, &callable TSRMLS_CC)) {
-+              php_error_docref(NULL TSRMLS_CC, E_WARNING, "function `%s' is not callable", callable);
-+              efree(callable);
-+              return;
-+      }
-+      efree(callable);
-+
-+      if (prep_callback_struct(db, 0, funcname, zcall, NULL, &funcs) == DO_REG) {
-+              sqlite_create_function(db->db, funcname, num_args, php_sqlite_function_callback, funcs);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_udf_encode_binary(string data)
-+   Apply binary encoding (if required) to a string to return from an UDF. */
-+PHP_FUNCTION(sqlite_udf_encode_binary)
-+{
-+      char *data = NULL;
-+      int datalen;
-+
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
-+              return;
-+      }
-+
-+      if (data == NULL) {
-+              RETURN_NULL();
-+      }
-+      if (datalen && (data[0] == '\x01' || memchr(data, '\0', datalen) != NULL)) {
-+              /* binary string */
-+              int enclen;
-+              char *ret;
-+
-+              ret = safe_emalloc(1 + datalen / 254, 257, 3);
-+              ret[0] = '\x01';
-+              enclen = php_sqlite_encode_binary(data, datalen, ret+1);
-+              RETVAL_STRINGL(ret, enclen+1, 0);
-+      } else {
-+              RETVAL_STRINGL(data, datalen, 1);
-+      }
-+}
-+/* }}} */
-+
-+/* {{{ proto string sqlite_udf_decode_binary(string data)
-+   Decode binary encoding on a string parameter passed to an UDF. */
-+PHP_FUNCTION(sqlite_udf_decode_binary)
-+{
-+      char *data = NULL;
-+      int datalen;
-+
-+      if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &data, &datalen)) {
-+              return;
-+      }
-+
-+      if (data == NULL) {
-+              RETURN_NULL();
-+      }
-+      if (datalen && data[0] == '\x01') {
-+              /* encoded string */
-+              int enclen;
-+              char *ret;
-+
-+              ret = emalloc(datalen);
-+              enclen = php_sqlite_decode_binary(data+1, ret);
-+              ret[enclen] = '\0';
-+              RETVAL_STRINGL(ret, enclen, 0);
-+      } else {
-+              RETVAL_STRINGL(data, datalen, 1);
-+      }
-+}
-+/* }}} */
-+
-+
-+/*
-+ * Local variables:
-+ * tab-width: 4
-+ * c-basic-offset: 4
-+ * End:
-+ * vim600: sw=4 ts=4 fdm=marker
-+ * vim<600: sw=4 ts=4
-+ */
---- /dev/null
-+++ b/ext/sqlite/sqlite.dsp
-@@ -0,0 +1,339 @@
-+# Microsoft Developer Studio Project File - Name="sqlite" - Package Owner=<4>\r
-+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
-+# ** DO NOT EDIT **\r
-+\r
-+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
-+\r
-+CFG=sqlite - Win32 Debug_TS\r
-+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-+!MESSAGE use the Export Makefile command and run\r
-+!MESSAGE \r
-+!MESSAGE NMAKE /f "sqlite.mak".\r
-+!MESSAGE \r
-+!MESSAGE You can specify a configuration when running NMAKE\r
-+!MESSAGE by defining the macro CFG on the command line. For example:\r
-+!MESSAGE \r
-+!MESSAGE NMAKE /f "sqlite.mak" CFG="sqlite - Win32 Debug_TS"\r
-+!MESSAGE \r
-+!MESSAGE Possible choices for configuration are:\r
-+!MESSAGE \r
-+!MESSAGE "sqlite - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
-+!MESSAGE "sqlite - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
-+!MESSAGE \r
-+\r
-+# Begin Project\r
-+# PROP AllowPerConfigDependencies 0\r
-+# PROP Scc_ProjName ""\r
-+# PROP Scc_LocalPath ""\r
-+CPP=cl.exe\r
-+MTL=midl.exe\r
-+RSC=rc.exe\r
-+\r
-+!IF  "$(CFG)" == "sqlite - Win32 Release_TS"\r
-+\r
-+# PROP BASE Use_MFC 0\r
-+# PROP BASE Use_Debug_Libraries 0\r
-+# PROP BASE Output_Dir "Release_TS"\r
-+# PROP BASE Intermediate_Dir "Release_TS"\r
-+# PROP BASE Ignore_Export_Lib 0\r
-+# PROP BASE Target_Dir ""\r
-+# PROP Use_MFC 0\r
-+# PROP Use_Debug_Libraries 0\r
-+# PROP Output_Dir "Release_TS"\r
-+# PROP Intermediate_Dir "Release_TS"\r
-+# PROP Ignore_Export_Lib 0\r
-+# PROP Target_Dir ""\r
-+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SQLITE_EXPORTS" /YX /FD /c\r
-+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\win32" /I "..\..\..\php_build" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /FR /YX /FD /c\r
-+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
-+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
-+# ADD BASE RSC /l 0x407 /d "NDEBUG"\r
-+# ADD RSC /l 0x407 /d "NDEBUG"\r
-+BSC32=bscmake.exe\r
-+# ADD BASE BSC32 /nologo\r
-+# ADD BSC32 /nologo\r
-+LINK32=link.exe\r
-+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
-+# ADD LINK32 php5ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_sqlite.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\release"\r
-+\r
-+!ELSEIF  "$(CFG)" == "sqlite - Win32 Debug_TS"\r
-+\r
-+# PROP BASE Use_MFC 0\r
-+# PROP BASE Use_Debug_Libraries 1\r
-+# PROP BASE Output_Dir "Debug_TS"\r
-+# PROP BASE Intermediate_Dir "Debug_TS"\r
-+# PROP BASE Target_Dir ""\r
-+# PROP Use_MFC 0\r
-+# PROP Use_Debug_Libraries 1\r
-+# PROP Output_Dir "Debug_TS"\r
-+# PROP Intermediate_Dir "Debug_TS"\r
-+# PROP Ignore_Export_Lib 0\r
-+# PROP Target_Dir ""\r
-+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SQLITE_EXPORTS" /YX /FD /GZ /c\r
-+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\win32" /I "..\..\..\php_build" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "COMPILE_DL_SQLITE" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_SQLITE=1 /D "PHP_SQLITE_EXPORTS" /YX /FD /GZ /c\r
-+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
-+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
-+# ADD BASE RSC /l 0x407 /d "_DEBUG"\r
-+# ADD RSC /l 0x407 /d "_DEBUG"\r
-+BSC32=bscmake.exe\r
-+# ADD BASE BSC32 /nologo\r
-+# ADD BSC32 /nologo\r
-+LINK32=link.exe\r
-+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
-+# ADD LINK32 php5ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_sqlite.dll" /pdbtype:sept /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\release"\r
-+\r
-+!ENDIF \r
-+\r
-+# Begin Target\r
-+\r
-+# Name "sqlite - Win32 Release_TS"\r
-+# Name "sqlite - Win32 Debug_TS"\r
-+# Begin Group "Source Files"\r
-+\r
-+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
-+# Begin Group "libsqlite"\r
-+\r
-+# PROP Default_Filter ""\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\attach.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\auth.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\btree.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\btree.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\btree_rb.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\build.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\config.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\copy.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\date.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\delete.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\encode.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\expr.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\func.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\hash.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\hash.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\insert.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\main.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\opcodes.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\opcodes.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\os.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\os.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\pager.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\pager.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\parse.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\parse.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\pragma.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\printf.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\random.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\select.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\sqlite.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\sqlite.w32.h\r
-+\r
-+!IF  "$(CFG)" == "sqlite - Win32 Release_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\libsqlite\src\r
-+InputPath=.\libsqlite\src\sqlite.w32.h\r
-+\r
-+"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\sqlite.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "sqlite - Win32 Debug_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\libsqlite\src\r
-+InputPath=.\libsqlite\src\sqlite.w32.h\r
-+\r
-+"$(InputDir)\sqlite.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\sqlite.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ENDIF \r
-+\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\sqlite_config.w32.h\r
-+\r
-+!IF  "$(CFG)" == "sqlite - Win32 Release_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\libsqlite\src\r
-+InputPath=.\libsqlite\src\sqlite_config.w32.h\r
-+\r
-+"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\config.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ELSEIF  "$(CFG)" == "sqlite - Win32 Debug_TS"\r
-+\r
-+# Begin Custom Build\r
-+InputDir=.\libsqlite\src\r
-+InputPath=.\libsqlite\src\sqlite_config.w32.h\r
-+\r
-+"$(InputDir)\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
-+      copy $(InputPath) $(InputDir)\config.h\r
-+\r
-+# End Custom Build\r
-+\r
-+!ENDIF \r
-+\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\sqliteInt.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\table.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\tokenize.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\trigger.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\update.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\util.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\vacuum.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\vdbe.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\vdbe.h\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\vdbeaux.c\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\libsqlite\src\where.c\r
-+# End Source File\r
-+# End Group\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\php_sqlite.def\r
-+# End Source File\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\sqlite.c\r
-+# ADD CPP /I "libsqlite\src"\r
-+# End Source File\r
-+# End Group\r
-+# Begin Group "Header Files"\r
-+\r
-+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
-+# Begin Source File\r
-+\r
-+SOURCE=.\php_sqlite.h\r
-+# End Source File\r
-+# End Group\r
-+# End Target\r
-+# End Project\r
---- /dev/null
-+++ b/ext/sqlite/sqlite.php
-@@ -0,0 +1,36 @@
-+<?php
-+if (!extension_loaded("sqlite")) {
-+      dl("sqlite.so");
-+      if (!extension_loaded("sqlite")) {
-+              exit("Please enable SQLite support\n");
-+      }
-+}
-+
-+debug_zval_dump(sqlite_libversion());
-+debug_zval_dump(sqlite_libencoding());
-+
-+$s = sqlite_open("weztest.sqlite", 0666, $err);
-+
-+debug_zval_dump($err);
-+debug_zval_dump($s);
-+
-+$r = sqlite_query("create table foo (a INTEGER PRIMARY KEY, b INTEGER )", $s);
-+debug_zval_dump(sqlite_last_error($s));
-+debug_zval_dump(sqlite_error_string(sqlite_last_error($s)));
-+
-+$r = sqlite_query("select *, php('md5', sql) as o from sqlite_master", $s);
-+debug_zval_dump($r);
-+debug_zval_dump(sqlite_num_rows($r));
-+debug_zval_dump(sqlite_num_fields($r));
-+
-+for ($j = 0; $j < sqlite_num_fields($r); $j++) {
-+      echo "Field $j is " . sqlite_field_name($r, $j) . "\n";
-+}
-+
-+while ($row = sqlite_fetch_array($r, SQLITE_ASSOC)) {
-+      print_r($row);
-+}
-+
-+sqlite_close($s);
-+
-+?>
---- /dev/null
-+++ b/ext/sqlite/tests/blankdb.inc
-@@ -0,0 +1,3 @@
-+<?php #vim:ft=php
-+$db = sqlite_open(":memory:");
-+?>
---- /dev/null
-+++ b/ext/sqlite/tests/blankdb_oo.inc
-@@ -0,0 +1,3 @@
-+<?php #vim:ft=php
-+$db = new SQLiteDatabase(":memory:");
-+?>
---- /dev/null
-+++ b/ext/sqlite/tests/bug26911.phpt
-@@ -0,0 +1,12 @@
-+--TEST--
-+Bug #26911 (crash when fetching data from empty queries)
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+      $db = sqlite_open(":memory:");
-+      $a = sqlite_query($db, "  ");
-+      echo "I am ok\n";
-+?>
-+--EXPECT--
-+I am ok
---- /dev/null
-+++ b/ext/sqlite/tests/bug28112.phpt
-@@ -0,0 +1,16 @@
-+--TEST--
-+Bug #28112 (sqlite_query() crashing apache on malformed query)
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+
-+if (!($db = sqlite_open(":memory:", 666, $error))) die ("Couldn't open the database");
-+sqlite_query($db, "create table frob (foo INTEGER PRIMARY KEY, bar text);");
-+$res = @sqlite_array_query($db, "");
-+
-+?>
-+===DONE===
-+<?php exit(0); ?>
-+--EXPECTF--
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/bug35248.phpt
-@@ -0,0 +1,15 @@
-+--TEST--
-+Bug #35248 (sqlite_query does not return parse error message)
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+      $db = sqlite_open(":memory:");
-+      $res = @sqlite_query($db, "asdfesdfa", SQLITE_NUM, $err);
-+      var_dump($err);
-+      $res = @sqlite_unbuffered_query($db, "asdfesdfa", SQLITE_NUM, $err);
-+      var_dump($err);
-+?>
-+--EXPECT--
-+string(30) "near "asdfesdfa": syntax error"
-+string(30) "near "asdfesdfa": syntax error"
---- /dev/null
-+++ b/ext/sqlite/tests/bug38759.phpt
-@@ -0,0 +1,18 @@
-+--TEST--
-+Bug #38759 (sqlite2 empty query causes segfault)
-+--SKIPIF--
-+<?php 
-+if (!extension_loaded("pdo")) print "skip"; 
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php
-+
-+$dbh = new PDO('sqlite2::memory:');
-+var_dump($dbh->query(" "));
-+
-+echo "Done\n";
-+?>
-+--EXPECTF--   
-+bool(false)
-+Done
---- /dev/null
-+++ b/ext/sqlite/tests/bug48679.phpt
-@@ -0,0 +1,20 @@
-+--TEST--
-+Bug #48679 (sqlite2 count on unbuffered query causes segfault)
-+--SKIPIF--
-+<?php 
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php
-+
-+try {
-+      $x = new sqliteunbuffered;
-+      count($x);
-+} catch (SQLiteException $e) {
-+      var_dump($e->getMessage());
-+}
-+echo "Done\n";
-+?>
-+--EXPECT--    
-+string(41) "Row count is not available for this query"
-+Done
---- /dev/null
-+++ b/ext/sqlite/tests/pdo/common.phpt
-@@ -0,0 +1,12 @@
-+--TEST--
-+SQLite2
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded('pdo') || !extension_loaded('sqlite')) print 'skip'; ?>
-+--REDIRECTTEST--
-+return array(
-+      'ENV' => array(
-+                      'PDOTEST_DSN' => 'sqlite2::memory:'
-+              ),
-+      'TESTS' => 'ext/pdo/tests'
-+      );
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_001.phpt
-@@ -0,0 +1,16 @@
-+--TEST--
-+sqlite: sqlite_open/close
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+require_once('blankdb.inc');
-+echo "$db\n";
-+sqlite_close($db);
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+Resource id #%d
-+Done
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_002.phpt
-@@ -0,0 +1,32 @@
-+--TEST--
-+sqlite: Simple insert/select
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))", $db);
-+sqlite_query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)", $db);
-+$r = sqlite_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r));
-+sqlite_close($db);
-+?>
-+--EXPECT--
-+array(6) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+  ["c3"]=>
-+  NULL
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_003.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+sqlite: Simple insert/select, different result represenatation
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))", $db);
-+sqlite_query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)", $db);
-+$r = sqlite_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_BOTH));
-+$r = sqlite_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_NUM));
-+$r = sqlite_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_ASSOC));
-+sqlite_close($db);
-+?>
-+--EXPECT--
-+array(6) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+  ["c3"]=>
-+  NULL
-+}
-+array(3) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+}
-+array(3) {
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  ["c3"]=>
-+  NULL
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_004.phpt
-@@ -0,0 +1,49 @@
-+--TEST--
-+sqlite: binary encoding
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$strings = array(
-+      "hello",
-+      "hello\x01o",
-+      "\x01hello there",
-+      "hello\x00there",
-+      ""
-+);
-+
-+sqlite_query("CREATE TABLE strings(a)", $db);
-+
-+foreach ($strings as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($str) . "')", $db);
-+}
-+
-+$i = 0;
-+$r = sqlite_query("SELECT * from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      if ($row[0] !== $strings[$i]) {
-+              echo "FAIL!\n";
-+              var_dump($row[0]);
-+              var_dump($strings[$i]);
-+      } else {
-+              echo "OK!\n";
-+      }
-+      $i++;
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+OK!
-+OK!
-+OK!
-+OK!
-+OK!
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_005.phpt
-@@ -0,0 +1,50 @@
-+--TEST--
-+sqlite: aggregate functions
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($str) . "')", $db);
-+}
-+
-+function cat_step(&$context, $string)
-+{
-+      $context .= $string;
-+}
-+
-+function cat_fin(&$context)
-+{
-+      return $context;
-+}
-+
-+sqlite_create_aggregate($db, "cat", "cat_step", "cat_fin");
-+
-+$r = sqlite_query("SELECT cat(a) from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(11) "onetwothree"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_006.phpt
-@@ -0,0 +1,55 @@
-+--TEST--
-+sqlite: regular functions
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      array("one", "uno"),
-+      array("two", "dos"),
-+      array("three", "tres"),
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a,b)", $db);
-+
-+function implode_args()
-+{
-+      $args = func_get_args();
-+      $sep = array_shift($args);
-+      return implode($sep, $args);
-+}
-+
-+foreach ($data as $row) {
-+      sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($row[0]) . "','" . sqlite_escape_string($row[1]) . "')", $db);
-+}
-+
-+sqlite_create_function($db, "implode", "implode_args");
-+
-+$r = sqlite_query("SELECT implode('-', a, b) from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(7) "one-uno"
-+}
-+array(1) {
-+  [0]=>
-+  string(7) "two-dos"
-+}
-+array(1) {
-+  [0]=>
-+  string(10) "three-tres"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_007.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+sqlite: Simple insert/select (unbuffered)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))", $db);
-+sqlite_query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)", $db);
-+$r = sqlite_unbuffered_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_BOTH));
-+$r = sqlite_unbuffered_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_NUM));
-+$r = sqlite_unbuffered_query("SELECT * from foo", $db);
-+var_dump(sqlite_fetch_array($r, SQLITE_ASSOC));
-+sqlite_close($db);
-+?>
-+--EXPECT--
-+array(6) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+  ["c3"]=>
-+  NULL
-+}
-+array(3) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+}
-+array(3) {
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  ["c3"]=>
-+  NULL
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_008.phpt
-@@ -0,0 +1,46 @@
-+--TEST--
-+sqlite: fetch all (buffered)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$r = sqlite_query("SELECT a from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_009.phpt
-@@ -0,0 +1,46 @@
-+--TEST--
-+sqlite: fetch all (unbuffered)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$r = sqlite_unbuffered_query("SELECT a from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_010.phpt
-@@ -0,0 +1,81 @@
-+--TEST--
-+sqlite: fetch all (iterator)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$r = sqlite_unbuffered_query("SELECT a from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_current($r, SQLITE_NUM));
-+      sqlite_next($r);
-+}
-+$r = sqlite_query("SELECT a from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_current($r, SQLITE_NUM));
-+      sqlite_next($r);
-+}
-+sqlite_rewind($r);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_current($r, SQLITE_NUM));
-+      sqlite_next($r);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_011.phpt
-@@ -0,0 +1,34 @@
-+--TEST--
-+sqlite: returned associative column names
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query("CREATE TABLE foo (c1 char, c2 char, c3 char)", $db);
-+sqlite_query("CREATE TABLE bar (c1 char, c2 char, c3 char)", $db);
-+sqlite_query("INSERT INTO foo VALUES ('1', '2', '3')", $db);
-+sqlite_query("INSERT INTO bar VALUES ('4', '5', '6')", $db);
-+$r = sqlite_query("SELECT * from foo, bar", $db, SQLITE_ASSOC);
-+var_dump(sqlite_fetch_array($r));
-+sqlite_close($db);
-+?>
-+--EXPECT--
-+array(6) {
-+  ["foo.c1"]=>
-+  string(1) "1"
-+  ["foo.c2"]=>
-+  string(1) "2"
-+  ["foo.c3"]=>
-+  string(1) "3"
-+  ["bar.c1"]=>
-+  string(1) "4"
-+  ["bar.c2"]=>
-+  string(1) "5"
-+  ["bar.c3"]=>
-+  string(1) "6"
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_012.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+sqlite: read field names
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query("CREATE TABLE strings(foo VARCHAR, bar VARCHAR, baz VARCHAR)", $db);
-+
-+echo "Buffered\n";
-+$r = sqlite_query("SELECT * from strings", $db);
-+for($i=0; $i<sqlite_num_fields($r); $i++) {
-+      var_dump(sqlite_field_name($r, $i));
-+}
-+echo "Unbuffered\n";
-+$r = sqlite_unbuffered_query("SELECT * from strings", $db);
-+for($i=0; $i<sqlite_num_fields($r); $i++) {
-+      var_dump(sqlite_field_name($r, $i));
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+Buffered
-+string(3) "foo"
-+string(3) "bar"
-+string(3) "baz"
-+Unbuffered
-+string(3) "foo"
-+string(3) "bar"
-+string(3) "baz"
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_013.phpt
-@@ -0,0 +1,78 @@
-+--TEST--
-+sqlite: fetch column
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      array (0 => 'one', 1 => 'two'),
-+      array (0 => 'three', 1 => 'four')
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR, b VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')", $db);
-+}
-+
-+echo "====BUFFERED====\n";
-+$r = sqlite_query("SELECT a, b from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_current($r, SQLITE_NUM));
-+      var_dump(sqlite_column($r, 0));
-+      var_dump(sqlite_column($r, 1));
-+      var_dump(sqlite_column($r, 'a'));
-+      var_dump(sqlite_column($r, 'b'));
-+      sqlite_next($r);
-+}
-+echo "====UNBUFFERED====\n";
-+$r = sqlite_unbuffered_query("SELECT a, b from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_column($r, 0));
-+      var_dump(sqlite_column($r, 'b'));
-+      var_dump(sqlite_column($r, 1));
-+      var_dump(sqlite_column($r, 'a'));
-+      sqlite_next($r);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+====BUFFERED====
-+array(2) {
-+  [0]=>
-+  string(3) "one"
-+  [1]=>
-+  string(3) "two"
-+}
-+string(3) "one"
-+string(3) "two"
-+string(3) "one"
-+string(3) "two"
-+array(2) {
-+  [0]=>
-+  string(5) "three"
-+  [1]=>
-+  string(4) "four"
-+}
-+string(5) "three"
-+string(4) "four"
-+string(5) "three"
-+string(4) "four"
-+====UNBUFFERED====
-+string(3) "one"
-+string(3) "two"
-+NULL
-+NULL
-+string(5) "three"
-+string(4) "four"
-+NULL
-+NULL
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_014.phpt
-@@ -0,0 +1,120 @@
-+--TEST--
-+sqlite: fetch all (fetch_all)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+echo "unbuffered twice\n";
-+$r = sqlite_unbuffered_query("SELECT a from strings", $db, SQLITE_NUM);
-+var_dump(sqlite_fetch_all($r));
-+var_dump(sqlite_fetch_all($r));
-+
-+echo "unbuffered with fetch_array\n";
-+$r = sqlite_unbuffered_query("SELECT a from strings", $db, SQLITE_NUM);
-+var_dump(sqlite_fetch_array($r));
-+var_dump(sqlite_fetch_all($r));
-+
-+echo "buffered\n";
-+$r = sqlite_query("SELECT a from strings", $db, SQLITE_NUM);
-+var_dump(sqlite_fetch_all($r));
-+var_dump(sqlite_fetch_array($r));
-+var_dump(sqlite_fetch_all($r));
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+unbuffered twice
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+
-+Warning: sqlite_fetch_all(): One or more rowsets were already returned; returning NULL this time in %ssqlite_014.php on line %d
-+array(0) {
-+}
-+unbuffered with fetch_array
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(2) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+buffered
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+bool(false)
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_015.phpt
-@@ -0,0 +1,49 @@
-+--TEST--
-+sqlite: fetch all (array_query)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$res = sqlite_array_query("SELECT a from strings", $db, SQLITE_NUM);
-+var_dump($res);
-+
-+$db = null;
-+
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_016.phpt
-@@ -0,0 +1,45 @@
-+--TEST--
-+sqlite: fetch single
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      array (0 => 'one', 1 => 'two'),
-+      array (0 => 'three', 1 => 'four')
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a VARCHAR, b VARCHAR)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')", $db);
-+}
-+
-+echo "====BUFFERED====\n";
-+$r = sqlite_query("SELECT a, b from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_fetch_single($r));
-+}
-+echo "====UNBUFFERED====\n";
-+$r = sqlite_unbuffered_query("SELECT a, b from strings", $db);
-+while (sqlite_valid($r)) {
-+      var_dump(sqlite_fetch_single($r));
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+====BUFFERED====
-+string(3) "one"
-+string(5) "three"
-+====UNBUFFERED====
-+string(3) "one"
-+string(5) "three"
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_017.phpt
-@@ -0,0 +1,33 @@
-+--TEST--
-+sqlite: UDF binary handling functions
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+
-+$data = array(
-+      "hello there",
-+      "this has a \x00 char in the middle",
-+      "\x01 this has an 0x01 at the start",
-+      "this has \x01 in the middle"
-+      );
-+
-+foreach ($data as $item) {
-+      $coded = sqlite_udf_encode_binary($item);
-+      echo bin2hex($coded) . "\n";
-+      $decoded = sqlite_udf_decode_binary($coded);
-+      if ($item != $decoded) {
-+              echo "FAIL! $item decoded is $decoded\n";
-+      }
-+}
-+
-+echo "OK!\n";
-+
-+?>
-+--EXPECT--
-+68656c6c6f207468657265
-+0101736768721f6760721f601fff1f626760711f686d1f7367641f6c6863636b64
-+0102ff1e726667711e665f711e5f6c1e2e762e2f1e5f721e7266631e71725f7072
-+7468697320686173200120696e20746865206d6964646c65
-+OK!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_018.phpt
-@@ -0,0 +1,14 @@
-+--TEST--
-+sqlite: crash on bad queries inside sqlite_array_query()
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+include "blankdb.inc";
-+
-+sqlite_array_query($db, "SELECT foo FROM foobar");
-+sqlite_close($db);
-+?>
-+--EXPECTF--
-+Warning: sqlite_array_query(): no such table: foobar in %s on line %d
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_019.phpt
-@@ -0,0 +1,47 @@
-+--TEST--
-+sqlite: single query
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+include "blankdb.inc";
-+      
-+sqlite_query($db, "CREATE TABLE test_db ( id INTEGER PRIMARY KEY, data VARCHAR(100) )");
-+for ($i = 0; $i < 10; $i++) {
-+      sqlite_query($db, "INSERT INTO test_db (data) VALUES('{$i}data')");
-+}
-+sqlite_query($db, "INSERT INTO test_db (data) VALUES(NULL)");
-+                                               
-+var_dump(sqlite_single_query($db, "SELECT id FROM test_db WHERE id=5"));
-+var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id=4"));
-+var_dump(sqlite_single_query($db, "SELECT data FROM test_db WHERE id=6"));
-+var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id < 5"));
-+var_dump(sqlite_single_query($db, "SELECT * FROM test db WHERE id < 4"));
-+var_dump(sqlite_single_query($db, "SELECT * FROM test_db WHERE id=999999"));
-+var_dump(sqlite_single_query($db, "SELECT id FROM test_db WHERE id=5", FALSE));
-+
-+sqlite_close($db);
-+?>
-+--EXPECTF--
-+string(1) "5"
-+string(1) "4"
-+string(5) "5data"
-+array(4) {
-+  [0]=>
-+  string(1) "1"
-+  [1]=>
-+  string(1) "2"
-+  [2]=>
-+  string(1) "3"
-+  [3]=>
-+  string(1) "4"
-+}
-+
-+Warning: sqlite_single_query(): no such table: test in %s on line %d
-+bool(false)
-+NULL
-+array(1) {
-+  [0]=>
-+  string(1) "5"
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_022.phpt
-@@ -0,0 +1,101 @@
-+--TEST--
-+sqlite: sqlite_seek
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$res = sqlite_query("SELECT a FROM strings", $db, SQLITE_NUM);
-+for ($idx = -1; $idx < 4; $idx++) {
-+      echo "====SEEK:$idx====\n";
-+      sqlite_seek($res, $idx);
-+      var_dump(sqlite_current($res));
-+}
-+echo "====AGAIN====\n";
-+for ($idx = -1; $idx < 4; $idx++) {
-+      echo "====SEEK:$idx====\n";
-+      sqlite_seek($res, $idx);
-+      var_dump(sqlite_current($res));
-+}
-+
-+sqlite_close($db);
-+
-+echo "====DONE!====\n";
-+?>
-+--EXPECTF--
-+====SEEK:-1====
-+
-+Warning: sqlite_seek(): row -1 out of range in %ssqlite_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:0====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:1====
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+====SEEK:2====
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:3====
-+
-+Warning: sqlite_seek(): row 3 out of range in %ssqlite_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====AGAIN====
-+====SEEK:-1====
-+
-+Warning: sqlite_seek(): row -1 out of range in %ssqlite_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:0====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:1====
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+====SEEK:2====
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:3====
-+
-+Warning: sqlite_seek(): row 3 out of range in %ssqlite_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====DONE!====
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_023.phpt
-@@ -0,0 +1,105 @@
-+--TEST--
-+sqlite: sqlite_[has_]prev
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+include "blankdb.inc";
-+
-+$data = array(
-+              "one",
-+              "two",
-+              "three"
-+              );
-+
-+sqlite_query("CREATE TABLE strings(a)", $db);
-+
-+foreach ($data as $str) {
-+  sqlite_query("INSERT INTO strings VALUES('$str')", $db);
-+}
-+
-+$r = sqlite_query("SELECT a FROM strings", $db, SQLITE_NUM);
-+
-+echo "====TRAVERSE====\n";
-+for(sqlite_rewind($r); sqlite_valid($r); sqlite_next($r)) {
-+  var_dump(sqlite_current($r));
-+
-+}
-+echo "====REVERSE====\n";
-+do {
-+  sqlite_prev($r);
-+  var_dump(sqlite_current($r));
-+} while(sqlite_has_prev($r));
-+
-+echo "====UNBUFFERED====\n";
-+
-+$r = sqlite_unbuffered_query("SELECT a FROM strings", $db, SQLITE_NUM);
-+
-+echo "====TRAVERSE====\n";
-+for(sqlite_rewind($r); sqlite_valid($r); sqlite_next($r)) {
-+  var_dump(sqlite_current($r));
-+
-+}
-+echo "====REVERSE====\n";
-+do {
-+  sqlite_prev($r);
-+  var_dump(sqlite_current($r));
-+} while(sqlite_has_prev($r));
-+
-+sqlite_close($db);
-+
-+echo "====DONE!====\n";
-+?>
-+--EXPECTF--
-+====TRAVERSE====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====REVERSE====
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====UNBUFFERED====
-+====TRAVERSE====
-+
-+Warning: sqlite_rewind(): Cannot rewind an unbuffered result set in %ssqlite_023.php on line %d
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====REVERSE====
-+
-+Warning: sqlite_prev(): you cannot use sqlite_prev on unbuffered querys in %ssqlite_023.php on line %d
-+bool(false)
-+
-+Warning: sqlite_has_prev(): you cannot use sqlite_has_prev on unbuffered querys in %ssqlite_023.php on line %d
-+====DONE!====
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_024.phpt
-@@ -0,0 +1,76 @@
-+--TEST--
-+sqlite: sqlite_fetch_object
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+class class24 {
-+      function __construct() {
-+              echo __METHOD__ . "\n";
-+      }
-+}
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query($db, "CREATE TABLE strings(a)");
-+
-+foreach ($data as $str) {
-+      sqlite_query($db, "INSERT INTO strings VALUES('$str')");
-+}
-+
-+echo "====class24====\n";
-+$res = sqlite_query($db, "SELECT a FROM strings", SQLITE_ASSOC);
-+while (sqlite_valid($res)) {
-+      var_dump(sqlite_fetch_object($res, 'class24'));
-+}
-+
-+echo "====stdclass====\n";
-+$res = sqlite_query($db, "SELECT a FROM strings", SQLITE_ASSOC);
-+while (sqlite_valid($res)) {
-+      var_dump(sqlite_fetch_object($res));
-+}
-+
-+sqlite_close($db);
-+
-+echo "====DONE!====\n";
-+?>
-+--EXPECTF--
-+====class24====
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(3) "one"
-+}
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(3) "two"
-+}
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(5) "three"
-+}
-+====stdclass====
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(3) "one"
-+}
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(3) "two"
-+}
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(5) "three"
-+}
-+====DONE!====
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_025.phpt
-@@ -0,0 +1,38 @@
-+--TEST--
-+sqlite: sqlite_fetch_object in a loop
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query($db, "CREATE TABLE strings(a)");
-+
-+foreach (array("one", "two", "three") as $str) {
-+      sqlite_query($db, "INSERT INTO strings VALUES('$str')");
-+}
-+
-+$res = sqlite_query("SELECT * FROM strings", $db);
-+
-+while (($obj = sqlite_fetch_object($res))) {
-+      var_dump($obj);
-+}
-+
-+sqlite_close($db);
-+?>
-+--EXPECTF--
-+object(stdClass)#1 (1) {
-+  ["a"]=>
-+  string(3) "one"
-+}
-+object(stdClass)#2 (1) {
-+  ["a"]=>
-+  string(3) "two"
-+}
-+object(stdClass)#1 (1) {
-+  ["a"]=>
-+  string(5) "three"
-+}
-\ No newline at end of file
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_026.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+sqlite: sqlite_fetch_column_types
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+sqlite_query($db, "CREATE TABLE strings(a, b INTEGER, c VARCHAR(10), d)");
-+sqlite_query($db, "INSERT INTO strings VALUES('1', '2', '3', 'abc')");
-+
-+var_dump(sqlite_fetch_column_types($db, "strings"));
-+
-+sqlite_close($db);
-+?>
-+--EXPECT--
-+array(4) {
-+  ["a"]=>
-+  string(0) ""
-+  ["b"]=>
-+  string(7) "INTEGER"
-+  ["c"]=>
-+  string(11) "VARCHAR(10)"
-+  ["d"]=>
-+  string(0) ""
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_027.phpt
-@@ -0,0 +1,15 @@
-+--TEST--
-+sqlite: crash inside sqlite_escape_string() & sqlite_udf_encode_binary
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--INI--
-+memory_limit=-1
-+--FILE--
-+<?php
-+      var_dump(strlen(sqlite_escape_string(str_repeat("\0", 20000000))));
-+      var_dump(strlen(sqlite_udf_encode_binary(str_repeat("\0", 20000000))));
-+?>
-+--EXPECT--
-+int(20000002)
-+int(20000002)
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_closures_001.phpt
-@@ -0,0 +1,54 @@
-+--TEST--
-+sqlite: aggregate functions with closures
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a)", $db);
-+
-+foreach ($data as $str) {
-+      sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($str) . "')", $db);
-+}
-+
-+function cat_step(&$context, $string)
-+{
-+      $context .= $string;
-+}
-+
-+function cat_fin(&$context)
-+{
-+      return $context;
-+}
-+
-+sqlite_create_aggregate($db, "cat", function (&$context, $string) {
-+      $context .= $string;
-+}, function (&$context) {
-+      return $context;
-+});
-+
-+$r = sqlite_query("SELECT cat(a) from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(11) "onetwothree"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_closures_002.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+sqlite: regular functions with closures
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb.inc";
-+
-+$data = array(
-+      array("one", "uno"),
-+      array("two", "dos"),
-+      array("three", "tres"),
-+      );
-+
-+sqlite_query("CREATE TABLE strings(a,b)", $db);
-+
-+foreach ($data as $row) {
-+      sqlite_query("INSERT INTO strings VALUES('" . sqlite_escape_string($row[0]) . "','" . sqlite_escape_string($row[1]) . "')", $db);
-+}
-+
-+sqlite_create_function($db, "implode", function () {
-+      $args = func_get_args();
-+      $sep = array_shift($args);
-+      return implode($sep, $args);
-+});
-+
-+$r = sqlite_query("SELECT implode('-', a, b) from strings", $db);
-+while ($row = sqlite_fetch_array($r, SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+
-+sqlite_close($db);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(7) "one-uno"
-+}
-+array(1) {
-+  [0]=>
-+  string(7) "two-dos"
-+}
-+array(1) {
-+  [0]=>
-+  string(10) "three-tres"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlitedatabase_arrayquery.phpt
-@@ -0,0 +1,23 @@
-+--TEST--
-+Testing SQLiteDatabase::ArrayQuery with NULL-byte string
-+--SKIPIF--
-+<?php
-+if (!extension_loaded("sqlite")) print "skip";
-+?>
-+--FILE--
-+<?php
-+
-+$method = new ReflectionMethod('sqlitedatabase::arrayquery');
-+
-+$class = $method->getDeclaringClass()->newInstanceArgs(array(':memory:'));
-+
-+$p = "\0";
-+
-+$method->invokeArgs($class, array_fill(0, 2, $p));
-+$method->invokeArgs($class, array_fill(0, 1, $p));
-+
-+?>
-+--EXPECTF--
-+Warning: SQLiteDatabase::arrayQuery() expects parameter 2 to be long, string given in %s on line %d
-+
-+Warning: SQLiteDatabase::arrayQuery(): Cannot execute empty query. in %s on line %d
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_exec_basic.phpt
-@@ -0,0 +1,34 @@
-+--TEST--
-+Test sqlite_exec() function : basic functionality 
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : boolean sqlite_exec(string query, resource db[, string &error_message])
-+ * Description: Executes a result-less query against a given database 
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions: 
-+ */
-+
-+echo "*** Testing sqlite_exec() : basic functionality ***\n";
-+
-+// set up variables
-+$query = 'CREATE TABLE foobar (id INTEGER PRIMARY KEY, name CHAR(255));';
-+$error_message = null;
-+
-+// procedural
-+$db = sqlite_open(':memory:');
-+var_dump( sqlite_exec($db, $query) );
-+sqlite_close($db);
-+
-+// oo-style
-+$db = new SQLiteDatabase(':memory:');
-+var_dump( $db->queryExec($query, $error_message) );
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+*** Testing sqlite_exec() : basic functionality ***
-+bool(true)
-+bool(true)
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_exec_error.phpt
-@@ -0,0 +1,44 @@
-+--TEST--
-+Test sqlite_exec() function : error behaviour and functionality 
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : boolean sqlite_exec(string query, resource db[, string &error_message])
-+ * Description: Executes a result-less query against a given database 
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions: 
-+ */
-+
-+echo "*** Testing sqlite_exec() : error functionality ***\n";
-+
-+// set up variables
-+$fail = 'CRE ATE TABLE';
-+$error_message = null;
-+
-+// procedural
-+$db = sqlite_open(':memory:');
-+var_dump( sqlite_exec($db, $fail, $error_message) );
-+var_dump( $error_message );
-+var_dump( sqlite_exec($db) );
-+sqlite_close($db);
-+
-+// oo-style
-+$db = new SQLiteDatabase(':memory:');
-+var_dump( $db->queryExec($fail, $error_message, 'fooparam') );
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+*** Testing sqlite_exec() : error functionality ***
-+
-+Warning: sqlite_exec(): near "CRE": syntax error in %s on line %d
-+bool(false)
-+%string|unicode%(24) "near "CRE": syntax error"
-+
-+Warning: sqlite_exec() expects at least 2 parameters, 1 given in %s on line %d
-+NULL
-+
-+Warning: SQLiteDatabase::queryExec() expects at most 2 parameters, 3 given in %s on line %d
-+NULL
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_last_error_basic.phpt
-@@ -0,0 +1,48 @@
-+--TEST--
-+Test sqlite_last_error() function : basic functionality 
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : int sqlite_last_error(resource db)
-+ * Description: Returns the error code of the last error for a database. 
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions: 
-+ */
-+
-+echo "*** Testing sqlite_last_error() : basic functionality ***\n";
-+
-+// set up variables
-+$query = 'CREATE TAB LE foobar (id INTEGER PRIMARY KEY, name CHAR(255));';
-+$query_ok = 'CREATE TABLE foobar (id INTEGER, name CHAR(255));';
-+
-+// procedural
-+$db = sqlite_open(':memory:');
-+var_dump( sqlite_last_error($db) === SQLITE_OK );
-+sqlite_exec($db, $query);
-+var_dump( sqlite_last_error($db) === SQLITE_ERROR );
-+sqlite_exec($db, $query_ok);
-+var_dump( sqlite_last_error($db) === SQLITE_OK );
-+sqlite_close($db);
-+
-+// oo-style
-+$db = new SQLiteDatabase(':memory:');
-+$db->queryExec($query);
-+var_dump( $db->lastError() === SQLITE_ERROR );
-+$db->queryExec($query_ok);
-+var_dump( $db->lastError() === SQLITE_OK );
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+*** Testing sqlite_last_error() : basic functionality ***
-+bool(true)
-+
-+Warning: sqlite_exec(): near "TAB": syntax error in %s on line %d
-+bool(true)
-+bool(true)
-+
-+Warning: SQLiteDatabase::queryExec(): near "TAB": syntax error in %s on line %d
-+bool(true)
-+bool(true)
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_last_error_error.phpt
-@@ -0,0 +1,47 @@
-+--TEST--
-+Test sqlite_last_error() function : error conditions 
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : int sqlite_last_error(resource db)
-+ * Description: Returns the error code of the last error for a database. 
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions: 
-+ */
-+
-+echo "*** Testing sqlite_last_error() : error conditions ***\n";
-+
-+// Zero arguments
-+echo "\n-- Testing sqlite_last_error() function with Zero arguments --\n";
-+var_dump( sqlite_last_error() );
-+
-+//Test sqlite_last_error with one more than the expected number of arguments
-+echo "\n-- Testing sqlite_last_error() function with more than expected no. of arguments --\n";
-+
-+$db = sqlite_open(':memory:');
-+$extra_arg = 10;
-+var_dump( sqlite_last_error($db, $extra_arg) );
-+sqlite_close($db);
-+
-+$db = new SQLiteDatabase(':memory:');
-+var_dump( $db->lastError($extra_arg) );
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+*** Testing sqlite_last_error() : error conditions ***
-+
-+-- Testing sqlite_last_error() function with Zero arguments --
-+
-+Warning: sqlite_last_error() expects exactly 1 parameter, 0 given in %s on line %d
-+NULL
-+
-+-- Testing sqlite_last_error() function with more than expected no. of arguments --
-+
-+Warning: sqlite_last_error() expects exactly 1 parameter, 2 given in %s on line %d
-+NULL
-+
-+Warning: SQLiteDatabase::lastError() expects exactly 0 parameters, 1 given in %s on line %d
-+NULL
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_001.phpt
-@@ -0,0 +1,17 @@
-+--TEST--
-+sqlite-oo: sqlite_open/close
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+require_once('blankdb_oo.inc');
-+var_dump($db);
-+$db = NULL;
-+echo "Done\n";
-+?>
-+--EXPECTF--
-+object(SQLiteDatabase)#%d (0) {
-+}
-+Done
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_002.phpt
-@@ -0,0 +1,41 @@
-+--TEST--
-+sqlite-oo: Simple insert/select
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+require_once('blankdb_oo.inc');
-+var_dump($db);
-+
-+var_dump($db->query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))"));
-+var_dump($db->query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)"));
-+$r = $db->query("SELECT * from foo");
-+var_dump($r);
-+var_dump($r->fetch());
-+?>
-+--EXPECTF--
-+object(SQLiteDatabase)#%d (0) {
-+}
-+object(SQLiteResult)#%d (0) {
-+}
-+object(SQLiteResult)#%d (0) {
-+}
-+object(SQLiteResult)#%d (0) {
-+}
-+array(6) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+  ["c3"]=>
-+  NULL
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_003.phpt
-@@ -0,0 +1,51 @@
-+--TEST--
-+sqlite-oo: Simple insert/select, different result representation
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE foo(c1 date, c2 time, c3 varchar(64))");
-+$db->query("INSERT INTO foo VALUES ('2002-01-02', '12:49:00', NULL)");
-+$r = $db->query("SELECT * from foo");
-+var_dump($r->fetch(SQLITE_BOTH));
-+$r = $db->query("SELECT * from foo");
-+var_dump($r->fetch(SQLITE_NUM));
-+$r = $db->query("SELECT * from foo");
-+var_dump($r->fetch(SQLITE_ASSOC));
-+?>
-+--EXPECT--
-+array(6) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+  ["c3"]=>
-+  NULL
-+}
-+array(3) {
-+  [0]=>
-+  string(10) "2002-01-02"
-+  [1]=>
-+  string(8) "12:49:00"
-+  [2]=>
-+  NULL
-+}
-+array(3) {
-+  ["c1"]=>
-+  string(10) "2002-01-02"
-+  ["c2"]=>
-+  string(8) "12:49:00"
-+  ["c3"]=>
-+  NULL
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_008.phpt
-@@ -0,0 +1,43 @@
-+--TEST--
-+sqlite-oo: fetch all (buffered)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+$r = $db->query("SELECT a from strings");
-+while ($row = $r->fetch(SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_009.phpt
-@@ -0,0 +1,43 @@
-+--TEST--
-+sqlite-oo: fetch all (unbuffered)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+$r = $db->unbufferedQuery("SELECT a from strings");
-+while ($row = $r->fetch(SQLITE_NUM)) {
-+      var_dump($row);
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_010.phpt
-@@ -0,0 +1,44 @@
-+--TEST--
-+sqlite-oo: fetch all (iterator)
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+while ($row = $r->valid()) {
-+      var_dump($r->current());
-+      $r->next();
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_011.phpt
-@@ -0,0 +1,33 @@
-+--TEST--
-+sqlite-oo: returned associative column names
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE foo (c1 char, c2 char, c3 char)");
-+$db->query("CREATE TABLE bar (c1 char, c2 char, c3 char)");
-+$db->query("INSERT INTO foo VALUES ('1', '2', '3')");
-+$db->query("INSERT INTO bar VALUES ('4', '5', '6')");
-+$r = $db->query("SELECT * from foo, bar", SQLITE_ASSOC);
-+var_dump($r->fetch());
-+?>
-+--EXPECT--
-+array(6) {
-+  ["foo.c1"]=>
-+  string(1) "1"
-+  ["foo.c2"]=>
-+  string(1) "2"
-+  ["foo.c3"]=>
-+  string(1) "3"
-+  ["bar.c1"]=>
-+  string(1) "4"
-+  ["bar.c2"]=>
-+  string(1) "5"
-+  ["bar.c3"]=>
-+  string(1) "6"
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_012.phpt
-@@ -0,0 +1,35 @@
-+--TEST--
-+sqlite-oo: read field names
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE strings(foo VARCHAR, bar VARCHAR, baz VARCHAR)");
-+
-+echo "Buffered\n";
-+$r = $db->query("SELECT * from strings");
-+for($i=0; $i<$r->numFields(); $i++) {
-+      var_dump($r->fieldName($i));
-+}
-+echo "Unbuffered\n";
-+$r = $db->unbufferedQuery("SELECT * from strings");
-+for($i=0; $i<$r->numFields(); $i++) {
-+      var_dump($r->fieldName($i));
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+Buffered
-+string(3) "foo"
-+string(3) "bar"
-+string(3) "baz"
-+Unbuffered
-+string(3) "foo"
-+string(3) "bar"
-+string(3) "baz"
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_013.phpt
-@@ -0,0 +1,75 @@
-+--TEST--
-+sqlite-oo: fetch column
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      array (0 => 'one', 1 => 'two'),
-+      array (0 => 'three', 1 => 'four')
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
-+}
-+
-+echo "====BUFFERED====\n";
-+$r = $db->query("SELECT a, b from strings");
-+while ($r->valid()) {
-+      var_dump($r->current(SQLITE_NUM));
-+      var_dump($r->column(0));
-+      var_dump($r->column(1));
-+      var_dump($r->column('a'));
-+      var_dump($r->column('b'));
-+      $r->next();
-+}
-+echo "====UNBUFFERED====\n";
-+$r = $db->unbufferedQuery("SELECT a, b from strings");
-+while ($r->valid()) {
-+      var_dump($r->column(0));
-+      var_dump($r->column('b'));
-+      var_dump($r->column(1));
-+      var_dump($r->column('a'));
-+      $r->next();
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+====BUFFERED====
-+array(2) {
-+  [0]=>
-+  string(3) "one"
-+  [1]=>
-+  string(3) "two"
-+}
-+string(3) "one"
-+string(3) "two"
-+string(3) "one"
-+string(3) "two"
-+array(2) {
-+  [0]=>
-+  string(5) "three"
-+  [1]=>
-+  string(4) "four"
-+}
-+string(5) "three"
-+string(4) "four"
-+string(5) "three"
-+string(4) "four"
-+====UNBUFFERED====
-+string(3) "one"
-+string(3) "two"
-+NULL
-+NULL
-+string(5) "three"
-+string(4) "four"
-+NULL
-+NULL
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_014.phpt
-@@ -0,0 +1,118 @@
-+--TEST--
-+sqlite-oo: fetch all
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+echo "unbuffered twice\n";
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+var_dump($r->fetchAll());
-+var_dump($r->fetchAll());
-+
-+echo "unbuffered with fetch_array\n";
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+var_dump($r->fetch());
-+var_dump($r->fetchAll());
-+
-+echo "buffered\n";
-+$r = $db->query("SELECT a from strings", SQLITE_NUM);
-+var_dump($r->fetchAll());
-+var_dump($r->fetch());
-+var_dump($r->fetchAll());
-+
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+unbuffered twice
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+
-+Warning: SQLiteUnbuffered::fetchAll(): One or more rowsets were already returned; returning NULL this time in %ssqlite_oo_014.php on line %d
-+array(0) {
-+}
-+unbuffered with fetch_array
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(2) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+buffered
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+bool(false)
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_015.phpt
-@@ -0,0 +1,47 @@
-+--TEST--
-+sqlite-oo: array_query
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+$res = $db->arrayQuery("SELECT a from strings", SQLITE_NUM);
-+var_dump($res);
-+
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+array(3) {
-+  [0]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "one"
-+  }
-+  [1]=>
-+  array(1) {
-+    [0]=>
-+    string(3) "two"
-+  }
-+  [2]=>
-+  array(1) {
-+    [0]=>
-+    string(5) "three"
-+  }
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_016.phpt
-@@ -0,0 +1,42 @@
-+--TEST--
-+sqlite-oo: fetch single
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      array (0 => 'one', 1 => 'two'),
-+      array (0 => 'three', 1 => 'four')
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
-+}
-+
-+echo "====BUFFERED====\n";
-+$r = $db->query("SELECT a, b from strings");
-+while ($r->valid()) {
-+      var_dump($r->fetchSingle());
-+}
-+echo "====UNBUFFERED====\n";
-+$r = $db->unbufferedQuery("SELECT a, b from strings");
-+while ($r->valid()) {
-+      var_dump($r->fetchSingle());
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+====BUFFERED====
-+string(3) "one"
-+string(5) "three"
-+====UNBUFFERED====
-+string(3) "one"
-+string(5) "three"
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_020.phpt
-@@ -0,0 +1,66 @@
-+--TEST--
-+sqlite-oo: factory and exception
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+$dbname = tempnam(dirname(__FILE__), "phpsql");
-+function cleanup() {
-+      global $db, $dbname;
-+
-+      $db = NULL;
-+      unlink($dbname);
-+}
-+register_shutdown_function("cleanup");
-+
-+try {
-+      $db = sqlite_factory();
-+} catch(SQLiteException $err) {
-+      echo "Message: ".$err->getMessage()."\n";
-+      echo "File: ".$err->getFile()."\n";
-+      //echo "Line: ".$err->getLine()."\n";
-+      //print_r($err->getTrace());
-+      //echo "BackTrace: ".$err->getTraceAsString()."\n";
-+}
-+
-+$db = sqlite_factory($dbname);
-+
-+$data = array(
-+      array (0 => 'one', 1 => 'two'),
-+      array (0 => 'three', 1 => 'four')
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR, b VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('${str[0]}','${str[1]}')");
-+}
-+
-+$r = $db->unbufferedQuery("SELECT a, b from strings");
-+while ($r->valid()) {
-+      var_dump($r->current(SQLITE_NUM));
-+      $r->next();
-+}
-+$r = null;
-+$db = null;
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+Message: sqlite_factory() expects at least 1 parameter, 0 given
-+File: %ssqlite_oo_020.php
-+array(2) {
-+  [0]=>
-+  string(3) "one"
-+  [1]=>
-+  string(3) "two"
-+}
-+array(2) {
-+  [0]=>
-+  string(5) "three"
-+  [1]=>
-+  string(4) "four"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_021.phpt
-@@ -0,0 +1,48 @@
-+--TEST--
-+sqlite-oo: single query
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE test_db ( id INTEGER PRIMARY KEY, data VARCHAR(100) )");
-+for ($i = 0; $i < 10; $i++) {
-+      $db->query("INSERT INTO test_db (data) VALUES('{$i}data')");
-+}
-+$db->query("INSERT INTO test_db (data) VALUES(NULL)");
-+
-+var_dump($db->singleQuery("SELECT id FROM test_db WHERE id=5"));
-+var_dump($db->singleQuery("SELECT * FROM test_db WHERE id=4"));
-+var_dump($db->singleQuery("SELECT data FROM test_db WHERE id=6"));
-+var_dump($db->singleQuery("SELECT * FROM test_db WHERE id < 5"));
-+var_dump($db->singleQuery("SELECT * FROM test db WHERE id < 4"));
-+var_dump($db->singleQuery("SELECT * FROM test_db WHERE id=999999"));
-+var_dump($db->singleQuery("SELECT id FROM test_db WHERE id=5", FALSE));
-+
-+echo "DONE!\n";
-+?>
-+--EXPECTF--
-+string(1) "5"
-+string(1) "4"
-+string(5) "5data"
-+array(4) {
-+  [0]=>
-+  string(1) "1"
-+  [1]=>
-+  string(1) "2"
-+  [2]=>
-+  string(1) "3"
-+  [3]=>
-+  string(1) "4"
-+}
-+
-+Warning: SQLiteDatabase::singleQuery(): no such table: test in %s on line %d
-+bool(false)
-+NULL
-+array(1) {
-+  [0]=>
-+  string(1) "5"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_022.phpt
-@@ -0,0 +1,98 @@
-+--TEST--
-+sqlite-oo: sqlite::seek
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+$res = $db->query("SELECT a FROM strings", SQLITE_NUM);
-+for ($idx = -1; $idx < 4; $idx++) {
-+      echo "====SEEK:$idx====\n";
-+      $res->seek($idx);
-+      var_dump($res->current());
-+}
-+echo "====AGAIN====\n";
-+for ($idx = -1; $idx < 4; $idx++) {
-+      echo "====SEEK:$idx====\n";
-+      $res->seek($idx);
-+      var_dump($res->current());
-+}
-+echo "====DONE!====\n";
-+?>
-+--EXPECTF--
-+====SEEK:-1====
-+
-+Warning: SQLiteResult::seek(): row -1 out of range in %ssqlite_oo_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:0====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:1====
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+====SEEK:2====
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:3====
-+
-+Warning: SQLiteResult::seek(): row 3 out of range in %ssqlite_oo_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====AGAIN====
-+====SEEK:-1====
-+
-+Warning: SQLiteResult::seek(): row -1 out of range in %ssqlite_oo_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:0====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+====SEEK:1====
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+====SEEK:2====
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====SEEK:3====
-+
-+Warning: SQLiteResult::seek(): row 3 out of range in %ssqlite_oo_022.php on line %d
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====DONE!====
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_024.phpt
-@@ -0,0 +1,74 @@
-+--TEST--
-+sqlite-oo: sqlite::fetch_object
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+class class24 {
-+      function __construct() {
-+              echo __METHOD__ . "\n";
-+      }
-+}
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+echo "====class24====\n";
-+$res = $db->query("SELECT a FROM strings", SQLITE_ASSOC);
-+while ($res->valid()) {
-+      var_dump($res->fetchObject('class24'));
-+}
-+
-+echo "====stdclass====\n";
-+$res = $db->query("SELECT a FROM strings", SQLITE_ASSOC);
-+while ($res->valid()) {
-+      var_dump($res->fetchObject());
-+}
-+
-+echo "====DONE!====\n";
-+?>
-+--EXPECTF--
-+====class24====
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(3) "one"
-+}
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(3) "two"
-+}
-+class24::__construct
-+object(class24)#%d (1) {
-+  ["a"]=>
-+  string(5) "three"
-+}
-+====stdclass====
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(3) "one"
-+}
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(3) "two"
-+}
-+object(stdClass)#%d (1) {
-+  ["a"]=>
-+  string(5) "three"
-+}
-+====DONE!====
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_025.phpt
-@@ -0,0 +1,103 @@
-+--TEST--
-+sqlite-oo: sqlite / foreach
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+echo "====UNBUFFERED====\n";
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+//var_dump(class_implements($r));
-+foreach($r as $row) {
-+      var_dump($row);
-+}
-+echo "====NO-MORE====\n";
-+foreach($r as $row) {
-+      var_dump($row);
-+}
-+echo "====DIRECT====\n";
-+foreach($db->unbufferedQuery("SELECT a from strings", SQLITE_NUM) as $row) {
-+      var_dump($row);
-+}
-+echo "====BUFFERED====\n";
-+$r = $db->query("SELECT a from strings", SQLITE_NUM);
-+//var_dump(class_implements($r));
-+foreach($r as $row) {
-+      var_dump($row);
-+}
-+foreach($r as $row) {
-+      var_dump($row);
-+}
-+echo "DONE!\n";
-+?>
-+--EXPECT--
-+====UNBUFFERED====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====NO-MORE====
-+====DIRECT====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+====BUFFERED====
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "one"
-+}
-+array(1) {
-+  [0]=>
-+  string(3) "two"
-+}
-+array(1) {
-+  [0]=>
-+  string(5) "three"
-+}
-+DONE!
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_026.phpt
-@@ -0,0 +1,56 @@
-+--TEST--
-+sqlite-oo: unbuffered
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array(
-+      "one",
-+      "two",
-+      "three"
-+      );
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+}
-+
-+echo "====FOREACH====\n";
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+foreach($r as $idx => $row) {
-+      var_dump($row[0]);
-+      var_dump($row[0]);
-+}
-+echo "====FOR====\n";
-+$r = $db->unbufferedQuery("SELECT a from strings", SQLITE_NUM);
-+for(;$r->valid(); $r->next()) {
-+      $v = $r->column(0);
-+      var_dump($v);
-+      $c = $r->column(0);
-+      var_dump(is_null($c) || $c==$v);
-+}
-+echo "===DONE===\n";
-+?>
-+--EXPECT--
-+====FOREACH====
-+string(3) "one"
-+string(3) "one"
-+string(3) "two"
-+string(3) "two"
-+string(5) "three"
-+string(5) "three"
-+====FOR====
-+string(3) "one"
-+bool(true)
-+string(3) "two"
-+bool(true)
-+string(5) "three"
-+bool(true)
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_027.phpt
-@@ -0,0 +1,42 @@
-+--TEST--
-+sqlite-oo: changes
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$data = array("one", "two", "three");
-+
-+$db->query("CREATE TABLE strings(a VARCHAR)");
-+
-+foreach ($data as $str) {
-+      $db->query("INSERT INTO strings VALUES('$str')");
-+      echo $db->changes() . "\n";
-+}
-+
-+$db->query("UPDATE strings SET a='foo' WHERE a!='two'");
-+echo $db->changes() . "\n";
-+
-+$db->query("DELETE FROM strings WHERE 1");
-+echo $db->changes() . "\n";
-+
-+$str = '';
-+foreach ($data as $s) {
-+      $str .= "INSERT INTO strings VALUES('".$s."');";
-+}
-+$db->query($str);
-+echo $db->changes() . "\n";
-+
-+?>
-+--EXPECT--
-+1
-+1
-+1
-+2
-+3
-+3
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_028.phpt
-@@ -0,0 +1,25 @@
-+--TEST--
-+sqlite-oo: sqlite_fetch_column_types
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php 
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE strings(a, b INTEGER, c VARCHAR(10), d)");
-+$db->query("INSERT INTO strings VALUES('1', '2', '3', 'abc')");
-+
-+var_dump($db->fetchColumnTypes("strings"));
-+?>
-+--EXPECT--
-+array(4) {
-+  ["a"]=>
-+  string(0) ""
-+  ["b"]=>
-+  string(7) "INTEGER"
-+  ["c"]=>
-+  string(11) "VARCHAR(10)"
-+  ["d"]=>
-+  string(0) ""
-+}
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_029.phpt
-@@ -0,0 +1,53 @@
-+--TEST--
-+sqlite-oo: call method with $this
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE strings(key VARCHAR(10), var VARCHAR(10))");
-+$db->query("INSERT INTO strings VALUES('foo', 'foo')");
-+
-+class sqlite_help
-+{
-+      function __construct($db){
-+              $this->db = $db;
-+              $this->db->createFunction('link_keywords', array(&$this, 'linkers'), 1);
-+      }
-+
-+      function getSingle($key)
-+      {
-+              return $this->db->singleQuery('SELECT link_keywords(var) FROM strings WHERE key=\''.$key.'\'', 1);
-+      }
-+
-+      function linkers($str)
-+      {
-+              $str = str_replace('foo', 'bar', $str);
-+              return $str;
-+      }
-+
-+      function free()
-+      {
-+              unset($this->db);
-+      }
-+
-+      function __destruct()
-+      {
-+              echo "DESTRUCTED\n";
-+      }
-+}
-+
-+$obj = new sqlite_help($db);
-+echo $obj->getSingle('foo')."\n";
-+$obj->free();
-+unset($obj);
-+
-+?>
-+===DONE===
-+--EXPECT--
-+bar
-+===DONE===
-+DESTRUCTED
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_oo_030.phpt
-@@ -0,0 +1,44 @@
-+--TEST--
-+sqlite-oo: calling static methods
-+--INI--
-+sqlite.assoc_case=0
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+?>
-+--FILE--
-+<?php
-+
-+require_once('blankdb_oo.inc'); 
-+
-+class foo {
-+    static function bar($param = NULL) {
-+              return $param;
-+    }
-+}
-+
-+function baz($param = NULL) {
-+      return $param;
-+}
-+
-+var_dump($db->singleQuery("select php('baz')", 1));
-+var_dump($db->singleQuery("select php('baz', 1)", 1));
-+var_dump($db->singleQuery("select php('baz', \"PHP\")", 1));
-+var_dump($db->singleQuery("select php('foo::bar')", 1));
-+var_dump($db->singleQuery("select php('foo::bar', 1)", 1));
-+var_dump($db->singleQuery("select php('foo::bar', \"PHP\")", 1));
-+var_dump($db->singleQuery("select php('foo::bar(\"PHP\")')", 1));
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+NULL
-+string(1) "1"
-+string(3) "PHP"
-+NULL
-+string(1) "1"
-+string(3) "PHP"
-+
-+Warning: SQLiteDatabase::singleQuery(): function `foo::bar("PHP")' is not a function name in %ssqlite_oo_030.php on line %d
-+bool(false)
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_popen_basic.phpt
-@@ -0,0 +1,27 @@
-+--TEST--
-+SQLite: sqlite_popen() basic tests
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : resource sqlite_popen(string filename [, int mode [, string &error_message]])
-+ * Description: Opens a persistent handle to a SQLite database. Will create the database if it does not exist.
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions:
-+*/
-+
-+      $db1 = sqlite_popen(":memory:");
-+      $db2 = sqlite_popen(":memory:");
-+
-+      var_dump($db1);
-+      var_dump($db2);
-+
-+      list($resourceId1) = sscanf((string) $db1, "resource(%d) of type (sqlite database (persistent))");
-+      list($resourceId2) = sscanf((string) $db2, "resource(%d) of type (sqlite database (persistent))");
-+
-+      var_dump($resourceId1 === $resourceId2);
-+?>
-+--EXPECTF--
-+resource(%d) of type (sqlite database (persistent))
-+resource(%d) of type (sqlite database (persistent))
-+bool(true)
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_popen_error.phpt
-@@ -0,0 +1,34 @@
-+--TEST--
-+Test sqlite_popen() function : error conditions 
-+--SKIPIF--
-+<?php if (!extension_loaded("sqlite")) print "skip sqlite extension not loaded"; ?>
-+--FILE--
-+<?php
-+/* Prototype  : resource sqlite_popen(string filename [, int mode [, string &error_message]])
-+ * Description: Opens a persistent handle to a SQLite database. Will create the database if it does not exist. 
-+ * Source code: ext/sqlite/sqlite.c
-+ * Alias to functions: 
-+ */
-+
-+$message = '';
-+
-+echo "*** Testing sqlite_popen() : error conditions ***\n";
-+
-+var_dump( sqlite_popen() );
-+var_dump( sqlite_popen(":memory:", 0666, $message, 'foobar') );
-+var_dump( sqlite_popen("", 0666, $message) );
-+var_dump( $message );
-+
-+?>
-+===DONE===
-+--EXPECTF--
-+*** Testing sqlite_popen() : error conditions ***
-+
-+Warning: sqlite_popen() expects at least 1 parameter, 0 given in %s on line %d
-+NULL
-+
-+Warning: sqlite_popen() expects at most 3 parameters, 4 given in %s on line %d
-+NULL
-+bool(false)
-+NULL
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_session_001.phpt
-@@ -0,0 +1,46 @@
-+--TEST--
-+sqlite, session storage test
-+--CREDITS--
-+Mats Lindh <mats at lindh.no>
-+#Testfest php.no
-+--INI--
-+session.save_handler = sqlite
-+--SKIPIF--
-+if (!extension_loaded("session"))
-+{
-+      die("skip Session module not loaded");
-+}
-+if (!extension_loaded("sqlite"))
-+{
-+      die("skip Session module not loaded");
-+}
-+--FILE--
-+<?php
-+/* Description: Tests that sqlite can be used as a session save handler
-+* Source code: ext/sqlite/sess_sqlite.c
-+*/
-+
-+ob_start();
-+session_save_path(__DIR__ . "/sessiondb.sdb");
-+
-+// create the session and set a session value
-+session_start();
-+$_SESSION["test"] = "foo_bar";
-+
-+// close the session and unset the value
-+session_write_close();
-+unset($_SESSION["test"]);
-+var_dump(isset($_SESSION["test"]));
-+
-+// start the session again and check that we have the proper value
-+session_start();
-+var_dump($_SESSION["test"]);
-+ob_end_flush();
-+?>
-+--EXPECTF--
-+bool(false)
-+%unicode|string%(7) "foo_bar"
-+--CLEAN--
-+<?php
-+      unlink(__DIR__ . "/sessiondb.sdb")
-+?>
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_session_002.phpt
-@@ -0,0 +1,54 @@
-+--TEST--
-+sqlite, session destroy test
-+--CREDITS--
-+Mats Lindh <mats at lindh.no>
-+#Testfest php.no
-+--INI--
-+session.save_handler = sqlite
-+--SKIPIF--
-+if (!extension_loaded("session"))
-+{
-+      die("skip Session module not loaded");
-+}
-+if (!extension_loaded("sqlite"))
-+{
-+      die("skip sqlite module not loaded");
-+}
-+--FILE--
-+<?php
-+/* Description: Tests that sqlite will destroy a session when used as a session handler
-+* Source code: ext/sqlite/sess_sqlite.c
-+*/
-+ob_start();
-+session_save_path(__DIR__ . "/sessiondb.sdb");
-+
-+// start a session and save a value to it before commiting the session to the database
-+session_start();
-+$_SESSION["test"] = "foo_bar";
-+session_write_close();
-+
-+// remove the session value
-+unset($_SESSION["test"]);
-+var_dump(isset($_SESSION["test"]));
-+
-+// start the session again and destroy it
-+session_start();
-+var_dump($_SESSION["test"]);
-+session_destroy();
-+session_write_close();
-+
-+unset($_SESSION["test"]);
-+
-+// check that the session has been destroyed
-+session_start();
-+var_dump(isset($_SESSION["test"]));
-+ob_end_flush();
-+?>
-+--EXPECTF--
-+bool(false)
-+%unicode|string%(7) "foo_bar"
-+bool(false)
-+--CLEAN--
-+<?php
-+      unlink(__DIR__ . "/sessiondb.sdb")
-+?>
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_spl_001.phpt
-@@ -0,0 +1,125 @@
-+--TEST--
-+sqlite-spl: Iteration
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+if (!extension_loaded("spl")) print "skip SPL is not present"; 
-+?>
-+--FILE--
-+<?php
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE menu(id_l int PRIMARY KEY, id_r int UNIQUE, key VARCHAR(10))");
-+$db->query("INSERT INTO menu VALUES( 1, 12, 'A')"); 
-+$db->query("INSERT INTO menu VALUES( 2,  9, 'B')"); 
-+$db->query("INSERT INTO menu VALUES(10, 11, 'F')"); 
-+$db->query("INSERT INTO menu VALUES( 3,  6, 'C')"); 
-+$db->query("INSERT INTO menu VALUES( 7,  8, 'E')"); 
-+$db->query("INSERT INTO menu VALUES( 4,  5, 'D')"); 
-+
-+class SqliteNestedsetElement
-+{
-+      protected $id_l;
-+      protected $id_r;
-+      protected $key;
-+
-+      function __construct($db)
-+      {
-+              $this->db = $db;
-+      }
-+      
-+      function getLeft()
-+      {
-+              return $this->id_l;
-+      }
-+      
-+      function getRight()
-+      {
-+              return $this->id_r;
-+      }
-+      
-+      function __toString()
-+      {
-+              return $this->key;
-+      }
-+
-+      function key()
-+      {
-+              return $this->key;
-+      }
-+}
-+
-+class SqliteNestedset implements RecursiveIterator
-+{
-+      protected $id;
-+      protected $id_l;
-+      protected $id_r;
-+      protected $entry;
-+
-+      function __construct($db, $id_l = 1)
-+      {
-+              $this->db = $db;
-+              $this->id_l = $id_l;
-+              $this->id_r = $this->db->singleQuery('SELECT id_r FROM menu WHERE id_l='.$id_l, 1);
-+              $this->id = $id_l;
-+      }
-+      
-+      function rewind()
-+      {
-+              $this->id = $this->id_l;
-+              $this->fetch();
-+      }
-+
-+      function valid()
-+      {
-+              return is_object($this->entry);
-+      }
-+      
-+      function current()
-+      {
-+              return $this->entry->__toString();
-+      }
-+      
-+      function key()
-+      {
-+              return $this->entry->key();;
-+      }
-+      
-+      function next()
-+      {
-+              $this->id = $this->entry->getRight() + 1;
-+              $this->fetch();
-+      }
-+
-+      protected function fetch()
-+      {
-+              $res = $this->db->unbufferedQuery('SELECT * FROM menu WHERE id_l='.$this->id);
-+              $this->entry = $res->fetchObject('SqliteNestedsetElement', array(&$this->db));
-+              unset($res);
-+      }
-+      
-+      function hasChildren()
-+      {
-+              return $this->entry->getLeft() + 1 < $this->entry->getRight();
-+      }
-+      
-+      function getChildren()
-+      {
-+              return new SqliteNestedset($this->db, $this->entry->getLeft() + 1, $this->entry->getRight() - 1);
-+      }
-+}
-+
-+$menu_iterator = new RecursiveIteratorIterator(new SqliteNestedset($db), RecursiveIteratorIterator::SELF_FIRST);
-+foreach($menu_iterator as $entry) {
-+      echo $menu_iterator->getDepth() . $entry . "\n";
-+}
-+?>
-+===DONE===
-+--EXPECT--
-+0A
-+1B
-+2C
-+3D
-+2E
-+1F
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_spl_002.phpt
-@@ -0,0 +1,29 @@
-+--TEST--
-+sqlite-spl: Countable
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+if (!extension_loaded("spl")) print "skip SPL is not present"; 
-+?>
-+--FILE--
-+<?php
-+include "blankdb_oo.inc";
-+
-+$db->query("CREATE TABLE menu(id_l int PRIMARY KEY, id_r int UNIQUE, key VARCHAR(10))");
-+$db->query("INSERT INTO menu VALUES( 1, 12, 'A')"); 
-+$db->query("INSERT INTO menu VALUES( 2,  9, 'B')"); 
-+$db->query("INSERT INTO menu VALUES(10, 11, 'F')"); 
-+$db->query("INSERT INTO menu VALUES( 3,  6, 'C')"); 
-+$db->query("INSERT INTO menu VALUES( 7,  8, 'E')"); 
-+$db->query("INSERT INTO menu VALUES( 4,  5, 'D')"); 
-+
-+$res = $db->query("SELECT * from menu");
-+
-+var_dump($res->count());
-+var_dump(count($res));
-+?>
-+===DONE===
-+--EXPECT--
-+int(6)
-+int(6)
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/tests/sqlite_spl_003.phpt
-@@ -0,0 +1,28 @@
-+--TEST--
-+sqlite-spl: Exception
-+--SKIPIF--
-+<?php # vim:ft=php
-+if (!extension_loaded("sqlite")) print "skip"; 
-+if (!extension_loaded("spl")) print "skip SPL is not present"; 
-+?>
-+--FILE--
-+<?php
-+
-+try
-+{
-+      $db = sqlite_factory();
-+}
-+catch(SQLiteException $e)
-+{
-+      $parents = class_parents($e);
-+      if (array_key_exists('RuntimeException', $parents))
-+      {
-+              echo "GOOD\n";
-+      }
-+}
-+
-+?>
-+===DONE===
-+--EXPECT--
-+GOOD
-+===DONE===
---- /dev/null
-+++ b/ext/sqlite/TODO
-@@ -0,0 +1,19 @@
-+- Implement a PDO driver, called sqlite2
-+
-+- Transparent binary encoding of return values from PHP callback functions.
-+
-+- Add user-space callback for the authorizer function (this is potentially
-+  very slow, so it needs to be implemented carefully).
-+
-+- Add user-space callback to handle busy databases.
-+
-+  o Test how robust we are when a user-space function is registered as
-+    a callback for a persistent connection in script A, then script B is
-+      called that doesn't register the callback but does make use of the
-+      function in an SQL query.
-+      --> Our test suite doesn't allow us to test persistent connections
-+          at this time :/
-+
-+- Use later version of built-in library
-+
-+vim:tw=78
diff --git a/lang/php5/patches/091-fix-sqlite2.patch b/lang/php5/patches/091-fix-sqlite2.patch
deleted file mode 100644 (file)
index fcbfb23..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
---- a/ext/sqlite/pdo_sqlite2.c
-+++ b/ext/sqlite/pdo_sqlite2.c
-@@ -522,11 +522,6 @@ static char *make_filename_safe(const ch
-                       return NULL;
-               }
--              if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
--                      efree(fullpath);
--                      return NULL;
--              }
--
-               if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                       efree(fullpath);
-                       return NULL;
-@@ -585,7 +580,7 @@ static int pdo_sqlite2_handle_factory(pd
-       if (!filename) {
-               zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
--                              "safe_mode/open_basedir prohibits opening %s",
-+                              "open_basedir prohibits opening %s",
-                               dbh->data_source);
-               goto cleanup;
-       }
---- a/ext/sqlite/sqlite.c
-+++ b/ext/sqlite/sqlite.c
-@@ -1066,10 +1066,6 @@ static int php_sqlite_authorizer(void *a
-               case SQLITE_COPY:
-                       if (strncmp(arg4, ":memory:", sizeof(":memory:") - 1)) {
-                               TSRMLS_FETCH();
--                              if (PG(safe_mode) && (!php_checkuid(arg4, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
--                                      return SQLITE_DENY;
--                              }
--
-                               if (php_check_open_basedir(arg4 TSRMLS_CC)) {
-                                       return SQLITE_DENY;
-                               }
-@@ -1079,10 +1075,6 @@ static int php_sqlite_authorizer(void *a
-               case SQLITE_ATTACH:
-                       if (strncmp(arg3, ":memory:", sizeof(":memory:") - 1)) {
-                               TSRMLS_FETCH();
--                              if (PG(safe_mode) && (!php_checkuid(arg3, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
--                                      return SQLITE_DENY;
--                              }
--
-                               if (php_check_open_basedir(arg3 TSRMLS_CC)) {
-                                       return SQLITE_DENY;
-                               }
-@@ -1160,13 +1152,12 @@ static void sqlite_object_free_storage(v
- static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC)
- {
-       sqlite_object *intern;
--      zval *tmp;
-       intern = emalloc(sizeof(sqlite_object));
-       memset(intern, 0, sizeof(sqlite_object));
-       zend_object_std_init(&intern->std, class_type TSRMLS_CC);
--      zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-+      object_properties_init(&intern->std, class_type);
-       retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) sqlite_object_free_storage, NULL TSRMLS_CC);
-       retval->handlers = handlers;
-@@ -1510,7 +1501,7 @@ static struct php_sqlite_db *php_sqlite_
-       /* authorizer hook so we can enforce safe mode
-        * Note: the declaration of php_sqlite_authorizer is correct for 2.8.2 of libsqlite,
-        * and IS backwards binary compatible with earlier versions */
--      if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
-+      if (PG(open_basedir) && *PG(open_basedir)) {
-               sqlite_set_authorizer(sdb, php_sqlite_authorizer, NULL);
-       }
-@@ -1569,8 +1560,7 @@ PHP_FUNCTION(sqlite_popen)
-                       RETURN_FALSE;
-               }
--              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || 
--                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+              if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                       efree(fullpath);
-                       RETURN_FALSE;
-               }
-@@ -1656,8 +1646,7 @@ PHP_FUNCTION(sqlite_open)
-                       }
-               }
--              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
--                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+              if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                       efree(fullpath);
-                       zend_restore_error_handling(&error_handling TSRMLS_CC);
-                       if (object) {
-@@ -1710,8 +1699,7 @@ PHP_FUNCTION(sqlite_factory)
-                       RETURN_NULL();
-               }
--              if ((PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) ||
--                              php_check_open_basedir(fullpath TSRMLS_CC)) {
-+              if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                       efree(fullpath);
-                       zend_restore_error_handling(&error_handling TSRMLS_CC);
-                       RETURN_NULL();
diff --git a/lang/php5/patches/800-gd-iconv.patch b/lang/php5/patches/800-gd-iconv.patch
new file mode 100644 (file)
index 0000000..1418c27
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/ext/gd/libgd/gdkanji.c
++++ b/ext/gd/libgd/gdkanji.c
+@@ -9,6 +9,11 @@
+ #include "gdhelpers.h"
+ #include <stdarg.h>
++
++/* force usage of internal conversation routine */
++#undef HAVE_ICONV_H
++#undef HAVE_ICONV
++
+ #if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)
+ #include <iconv.h>
+ #ifdef HAVE_ERRNO_H
diff --git a/lang/python-dns/Makefile b/lang/python-dns/Makefile
new file mode 100644 (file)
index 0000000..8dd7106
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-dns
+PKG_RELEASE:=1
+PKG_VERSION:=1.12.0
+PKG_SOURCE_URL:=http://www.dnspython.org/kits/$(PKG_VERSION)
+PKG_MD5SUM:=3f2601ef3c8b77fc6d21a9c77a81efeb
+PKG_SOURCE:=dnspython-$(PKG_VERSION).tar.gz
+PKG_MAINTAINER:=Denis Shulyaka <Shulyaka@gmail.com>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_DIR:=$(BUILD_DIR)/dnspython-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/python-dns
+       SECTION:=language-python
+       CATEGORY:=Languages
+       SUBMENU:=Python
+       TITLE:=dnspython
+       URL:=http://www.dnspython.org/
+       DEPENDS:=+python
+endef
+
+define Package/python-dns/description
+ dnspython is a DNS toolkit for Python. It supports almost all record types. It can be used for queries, zone transfers, and dynamic updates. It supports TSIG authenticated messages and EDNS0.
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,,\
+               install --prefix="$(PKG_INSTALL_DIR)/usr" \
+       )
+endef
+
+$(eval $(call PyPackage,python-dns))
+$(eval $(call BuildPackage,python-dns))
diff --git a/lang/python-imglib/Makefile b/lang/python-imglib/Makefile
new file mode 100644 (file)
index 0000000..1d12004
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 1997-2009 by Secret Labs AB
+# Copyright (c) 1995-2009 by Fredrik Lundh
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-imglib
+PKG_VERSION:=1.1.7
+PKG_RELEASE:=1
+PKG_LICENSE:=CUSTOM
+PKG_LICENSE_FILES:=README
+
+PKG_SOURCE:=Imaging-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://effbot.org/downloads
+PKG_MD5SUM:=fc14a54e1ce02a0225be8854bfba478e
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/Imaging-$(PKG_VERSION)
+PKG_BUILD_DEPENDS:=python python-setuptools
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/python-imglib
+  SECTION:=language-python
+  CATEGORY:=Languages
+  SUBMENU:=Python
+  TITLE:=Python Imaging Library (PIL)
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+  URL:=http://www.pythonware.com/products/pil/
+  DEPENDS:=+python +libfreetype +libjpeg +zlib
+endef
+
+define Package/python-imglib/description
+ The Python Imaging Library adds image processing capabilities to your
+ Python interpreter.
+
+ This library provides extensive file format support, an efficient
+ internal representation, and fairly powerful image processing
+ capabilities.
+
+ The core image library is designed for fast access to data stored in a
+ few basic pixel formats. It should provide a solid foundation for a
+ general image processing tool.
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,., \
+               install --prefix="/usr" --root="$(PKG_INSTALL_DIR)", \
+       )
+endef
+
+define Package/python-imglib/install
+       $(INSTALL_DIR) $(1)$(PYTHON_PKG_DIR)
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) \
+               $(PKG_INSTALL_DIR)$(PYTHON_PKG_DIR)/* \
+               $(1)$(PYTHON_PKG_DIR)/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,python-imglib))
diff --git a/lang/python-imglib/patches/010-cross-compile.patch b/lang/python-imglib/patches/010-cross-compile.patch
new file mode 100644 (file)
index 0000000..0aca43b
--- /dev/null
@@ -0,0 +1,48 @@
+diff -rupN Imaging-1.1.7.orig/setup.py Imaging-1.1.7/setup.py
+--- Imaging-1.1.7.orig/setup.py        2009-11-15 17:06:10.000000000 +0100
++++ Imaging-1.1.7/setup.py     2014-12-11 01:01:10.857100877 +0100
+@@ -34,10 +34,10 @@ def libinclude(root):
+ # TIFF_ROOT = libinclude("/opt/tiff")
+ TCL_ROOT = None
+-JPEG_ROOT = None
+-ZLIB_ROOT = None
++JPEG_ROOT = os.environ['STAGING_DIR'] + "/usr/lib", os.environ['STAGING_DIR'] + "/usr/include"
++ZLIB_ROOT = os.environ['STAGING_DIR'] + "/usr/lib", os.environ['STAGING_DIR'] + "/usr/include"
+ TIFF_ROOT = None
+-FREETYPE_ROOT = None
++FREETYPE_ROOT = os.environ['STAGING_DIR'] + "/usr/lib", os.environ['STAGING_DIR'] + "/usr/include"
+ LCMS_ROOT = None
+ # FIXME: add mechanism to explicitly *disable* the use of a library
+@@ -147,7 +147,6 @@ class pil_build_ext(build_ext):
+             add_directory(library_dirs, "/opt/local/lib")
+             add_directory(include_dirs, "/opt/local/include")
+-        add_directory(library_dirs, "/usr/local/lib")
+         # FIXME: check /opt/stuff directories here?
+         prefix = sysconfig.get_config_var("prefix")
+@@ -199,22 +198,6 @@ class pil_build_ext(build_ext):
+             add_directory(include_dirs, include_root)
+         #
+-        # add standard directories
+-
+-        # look for tcl specific subdirectory (e.g debian)
+-        if _tkinter:
+-            tcl_dir = "/usr/include/tcl" + TCL_VERSION
+-            if os.path.isfile(os.path.join(tcl_dir, "tk.h")):
+-                add_directory(include_dirs, tcl_dir)
+-
+-        # standard locations
+-        add_directory(library_dirs, "/usr/local/lib")
+-        add_directory(include_dirs, "/usr/local/include")
+-
+-        add_directory(library_dirs, "/usr/lib")
+-        add_directory(include_dirs, "/usr/include")
+-
+-        #
+         # insert new dirs *before* default libs, to avoid conflicts
+         # between Python PYD stub libs and real libraries
diff --git a/lang/python-imglib/patches/020-freetype-header-include.patch b/lang/python-imglib/patches/020-freetype-header-include.patch
new file mode 100644 (file)
index 0000000..bf131aa
--- /dev/null
@@ -0,0 +1,21 @@
+diff -rupN Imaging-1.1.7.orig/_imagingft.c Imaging-1.1.7/_imagingft.c
+--- Imaging-1.1.7.orig/_imagingft.c    2009-11-01 01:44:12.000000000 +0100
++++ Imaging-1.1.7/_imagingft.c 2014-12-11 01:05:21.290135484 +0100
+@@ -32,7 +32,7 @@
+ #include FT_FREETYPE_H
+ #else
+ /* freetype 2.0 */
+-#include <freetype/freetype.h>
++#include <freetype2/freetype.h>
+ #endif
+ #if PY_VERSION_HEX < 0x01060000
+@@ -70,7 +70,7 @@ struct {
+     const char* message;
+ } ft_errors[] =
+-#include <freetype/fterrors.h>
++#include <freetype2/fterrors.h>
+ /* -------------------------------------------------------------------- */
+ /* font objects */
diff --git a/lang/python-mysql/Makefile b/lang/python-mysql/Makefile
new file mode 100644 (file)
index 0000000..04ebe5b
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=MySQL-python
+PKG_VERSION:=1.2.5
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
+PKG_SOURCE_URL:=https://pypi.python.org/packages/source/M/MySQL-python/
+PKG_MD5SUM:=654f75b302db6ed8dc5a898c625e030c
+
+PKG_BUILD_DEPENDS:=python python-setuptools libmysqlclient
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/python-mysql
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=MySQL database adapter for Python
+  URL:=https://pypi.python.org/pypi/MySQL-python
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+  DEPENDS:=+python +libmysqlclient
+endef
+
+define Package/python-mysql/description
+ MySQLdb is an thread-compatible interface to the popular MySQL database
+ server that provides the Python database API.
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,,install --prefix=/usr --root=$(PKG_INSTALL_DIR))
+endef
+
+define Package/python-mysql/install
+       $(INSTALL_DIR) $(1)$(PYTHON_PKG_DIR)
+       $(CP) \
+           $(PKG_INSTALL_DIR)$(PYTHON_PKG_DIR)/* \
+           $(1)$(PYTHON_PKG_DIR)
+endef
+
+$(eval $(call BuildPackage,python-mysql))
diff --git a/lang/python-mysql/patches/010-threadsafe.patch b/lang/python-mysql/patches/010-threadsafe.patch
new file mode 100644 (file)
index 0000000..bcd9af8
--- /dev/null
@@ -0,0 +1,11 @@
+--- MySQL-python-1.2.2/site_orig.cfg   2007-08-15 12:58:40.000000000 +0200
++++ MySQL-python-1.2.2/site.cfg        2007-08-15 12:58:49.000000000 +0200
+@@ -4,7 +4,7 @@
+ # static: link against a static library (probably required for embedded)
+ embedded = False
+-threadsafe = True
++threadsafe = False
+ static = False
+ # The path to mysql_config.
diff --git a/lang/python-pip/Makefile b/lang/python-pip/Makefile
new file mode 100644 (file)
index 0000000..d0607d1
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# 
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-pip
+PKG_VERSION:=1.5.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=pip-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://pypi.python.org/packages/source/p/pip/
+PKG_MD5SUM:=01026f87978932060cc86c1dc527903e
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/pip-$(PKG_VERSION)
+PKG_USE_MIPS16:=0
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/python-pip
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Tool for installing Python packages.
+  URL:=https://pip.pypa.io
+  DEPENDS:=+python +python-setuptools
+endef
+
+define Package/python-pip/description
+  A tool for installing and managing Python packages.
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,,\
+               install --prefix="$(PKG_INSTALL_DIR)/usr" \
+       )
+endef
+
+PYTHON_PIP_PKG_DIR:=$(PYTHON_PKG_DIR)/pip-$(PKG_VERSION)-py$(PYTHON_VERSION).egg/pip
+define PyPackage/python-pip/filespec
++|$(PYTHON_PKG_DIR)
+-|$(PYTHON_PIP_PKG_DIR)/_vendor/distlib/*.exe
+endef
+
+# Backup these files, so that they do not clash with python-setuptools
+# If we install python-pip python-setuptools, we want these to be replaced,
+# since python-pip replaces python-setuptools (when installed)
+define Package/python-pip/preinst
+#!/bin/sh
+cd "$${IPKG_INSTROOT}$(PYTHON_PKG_DIR)"
+mv -f easy-install.pth easy-install.pth.old
+mv -f site.py site.py.old
+exit 0
+endef
+
+# And put them back on remove
+define Package/python-pip/postrm
+#!/bin/sh
+cd "$${IPKG_INSTROOT}$(PYTHON_PKG_DIR)"
+mv -f easy-install.pth.old easy-install.pth
+mv -f site.py.old site.py
+exit 0
+endef
+
+define PyPackage/python-pip/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+endef
+
+$(eval $(call PyPackage,python-pip))
+$(eval $(call BuildPackage,python-pip))
+
diff --git a/lang/python-setuptools/Makefile b/lang/python-setuptools/Makefile
new file mode 100644 (file)
index 0000000..a252119
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# 
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-setuptools
+PKG_VERSION:=7.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=setuptools-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://pypi.python.org/packages/source/s/setuptools/
+PKG_MD5SUM:=6245d6752e2ef803c365f560f7f2f940
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/setuptools-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/python-setuptools
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Tool for installing Python packages.
+  URL:=https://bitbucket.org/pypa/setuptools
+  DEPENDS:=+python
+endef
+
+define Package/python-setuptools/description
+  Easily download, build, install, upgrade, and uninstall Python packages
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,,\
+               install --prefix="$(PKG_INSTALL_DIR)/usr" \
+       )
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(PYTHON_LIB_DIR)
+       $(CP) \
+               $(PKG_INSTALL_DIR)$(PYTHON_PKG_DIR)/* \
+               $(PYTHON_LIB_DIR)
+endef
+
+define PyPackage/python-setuptools/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call PyPackage,python-setuptools))
+$(eval $(call BuildPackage,python-setuptools))
+
diff --git a/lang/python-setuptools/patches/0001-remove-windows-support.patch b/lang/python-setuptools/patches/0001-remove-windows-support.patch
new file mode 100644 (file)
index 0000000..0a2d50b
--- /dev/null
@@ -0,0 +1,20 @@
+diff --git a/setuptools/dist.py b/setuptools/dist.py
+index 6b9d350..1350e8a 100644
+--- a/setuptools/dist.py
++++ b/setuptools/dist.py
+@@ -15,7 +15,6 @@ from distutils.errors import (DistutilsOptionError, DistutilsPlatformError,
+ from setuptools.depends import Require
+ from setuptools.compat import basestring, PY2
+-from setuptools import windows_support
+ import pkg_resources
+ def _get_unpatched(cls):
+@@ -310,7 +309,6 @@ class Distribution(_Distribution):
+         egg_cache_dir = os.path.join(os.curdir, '.eggs')
+         if not os.path.exists(egg_cache_dir):
+             os.mkdir(egg_cache_dir)
+-            windows_support.hide_file(egg_cache_dir)
+             readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')
+             with open(readme_txt_filename, 'w') as f:
+                 f.write('This directory contains eggs that were downloaded '
diff --git a/lang/python/Makefile b/lang/python/Makefile
new file mode 100644 (file)
index 0000000..0c1be6d
--- /dev/null
@@ -0,0 +1,215 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+# The file included below defines PYTHON_VERSION
+include ./files/python-package.mk
+
+PKG_NAME:=python
+PKG_VERSION:=$(PYTHON_VERSION).$(PYTHON_VERSION_MICRO)
+PKG_RELEASE:=4
+
+PKG_SOURCE:=Python-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://www.python.org/ftp/python/$(PKG_VERSION)
+PKG_MD5SUM:=38d530f7efc373d64a8fb1637e3baaa7
+
+PKG_LICENSE:=PSF
+PKG_LICENSE_FILES:=LICENSE Modules/_ctypes/libffi_msvc/LICENSE Modules/_ctypes/darwin/LICENSE Modules/_ctypes/libffi/LICENSE Modules/_ctypes/libffi_osx/LICENSE Tools/pybench/LICENSE
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+HOST_BUILD_PARALLEL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/Python-$(PKG_VERSION)
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/Python-$(PKG_VERSION)
+
+PKG_BUILD_DEPENDS:=python/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/python/Default
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Python $(PYTHON_VERSION) programming language
+  URL:=http://www.python.org/
+  MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
+endef
+
+define Package/python/Default/description
+ Python is a dynamic object-oriented programming language that can be used
+ for many kinds of software development. It offers strong support for
+ integration with other languages and tools, comes with extensive standard
+ libraries, and can be learned in a few days. Many Python programmers
+ report substantial productivity gains and feel the language encourages
+ the development of higher quality, more maintainable code.
+endef
+
+define Package/python-base
+$(call Package/python/Default)
+  TITLE:=Python $(PYTHON_VERSION) interpreter
+  DEPENDS:=+libpthread +zlib +libffi +libopenssl
+endef
+
+define Package/python-base/description
+  This package contains only the interpreter and the bare minimum
+  for the interpreter to start.
+endef
+
+define Package/python
+$(call Package/python/Default)
+  DEPENDS:=+python-base +libncursesw +libbz2 +libgdbm +libsqlite3 +libexpat +libdb47
+endef
+
+define Package/python/description
+  This package contains the (almost) full Python install.
+endef
+
+MAKE_FLAGS+=\
+       CROSS_COMPILE=yes \
+       LD="$(TARGET_CC)" \
+       PGEN=pgen2
+
+EXTRA_CFLAGS+= \
+       -DNDEBUG -fno-inline
+EXTRA_LDFLAGS+= \
+       -L$(PKG_BUILD_DIR)
+
+ENABLE_IPV6:=
+ifeq ($(CONFIG_IPV6),y)
+       ENABLE_IPV6 += --enable-ipv6
+endif
+
+CONFIGURE_ARGS+= \
+       --sysconfdir=/etc \
+       --enable-shared \
+       --without-cxx-main \
+       --with-threads \
+       --with-system-ffi="$(STAGING_DIR)/usr" \
+       --without-pymalloc \
+       $(ENABLE_IPV6) \
+       CONFIG_SITE="$(PKG_BUILD_DIR)/config.site" \
+       OPT="$(TARGET_CFLAGS)"
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       $(CP) ./files/config.site $(PKG_BUILD_DIR)/config.site
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(STAGING_DIR)/mk/
+       $(INSTALL_DIR) $(1)/usr/include/ $(1)/usr/lib/ $(1)/usr/lib/pkgconfig
+       $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/
+       $(INSTALL_DATA) ./files/python-package.mk $(STAGING_DIR)/mk/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/include/python$(PYTHON_VERSION) \
+               $(1)/usr/include/
+       $(CP) \
+               $(STAGING_DIR_HOST)/lib/python$(PYTHON_VERSION) \
+               $(PKG_INSTALL_DIR)/usr/lib/libpython$(PYTHON_VERSION).so* \
+               $(1)/usr/lib/
+       $(CP) \
+               $(STAGING_DIR_HOST)/lib/pkgconfig/python.pc \
+               $(STAGING_DIR_HOST)/lib/pkgconfig/python2.pc \
+               $(STAGING_DIR_HOST)/lib/pkgconfig/python-$(PYTHON_VERSION).pc \
+               $(1)/usr/lib/pkgconfig
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/python$(PYTHON_VERSION)/config \
+               $(1)/usr/lib/python$(PYTHON_VERSION)/
+endef
+
+define PyPackage/python-base/filespec
++|/usr/bin/python$(PYTHON_VERSION)
++|/usr/lib/python$(PYTHON_VERSION)/_abcoll.py
++|/usr/lib/python$(PYTHON_VERSION)/_sysconfigdata.py
++|/usr/lib/python$(PYTHON_VERSION)/_weakrefset.py
++|/usr/lib/python$(PYTHON_VERSION)/abc.py
++|/usr/lib/python$(PYTHON_VERSION)/copy_reg.py
++|/usr/lib/python$(PYTHON_VERSION)/genericpath.py
++|/usr/lib/python$(PYTHON_VERSION)/linecache.py
++|/usr/lib/python$(PYTHON_VERSION)/posixpath.py
++|/usr/lib/python$(PYTHON_VERSION)/os.py
++|/usr/lib/python$(PYTHON_VERSION)/re.py
++|/usr/lib/python$(PYTHON_VERSION)/site.py
++|/usr/lib/python$(PYTHON_VERSION)/sre_compile.py
++|/usr/lib/python$(PYTHON_VERSION)/sre_constants.py
++|/usr/lib/python$(PYTHON_VERSION)/sre_parse.py
++|/usr/lib/python$(PYTHON_VERSION)/sysconfig.py
++|/usr/lib/python$(PYTHON_VERSION)/stat.py
++|/usr/lib/python$(PYTHON_VERSION)/traceback.py
++|/usr/lib/python$(PYTHON_VERSION)/types.py
++|/usr/lib/python$(PYTHON_VERSION)/UserDict.py
++|/usr/lib/python$(PYTHON_VERSION)/warnings.py
+endef
+
+define PyPackage/python/filespec
++|/usr/lib/python$(PYTHON_VERSION)
+-|/usr/lib/python$(PYTHON_VERSION)/config
+-|/usr/lib/python$(PYTHON_VERSION)/distutils/cygwinccompiler.py
+-|/usr/lib/python$(PYTHON_VERSION)/distutils/command/wininst*
+-|/usr/lib/python$(PYTHON_VERSION)/idlelib
+-|/usr/lib/python$(PYTHON_VERSION)/lib2to3
+-|/usr/lib/python$(PYTHON_VERSION)/lib-tk
+-|/usr/lib/python$(PYTHON_VERSION)/lib-dynload/_testcapi.so
+-|/usr/lib/python$(PYTHON_VERSION)/pdb.doc
+-|/usr/lib/python$(PYTHON_VERSION)/test
+-|/usr/lib/python$(PYTHON_VERSION)/webbrowser.py
+-|/usr/lib/python$(PYTHON_VERSION)/*/test
+-|/usr/lib/python$(PYTHON_VERSION)/*/tests
+-|/usr/lib/python$(PYTHON_VERSION)/lib-dynload/readline.so
+-|/usr/lib/python$(PYTHON_VERSION)/_abcoll.py
+-|/usr/lib/python$(PYTHON_VERSION)/_sysconfigdata.py
+-|/usr/lib/python$(PYTHON_VERSION)/_weakrefset.py
+-|/usr/lib/python$(PYTHON_VERSION)/abc.py
+-|/usr/lib/python$(PYTHON_VERSION)/copy_reg.py
+-|/usr/lib/python$(PYTHON_VERSION)/genericpath.py
+-|/usr/lib/python$(PYTHON_VERSION)/linecache.py
+-|/usr/lib/python$(PYTHON_VERSION)/posixpath.py
+-|/usr/lib/python$(PYTHON_VERSION)/os.py
+-|/usr/lib/python$(PYTHON_VERSION)/re.py
+-|/usr/lib/python$(PYTHON_VERSION)/site.py
+-|/usr/lib/python$(PYTHON_VERSION)/sre_compile.py
+-|/usr/lib/python$(PYTHON_VERSION)/sre_constants.py
+-|/usr/lib/python$(PYTHON_VERSION)/sre_parse.py
+-|/usr/lib/python$(PYTHON_VERSION)/sysconfig.py
+-|/usr/lib/python$(PYTHON_VERSION)/stat.py
+-|/usr/lib/python$(PYTHON_VERSION)/traceback.py
+-|/usr/lib/python$(PYTHON_VERSION)/types.py
+-|/usr/lib/python$(PYTHON_VERSION)/UserDict.py
+-|/usr/lib/python$(PYTHON_VERSION)/warnings.py
+endef
+
+define PyPackage/python-base/install
+       $(LN) python$(PYTHON_VERSION) $(1)/usr/bin/python
+       $(LN) python$(PYTHON_VERSION) $(1)/usr/bin/python2
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpython$(PYTHON_VERSION).so* $(1)/usr/lib/
+endef
+
+HOST_CONFIGURE_ARGS+= \
+       --without-cxx-main \
+       --without-pymalloc \
+       --with-threads \
+       --prefix=$(STAGING_DIR_HOST) \
+       --with-ensurepip=upgrade \
+       CONFIG_SITE= \
+       OPT="$(HOST_CFLAGS)"
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/
+       $(MAKE) -C $(HOST_BUILD_DIR) install
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/Parser/pgen $(STAGING_DIR_HOST)/bin/pgen2
+endef
+
+$(eval $(call HostBuild))
+
+$(eval $(call PyPackage,python-base))
+$(eval $(call PyPackage,python))
+
+$(eval $(call BuildPackage,python-base))
+$(eval $(call BuildPackage,python))
diff --git a/lang/python/files/config.site b/lang/python/files/config.site
new file mode 100644 (file)
index 0000000..cfa56b8
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ac_cv_file__dev_ptmx=yes
+ac_cv_file__dev_ptc=no
+ac_cv_buggy_getaddrinfo=no
+
diff --git a/lang/python/files/python-package.mk b/lang/python/files/python-package.mk
new file mode 100644 (file)
index 0000000..c8cbcda
--- /dev/null
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PYTHON_VERSION:=2.7
+PYTHON_VERSION_MICRO:=9
+
+PYTHON_DIR:=$(STAGING_DIR)/usr
+PYTHON_BIN_DIR:=$(PYTHON_DIR)/bin
+PYTHON_INC_DIR:=$(PYTHON_DIR)/include/python$(PYTHON_VERSION)
+PYTHON_LIB_DIR:=$(PYTHON_DIR)/lib/python$(PYTHON_VERSION)
+
+PYTHON_PKG_DIR:=/usr/lib/python$(PYTHON_VERSION)/site-packages
+
+PYTHON:=python$(PYTHON_VERSION)
+
+HOST_PYTHON_LIB_DIR:=$(STAGING_DIR_HOST)/lib/python$(PYTHON_VERSION)
+HOST_PYTHON_BIN:=$(STAGING_DIR_HOST)/bin/python2
+
+PYTHONPATH:=$(PYTHON_LIB_DIR):$(STAGING_DIR)/$(PYTHON_PKG_DIR):$(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)
+define HostPython
+       (       export PYTHONPATH="$(PYTHONPATH)"; \
+               export PYTHONOPTIMIZE=""; \
+               export PYTHONDONTWRITEBYTECODE=1; \
+               $(1) \
+               $(HOST_PYTHON_BIN) $(2); \
+       )
+endef
+
+PKG_USE_MIPS16:=0
+# This is required in addition to PKG_USE_MIPS16:=0 because otherwise MIPS16
+# flags are inherited from the Python base package (via sysconfig module)
+ifdef CONFIG_USE_MIPS16
+  TARGET_CFLAGS += -mno-mips16 -mno-interlink-mips16
+endif
+
+define PyPackage
+
+  # Add default PyPackage filespec none defined
+  ifndef PyPackage/$(1)/filespec
+    define PyPackage/$(1)/filespec
+      +|$(PYTHON_PKG_DIR)
+    endef
+  endif
+
+  $(call shexport,PyPackage/$(1)/filespec)
+
+  define Package/$(1)/install
+       find $(PKG_INSTALL_DIR) -name "*\.pyc" -o -name "*\.pyo" | xargs rm -f
+       @echo "$$$$$$$$$$(call shvar,PyPackage/$(1)/filespec)" | ( \
+               IFS='|'; \
+               while read fop fspec fperm; do \
+                 fop=`echo "$$$$$$$$fop" | tr -d ' \t\n'`; \
+                 if [ "$$$$$$$$fop" = "+" ]; then \
+                       if [ ! -e "$(PKG_INSTALL_DIR)$$$$$$$$fspec" ]; then \
+                         echo "File not found '$(PKG_INSTALL_DIR)$$$$$$$$fspec'"; \
+                         exit 1; \
+                       fi; \
+                       dpath=`dirname "$$$$$$$$fspec"`; \
+                       if [ -n "$$$$$$$$fperm" ]; then \
+                         dperm="-m$$$$$$$$fperm"; \
+                       else \
+                         dperm=`stat -c "%a" $(PKG_INSTALL_DIR)$$$$$$$$dpath`; \
+                       fi; \
+                       mkdir -p $$$$$$$$$dperm $$(1)$$$$$$$$dpath; \
+                       echo "copying: '$$$$$$$$fspec'"; \
+                       cp -fpR $(PKG_INSTALL_DIR)$$$$$$$$fspec $$(1)$$$$$$$$dpath/; \
+                       if [ -n "$$$$$$$$fperm" ]; then \
+                         chmod -R $$$$$$$$fperm $$(1)$$$$$$$$fspec; \
+                       fi; \
+                 elif [ "$$$$$$$$fop" = "-" ]; then \
+                       echo "removing: '$$$$$$$$fspec'"; \
+                       rm -fR $$(1)$$$$$$$$fspec; \
+                 elif [ "$$$$$$$$fop" = "=" ]; then \
+                       echo "setting permissions: '$$$$$$$$fperm' on '$$$$$$$$fspec'"; \
+                       chmod -R $$$$$$$$fperm $$(1)$$$$$$$$fspec; \
+                 fi; \
+               done; \
+       )
+       $(call PyPackage/$(1)/install,$$(1))
+  endef
+endef
+
+# $(1) => build subdir
+# $(2) => additional arguments to setup.py
+# $(3) => additional variables
+define Build/Compile/PyMod
+       $(INSTALL_DIR) $(PKG_INSTALL_DIR)/$(PYTHON_PKG_DIR)
+       $(call HostPython, \
+               cd $(PKG_BUILD_DIR)/$(strip $(1)); \
+               CC="$(TARGET_CC)" \
+               CCSHARED="$(TARGET_CC) $(FPIC)" \
+               LD="$(TARGET_CC)" \
+               LDSHARED="$(TARGET_CC) -shared" \
+               CFLAGS="$(TARGET_CFLAGS)" \
+               CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PYTHON_INC_DIR)" \
+               LDFLAGS="$(TARGET_LDFLAGS) -lpython$(PYTHON_VERSION)" \
+               _PYTHON_HOST_PLATFORM=linux2 \
+               __PYVENV_LAUNCHER__="/usr/bin/$(PYTHON)" \
+               $(3) \
+               , \
+               ./setup.py $(2) \
+       )
+       find $(PKG_INSTALL_DIR) -name "*\.pyc" -o -name "*\.pyo" | xargs rm -f
+endef
+
diff --git a/lang/python/patches/110-enable-zlib.patch b/lang/python/patches/110-enable-zlib.patch
new file mode 100644 (file)
index 0000000..780831e
--- /dev/null
@@ -0,0 +1,25 @@
+From 6eeab87bc852481e599325549c854b701bf2e39f Mon Sep 17 00:00:00 2001
+From: Alexandru Ardelean <aa@ocedo.com>
+Date: Thu, 25 Sep 2014 18:18:29 +0300
+Subject: [PATCH] enable zlib
+
+---
+ Modules/Setup.dist | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Modules/Setup.dist b/Modules/Setup.dist
+index 01fb85f..01ac492 100644
+--- a/Modules/Setup.dist
++++ b/Modules/Setup.dist
+@@ -358,7 +358,7 @@ _symtable symtablemodule.c
+ # Andrew Kuchling's zlib module.
+ # This require zlib 1.1.3 (or later).
+ # See http://www.gzip.org/zlib/
+-#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
++zlib zlibmodule.c -lz
+ # Interface to the Expat XML parser
+ #
+-- 
+1.8.4.5
+
diff --git a/lang/python/patches/120-do-not-add-include-dirs-when-cross-compiling.patch b/lang/python/patches/120-do-not-add-include-dirs-when-cross-compiling.patch
new file mode 100644 (file)
index 0000000..fb2fe8a
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/setup.py b/setup.py
+index cbdeaf3..5154412 100644
+--- a/setup.py
++++ b/setup.py
+@@ -480,7 +480,8 @@ class PyBuildExt(build_ext):
+                         add_dir_to_list(dir_list, directory)
+         if os.path.normpath(sys.prefix) != '/usr' \
+-                and not sysconfig.get_config_var('PYTHONFRAMEWORK'):
++                and not sysconfig.get_config_var('PYTHONFRAMEWORK') \
++                and not cross_compiling:
+             # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
+             # (PYTHONFRAMEWORK is set) to avoid # linking problems when
+             # building a framework with different architectures than
diff --git a/lang/python/patches/130-do-not-run-distutils-tests.patch b/lang/python/patches/130-do-not-run-distutils-tests.patch
new file mode 100644 (file)
index 0000000..4fdd2bb
--- /dev/null
@@ -0,0 +1,37 @@
+diff --git a/Makefile.pre.in b/Makefile.pre.in
+index bcd83bf..c4dcc6d 100644
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -1005,32 +1005,6 @@ libinstall:     build_all $(srcdir)/Lib/$(PLATDIR) $(srcdir)/Modules/xxmodule.c
+               done; \
+       done
+       $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
+-      if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \
+-              $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
+-                      $(DESTDIR)$(LIBDEST)/distutils/tests ; \
+-      fi
+-      PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST) -f \
+-              -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
+-              $(DESTDIR)$(LIBDEST)
+-      PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST) -f \
+-              -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
+-              $(DESTDIR)$(LIBDEST)
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST)/site-packages -f \
+-              -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST)/site-packages -f \
+-              -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/PatternGrammar.txt
+ # Create the PLATDIR source directory, if one wasn't distributed..
+ $(srcdir)/Lib/$(PLATDIR):
diff --git a/lang/python/patches/140-do-not-write-bytes-codes.patch b/lang/python/patches/140-do-not-write-bytes-codes.patch
new file mode 100644 (file)
index 0000000..f67e7dc
--- /dev/null
@@ -0,0 +1,22 @@
+diff --git a/Python/pythonrun.c b/Python/pythonrun.c
+index 748a63b..cb6e291 100644
+--- a/Python/pythonrun.c
++++ b/Python/pythonrun.c
+@@ -79,7 +79,7 @@ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
+ int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */
+ int Py_NoSiteFlag; /* Suppress 'import site' */
+ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
+-int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
++int Py_DontWriteBytecodeFlag = 1; /* Suppress writing bytecode files (*.py[co]) */
+ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
+ int Py_FrozenFlag; /* Needed by getpath.c */
+ int Py_UnicodeFlag = 0; /* Needed by compile.c */
+@@ -174,7 +174,7 @@ Py_InitializeEx(int install_sigs)
+     if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
+         Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
+     if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')
+-        Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p);
++        Py_DontWriteBytecodeFlag = atoi(p);
+     /* The variable is only tested for existence here; _PyRandom_Init will
+        check its value further. */
+     if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
diff --git a/lang/python/patches/150-fix-libffi-x86-64-configure.patch b/lang/python/patches/150-fix-libffi-x86-64-configure.patch
new file mode 100644 (file)
index 0000000..ea062a3
--- /dev/null
@@ -0,0 +1,31 @@
+diff --git a/Modules/_ctypes/libffi/configure b/Modules/_ctypes/libffi/configure
+index 75f62a7..4d6c9f2 100755
+--- a/Modules/_ctypes/libffi/configure
++++ b/Modules/_ctypes/libffi/configure
+@@ -17257,20 +17257,12 @@ case "$host" in
+       fi
+       ;;
+-  i?86-*-* | x86_64-*-*)
+-      TARGETDIR=x86
+-      if test $ac_cv_sizeof_size_t = 4; then
+-        case "$host" in
+-          *-gnux32)
+-            TARGET=X86_64
+-            ;;
+-          *)
+-            TARGET=X86
+-            ;;
+-          esac
+-      else
+-        TARGET=X86_64;
+-      fi
++  i?86-*-*)
++      TARGET=X86; TARGETDIR=x86
++      ;;
++
++  x86_64-*-*)
++      TARGET=X86_64; TARGETDIR=x86
+       ;;
+   ia64*-*-*)
diff --git a/lang/python/patches/160-remove-debian-multiarch-support.patch b/lang/python/patches/160-remove-debian-multiarch-support.patch
new file mode 100644 (file)
index 0000000..52d52b9
--- /dev/null
@@ -0,0 +1,12 @@
+diff --git a/setup.py b/setup.py
+index 7868b7b..9ae0ef2 100644
+--- a/setup.py
++++ b/setup.py
+@@ -444,7 +444,6 @@ class PyBuildExt(build_ext):
+             add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
+         if cross_compiling:
+             self.add_gcc_paths()
+-        self.add_multiarch_paths()
+         # Add paths specified in the environment variables LDFLAGS and
+         # CPPFLAGS for header and library files.
diff --git a/lang/python3/Makefile b/lang/python3/Makefile
new file mode 100644 (file)
index 0000000..d13a9f4
--- /dev/null
@@ -0,0 +1,196 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+# The file included below defines PYTHON_VERSION
+include ./files/python3-package.mk
+
+PYTHON_VERSION:=$(PYTHON3_VERSION)
+PYTHON_VERSION_MICRO:=$(PYTHON3_VERSION_MICRO)
+
+PKG_NAME:=python3
+PKG_RELEASE:=1
+PKG_VERSION:=$(PYTHON_VERSION).$(PYTHON_VERSION_MICRO)
+
+PKG_SOURCE:=Python-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://www.python.org/ftp/python/$(PKG_VERSION)
+PKG_MD5SUM:=36fc7327c02c6f12fa24fc9ba78039e3
+
+PKG_LICENSE:=PSF
+PKG_LICENSE_FILES:=LICENSE Modules/_ctypes/libffi_msvc/LICENSE Modules/_ctypes/darwin/LICENSE Modules/_ctypes/libffi/LICENSE Modules/_ctypes/libffi_osx/LICENSE Tools/pybench/LICENSE
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+HOST_BUILD_PARALLEL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/Python-$(PKG_VERSION)
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/Python-$(PKG_VERSION)
+
+PKG_BUILD_DEPENDS:=python3/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/python3/Default
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Python $(PYTHON_VERSION) programming language
+  URL:=http://www.python.org/
+  MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
+endef
+
+define Package/python3/Default/description
+ Python is a dynamic object-oriented programming language that can be used
+ for many kinds of software development. It offers strong support for
+ integration with other languages and tools, comes with extensive standard
+ libraries, and can be learned in a few days. Many Python programmers
+ report substantial productivity gains and feel the language encourages
+ the development of higher quality, more maintainable code.
+endef
+
+define Package/python3-base
+$(call Package/python3/Default)
+  TITLE:=Python $(PYTHON_VERSION) interpreter
+  DEPENDS:=+libpthread +zlib +libffi +libopenssl
+endef
+
+define Package/python3-base/description
+  This package contains only the interpreter and the bare minimum
+  for the interpreter to start.
+endef
+
+define Package/python3
+$(call Package/python3/Default)
+  DEPENDS:=+python3-base +libncursesw +libbz2 +libgdbm +libsqlite3 +libdb47
+endef
+
+define Package/python3/description
+  This package contains the (almost) full Python install.
+endef
+
+MAKE_FLAGS+=\
+       CROSS_COMPILE=yes \
+       LD="$(TARGET_CC)" \
+       PGEN=pgen3
+
+EXTRA_CFLAGS+= \
+       -DNDEBUG -fno-inline
+EXTRA_LDFLAGS+= \
+       -L$(PKG_BUILD_DIR)
+
+ENABLE_IPV6:=
+ifeq ($(CONFIG_IPV6),y)
+       ENABLE_IPV6 += --enable-ipv6
+endif
+
+CONFIGURE_ARGS+= \
+       --sysconfdir=/etc \
+       --enable-shared \
+       --without-cxx-main \
+       --with-threads \
+       --with-system-ffi="$(STAGING_DIR)/usr" \
+       --without-pymalloc \
+       --without-ensurepip \
+       $(ENABLE_IPV6) \
+       CONFIG_SITE="$(PKG_BUILD_DIR)/config.site" \
+       OPT="$(TARGET_CFLAGS)"
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       $(CP) ./files/config.site $(PKG_BUILD_DIR)/config.site
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(STAGING_DIR)/mk/
+       $(INSTALL_DIR) $(1)/usr/include/ $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/
+       $(INSTALL_DATA) ./files/python3-package.mk $(STAGING_DIR)/mk/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/include/python$(PYTHON_VERSION) \
+               $(1)/usr/include/
+       $(CP) \
+               $(STAGING_DIR_HOST)/lib/python$(PYTHON_VERSION) \
+               $(PKG_INSTALL_DIR)/usr/lib/libpython$(PYTHON_VERSION).so* \
+               $(1)/usr/lib/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/python$(PYTHON_VERSION)/config-$(PYTHON_VERSION) \
+               $(1)/usr/lib/python$(PYTHON_VERSION)/
+endef
+
+define Py3Package/python3-base/filespec
++|/usr/bin/python$(PYTHON_VERSION)
++|/usr/lib/python$(PYTHON_VERSION)/encodings
++|/usr/lib/python$(PYTHON_VERSION)/_collections_abc.py
++|/usr/lib/python$(PYTHON_VERSION)/_sitebuiltins.py
++|/usr/lib/python$(PYTHON_VERSION)/_sysconfigdata.py
++|/usr/lib/python$(PYTHON_VERSION)/_weakrefset.py
++|/usr/lib/python$(PYTHON_VERSION)/abc.py
++|/usr/lib/python$(PYTHON_VERSION)/codecs.py
++|/usr/lib/python$(PYTHON_VERSION)/genericpath.py
++|/usr/lib/python$(PYTHON_VERSION)/io.py
++|/usr/lib/python$(PYTHON_VERSION)/os.py
++|/usr/lib/python$(PYTHON_VERSION)/posixpath.py
++|/usr/lib/python$(PYTHON_VERSION)/site.py
++|/usr/lib/python$(PYTHON_VERSION)/sysconfig.py
++|/usr/lib/python$(PYTHON_VERSION)/stat.py
+endef
+
+define Py3Package/python3/filespec
++|/usr/lib/python$(PYTHON_VERSION)
+-|/usr/lib/python$(PYTHON_VERSION)/config-$(PYTHON_VERSION)
+-|/usr/lib/python$(PYTHON_VERSION)/distutils/cygwinccompiler.py
+-|/usr/lib/python$(PYTHON_VERSION)/distutils/command/wininst*
+-|/usr/lib/python$(PYTHON_VERSION)/idlelib
+-|/usr/lib/python$(PYTHON_VERSION)/lib2to3
+-|/usr/lib/python$(PYTHON_VERSION)/tkinter
+-|/usr/lib/python$(PYTHON_VERSION)/turtledemo
+-|/usr/lib/python$(PYTHON_VERSION)/lib-dynload/_test*.so
+-|/usr/lib/python$(PYTHON_VERSION)/lib-dynload/readline*.so
+-|/usr/lib/python$(PYTHON_VERSION)/pdb.doc
+-|/usr/lib/python$(PYTHON_VERSION)/test
+-|/usr/lib/python$(PYTHON_VERSION)/webbrowser.py
+-|/usr/lib/python$(PYTHON_VERSION)/*/test
+-|/usr/lib/python$(PYTHON_VERSION)/*/tests
+endef
+
+define Py3Package/python3-base/install
+       # Adding the lib-dynload folder (even just empty) suppresses 2 warnings when starting Python
+       $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/lib-dynload/
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(LN) python$(PYTHON_VERSION) $(1)/usr/bin/python3
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpython$(PYTHON_VERSION).so* $(1)/usr/lib/
+endef
+
+HOST_CONFIGURE_ARGS+= \
+       --without-cxx-main \
+       --without-pymalloc \
+       --with-threads \
+       --prefix=$(STAGING_DIR_HOST) \
+       --with-ensurepip=upgrade \
+       CONFIG_SITE= \
+       OPT="$(HOST_CFLAGS)"
+
+define Host/Compile
+       +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) python Parser/pgen
+       +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) sharedmods
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/
+       $(MAKE) -C $(HOST_BUILD_DIR) install
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/Parser/pgen $(STAGING_DIR_HOST)/bin/pgen3
+endef
+
+$(eval $(call HostBuild))
+
+$(eval $(call Py3Package,python3-base))
+$(eval $(call Py3Package,python3))
+
+$(eval $(call BuildPackage,python3-base))
+$(eval $(call BuildPackage,python3))
diff --git a/lang/python3/files/config.site b/lang/python3/files/config.site
new file mode 100644 (file)
index 0000000..cfa56b8
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ac_cv_file__dev_ptmx=yes
+ac_cv_file__dev_ptc=no
+ac_cv_buggy_getaddrinfo=no
+
diff --git a/lang/python3/files/python3-package.mk b/lang/python3/files/python3-package.mk
new file mode 100644 (file)
index 0000000..b28ec58
--- /dev/null
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PYTHON3_VERSION:=3.4
+PYTHON3_VERSION_MICRO:=2
+
+PYTHON3_DIR:=$(STAGING_DIR)/usr
+PYTHON3_BIN_DIR:=$(PYTHON3_DIR)/bin
+PYTHON3_INC_DIR:=$(PYTHON3_DIR)/include/python$(PYTHON3_VERSION)
+PYTHON3_LIB_DIR:=$(PYTHON3_DIR)/lib/python$(PYTHON3_VERSION)
+
+PYTHON3_PKG_DIR:=/usr/lib/python$(PYTHON3_VERSION)/site-packages
+
+PYTHON3:=python$(PYTHON3_VERSION)
+
+HOST_PYTHON3_LIB_DIR:=$(STAGING_DIR_HOST)/lib/python$(PYTHON3_VERSION)
+HOST_PYTHON3_BIN:=$(STAGING_DIR_HOST)/bin/python3
+
+PYTHON3PATH:=$(PYTHON3_LIB_DIR):$(STAGING_DIR)/$(PYTHON3_PKG_DIR):$(PKG_INSTALL_DIR)/$(PYTHON3_PKG_DIR)
+define HostPython3
+       (       export PYTHONPATH="$(PYTHON3PATH)"; \
+               export PYTHONOPTIMIZE=""; \
+               export PYTHONDONTWRITEBYTECODE=1; \
+               $(1) \
+               $(HOST_PYTHON3_BIN) $(2); \
+       )
+endef
+
+PKG_USE_MIPS16:=0
+# This is required in addition to PKG_USE_MIPS16:=0 because otherwise MIPS16
+# flags are inherited from the Python base package (via sysconfig module)
+ifdef CONFIG_USE_MIPS16
+  TARGET_CFLAGS += -mno-mips16 -mno-interlink-mips16
+endif
+
+define Py3Package
+
+  # Add default PyPackage filespec none defined
+  ifndef Py3Package/$(1)/filespec
+    define Py3Package/$(1)/filespec
+      +|$(PYTHON3_PKG_DIR)
+    endef
+  endif
+
+  $(call shexport,Py3Package/$(1)/filespec)
+
+  define Package/$(1)/install
+       find $(PKG_INSTALL_DIR) -name "*\.pyc" -o -name "*\.pyo" | xargs rm -f
+       @echo "$$$$$$$$$$(call shvar,Py3Package/$(1)/filespec)" | ( \
+               IFS='|'; \
+               while read fop fspec fperm; do \
+                 fop=`echo "$$$$$$$$fop" | tr -d ' \t\n'`; \
+                 if [ "$$$$$$$$fop" = "+" ]; then \
+                       if [ ! -e "$(PKG_INSTALL_DIR)$$$$$$$$fspec" ]; then \
+                         echo "File not found '$(PKG_INSTALL_DIR)$$$$$$$$fspec'"; \
+                         exit 1; \
+                       fi; \
+                       dpath=`dirname "$$$$$$$$fspec"`; \
+                       if [ -n "$$$$$$$$fperm" ]; then \
+                         dperm="-m$$$$$$$$fperm"; \
+                       else \
+                         dperm=`stat -c "%a" $(PKG_INSTALL_DIR)$$$$$$$$dpath`; \
+                       fi; \
+                       mkdir -p $$$$$$$$$dperm $$(1)$$$$$$$$dpath; \
+                       echo "copying: '$$$$$$$$fspec'"; \
+                       cp -fpR $(PKG_INSTALL_DIR)$$$$$$$$fspec $$(1)$$$$$$$$dpath/; \
+                       if [ -n "$$$$$$$$fperm" ]; then \
+                         chmod -R $$$$$$$$fperm $$(1)$$$$$$$$fspec; \
+                       fi; \
+                 elif [ "$$$$$$$$fop" = "-" ]; then \
+                       echo "removing: '$$$$$$$$fspec'"; \
+                       rm -fR $$(1)$$$$$$$$fspec; \
+                 elif [ "$$$$$$$$fop" = "=" ]; then \
+                       echo "setting permissions: '$$$$$$$$fperm' on '$$$$$$$$fspec'"; \
+                       chmod -R $$$$$$$$fperm $$(1)$$$$$$$$fspec; \
+                 fi; \
+               done; \
+       )
+       $(call Py3Package/$(1)/install,$$(1))
+  endef
+endef
+
+# $(1) => build subdir
+# $(2) => additional arguments to setup.py
+# $(3) => additional variables
+define Build/Compile/Py3Mod
+       $(INSTALL_DIR) $(PKG_INSTALL_DIR)/$(PYTHON3_PKG_DIR)
+       $(call HostPython3, \
+               cd $(PKG_BUILD_DIR)/$(strip $(1)); \
+               CC="$(TARGET_CC)" \
+               CCSHARED="$(TARGET_CC) $(FPIC)" \
+               LD="$(TARGET_CC)" \
+               LDSHARED="$(TARGET_CC) -shared" \
+               CFLAGS="$(TARGET_CFLAGS)" \
+               CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PYTHON3_INC_DIR)" \
+               LDFLAGS="$(TARGET_LDFLAGS) -lpython$(PYTHON3_VERSION)" \
+               _PYTHON_HOST_PLATFORM=linux2 \
+               __PYVENV_LAUNCHER__="/usr/bin/$(PYTHON3)" \
+               $(3) \
+               , \
+               ./setup.py $(2) \
+       )
+       find $(PKG_INSTALL_DIR) -name "*\.pyc" -o -name "*\.pyo" | xargs rm -f
+endef
+
diff --git a/lang/python3/patches/110-enable-zlib.patch b/lang/python3/patches/110-enable-zlib.patch
new file mode 100644 (file)
index 0000000..780831e
--- /dev/null
@@ -0,0 +1,25 @@
+From 6eeab87bc852481e599325549c854b701bf2e39f Mon Sep 17 00:00:00 2001
+From: Alexandru Ardelean <aa@ocedo.com>
+Date: Thu, 25 Sep 2014 18:18:29 +0300
+Subject: [PATCH] enable zlib
+
+---
+ Modules/Setup.dist | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Modules/Setup.dist b/Modules/Setup.dist
+index 01fb85f..01ac492 100644
+--- a/Modules/Setup.dist
++++ b/Modules/Setup.dist
+@@ -358,7 +358,7 @@ _symtable symtablemodule.c
+ # Andrew Kuchling's zlib module.
+ # This require zlib 1.1.3 (or later).
+ # See http://www.gzip.org/zlib/
+-#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
++zlib zlibmodule.c -lz
+ # Interface to the Expat XML parser
+ #
+-- 
+1.8.4.5
+
diff --git a/lang/python3/patches/120-do-not-add-include-dirs-when-cross-compiling.patch b/lang/python3/patches/120-do-not-add-include-dirs-when-cross-compiling.patch
new file mode 100644 (file)
index 0000000..44be1c8
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/setup.py b/setup.py
+index 93f390f..ace1494 100644
+--- a/setup.py
++++ b/setup.py
+@@ -461,7 +461,8 @@ class PyBuildExt(build_ext):
+                         add_dir_to_list(dir_list, directory)
+         if os.path.normpath(sys.base_prefix) != '/usr' \
+-                and not sysconfig.get_config_var('PYTHONFRAMEWORK'):
++                and not sysconfig.get_config_var('PYTHONFRAMEWORK') \
++                and not cross_compiling:
+             # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
+             # (PYTHONFRAMEWORK is set) to avoid # linking problems when
+             # building a framework with different architectures than
diff --git a/lang/python3/patches/130-do-not-run-distutils-tests.patch b/lang/python3/patches/130-do-not-run-distutils-tests.patch
new file mode 100644 (file)
index 0000000..0291eb1
--- /dev/null
@@ -0,0 +1,37 @@
+diff --git a/Makefile.pre.in b/Makefile.pre.in
+index f36c11d..f2b6c71 100644
+--- a/Makefile.pre.in
++++ b/Makefile.pre.in
+@@ -1217,32 +1217,6 @@ libinstall:     build_all $(srcdir)/Lib/$(PLATDIR) $(srcdir)/Modules/xxmodule.c
+               done; \
+       done
+       $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
+-      if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \
+-              $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
+-                      $(DESTDIR)$(LIBDEST)/distutils/tests ; \
+-      fi
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST) -f \
+-              -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
+-              $(DESTDIR)$(LIBDEST)
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST) -f \
+-              -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
+-              $(DESTDIR)$(LIBDEST)
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST)/site-packages -f \
+-              -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
+-              -d $(LIBDEST)/site-packages -f \
+-              -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt
+-      -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+-              $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/PatternGrammar.txt
+ # Create the PLATDIR source directory, if one wasn't distributed..
+ $(srcdir)/Lib/$(PLATDIR):
diff --git a/lang/python3/patches/140-do-not-write-bytes-codes.patch b/lang/python3/patches/140-do-not-write-bytes-codes.patch
new file mode 100644 (file)
index 0000000..f624d58
--- /dev/null
@@ -0,0 +1,22 @@
+diff --git a/Python/pythonrun.c b/Python/pythonrun.c
+index 0327830..df41cda 100644
+--- a/Python/pythonrun.c
++++ b/Python/pythonrun.c
+@@ -124,7 +124,7 @@ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
+ int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */
+ int Py_NoSiteFlag; /* Suppress 'import site' */
+ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
+-int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
++int Py_DontWriteBytecodeFlag = 1; /* Suppress writing bytecode files (*.py[co]) */
+ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
+ int Py_FrozenFlag; /* Needed by getpath.c */
+ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
+@@ -350,7 +350,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
+     if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
+         Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
+     if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')
+-        Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p);
++        Py_DontWriteBytecodeFlag = atoi(p);
+     /* The variable is only tested for existence here; _PyRandom_Init will
+        check its value further. */
+     if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
index be2a669edca245d08d640c186e14ebcd9b821912..1d419b6b73028dfbca64c12646c62f805fd97e02 100644 (file)
@@ -3,29 +3,24 @@
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
-#
-
 #
 # To Do:
-#  - split up encodings
-#  - allow selection of either native or pure version of a library where supported
-#  +-> some native libraries are probably only supported if ruby-dl is enabled
-# anything else?
-
+#  - dirs not removed when uninstalling!
+#
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ruby
-PKG_VERSION:=2.1.2
+PKG_VERSION:=2.2.0
 PKG_RELEASE:=1
 
-PKG_LIBVER:=2.1
+PKG_LIBVER:=2.2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://cache.ruby-lang.org/pub/ruby/$(PKG_LIBVER)/
-PKG_MD5SUM:=ed9b8565bdeccb401d628ec8d54a0774
+PKG_MD5SUM:=d03cd4690fec1fff81d096d1c1255fde
 PKG_MAINTAINER:=Luiz Angelo Daros de Luca <luizluca@gmail.com>
 PKG_LICENSE:=BSD-2-Clause
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DEPENDS:=ruby/host
 PKG_INSTALL:=1
@@ -45,10 +40,11 @@ define Package/ruby/Default
 endef
 
 define Package/ruby/Default/description
- Ruby is the interpreted scripting language for quick and  easy
+ Ruby is the interpreted scripting language for quick and easy
  object-oriented programming.  It has many features to process text files
  and to do system management tasks (as in perl).  It is simple,
  straight-forward, and extensible.
+
 endef
 
 define Package/ruby
@@ -70,37 +66,249 @@ $(call Package/ruby/Default)
   DEPENDS+= +libpthread +librt +libgmp
 endef
 
-# Ongoing work to break up ruby's standard library into coherent pieces
-# with minimal dependencies between them
+define Package/ruby-stdlib
+$(call Package/ruby/Default)
+  TITLE:=Ruby standard libraries (metadata for all stdlib subsets)
+  DEPENDS:=ruby +ruby-misc +ruby-bigdecimal +ruby-cgi +ruby-csv +ruby-datetime +ruby-dbm +ruby-debuglib\
+                       +ruby-digest +ruby-drb +ruby-enc +ruby-enc-extra +ruby-erb +ruby-gdbm +ruby-gems \
+                       +ruby-json +ruby-io-console +ruby-irb +ruby-fiddle +ruby-filelib +ruby-logger +ruby-math \
+                       +ruby-minitest +ruby-mkmf +ruby-multithread +ruby-nkf +ruby-net +ruby-openssl +ruby-optparse \
+                       +ruby-patterns +ruby-powerassert +ruby-prettyprint +ruby-pstore +ruby-psych +ruby-racc +ruby-rake \
+                       +ruby-rbconfig +ruby-rdoc +ruby-readline +ruby-rexml +ruby-rinda +ruby-ripper +ruby-rss +ruby-sdbm \
+                       +ruby-shell +ruby-socket +ruby-testunit +ruby-unicodenormalize +ruby-uri +ruby-webrick +ruby-xmlrpc \
+                       +ruby-yaml +ruby-zlib
+endef
+
+define Package/ruby-stdlib/description
+ This metapackage currently install all ruby-* packages,
+ providing a complete Ruby Standard Library.
+
+endef
 
-define Package/ruby-core
+define Package/ruby-bigdecimal
 $(call Package/ruby/Default)
-  TITLE:=Ruby standard libraries
-  DEPENDS:=ruby +libdb47 +libffi
+  TITLE:=Arbitrary-precision decimal floating-point lib for Ruby
+  DEPENDS:=ruby
+endef
+
+define Package/ruby-bigdecimal/description
+ Provides bigdecimal* files
 endef
 
 define Package/ruby-cgi
 $(call Package/ruby/Default)
   TITLE:=Ruby CGI support toolkit
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-filelib +ruby-pstore
 endef
 
-define Package/ruby-dl
+define Package/ruby-bigdecimal/description
+ Provides bigdecimal* files
+
+endef
+
+define Package/ruby-csv
 $(call Package/ruby/Default)
-  TITLE+= (dynamic linker support) (adds 5MB+)
+  TITLE+=CSV library
+  DEPENDS:=ruby +ruby-patterns +ruby-datetime +ruby-enc
+endef
+
+define Package/ruby-csv/description
+ Provides csv.rb file
+
+endef
+
+define Package/ruby-datetime
+$(call Package/ruby/Default)
+  TITLE+= date library
   DEPENDS:=ruby
 endef
 
+define Package/ruby-datetime/description
+ Provides date.rb and time.rb
+
+endef
+
+define Package/ruby-dbm
+$(call Package/ruby/Default)
+  TITLE:=Ruby support for dbm
+  DEPENDS:=ruby +libdb47
+endef
+
+define Package/ruby-dbm/description
+ The DBM class provides a wrapper to a Unix-style dbm or Database Manager library.
+ This package provides dbm.so file.
+
+endef
+
+define Package/ruby-debuglib
+$(call Package/ruby/Default)
+  TITLE+= debug library
+  DEPENDS:=ruby +ruby-multithread +ruby-prettyprint
+endef
+
+define Package/ruby-debuglib/description
+ Provides files for debugging:
+ - benchmark.rb
+ - debug.rb
+ - objspace.so
+ - profile.rb
+ - profiler.rb
+ - tracer.rb
+
+endef
+
+define Package/ruby-digest
+$(call Package/ruby/Default)
+  TITLE:=Ruby Digest Library
+  DEPENDS:=ruby +RUBY_DIGEST_USE_OPENSSL:libopenssl
+endef
+
+define Package/ruby-digest/description
+ Provides digest* files. Can be configured to use OpenSSL or
+ bundled hash functions.
+
+endef
+
+define Package/ruby-digest/config
+
+       config RUBY_DIGEST_USE_OPENSSL
+               bool "Use OpenSSL functions for ruby digest hash functions"
+        depends on PACKAGE_ruby-digest
+               help
+                       Ruby can use OpenSSL hash functions or compile alternative implementations. Using
+                       OpenSSL saves about 30KBytes (less when compressed) but requires OpenSSL (that
+                       is way bigger than that). However, if OpenSSL is already needed by another usage,
+                       as ruby-openssl or any other non ruby package, it is better to mark this option.
+               default n
+
+endef
+
+define Package/ruby-drb
+$(call Package/ruby/Default)
+  TITLE:=Ruby distributed object system
+  DEPENDS:=ruby +ruby-filelib +ruby-patterns +ruby-socket
+endef
+
+define Package/ruby-drb/description
+ Provides drb* files
+
+endef
+
 define Package/ruby-enc
 $(call Package/ruby/Default)
-  TITLE+= (character re-coding library) (adds 2MB+)
+  TITLE:=Ruby character re-coding library charset (small subset)
   DEPENDS:=ruby
 endef
 
+define Package/ruby-enc/description
+ Provides ruby encoding library for encodings used directly by
+ libraries in Ruby Standard Library:
+ - enc/encdb.so
+ - enc/euc_jp.so
+ - enc/iso_8859_1.so
+ - enc/utf_16be.so
+ - enc/utf_16le.so
+ - enc/utf_32be.so
+ - enc/utf_32le.so
+ FYI: ASCII-8BIT, UTF-7, UTF-8 and US-ASCII are already in Core.
+
+endef
+
+define Package/ruby-enc-extra
+$(call Package/ruby/Default)
+  TITLE:=Ruby character re-coding library charset (extra subset)
+  DEPENDS:=ruby +ruby-enc
+endef
+
+define Package/ruby-enc-extra/description
+ Provides extra encodings not provided by ruby-enc:
+ - enc/big5.so
+ - enc/cp949.so
+ - enc/emacs_mule.so
+ - enc/euc_kr.so
+ - enc/euc_tw.so
+ - enc/gb18030.so
+ - enc/gb2312.so
+ - enc/gbk.so
+ - enc/iso_8859_10.so
+ - enc/iso_8859_11.so
+ - enc/iso_8859_13.so
+ - enc/iso_8859_14.so
+ - enc/iso_8859_15.so
+ - enc/iso_8859_16.so
+ - enc/iso_8859_2.so
+ - enc/iso_8859_3.so
+ - enc/iso_8859_4.so
+ - enc/iso_8859_5.so
+ - enc/iso_8859_6.so
+ - enc/iso_8859_7.so
+ - enc/iso_8859_8.so
+ - enc/iso_8859_9.so
+ - enc/koi8_r.so
+ - enc/koi8_u.so
+ - enc/shift_jis.so
+ - enc/trans/big5.so
+ - enc/trans/chinese.so
+ - enc/trans/emoji.so
+ - enc/trans/emoji_iso2022_kddi.so
+ - enc/trans/emoji_sjis_docomo.so
+ - enc/trans/emoji_sjis_kddi.so
+ - enc/trans/emoji_sjis_softbank.so
+ - enc/trans/escape.so
+ - enc/trans/gb18030.so
+ - enc/trans/gbk.so
+ - enc/trans/iso2022.so
+ - enc/trans/japanese.so
+ - enc/trans/japanese_euc.so
+ - enc/trans/japanese_sjis.so
+ - enc/trans/korean.so
+ - enc/trans/single_byte.so
+ - enc/trans/transdb.so
+ - enc/trans/utf8_mac.so
+ - enc/trans/utf_16_32.so
+ - enc/windows_1251.so
+ - enc/windows_31j.so
+
+endef
+
 define Package/ruby-erb
 $(call Package/ruby/Default)
   TITLE+= (embedded interpreter)
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-cgi
+endef
+
+define Package/ruby-erb/description
+ Provides erb* files
+
+endef
+
+define Package/ruby-fiddle
+$(call Package/ruby/Default)
+  TITLE:=A libffi wrapper for Ruby
+  DEPENDS:=ruby +libffi
+endef
+
+define Package/ruby-fiddle/description
+ Provides fiddle* files
+
+endef
+
+define Package/ruby-filelib
+$(call Package/ruby/Default)
+  TITLE+= File utils library
+  DEPENDS:=ruby +ruby-enc +ruby-misc
+endef
+
+define Package/ruby-filelib/description
+ Provides filesystem interaction files, including
+ path and temp:
+ - fileutils.rb
+ - find.rb
+ - pathname.rb
+ - pathname.so
+ - tempfile.rb
+ - tmpdir.rb
+
 endef
 
 define Package/ruby-gdbm
@@ -109,94 +317,474 @@ $(call Package/ruby/Default)
   DEPENDS:=ruby +libgdbm
 endef
 
+define Package/ruby-gdbm/description
+ Provides gdbm* files
+
+endef
+
 define Package/ruby-gems
 $(call Package/ruby/Default)
   TITLE:=Ruby gems packet management
-  DEPENDS:=ruby +ruby-yaml +ruby-zlib +ruby-openssl +ruby-webrick +ruby-erb
+  DEPENDS:=ruby +ruby-net +ruby-rdoc
+endef
+
+define Package/ruby-gems/description
+ Provides rubygems for gems usage, download and installation
+
+endef
+
+define Package/ruby-io-console
+$(call Package/ruby/Default)
+  TITLE+= Console interface
+  DEPENDS:=ruby
+endef
+
+define Package/ruby-io-console/description
+ Provides io-console* files
+
 endef
 
 define Package/ruby-irb
 $(call Package/ruby/Default)
   TITLE+= (interactive shell)
-  DEPENDS:=ruby +ruby-core
+  DEPENDS:=ruby +ruby-debuglib +ruby-filelib +ruby-math
+endef
+
+define Package/ruby-irb/description
+ Provides irb* files
+
 endef
 
 define Package/ruby-json
 $(call Package/ruby/Default)
   TITLE:=Ruby support for JSON
+  DEPENDS:=ruby +ruby-datetime +ruby-misc
+endef
+
+define Package/ruby-json/description
+ Provides json* files
+
+endef
+
+define Package/ruby-logger
+$(call Package/ruby/Default)
+  TITLE+= logger and syslog library
+  DEPENDS:=ruby +ruby-multithread
+endef
+
+define Package/ruby-logger/description
+ Provides log library, including syslog:
+ - logger.rb
+ - syslog.so
+ - syslog/logger.rb
+
+endef
+
+define Package/ruby-math
+$(call Package/ruby/Default)
+  TITLE+= math library
+  DEPENDS:=ruby +ruby-patterns
+endef
+
+define Package/ruby-math/description
+ Provides math related files:
+ - cmath.rb
+ - complex.rb
+ - mathn.rb
+ - mathn/complex.so
+ - mathn/rational.so
+ - matrix.rb
+ - matrix/eigenvalue_decomposition.rb
+ - matrix/lup_decomposition.rb
+ - prime.rb
+ - rational.rb
+
+endef
+
+define Package/ruby-minitest
+$(call Package/ruby/Default)
+  TITLE:=Gem minitest shipped with Ruby
+  DEPENDS:=ruby +ruby-gems
+endef
+
+define Package/ruby-minitest/description
+ Provides minitest gem
+
+endef
+
+define Package/ruby-misc
+$(call Package/ruby/Default)
+  TITLE:=Ruby standard libraries subset (miscelaneous files)
   DEPENDS:=ruby
 endef
 
-define Package/ruby-ncurses
+define Package/ruby-misc/description
+ This package contains miscellaneous files from stdlib
+ not splitted in other ruby packages like stringio:
+ - English.rb
+ - abbrev.rb
+ - base64.rb
+ - continuation.so
+ - coverage.so
+ - delegate.rb
+ - e2mmap.rb
+ - etc.so
+ - expect.rb
+ - fcntl.so
+ - fiber.so
+ - getoptlong.rb
+ - open3.rb
+ - ostruct.rb
+ - pty.so
+ - scanf.rb
+ - securerandom.rb
+ - set.rb
+ - shellwords.rb
+ - stringio.so
+ - strscan.so
+ - tsort.rb
+ - weakref.rb
+
+endef
+
+define Package/ruby-mkmf
+$(call Package/ruby/Default)
+  TITLE+= makefile library
+  DEPENDS:=ruby +ruby-filelib +ruby-optparse +ruby-rbconfig
+endef
+
+define Package/ruby-mkmf/description
+ Provides mkmf* files
+
+endef
+
+define Package/ruby-multithread
+$(call Package/ruby/Default)
+  TITLE+= multithread library
+  DEPENDS:=ruby +ruby-misc
+endef
+
+define Package/ruby-multithread/description
+ Provides files for multithread usage:
+ - io/nonblock.so
+ - io/wait.so
+ - thread.so (FYI, Thread is a core class)
+ - monitor.rb
+ - mutex_m.rb
+ - sync.rb
+ - thwait.rb
+ - timeout.rb
+
+endef
+
+define Package/ruby-net
 $(call Package/ruby/Default)
-  TITLE:=Ruby support for ncurses
-  DEPENDS:=ruby +libncurses +libncursesw
+  TITLE:=Ruby Network Protocols Library
+  DEPENDS:=ruby +ruby-datetime +ruby-digest +ruby-filelib +ruby-uri
+endef
+
+define Package/ruby-net/description
+ Provides net* files
+
 endef
 
 define Package/ruby-nkf
 $(call Package/ruby/Default)
   TITLE:=Ruby Network Kanji Filter
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-enc
+endef
+
+define Package/ruby-nkf/description
+ Provides nkf* files
+
 endef
 
 define Package/ruby-openssl
 $(call Package/ruby/Default)
   TITLE:=Ruby support for openssl
-  DEPENDS:=ruby +libopenssl
+  DEPENDS:=ruby +ruby-enc +libopenssl +ruby-misc
 endef
 
-define Package/ruby-rdoc
+define Package/ruby-openssl/description
+ Provides openssl* files
+
+endef
+
+define Package/ruby-optparse
 $(call Package/ruby/Default)
-  TITLE+= (documentation generator)
+  TITLE:=Ruby command-line option analysis
+  DEPENDS:=ruby +ruby-misc
+endef
+
+define Package/ruby-optparse/description
+ Provides optparse* files
+
+endef
+
+define Package/ruby-patterns
+$(call Package/ruby/Default)
+  TITLE:=Ruby design patterns implementation
+  DEPENDS:=ruby +ruby-multithread
+endef
+
+define Package/ruby-patterns/description
+ Provides design patterns helpers files:
+ - forwardable.rb
+ - observer.rb
+ - singleton.rb
+
+endef
+
+define Package/ruby-powerassert
+$(call Package/ruby/Default)
+  TITLE:=Gem power_assert shipped with Ruby
+  DEPENDS:=ruby +ruby-ripper
+endef
+
+define Package/ruby-powerassert/description
+  Power Assert gem for Ruby. Power Assert shows each value of variables
+  and method calls in the expression. It is useful for testing, providing
+  which value wasn't correct when the condition is not satisfied
+
+endef
+
+define Package/ruby-prettyprint
+$(call Package/ruby/Default)
+  TITLE:=Ruby PrettyPrint librart
+  DEPENDS:=ruby +ruby-misc
+endef
+
+define Package/ruby-prettyprint/description
+ Provides Pretty Print library:
+ - pp.rb
+ - prettyprint.rb
+
+endef
+
+define Package/ruby-pstore
+$(call Package/ruby/Default)
+  TITLE+=file based persistence
+  DEPENDS:=ruby +ruby-digest +ruby-enc
+endef
+
+define Package/ruby-pstore/description
+ Provides pstore.rb file
+
+endef
+
+define Package/ruby-psych
+$(call Package/ruby/Default)
+  TITLE+=YAML parser and emitter
+  DEPENDS:=ruby +ruby-bigdecimal +ruby-datetime +ruby-misc +ruby-enc
+endef
+
+define Package/ruby-psych/description
+ Provides psych* files
+
+endef
+
+define Package/ruby-racc
+$(call Package/ruby/Default)
+  TITLE:=LALR parser generator in Ruby
   DEPENDS:=ruby
 endef
 
+define Package/ruby-racc/description
+ Provides racc* files
+
+endef
+
 define Package/ruby-rake
 $(call Package/ruby/Default)
   TITLE+=Ruby Rake (make replacement)
+  DEPENDS:=ruby +ruby-datetime +ruby-filelib +ruby-optparse +ruby-patterns +ruby-rbconfig
+endef
+
+define Package/ruby-rake/description
+ Provides rake* files
+
+endef
+
+define Package/ruby-rbconfig
+$(call Package/ruby/Default)
+  TITLE+=Ruby RbConfig
   DEPENDS:=ruby
 endef
 
+define Package/ruby-rbconfig/description
+ Provides rbconfig file
+
+endef
+
+define Package/ruby-rdoc
+$(call Package/ruby/Default)
+  TITLE+= (documentation generator)
+  DEPENDS:=ruby +ruby-erb +ruby-irb +ruby-json +ruby-racc +ruby-rake +ruby-yaml +ruby-zlib
+endef
+
+define Package/ruby-rdoc/description
+ Provides rdoc* and ri files
+
+endef
+
 define Package/ruby-readline
 $(call Package/ruby/Default)
   TITLE:=Ruby support for readline
   DEPENDS:=ruby +libncurses +libreadline
 endef
 
+define Package/ruby-readline/description
+ Provides readline* files
+
+endef
+
 define Package/ruby-rexml
 $(call Package/ruby/Default)
   TITLE:=Ruby XML toolkit
+  DEPENDS:=ruby +ruby-patterns +ruby-enc
+endef
+
+define Package/ruby-rexml/description
+ Provides rexml* files
+
+endef
+
+define Package/ruby-rinda
+$(call Package/ruby/Default)
+  TITLE:=Ruby Linda paradigm implementation
+  DEPENDS:=ruby +ruby-drb
+endef
+
+define Package/ruby-rinda/description
+ Provides rinda* files
+
+endef
+
+define Package/ruby-ripper
+$(call Package/ruby/Default)
+  TITLE:=Ruby script parser
   DEPENDS:=ruby
 endef
 
+define Package/ruby-ripper/description
+ Provides ripper* files
+
+endef
+
 define Package/ruby-rss
 $(call Package/ruby/Default)
   TITLE:=Ruby RSS toolkit
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-net +ruby-nkf +ruby-rexml
 endef
 
-define Package/ruby-unit
+define Package/ruby-rss/description
+ Provides rss* files
+
+endef
+
+define Package/ruby-sdbm
 $(call Package/ruby/Default)
-  TITLE:=Ruby unit testing toolkit
+  TITLE:=Ruby simple file-based key-value dbm implementation
   DEPENDS:=ruby
 endef
 
+define Package/ruby-sdbm/description
+ Provides sdbm* files
+
+endef
+
+define Package/ruby-shell
+$(call Package/ruby/Default)
+  TITLE:=Ruby idiomatic Ruby interface
+  DEPENDS:=ruby +ruby-patterns
+endef
+
+define Package/ruby-shell/description
+ Provides shell* files
+
+endef
+
+define Package/ruby-socket
+$(call Package/ruby/Default)
+  TITLE+= socket support
+  DEPENDS:=ruby +ruby-multithread
+endef
+
+define Package/ruby-socket/description
+ Provides socket-related files:
+ - gserver.rb
+ - ipaddr.rb
+ - resolv-replace.rb
+ - resolv.rb
+ - socket.rb
+ - socket.so
+
+endef
+
+define Package/ruby-testunit
+$(call Package/ruby/Default)
+  TITLE:=Gem test-unit shipped with Ruby
+  DEPENDS:=ruby +ruby-csv +ruby-erb +ruby-optparse +ruby-powerassert +ruby-prettyprint +ruby-rexml +ruby-yaml
+endef
+
+define Package/ruby-testunit/description
+ Provides test/unit* files
+
+endef
+
+define Package/ruby-unicodenormalize
+$(call Package/ruby/Default)
+  TITLE:=Ruby String additions for Unicode normalization
+  DEPENDS:=ruby +ruby-enc +ruby-enc-extra
+endef
+
+define Package/ruby-unicodenormalize/description
+  Additions to class String for Unicode normalization
+
+endef
+
+define Package/ruby-uri
+$(call Package/ruby/Default)
+  TITLE:=Ruby library to handle URI
+  DEPENDS:=ruby +ruby-socket +ruby-enc
+endef
+
+define Package/ruby-uri/description
+ Provides uri* files
+
+endef
+
 define Package/ruby-webrick
 $(call Package/ruby/Default)
   TITLE:=Ruby Web server toolkit
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-erb +ruby-net +ruby-patterns +ruby-rbconfig
+endef
+
+define Package/ruby-webrick/description
+ Provides webrick* files
+
 endef
 
 define Package/ruby-xmlrpc
 $(call Package/ruby/Default)
   TITLE:=Ruby XML-RPC toolkit
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-rexml +ruby-webrick
+endef
+
+define Package/ruby-xmlrpc/description
+ Provides xmlrpc* files
+
 endef
 
 define Package/ruby-yaml
 $(call Package/ruby/Default)
   TITLE:=Ruby YAML toolkit
-  DEPENDS:=ruby
+  DEPENDS:=ruby +ruby-dbm +ruby-pstore +ruby-psych
+endef
+
+define Package/ruby-yaml/description
+ Provides yaml* files
+
 endef
 
 define Package/ruby-zlib
@@ -205,6 +793,11 @@ $(call Package/ruby/Default)
   DEPENDS:=ruby +zlib
 endef
 
+define Package/ruby-zlib/description
+ Provides zlib* files
+
+endef
+
 HOST_CONFIGURE_ARGS += \
        --disable-install-doc \
        --disable-install-rdoc \
@@ -216,9 +809,20 @@ CONFIGURE_ARGS += \
        --enable-static \
        --disable-rpath \
        --enable-ipv6 \
+       --disable-install-doc \
+       --disable-install-capi \
        --with-ruby-version=minor \
        --with-iconv-dir=$(ICONV_PREFIX) \
 
+ifndef CONFIG_RUBY_DIGEST_USE_OPENSSL
+CONFIGURE_ARGS += \
+       --with-bundled-sha1\
+       --with-bundled-md5\
+       --with-bundled-rmd160\
+       --with-bundled-sha2 \
+
+endif
+
 TARGET_LDFLAGS += -L$(PKG_BUILD_DIR)
 
 MAKE_FLAGS += \
@@ -227,7 +831,15 @@ MAKE_FLAGS += \
 
 define Package/ruby/install
        $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ruby $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/vendor_ruby/$(PKG_LIBVER)
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/site_ruby/$(PKG_LIBVER)
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ruby $(1)/usr/lib/ruby/ruby$(PKG_LIBVER)-bin
+       $(INSTALL_BIN) ./files/ruby $(1)/usr/bin/ruby
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/vendor_ruby/$(PKG_LIBVER)/* $(1)/usr/lib/ruby/vendor_ruby/$(PKG_LIBVER)/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/site_ruby/$(PKG_LIBVER)/* $(1)/usr/lib/ruby/site_ruby/$(PKG_LIBVER)/
+       sed -i -e "s%@RUBY_LIBPATH@%/usr/lib/ruby/$(PKG_LIBVER)%" $(1)/usr/bin/ruby
+       sed -i -e "s%@RUBY_BINPATH@%/usr/lib/ruby/ruby$(PKG_LIBVER)-bin%" $(1)/usr/bin/ruby
 endef
 
 define Package/libruby/install
@@ -235,75 +847,16 @@ define Package/libruby/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libruby.so.* $(1)/usr/lib/
 endef
 
-define Package/ruby-core/install
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby $(1)/usr/lib/
-       rm -rf  \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/curses.so \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/gdbm.so \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/kconv.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/nkf.so \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/digest \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/digest.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/digest \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/digest.so \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/openssl \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/openssl.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/openssl.so \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/drb/ssl.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/net/https.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/webrick/ssl.rb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/dl.so \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/enc \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/readline.so \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/irb/completion.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/irb/ext/save-history.rb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/zlib.so \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/erb.rb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/json.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/json \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/json \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/irb.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/irb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rdoc \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rake.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rake \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rubygems.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rubygems \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/cgi.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/cgi \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rexml \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rss \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/rss.rb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/test \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/webrick \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/webrick.rb \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/xmlrpc \
-               \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/yaml \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/yaml.rb \
-               $(1)/usr/lib/ruby/$(PKG_LIBVER)/*/syck.so \
-
-       find $(1) -name '*.h' | xargs rm -f
+define Package/ruby-stdlib/install
+       # nothing to do
+endef
+
+define Package/ruby-bigdecimal/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/bigdecimal.so \
+               usr/lib/ruby/$(PKG_LIBVER)/bigdecimal/ \
+               usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/bigdecimal-*.gemspec \
+       ) | ( cd $(1); $(TAR) -xf - )
 endef
 
 define Package/ruby-cgi/install
@@ -312,14 +865,69 @@ define Package/ruby-cgi/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/cgi.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
 endef
 
-define Package/ruby-dl/install
+define Package/ruby-csv/install
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/csv.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+endef
+
+define Package/ruby-datetime/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/time.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/date.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/date/ \
+               usr/lib/ruby/$(PKG_LIBVER)/*/date_core.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-dbm/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/dbm.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-debuglib/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/profile.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/profiler.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/debug.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/tracer.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/benchmark.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/objspace.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-digest/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/digest \
+               usr/lib/ruby/$(PKG_LIBVER)/digest.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/digest.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/digest/* \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-drb/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
-               usr/lib/ruby/$(PKG_LIBVER)/*/dl.so \
+               usr/lib/ruby/$(PKG_LIBVER)/drb.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/drb \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
 
 define Package/ruby-enc/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/enc/encdb.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/enc/iso_8859_1.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/enc/utf_* \
+               usr/lib/ruby/$(PKG_LIBVER)/*/enc/euc_jp.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-enc-extra/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) \
+               --exclude=usr/lib/ruby/$(PKG_LIBVER)/*/enc/encdb.so \
+               --exclude=usr/lib/ruby/$(PKG_LIBVER)/*/enc/iso_8859_1.so \
+               --exclude=usr/lib/ruby/$(PKG_LIBVER)/*/enc/utf_* \
+               --exclude=usr/lib/ruby/$(PKG_LIBVER)/*/enc/euc_jp.so \
+               -cf - \
                usr/lib/ruby/$(PKG_LIBVER)/*/enc \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
@@ -331,6 +939,25 @@ define Package/ruby-erb/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/erb.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
 endef
 
+define Package/ruby-fiddle/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/fiddle.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/fiddle/ \
+               usr/lib/ruby/$(PKG_LIBVER)/*/fiddle.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-filelib/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/tmpdir.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/tempfile.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/pathname.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/pathname.so \
+               usr/lib/ruby/$(PKG_LIBVER)/find.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/fileutils.rb \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
 define Package/ruby-gdbm/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
                usr/lib/ruby/$(PKG_LIBVER)/*/gdbm.so \
@@ -341,8 +968,27 @@ define Package/ruby-gems/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/gem $(1)/usr/bin/
        $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/ubygems.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rubygems.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       # Remove tests (avoids extra deps)
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rubygems/test_case.rb
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rubygems/package/tar_test_case.rb
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rubygems/installer_test_case.rb
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rubygems $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/doc
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/cache
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/extensions
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/build_info
+endef
+
+define Package/ruby-io-console/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/io/console.so \
+               usr/lib/ruby/$(PKG_LIBVER)/io/console/ \
+               usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/io-console-*.gemspec \
+       ) | ( cd $(1); $(TAR) -xf - )
 endef
 
 define Package/ruby-irb/install
@@ -358,12 +1004,95 @@ define Package/ruby-json/install
                usr/lib/ruby/$(PKG_LIBVER)/json.rb \
                usr/lib/ruby/$(PKG_LIBVER)/json \
                usr/lib/ruby/$(PKG_LIBVER)/*/json \
+               usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/json-*.gemspec \
+       ) | ( cd $(1); $(TAR) -xf - )
+       rm -rf \
+               $(1)/usr/lib/ruby/$(PKG_LIBVER)/psych/json
+endef
+
+define Package/ruby-logger/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/logger.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/syslog/logger.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/syslog.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-math/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/prime.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/mathn.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/cmath.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/mathn \
+               usr/lib/ruby/$(PKG_LIBVER)/matrix.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/matrix \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-minitest/install
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/minitest-*.gemspec $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/
+       # Remove tests (avoids extra deps)
+       $(RM) -rf $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/minitest-*/test
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/minitest-* $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/
+endef
+
+define Package/ruby-misc/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/English.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/abbrev.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/base64.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/delegate.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/e2mmap.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/expect.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/getoptlong.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/open3.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/ostruct.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/scanf.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/securerandom.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/set.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/shellwords.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/tsort.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/weakref.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/continuation.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/coverage.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/etc.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/fcntl.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/fiber.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/pty.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/stringio.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/strscan.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+
+
+define Package/ruby-mkmf/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/mkmf.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/un.rb \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
 
-define Package/ruby-ncurses/install
+define Package/ruby-multithread/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
-               usr/lib/ruby/$(PKG_LIBVER)/*/curses.so \
+               usr/lib/ruby/$(PKG_LIBVER)/monitor.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/timeout.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/thwait.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/mutex_m.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/sync.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/thread.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/io/wait.so \
+               usr/lib/ruby/$(PKG_LIBVER)/*/io/nonblock.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-net/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/open-uri.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/net/* \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
 
@@ -376,24 +1105,63 @@ endef
 
 define Package/ruby-openssl/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
-               usr/lib/ruby/$(PKG_LIBVER)/digest \
-               usr/lib/ruby/$(PKG_LIBVER)/digest.rb \
-               usr/lib/ruby/$(PKG_LIBVER)/*/digest.so \
-               usr/lib/ruby/$(PKG_LIBVER)/*/digest/*.so \
                usr/lib/ruby/$(PKG_LIBVER)/openssl \
                usr/lib/ruby/$(PKG_LIBVER)/openssl.rb \
                usr/lib/ruby/$(PKG_LIBVER)/*/openssl.so \
-               usr/lib/ruby/$(PKG_LIBVER)/drb/ssl.rb \
-               usr/lib/ruby/$(PKG_LIBVER)/net/https.rb \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
 
-define Package/ruby-rdoc/install
-       $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rdoc $(1)/usr/bin/
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ri $(1)/usr/bin/
+define Package/ruby-optparse/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/optparse.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/optionparser.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/optparse \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-patterns/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/observer.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/singleton.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/forwardable.rb \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-powerassert/install
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/power_assert-*.gemspec $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/
+       # Remove tests (avoids extra deps)
+       $(RM) -rf $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/power_assert-*/test
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/power_assert-* $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/
+endef
+
+define Package/ruby-prettyprint/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/pp.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/prettyprint.rb \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-pstore/install
        $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/pstore.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+endef
+
+define Package/ruby-psych/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/psych \
+               usr/lib/ruby/$(PKG_LIBVER)/psych.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/psych.so \
+               usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/psych-*.gemspec \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-racc/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/racc \
+               usr/lib/ruby/$(PKG_LIBVER)/*/racc/*.so \
+       ) | ( cd $(1); $(TAR) -xf - )
 endef
 
 define Package/ruby-rake/install
@@ -401,7 +1169,41 @@ define Package/ruby-rake/install
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rake $(1)/usr/bin/
        $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rake.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       # Remove tests (avoids extra deps)
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rake/runtest.rb
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rake $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/rake-*.gemspec \
+               $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/rake-* $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/
+endef
+
+define Package/ruby-rbconfig/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/rbconfig.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/rbconfig/* \
+               usr/lib/ruby/$(PKG_LIBVER)/*/rbconfig/*.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-rdoc/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rdoc $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ri $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
+       # Remove tests (avoids extra deps)
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc/test_case.rb
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc/markup/formatter_test_case.rb
+       $(RM) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc/markup/text_formatter_test_case.rb
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rdoc $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/rdoc-*.gemspec \
+               $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/default/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/rdoc-* \
+               $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/
 endef
 
 define Package/ruby-readline/install
@@ -415,6 +1217,19 @@ define Package/ruby-rexml/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rexml $(1)/usr/lib/ruby/$(PKG_LIBVER)/
 endef
 
+define Package/ruby-rinda/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/rinda \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-ripper/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/ripper.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/ripper \
+               usr/lib/ruby/$(PKG_LIBVER)/*/ripper.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
 
 define Package/ruby-rss/install
        $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
@@ -422,11 +1237,52 @@ define Package/ruby-rss/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/rss.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
 endef
 
-define Package/ruby-unit/install
-       $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/testrb $(1)/usr/bin/
-       $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/test $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+define Package/ruby-sdbm/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/*/sdbm.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-shell/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/shell.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/shell \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-socket/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/gserver.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/ipaddr.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/resolv-replace.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/resolv.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/socket.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/*/socket.so \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-testunit/install
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications
+       $(INSTALL_DIR) $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/test-unit-*.gemspec $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/specifications/
+       # Remove tests (avoids extra deps)
+       $(RM) -rf $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/test-unit-*/test
+       $(RM) -rf $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/test-unit-*/sample
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/test-unit-* $(1)/usr/lib/ruby/gems/$(PKG_LIBVER)/gems/
+endef
+
+define Package/ruby-unicodenormalize/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/unicode_normalize.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/unicode_normalize \
+       ) | ( cd $(1); $(TAR) -xf - )
+endef
+
+define Package/ruby-uri/install
+       ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
+               usr/lib/ruby/$(PKG_LIBVER)/uri.rb \
+               usr/lib/ruby/$(PKG_LIBVER)/uri \
+       ) | ( cd $(1); $(TAR) -xf - )
 endef
 
 define Package/ruby-webrick/install
@@ -438,13 +1294,13 @@ endef
 define Package/ruby-xmlrpc/install
        $(INSTALL_DIR) $(1)/usr/lib/ruby/$(PKG_LIBVER)
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/xmlrpc $(1)/usr/lib/ruby/$(PKG_LIBVER)/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/ruby/$(PKG_LIBVER)/xmlrpc.rb $(1)/usr/lib/ruby/$(PKG_LIBVER)/
 endef
 
 define Package/ruby-yaml/install
        ( cd $(PKG_INSTALL_DIR); $(TAR) -cf - \
                usr/lib/ruby/$(PKG_LIBVER)/yaml \
                usr/lib/ruby/$(PKG_LIBVER)/yaml.rb \
-               usr/lib/ruby/$(PKG_LIBVER)/*/syck.so \
        ) | ( cd $(1); $(TAR) -xf - )
 endef
 
@@ -462,24 +1318,55 @@ endef
 
 $(eval $(call BuildPackage,ruby))
 $(eval $(call BuildPackage,libruby))
-$(eval $(call BuildPackage,ruby-core))
+$(eval $(call BuildPackage,ruby-stdlib))
+$(eval $(call BuildPackage,ruby-bigdecimal))
 $(eval $(call BuildPackage,ruby-cgi))
-$(eval $(call BuildPackage,ruby-dl))
+$(eval $(call BuildPackage,ruby-csv))
+$(eval $(call BuildPackage,ruby-datetime))
+$(eval $(call BuildPackage,ruby-dbm))
+$(eval $(call BuildPackage,ruby-debuglib))
+$(eval $(call BuildPackage,ruby-digest))
+$(eval $(call BuildPackage,ruby-drb))
 $(eval $(call BuildPackage,ruby-enc))
+$(eval $(call BuildPackage,ruby-enc-extra))
 $(eval $(call BuildPackage,ruby-erb))
+$(eval $(call BuildPackage,ruby-fiddle))
+$(eval $(call BuildPackage,ruby-filelib))
 $(eval $(call BuildPackage,ruby-gdbm))
 $(eval $(call BuildPackage,ruby-gems))
-$(eval $(call BuildPackage,ruby-json))
+$(eval $(call BuildPackage,ruby-io-console))
 $(eval $(call BuildPackage,ruby-irb))
-$(eval $(call BuildPackage,ruby-ncurses))
+$(eval $(call BuildPackage,ruby-json))
+$(eval $(call BuildPackage,ruby-logger))
+$(eval $(call BuildPackage,ruby-math))
+$(eval $(call BuildPackage,ruby-minitest))
+$(eval $(call BuildPackage,ruby-misc))
+$(eval $(call BuildPackage,ruby-mkmf))
+$(eval $(call BuildPackage,ruby-multithread))
+$(eval $(call BuildPackage,ruby-net))
 $(eval $(call BuildPackage,ruby-nkf))
 $(eval $(call BuildPackage,ruby-openssl))
+$(eval $(call BuildPackage,ruby-optparse))
+$(eval $(call BuildPackage,ruby-patterns))
+$(eval $(call BuildPackage,ruby-powerassert))
+$(eval $(call BuildPackage,ruby-prettyprint))
+$(eval $(call BuildPackage,ruby-pstore))
+$(eval $(call BuildPackage,ruby-psych))
+$(eval $(call BuildPackage,ruby-racc))
 $(eval $(call BuildPackage,ruby-rake))
+$(eval $(call BuildPackage,ruby-rbconfig))
 $(eval $(call BuildPackage,ruby-rdoc))
 $(eval $(call BuildPackage,ruby-readline))
 $(eval $(call BuildPackage,ruby-rexml))
+$(eval $(call BuildPackage,ruby-rinda))
+$(eval $(call BuildPackage,ruby-ripper))
 $(eval $(call BuildPackage,ruby-rss))
-$(eval $(call BuildPackage,ruby-unit))
+$(eval $(call BuildPackage,ruby-sdbm))
+$(eval $(call BuildPackage,ruby-shell))
+$(eval $(call BuildPackage,ruby-socket))
+$(eval $(call BuildPackage,ruby-testunit))
+$(eval $(call BuildPackage,ruby-unicodenormalize))
+$(eval $(call BuildPackage,ruby-uri))
 $(eval $(call BuildPackage,ruby-webrick))
 $(eval $(call BuildPackage,ruby-xmlrpc))
 $(eval $(call BuildPackage,ruby-yaml))
diff --git a/lang/ruby/files/ruby b/lang/ruby/files/ruby
new file mode 100644 (file)
index 0000000..e4904fc
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+if ! [ -r "@RUBY_LIBPATH@/rubygems.rb" ]; then
+       exec @RUBY_BINPATH@ --disable-gems "$@"
+fi
+exec @RUBY_BINPATH@ "$@"
diff --git a/lang/ruby/patches/001-rdoc-remove_gems_dep.patch b/lang/ruby/patches/001-rdoc-remove_gems_dep.patch
new file mode 100644 (file)
index 0000000..9630de5
--- /dev/null
@@ -0,0 +1,36 @@
+References:
+
+https://github.com/rdoc/rdoc/pull/340
+
+--- ruby-2.1.2.orig/lib/rdoc.rb        2014-09-02 17:14:28.719224215 -0300
++++ ruby-2.1.2/lib/rdoc.rb     2014-09-02 17:14:28.762223911 -0300
+@@ -109,6 +109,8 @@
+   def self.load_yaml
+     begin
+       gem 'psych'
++    rescue NameError => e # --disable-gems
++       raise unless e.name == :gem
+     rescue Gem::LoadError
+     end
+--- ruby-2.1.2.orig/lib/rdoc/markdown.rb       2014-09-02 17:14:28.761223918 -0300
++++ ruby-2.1.2/lib/rdoc/markdown.rb    2014-09-02 17:14:28.805223607 -0300
+@@ -525,7 +525,6 @@
+-  require 'rubygems'
+   require 'rdoc'
+   require 'rdoc/markup/to_joined_paragraph'
+   require 'rdoc/markdown/entities'
+--- ruby-2.1.2.orig/lib/rdoc/text.rb   2014-09-02 17:14:28.721224201 -0300
++++ ruby-2.1.2/lib/rdoc/text.rb        2014-09-02 17:14:28.764223897 -0300
+@@ -10,6 +10,8 @@
+ begin
+   gem 'json'
++rescue NameError => e # --disable-gems
++  raise unless e.name == :gem
+ rescue Gem::LoadError
+ end
diff --git a/lang/ruby/ruby_find_pkgsdeps b/lang/ruby/ruby_find_pkgsdeps
new file mode 100644 (file)
index 0000000..946ec1f
--- /dev/null
@@ -0,0 +1,270 @@
+#!/usr/bin/ruby -Eutf-8
+# encoding: utf-8
+#
+# Find dependencies between ruby packages
+#
+# Must run inside a openwrt with all *ruby* packages installed
+#
+
+failed = false
+
+puts "Looking for installed ruby packages..."
+packages=`opkg list-installed '*ruby*' | cut -d' ' -f 1`.split("\n")
+
+puts "Looking for packages files..."
+package_files=Hash.new([])
+packages.each do
+       |pkg|
+       files=`opkg files "#{pkg}" | sed -e 1d`.split("\n")
+       package_files[pkg]=files if files
+end
+
+require_regex=/^require ["']([^"']+)["'].*/
+require_regex_ignore=/^require ([a-zA-Z\$]|["']$|.*\/$)/
+require_ignore=%w{drb/invokemethod16 foo rubygems/defaults/operating_system win32console java Win32API
+                  builder/xchar json/pure simplecov win32/sspi rdoc/markdown/literals_1_8 enumerator win32/resolv rbtree
+                  nqxml/streamingparser nqxml/treeparser xmlscan/parser xmlscan/scanner xmltreebuilder xml/parser xmlparser xml/encoding-ja xmlencoding-ja
+                  iconv uconv win32ole gettext/po_parser gettext/mo libxml}
+
+builtin_enc=[
+       Encoding.find("ASCII-8BIT"),
+       Encoding.find("UTF-8"),
+       Encoding.find("UTF-7"),
+       Encoding.find("US-ASCII"),
+]
+
+puts "Looking for requires in files..."
+files_requires=Hash.new([])
+packages.each do
+        |pkg|
+       package_files[pkg].each do
+               |file|
+               next if not File.file?(file)
+
+               if not file =~ /.rb$/
+                       if File.executable?(file)
+                               magic=`head -c50 '#{file}' | head -1`
+                               begin
+                                       if not magic =~ /ruby/
+                                               next
+                                       end
+                               rescue
+                                       next
+                               end
+                       else
+                               next
+                       end
+               end
+               #puts "Checking #{file}..."
+               File.open(file, "r") do
+                       |f|
+                       lineno=0
+                       while line=f.gets() do
+                               lineno+=1; encs=[]; requires=[]; need_encdb=false
+
+                               line=line.chomp.gsub!(/^[[:blank:]]*/,"")
+
+                               case line
+                               when /^#.*coding *:/
+                                       if lineno <= 2
+                                               enc=line.sub(/.*coding *: */,"").sub(/ .*/,"")
+                                               encs << Encoding.find(enc)
+                                       end
+                               end
+                               line.gsub!(/#.*/,"")
+                               case line
+                               when "__END__"
+                                       break
+                               when /^require /
+                                       #puts "#{file}:#{line}"
+                                       if require_regex_ignore =~ line
+                                               #puts "Ignoring #{line} at #{file}:#{lineno} (REGEX)..."
+                                               next
+                                       end
+                                       if not require_regex =~ line
+                                               $stderr.puts "Unknown require: '#{line}' at file #{file}:#{lineno}"
+                                               failed=true
+                                       end
+                                       require=line.gsub(require_regex,"\\1")
+                                       require.gsub!(/\.(so|rb)$/,"")
+
+                                       if require_ignore.include?(require)
+                                               #puts "Ignoring #{line} at #{file}:#{lineno} (STR)..."
+                                               next
+                                       end
+
+                                       files_requires[file]=files_requires[file] + [require]
+
+                               when /Encoding::/
+                                       encs=line.scan(/Encoding::[[:alnum:]_]+/).collect {|enc| eval(enc) }.select {|enc| enc.kind_of? Encoding }
+                                       need_encdb=true
+                               end
+
+                               next if encs.empty?
+                               required_encs = (encs - builtin_enc).collect {|enc| "enc/#{enc.name.downcase.gsub("-","_")}" }
+                               required_encs << "enc/encdb" if need_encdb
+
+                               files_requires[file] = files_requires[file] + required_encs
+                       end
+               end
+       end
+end
+exit(1) if failed
+
+# Add deps from .so
+package_files.each do |(pkg,files)| files.each do |file|
+       case file
+       when /\/nkf\.so$/
+               files_requires[file]= files_requires[file] + ["enc/encdb"]
+       end
+end; end
+
+puts "Merging requirements into packages..."
+package_requires = Hash[packages.collect { |pkg| [pkg, package_files[pkg].collect {|file| files_requires[file] }.inject([],:+).uniq] }]
+
+weak_dependency=Hash.new([])
+weak_dependency.merge!({
+"ruby-misc"=>["ruby-openssl","ruby-fiddle"],                   #securerandom.rb
+"ruby-debuglib"=>["ruby-readline"],                            #debug.rb
+"ruby-drb"=>["ruby-openssl"],                                  #drb/ssl.rb
+"ruby-irb"=>["ruby-rdoc", "ruby-readline"],                    #irb/cmd/help.rb
+"ruby-gems"=>["ruby-openssl","ruby-io-console","ruby-webrick"], #rubygems/commands/cert_command.rb rubygems/user_interaction.rb rubygems/server.rb
+"ruby-mkmf"=>["ruby-webrick"],                                         #un.rb
+"ruby-net"=>["ruby-openssl","ruby-io-console","ruby-zlib"],    #net/*.rb
+"ruby-optparse"=>["ruby-uri","ruby-datetime"],                 #optparse/date.rb optparse/uri.rb
+"ruby-rake"=>["ruby-net","ruby-gems"],                         #rake/contrib/ftptools.rb /usr/bin/rake
+"ruby-rdoc"=>["ruby-gems","ruby-readline","ruby-webrick",      #/usr/bin/rdoc and others
+              "ruby-io-console"],                              #rdoc/stats/normal.rb
+"ruby-webrick"=>["ruby-openssl"],                              #webrick/ssl.rb
+})
+
+puts "Preloading gems..."
+Gem::Specification.all.each{ |x| gem x.name }
+
+puts "Looking for package dependencies..."
+package_provides = {}
+package_dependencies = Hash.new([])
+package_requires.each do
+       |(pkg,requires)|
+
+       requires.each do
+               |require|
+               if package_provides.include?(require)
+                       found = package_provides[require]
+               else
+                       found = package_files.detect {|(pkg,files)| files.detect {|file| $:.detect {|path| "#{path}/#{require}" == file.gsub(/\.(so|rb)$/,"") } } }
+                       if not found
+                               $stderr.puts "#{pkg}: Nothing provides #{require}"
+                               failed = true
+                               next
+                       end
+                       found = found.first
+                       package_provides[require]=found
+               end
+               if weak_dependency[pkg].include?(found)
+                       puts "#{pkg}: #{found} provides #{require} (ignored WEAK dep)"
+               else
+                       puts "#{pkg}: #{found} provides #{require}"
+                       package_dependencies[pkg]=package_dependencies[pkg] + [found]
+               end
+       end
+end
+if failed
+       puts "There is some missing requirements not mapped to files in packages."
+       puts "Please, fix the missing files or ignore them on require_ignore var"
+       exit(1)
+end
+
+package_dependencies.each do
+        |(pkg,deps)|
+        package_dependencies[pkg]=deps.uniq.sort - [pkg]
+end
+
+puts "Expanding dependencies..."
+begin
+       changed=false
+       package_dependencies.each do
+               |(pkg,deps)|
+
+               next if deps.empty?
+
+               deps_new = deps.collect {|dep| [dep] + package_dependencies[dep] }.inject([],:+).uniq.sort
+               if not deps == deps_new
+                       puts "#{pkg}: #{deps.join(",")}"
+                       puts "#{pkg}: #{deps_new.join(",")}"
+                       package_dependencies[pkg]=deps_new
+                       changed=true
+               end
+       end
+end if not changed
+
+puts "Checking for mutual dependencies..."
+package_dependencies.each do
+       |(pkg,deps)|
+       if deps.include? pkg
+               $stderr.puts "#{pkg}: Cycle dependency detected! "
+               failed = true
+       end
+end
+exit(1) if failed
+
+puts "Removing redundant dependencies..."
+package_dependencies.each do
+       |(pkg,deps)|
+       package_dependencies[pkg]=deps.uniq - [pkg]
+end
+
+package_dependencies2=package_dependencies.dup
+package_dependencies.each do
+       |(pkg,deps)|
+
+       # Ignore dependencies that are aready required by another dependency
+       deps_clean = deps.reject {|dep_suspect| deps.detect {|dep_provider|
+                       if package_dependencies[dep_provider].include?(dep_suspect)
+                               puts "#{pkg}: #{dep_suspect} is already required by #{dep_provider}"
+                               true
+                       end
+                } }
+
+       if not deps==deps_clean
+               puts "before: #{deps.join(",")}"
+               puts "after: #{deps_clean.join(",")}"
+               package_dependencies2[pkg]=deps_clean
+       end
+end
+package_dependencies=package_dependencies2
+
+puts "Checking current packages dependencies..."
+ok=true
+package_dependencies.each do
+       |(pkg,deps)|
+       current_deps=`opkg depends #{pkg} | sed -r -e '1d;s/^[[:blank:]]*//'`.split("\n")
+       current_deps.reject!{|dep| dep =~ /^lib/ }
+       current_deps -= ["ruby"]
+
+       extra_dep = current_deps - deps
+       $stderr.puts "Package #{pkg} does not need to depend on #{extra_dep.join(" ")} " if not extra_dep.empty?
+       missing_dep = deps - current_deps
+       $stderr.puts "Package #{pkg} needs to depend on #{missing_dep.join(" ")} " if not missing_dep.empty?
+
+       if not extra_dep.empty? or not missing_dep.empty?
+               $stderr.puts "define Package/#{pkg}"
+               $stderr.puts "  DEPENDS:=ruby#{([""] +deps).join(" +")}"
+               ok=false
+       end
+end
+
+puts "All dependencies are OK." if ok
+
+
+__END__
+
+puts RUBY_VERSION, RUBY_PLATFORM
+puts 123
+
+puts Object.contants
+
+#RUBY_VER=2.1
+#RUBY_ARCH=i486-linux-gnu
+#RUBYLIB=/usr/lib/ruby/$RUBY_VER/
+#RUBYLIB_A=/usr/lib/ruby/$RUBY_ARCH/$RUBY_VER/
diff --git a/lang/ruby/ruby_missingfiles b/lang/ruby/ruby_missingfiles
new file mode 100644 (file)
index 0000000..f05e9fe
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+
+function list_staging_files {
+       cd staging_dir/target-*/; find \
+               \( \( -name "root-x86" -or -name "packages" -or -name "stamp" -or -name "pkginfo" \) -prune \) -or -true \
+               \( -path "*ruby*" -or -name "erb" -or -name "gem" -or -name "irb" -or -name "rake" -or -name "rdoc" -or -name "ri" -or -name "testrb" \) \
+               -print | sort
+}
+
+function list_ipkg_files {
+       for OPKG in bin/*/packages/packages/*ruby*; do
+        tar --to-stdout -xzf "$OPKG" ./data.tar.gz | tar tz | sed -e 's%/$%%'
+       done | sort -u
+}
+
+
+echo "          Staging                    Packages"
+diff -y <(list_staging_files) <(list_ipkg_files)
+
diff --git a/lang/simplejson/Makefile b/lang/simplejson/Makefile
new file mode 100644 (file)
index 0000000..89da1b2
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=simplejson
+PKG_VERSION:=3.6.5
+PKG_RELEASE:=1
+PKG_LICENSE:=MIT
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://pypi.python.org/packages/source/s/simplejson/
+PKG_MD5SUM:=b65dc21c7aaad14c6b4ad0d9179e437d
+PKG_BUILD_DEPENDS:=python python-setuptools
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/simplejson
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+  TITLE:=Simple, fast, extensible JSON encoder/decoder for Python
+  URL:=http://simplejson.readthedocs.org/
+  DEPENDS:=+python
+endef
+
+define Package/simplejson/description
+  Simple, fast, extensible JSON encoder/decoder for Python
+endef
+
+define Build/Compile
+       $(call Build/Compile/PyMod,,install --prefix=/usr --root=$(PKG_INSTALL_DIR))
+endef
+
+define Package/simplejson/install
+       $(INSTALL_DIR) $(1)$(PYTHON_PKG_DIR)
+       $(CP) \
+           $(PKG_INSTALL_DIR)$(PYTHON_PKG_DIR)/* \
+           $(1)$(PYTHON_PKG_DIR)
+endef
+
+$(eval $(call BuildPackage,simplejson))
diff --git a/lang/vala/Makefile b/lang/vala/Makefile
new file mode 100644 (file)
index 0000000..d3dbc82
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=vala
+PKG_VERSION:=0.26.1
+PKG_RELEASE:=1
+PKG_LICENSE:=LGPL-2.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/vala/0.26/
+PKG_MD5SUM:=723a03b822d4cc47abc4019685970a3e
+
+PKG_BUILD_DEPENDS:=glib2/host vala/host
+HOST_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+TARGET_LDFLAGS+=\
+        -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
+
+define Package/vala
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=C-sharp like language for the GObject system
+  URL:=https://wiki.gnome.org/Projects/Vala
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+endef
+
+define Package/vala/description
+Vala is a C-sharp like language for the GObject system. This package contains
+the Vala-to-C compiler.
+endef
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               all install
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) \
+               $(1)/usr/share/vala-0.26/vapi \
+               $(1)/usr/lib \
+               $(1)/usr/share/pkgconfig \
+               $(1)/usr/bin
+
+       $(INSTALL_DATA) \
+               $(PKG_INSTALL_DIR)/usr/share/vala-0.26/vapi/* \
+               $(1)/usr/share/vala-0.26/vapi
+
+       $(INSTALL_DATA) \
+               $(PKG_INSTALL_DIR)/usr/lib/libvala-0.26.{so*,la} \
+               $(1)/usr/lib
+
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/{vala,vala-0.26,valac,valac-0.26,vapicheck,vapicheck-0.26,vapigen,vapigen-0.26,vala-gen-introspect,vala-gen-introspect-0.26} \
+               $(1)/usr/bin
+
+       $(INSTALL_DATA) \
+               $(PKG_INSTALL_DIR)/usr/share/pkgconfig/*.pc \
+               $(1)/usr/share/pkgconfig
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,vala))
index 09d72eb6897e4460746831c2de5fcdfe4a42f476..a4ccc233172718f26af6573db2a0c3e0664a2533 100644 (file)
@@ -18,7 +18,7 @@ PKG_MD5SUM:=c9e21b88a2b3e6e12ea7ba0f3b271fc3
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=LGPLv2.1 GPLv2
-PKG_LICENSE_FILE:=COPYING aserver/COPYING
+PKG_LICENSE_FILES:=COPYING aserver/COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/libs/alsa-lib/patches/002-remove_cross_compile_guess.patch b/libs/alsa-lib/patches/002-remove_cross_compile_guess.patch
new file mode 100644 (file)
index 0000000..d8f9f12
--- /dev/null
@@ -0,0 +1,23 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -27,20 +27,6 @@ AC_PREFIX_DEFAULT(/usr)
+ dnl Checks for programs.
+-dnl try to gues cross-compiler if not set
+-if test "x$host" != "x$build" -a -z "`echo $CC | grep -e '-gcc'`";
+-then
+-  AC_MSG_CHECKING(for cross-compiler)
+-
+-  which ${program_prefix}gcc >/dev/null 2>&1 && CC=${program_prefix}gcc
+-  which ${host_cpu}-${host_os}-gcc >/dev/null 2>&1 \
+-  && CC=${host_cpu}-${host_os}-gcc
+-  which ${host_cpu}-${host_vendor}-${host_os}-gcc >/dev/null 2>&1 \
+-  && CC=${host_cpu}-${host_vendor}-${host_os}-gcc
+-
+-  AC_MSG_RESULT($CC)
+-fi
+-          
+ CFLAGS="$CFLAGS -D_GNU_SOURCE"
index 627f1486cf81c98d5ef1b6ed8a8396c5b4c7999a..d5178d5679f71be826f8e14f1f97d3850a409931 100644 (file)
@@ -12,7 +12,7 @@ PKG_VERSION:=1.5.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=http://mirrors.ibiblio.org/apache/apr/
+PKG_SOURCE_URL:=https://archive.apache.org/dist/apr/
 PKG_MD5SUM:=2202b18f269ad606d70e1864857ed93c
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
 PKG_LICENSE:=Apache License
index f2d882d32cae8bf32edaa465b6b03c1aa01f3559..5f7ac1374a4e8f72e140b247ed94c5260bacbe1d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2014 OpenWrt.org
+# Copyright (C) 2007-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -7,19 +7,9 @@
 
 include $(TOPDIR)/rules.mk
 
-ifeq ($(BUILD_VARIANT),dbus)
-PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)/dbus/$(PKG_NAME)-$(PKG_VERSION)
-PKG_ALT_DIR=$(BUILD_DIR)/$(PKG_NAME)/nodbus/$(PKG_NAME)-$(PKG_VERSION)
-else
-PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)/nodbus/$(PKG_NAME)-$(PKG_VERSION)
-PKG_ALT_DIR=$(BUILD_DIR)/$(PKG_NAME)/dbus/$(PKG_NAME)-$(PKG_VERSION)
-endif
-
-
 PKG_NAME:=avahi
 PKG_VERSION:=0.6.31
-PKG_RELEASE:=6
-
+PKG_RELEASE:=11
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://avahi.org/download/
@@ -34,7 +24,11 @@ PKG_REMOVE_FILES:=autogen.sh
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
 
-
+ifeq ($(BUILD_VARIANT),dbus)
+PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)/dbus/$(PKG_NAME)-$(PKG_VERSION)
+else
+PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)/nodbus/$(PKG_NAME)-$(PKG_VERSION)
+endif
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -57,12 +51,12 @@ define Package/avahi/Default/description
  and is very convenient.
 endef
 
-define Package/libavahi
+define Package/libavahi/Default
   $(call Package/avahi/Default)
   SECTION:=libs
   CATEGORY:=Libraries
+  PROVIDES:=libavahi
   DEPENDS:=+libpthread +SSP_SUPPORT:libssp
-  TITLE+= (library)
 endef
 
 define Package/libavahi/description
@@ -71,10 +65,6 @@ $(call Package/avahi/Default/description)
  The libavahi package contains the mDNS/DNS-SD shared libraries,
  used by other programs. Specifically, it provides
  libavahi-core and libavahi-common libraries.
- By default, it is built without D-Bus support,
- i.e. the --disable-dbus configuration flag is set.
- To enable D-Bus support, select the package
- libavahi-dbus-support.
 endef
 
 define Package/avahi-autoipd
@@ -94,14 +84,21 @@ $(call Package/avahi/Default/description)
  DHCP server.
 endef
 
-define Package/avahi-daemon
+define Package/avahi-dbus-daemon
   $(call Package/avahi/Default)
+  PROVIDES:=avahi-daemon
+  VARIANT:=dbus
   SUBMENU:=IP Addresses and Names
-  ifeq ($(BUILD_VARIANT),dbus)
-  DEPENDS:=+libavahi +libexpat +librt +libdaemon +libdbus
-  else
-  DEPENDS:=+libavahi +libexpat +librt +libdaemon
-  endif
+  DEPENDS:=+libavahi-dbus-support +libexpat +librt +libdaemon
+  TITLE+= (daemon)
+endef
+
+define Package/avahi-nodbus-daemon
+  $(call Package/avahi/Default)
+  PROVIDES:=avahi-daemon
+  VARIANT:=nodbus
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+libavahi-nodbus-support +libexpat +librt +libdaemon
   TITLE+= (daemon)
 endef
 
@@ -111,17 +108,55 @@ $(call Package/avahi/Default/description)
  This package contains an mDNS/DNS-SD daemon.
 endef
 
+Package/avahi-dbus-daemon/description=$(Package/avahi-daemon/description)
+Package/avahi-nodbus-daemon/description=$(Package/avahi-daemon/description)
+
 define Package/avahi-daemon/conffiles
 /etc/avahi/avahi-daemon.conf
+endef
+
+Package/avahi-dbus-daemon/conffiles=$(Package/avahi-daemon/conffiles)
+Package/avahi-nodbus-daemon/conffiles=$(Package/avahi-daemon/conffiles)
+
+define Package/avahi-daemon-service-http
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+avahi-daemon
+  TITLE:=Announce HTTP service
+endef
+
+define Package/avahi-daemon-service-http/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains the service definition for announcing HTTP service.
+endef
+
+define Package/avahi-daemon-service-http/conffiles
 /etc/avahi/services/http.service
+endef
+
+define Package/avahi-daemon-service-ssh
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+avahi-daemon
+  TITLE:=Announce SSH service
+endef
+
+define Package/avahi-daemon-service-ssh/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains the service definition for announcing SSH service.
+endef
+
+define Package/avahi-daemon-service-ssh/conffiles
 /etc/avahi/services/ssh.service
 endef
 
 define Package/avahi-dnsconfd
   $(call Package/avahi/Default)
   SUBMENU:=IP Addresses and Names
-  DEPENDS:=+libavahi +libdaemon
-  TITLE:=A Unicast DNS server from mDNS/DNS-SD configuration daemon
+  DEPENDS:=+libavahi +libdaemon +libpthread +SSP_SUPPORT:libssp
+  TITLE:=A Unicast DNS server using avahi-daemon
 endef
 
 define Package/avahi-dnsconfd/description
@@ -133,20 +168,25 @@ $(call Package/avahi/Default/description)
 endef
 
 define Package/libavahi-dbus-support
-  $(call Package/avahi/Default)
-  SECTION:=libs
-  CATEGORY:=Libraries
+  $(call Package/libavahi/Default)
   VARIANT:=dbus
-  DEPENDS:=+dbus +libavahi
+  DEPENDS:=+dbus
   TITLE+= (D-Bus support)
 endef
 
+define Package/libavahi-nodbus-support
+  $(call Package/libavahi/Default)
+  VARIANT:=nodbus
+  TITLE+= (No D-Bus)
+endef
+
 define Package/libavahi-dbus-support/description
 $(call Package/libavahi/description)
  .
  The libavahi-dbus-support package enables
  D-Bus support in avahi, needed to support
  the libavahi-client library and avahi-utils.
+ .
  Selecting this package modifies the build configuration
  so that avahi packages are built with support for D-BUS enabled;
  it does not generate a separate binary of its own.
@@ -155,11 +195,20 @@ $(call Package/libavahi/description)
  libavahi-client or avahi-utils.
 endef
 
+define Package/libavahi-nodbus-support/description
+$(call Package/libavahi/description)
+ .
+ Selecting this package modifies the build configuration
+ so that avahi packages are built without support for D-BUS enabled;
+ it does not generate a separate binary of its own.
+endef
+
 define Package/libavahi-client
   $(call Package/avahi/Default)
   SECTION:=libs
   CATEGORY:=Libraries
-  DEPENDS:=+libavahi-dbus-support +avahi-daemon
+  VARIANT:=dbus
+  DEPENDS:=+avahi-dbus-daemon
   TITLE+= (libavahi-client library)
 endef
 
@@ -168,14 +217,32 @@ $(call Package/avahi/Default/description)
  .
  This packages adds the libavahi-client library.
  It also automatically adds the required
- libavahi-dbus-support and the avahi-daemon packages.
+ libavahi-dbus-support and the avahi-dbus-daemon packages.
+ For more information please see the avahi documentation.
+endef
+
+define Package/libavahi-compat-libdnssd
+  $(call Package/avahi/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  VARIANT:=dbus
+  DEPENDS:=+libavahi-client
+  TITLE+= (libdnssd)
+endef
+
+define Package/libavahi-compat-libdnssd/description
+$(call Package/avahi/Default/description)
+ .
+ This packages adds the libavahi-compat-libdnssd library.
+ It also automatically adds the required libavahi-client package.
  For more information please see the avahi documentation.
 endef
 
 define Package/avahi-utils
   $(call Package/avahi/Default)
   SUBMENU:=IP Addresses and Names
-  DEPENDS:=+libavahi-client +libgdbm
+  VARIANT:=dbus
+  DEPENDS:=libavahi-client +libgdbm
   TITLE+= (utilities)
 endef
 
@@ -203,6 +270,8 @@ CONFIGURE_ARGS+= \
        --disable-dbm \
        --enable-gdbm \
        --enable-libdaemon \
+       $(and $(CONFIG_PACKAGE_libavahi-compat-libdnssd),ifeq ($(BUILD_VARIANT),dbus),\
+               --enable-compat-libdns_sd) \
        --disable-python \
        --disable-pygtk \
        --disable-python-dbus \
@@ -247,40 +316,44 @@ define Build/InstallDev
        $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-* $(1)/usr/lib/
+ifeq ($(CONFIG_PACKAGE_libavahi-compat-libdnssd)-$(BUILD_VARIANT),y-dbus)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd* $(1)/usr/lib/
+endif
        $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
 endef
 
-define Package/libavahi-dbus-support/install
-       $(INSTALL_DIR) $(1)/etc/dbus-1/system.d
-       $(CP) $(PKG_INSTALL_DIR)/etc/dbus-1/system.d/* $(1)/etc/dbus-1/system.d
-endef
-
 define Package/libavahi/install
-       # The next line removes the ".build" file from the "other" build.
-       # The effect is that, if the other build is re-selected in the future,
-       # the build system will be forced to replace all the code in the
-       # installer packages, removing anything from the current build.
-       # "Other" means this: if the current build is "dbus", the other is "nodebus",
-       # and if the current build is "nodbus", the other is "dbus".
-       $(RM) -f $(PKG_ALT_DIR)/.built
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-{common,core}.so.* $(1)/usr/lib/
 endef
 
+define Package/libavahi-dbus-support/install
+       $(call Package/libavahi/install,$(1))
+       $(INSTALL_DIR) $(1)/etc/dbus-1/system.d
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/dbus-1/system.d/* $(1)/etc/dbus-1/system.d
+endef
+
+Package/libavahi-nodbus-support/install=$(Package/libavahi/install)
+
 define Package/libavahi-client/install
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-client.so.* $(1)/usr/lib/
 endef
 
+define Package/libavahi-compat-libdnssd/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so.* $(1)/usr/lib/
+endef
+
 define Package/avahi-utils/install
        $(INSTALL_DIR) $(1)/usr/bin
-       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
 endef
 
 define Package/avahi-autoipd/install
        $(INSTALL_DIR) $(1)/etc/avahi
-       $(CP) $(PKG_INSTALL_DIR)/etc/avahi/avahi-autoipd.action $(1)/etc/avahi/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/etc/avahi/avahi-autoipd.action $(1)/etc/avahi/
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-autoipd $(1)/usr/sbin/
 endef
@@ -290,24 +363,41 @@ define Package/avahi-daemon/install
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-daemon $(1)/usr/sbin/
        $(INSTALL_DIR) $(1)/etc/avahi
        $(INSTALL_DATA) ./files/avahi-daemon.conf $(1)/etc/avahi/
+       # install empty service directory so that user knows where
+       # to place custom service files
        $(INSTALL_DIR) $(1)/etc/avahi/services
-       $(INSTALL_DATA) ./files/service-http $(1)/etc/avahi/services/http.service
-       $(INSTALL_DATA) ./files/service-ssh $(1)/etc/avahi/services/ssh.service
        $(INSTALL_DIR) $(1)/etc/init.d
        $(INSTALL_BIN) ./files/avahi-daemon.init $(1)/etc/init.d/avahi-daemon
 endef
 
+Package/avahi-dbus-daemon/install=$(Package/avahi-daemon/install)
+Package/avahi-nodbus-daemon/install=$(Package/avahi-daemon/install)
+
+define Package/avahi-daemon-service-http/install
+       $(INSTALL_DIR) $(1)/etc/avahi/services
+       $(INSTALL_DATA) ./files/service-http $(1)/etc/avahi/services/http.service
+endef
+
+define Package/avahi-daemon-service-ssh/install
+       $(INSTALL_DIR) $(1)/etc/avahi/services
+       $(INSTALL_DATA) ./files/service-ssh $(1)/etc/avahi/services/ssh.service
+endef
+
 define Package/avahi-dnsconfd/install
        $(INSTALL_DIR) $(1)/etc/avahi
-       $(CP) $(PKG_INSTALL_DIR)/etc/avahi/avahi-dnsconfd.action $(1)/etc/avahi/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/etc/avahi/avahi-dnsconfd.action $(1)/etc/avahi/
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-dnsconfd $(1)/usr/sbin/
 endef
 
 $(eval $(call BuildPackage,libavahi-client))
+$(eval $(call BuildPackage,libavahi-compat-libdnssd))
 $(eval $(call BuildPackage,avahi-utils))
 $(eval $(call BuildPackage,libavahi-dbus-support))
-$(eval $(call BuildPackage,libavahi))
+$(eval $(call BuildPackage,libavahi-nodbus-support))
 $(eval $(call BuildPackage,avahi-autoipd))
-$(eval $(call BuildPackage,avahi-daemon))
+$(eval $(call BuildPackage,avahi-dbus-daemon))
+$(eval $(call BuildPackage,avahi-nodbus-daemon))
+$(eval $(call BuildPackage,avahi-daemon-service-http))
+$(eval $(call BuildPackage,avahi-daemon-service-ssh))
 $(eval $(call BuildPackage,avahi-dnsconfd))
index 7e9be2d424d2697e493efc0272f2e0247d9a3592..326203792eb8f08b9d955b8e742eccd8cf251a0f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" standalone='no'?><!--*-nxml-*-->
 <!DOCTYPE service-group SYSTEM "avahi-service.dtd">
 <service-group>
- <name replace-wildcards="yes">Web Server on %h</name>
+ <name replace-wildcards="yes">%h</name>
   <service>
    <type>_http._tcp</type>
    <port>80</port>
index b415803784dc817eccd8f4ea3645806ec28bae63..b44585157718eb829e074268d64060f456de0ceb 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" standalone='no'?><!--*-nxml-*-->
 <!DOCTYPE service-group SYSTEM "avahi-service.dtd">
 <service-group>
- <name replace-wildcards="yes">Secure Shell on %h</name>
+ <name replace-wildcards="yes">%h</name>
   <service>
    <type>_ssh._tcp</type>
    <port>22</port>
diff --git a/libs/classpath/Makefile b/libs/classpath/Makefile
new file mode 100644 (file)
index 0000000..273678e
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=classpath
+PKG_VERSION:=0.99
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Dana H. Myers <k6jq@comcast.net>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/classpath
+PKG_MD5SUM:=0ae1571249172acd82488724a3b8acb4
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/classpath
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU Classpath
+  URL:=http://www.gnu.org/software/classpath/
+  DEPENDS:=+alsa-lib +libgmp +libmagic
+endef
+
+define Package/classpath/Description
+       GNU Classpath, Essential Libraries for Java, is a GNU project
+       to create free core class libraries for use with virtual
+       machines and compilers for the java programming language.
+endef
+
+define Package/classpath-tools
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU Classpath tools
+  URL:=http://www.gnu.org/software/classpath/
+endef
+
+define Download/antlr
+  URL:=http://www.antlr.org/download
+  FILE:=antlr-3.4-complete.jar
+  MD5SUM:=1b91dea1c7d480b3223f7c8a9aa0e172
+endef
+$(eval $(call Download,antlr))
+
+CONFIGURE_ARGS += \
+       --with-gmp="$(STAGING_DIR)/usr" \
+       --without-x \
+       --disable-gtk-peer \
+       --disable-qt-peer \
+       --disable-dssi \
+       --disable-plugin \
+       --disable-gconf-peer \
+       --disable-gjdoc \
+       --disable-examples \
+       --with-antlr-jar=$(DL_DIR)/antlr-3.4-complete.jar
+
+define Package/classpath/install
+       $(INSTALL_DIR) \
+               $(1)/usr/lib/classpath \
+               $(1)/usr/share/classpath
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/security \
+               $(PKG_INSTALL_DIR)/usr/lib/logging.properties \
+               $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/classpath/*.so* $(1)/usr/lib/classpath/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/classpath/glibj.zip $(1)/usr/share/classpath/
+endef
+
+define Package/classpath-tools/install
+       $(INSTALL_DIR) \
+               $(1)/usr/bin \
+               $(1)/usr/share/classpath
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/classpath/tools.zip $(1)/usr/share/classpath/
+endef
+
+define Build/InstallDev
+       $(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+$(eval $(call BuildPackage,classpath))
+$(eval $(call BuildPackage,classpath-tools))
diff --git a/libs/classpath/patches/010-double-memleak.patch b/libs/classpath/patches/010-double-memleak.patch
new file mode 100644 (file)
index 0000000..02ec5ad
--- /dev/null
@@ -0,0 +1,91 @@
+--- classpath-0.99.orig/native/fdlibm/dtoa.c   2007-09-27 05:33:38.000000000 -0700
++++ classpath-0.99/native/fdlibm/dtoa.c        2014-12-21 14:22:42.451713851 -0800
+@@ -883,6 +883,16 @@ ret1:
+   return s0;
+ }
++void free_Bigints(struct _Jv_Bigint *p)
++{
++    struct _Jv_Bigint *l = p;
++    while (l)
++      {
++        struct _Jv_Bigint *next = l->_next;
++        free (l);
++        l = next;
++      }
++}
+ _VOID
+ _DEFUN (_dtoa,
+@@ -905,16 +915,15 @@ _DEFUN (_dtoa,
+   p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
+   strcpy (buf, p);
+-  for (i = 0; i < reent._result_k; ++i)
++  for (i = 0; i < reent._max_k; ++i)
+     {
+-      struct _Jv_Bigint *l = reent._freelist[i];
+-      while (l)
+-      {
+-        struct _Jv_Bigint *next = l->_next;
+-        free (l);
+-        l = next;
+-      }
++        free_Bigints(reent._freelist[i]);
+     }
+   if (reent._freelist)
+     free (reent._freelist);
++
++  if (reent._result)
++    free(reent._result);
++
++  free_Bigints(reent._p5s);
+ }
+--- classpath-0.99.orig/native/jni/java-lang/java_lang_VMDouble.c      2008-02-08 09:42:57.000000000 -0800
++++ classpath-0.99/native/jni/java-lang/java_lang_VMDouble.c   2014-12-21 14:35:50.733800626 -0800
+@@ -158,6 +158,17 @@ Java_java_lang_VMDouble_longBitsToDouble
+   return val.d;
+ }
++static void free_Bigints(struct _Jv_Bigint *p)
++{
++     struct _Jv_Bigint *l = p;
++     while (l)
++     {
++         struct _Jv_Bigint *next = l->_next;
++         free (l);
++         l = next;
++     }
++}
++ 
+ /**
+  * Parse a double from a char array.
+  */
+@@ -167,7 +178,7 @@ parseDoubleFromChars(JNIEnv * env, const
+   char *endptr;
+   jdouble val = 0.0;
+   const char *p = buf, *end, *last_non_ws, *temp;
+-  int ok = 1;
++  int i, ok = 1;
+ #ifdef DEBUG
+   fprintf (stderr, "java.lang.VMDouble.parseDouble (%s)\n", buf);
+@@ -224,6 +235,18 @@ parseDoubleFromChars(JNIEnv * env, const
+       val = _strtod_r (&reent, p, &endptr);
++      for (i = 0; i < reent._max_k; ++i)
++      {
++          free_Bigints(reent._freelist[i]);
++      }
++      if (reent._freelist)
++          free (reent._freelist);
++
++      if (reent._result)
++          free (reent._result);
++
++      free_Bigints(reent._p5s);
++
+ #ifdef DEBUG
+       fprintf (stderr, "java.lang.VMDouble.parseDouble val = %g\n", val);
+       fprintf (stderr, "java.lang.VMDouble.parseDouble %p != %p ???\n",
index 258365603cc9709731a5e47d859d832485a41282..dfc21d2ed04007b7d2a7a4e34552e5f9777e617c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2008 OpenWrt.org
+# Copyright (C) 2006-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=cyrus-sasl
 PKG_VERSION:=2.1.26
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
@@ -32,7 +32,7 @@ define Package/libsasl2
   CATEGORY:=Libraries
   TITLE:=A general purpose authentication library
   URL:=http://asg.web.cmu.edu/sasl/
-  DEPENDS:=libopenssl
+  DEPENDS:=+libopenssl
 endef
 
 TARGET_CFLAGS += $(FPIC)
@@ -104,9 +104,9 @@ endef
 
 define Package/libsasl2/install
        $(INSTALL_DIR) $(1)/usr/lib/
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsasl2.so.* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsasl2.so* $(1)/usr/lib/
        $(INSTALL_DIR) $(1)/usr/lib/sasl2
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/lib*.so.* $(1)/usr/lib/sasl2/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/lib*.so* $(1)/usr/lib/sasl2/
 endef
 
 $(eval $(call BuildPackage,libsasl2))
index 2083fc9dcabf74600bb896abdd99a96f11cd3763..563d47c881ae4d146fb34fb5a0344634e10f1625 100644 (file)
@@ -12,7 +12,7 @@ BASE_VERSION:=4.7.25
 
 PKG_NAME:=db47
 PKG_VERSION:=$(BASE_VERSION).4.NC
-PKG_RELEASE:=1
+PKG_RELEASE:=3
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/db-$(BASE_VERSION).NC
 PKG_SOURCE:=db-$(BASE_VERSION).NC.tar.gz
@@ -35,6 +35,7 @@ define Package/libdb47
   DEPENDS:=+libxml2
   TITLE:=Berkeley DB library (4.7)
   URL:=http://www.oracle.com/us/products/database/berkeley-db
+  PROVIDES:=libdb47-full
 endef
 
 define Package/libdb47/description
@@ -47,6 +48,7 @@ define Package/libdb47xx
   DEPENDS:=+libdb47 $(CXX_DEPENDS)
   TITLE:=Berkeley DB library (4.7) for C++
   URL:=http://www.oracle.com/us/products/database/berkeley-db
+  PROVIDES:=libdb47xx-full
 endef
 
 define Package/libdb47xx/description
@@ -64,9 +66,7 @@ CONFIGURE_ARGS += \
        --disable-tcl \
        --disable-rpc \
        --enable-compat185 \
-       --enable-smallbuild \
        --disable-debug \
-       --enable-cryptography \
        $(if $(CONFIG_PACKAGE_libdb47xx),--enable-cxx,--disable-cxx)
 
 TARGET_CFLAGS += $(FPIC)
diff --git a/libs/dmx_usb_module/Makefile b/libs/dmx_usb_module/Makefile
new file mode 100644 (file)
index 0000000..d9e458f
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=dmx_usb_module
+PKG_VERSION:=0.1.20130818
+PKG_RELEASE:=0.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://github.com/lowlander/dmx_usb_module.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=ee99ca7edbd9e093480ad63341ac007394047bde
+PKG_MAINTAINER:=Martijn Zilverschoon <martijn@friedzombie.com>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/usb-serial-dmx_usb_module
+       SECTION:=kernel
+       CATEGORY:=Kernel modules
+       SUBMENU:=USB Support
+       TITLE:=Support for FTDI RS485 based DMX modules
+       URL:=http://www.erwinrol.com/open-dmx-usb-linux-driver/
+       FILES:=$(PKG_BUILD_DIR)/dmx_usb.$(LINUX_KMOD_SUFFIX)
+       AUTOLOAD:=$(call AutoProbe,dmx_usb)
+       DEPENDS+=kmod-usb-serial
+endef
+
+define KernelPackage/usb-serial-dmx_usb_module/description
+       Open DMX USB is an open USB to DMX dongle hardware design developed by Enttec.
+       The Open in Open DMX USB refers to the fact that everybody is free to use the
+       design and produce its own USB DMX Dongle without paying any licenses.
+endef
+
+DMX_MAKE_OPTS:= -C $(PKG_BUILD_DIR) \
+       PATH="$(TARGET_PATH)" \
+       ARCH="$(LINUX_KARCH)" \
+       CROSS_COMPILE="$(TARGET_CROSS)" \
+       TARGET="$(HAL_TARGET)" \
+       TOOLPREFIX="$(KERNEL_CROSS)" \
+       TOOLPATH="$(KERNEL_CROSS)" \
+       KERNELPATH="$(LINUX_DIR)" \
+       LDOPTS=" "
+
+define Build/Compile
+  $(MAKE) $(DMX_MAKE_OPTS) M=$(PKG_BUILD_DIR)
+endef
+
+$(eval $(call KernelPackage,usb-serial-dmx_usb_module))
diff --git a/libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch b/libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch
new file mode 100644 (file)
index 0000000..2a03d94
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/Makefile
++++ b/Makefile
+@@ -12,8 +12,7 @@ KDIR := /lib/modules/$(shell uname -r)/build
+ PWD   := $(shell pwd)
+ default:
+-      $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+-      gcc -O2 -pipe -Wall dmx_usb_test.c -o dmx_usb_test
++      $(MAKE) -C $(KERNELPATH) SUBDIRS=$(PWD) modules
+ endif
+
diff --git a/libs/elfutils/Makefile b/libs/elfutils/Makefile
new file mode 100644 (file)
index 0000000..d3e1552
--- /dev/null
@@ -0,0 +1,97 @@
+#
+# Copyright (C) 2010-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=elfutils
+PKG_VERSION:=0.161
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://fedorahosted.org/releases/e/l/$(PKG_NAME)/$(PKG_VERSION)
+PKG_MD5SUM:=e1b9847c9a6a1ad340de8d47a863ec52
+PKG_MAINTAINER:=Luiz Angelo Daros de Luca <luizluca@gmail.com>
+PKG_LICENSE:=GPL-3.0+
+PKG_LICENSE_FILES:=COPYING COPYING-GPLV2 COPYING-LGPLV3
+
+PKG_INSTALL:=1
+PKG_USE_MIPS16:=0
+
+PKG_BUILD_DEPENDS:=USE_UCLIBC:argp-standalone USE_MUSL:argp-standalone
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/elfutils/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=$(INTL_DEPENDS)
+  TITLE:=ELF manipulation libraries
+  URL:=https://fedorahosted.org/elfutils/
+endef
+
+define Package/libasm
+  $(call Package/elfutils/Default)
+  TITLE+= (libasm)
+  DEPENDS:=libelf1
+endef
+
+define Package/libdw
+  $(call Package/elfutils/Default)
+  DEPENDS:=libelf1 +zlib +libbz2
+  TITLE+= (libdw)
+endef
+
+define Package/libelf1
+  $(call Package/elfutils/Default)
+  TITLE+= (libelf)
+endef
+
+ifeq ($(CONFIG_BUILD_NLS),y)
+TARGET_LDFLAGS += "-lintl"
+endif
+
+ifdef CONFIG_USE_UCLIBC
+CONFIGURE_VARS += \
+       LIBS="-largp"
+endif
+
+ifdef CONFIG_USE_MUSL
+CONFIGURE_VARS += \
+       LIBS="-largp"
+endif
+
+CONFIGURE_ARGS += \
+       --disable-werror \
+       --without-lzma
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libasm/libasm.{a,so*} $(1)/usr/lib/
+       $(CP) $(PKG_BUILD_DIR)/libdw/libdw.{a,so*} $(1)/usr/lib/
+       $(CP) $(PKG_BUILD_DIR)/libelf/libelf.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libasm/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libasm/libasm.so* $(1)/usr/lib/
+endef
+
+define Package/libdw/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libdw/libdw.so* $(1)/usr/lib/
+endef
+
+define Package/libelf1/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libelf/libelf.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libasm))
+$(eval $(call BuildPackage,libdw))
+$(eval $(call BuildPackage,libelf1))
diff --git a/libs/elfutils/patches/001-elfutils-portability.patch b/libs/elfutils/patches/001-elfutils-portability.patch
new file mode 100644 (file)
index 0000000..7539f8b
--- /dev/null
@@ -0,0 +1,1871 @@
+--- elfutils/backends/ChangeLog
++++ elfutils/backends/ChangeLog
+@@ -433,6 +433,10 @@
+       * ppc_attrs.c (ppc_check_object_attribute): Handle tag
+       GNU_Power_ABI_Struct_Return.
++2009-01-23  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (libebl_%.so): Use $(LD_AS_NEEDED).
++
+ 2008-10-04  Ulrich Drepper  <drepper@redhat.com>
+       * i386_reloc.def: Fix entries for TLS_GOTDESC, TLS_DESC_CALL, and
+@@ -760,6 +764,11 @@
+       * sparc_init.c: Likewise.
+       * x86_64_init.c: Likewise.
++2005-11-22  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (LD_AS_NEEDED): New variable, substituted by configure.
++      (libebl_%.so rule): Use it in place of -Wl,--as-needed.
++
+ 2005-11-19  Roland McGrath  <roland@redhat.com>
+       * ppc64_reloc.def: REL30 -> ADDR30.
+@@ -782,6 +791,9 @@
+       * Makefile.am (uninstall): Don't try to remove $(pkgincludedir).
+       (CLEANFILES): Add libebl_$(m).so.
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+       * ppc_reloc.def: Update bits per Alan Modra <amodra@bigpond.net.au>.
+       * ppc64_reloc.def: Likewise.
+--- elfutils/backends/Makefile.am
++++ elfutils/backends/Makefile.am
+@@ -119,7 +119,7 @@ libebl_%.so libebl_%.map: libebl_%_pic.a
+       $(LINK) -shared -o $(@:.map=.so) \
+               -Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
+               -Wl,--version-script,$(@:.so=.map) \
+-              -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
++              -Wl,-z,defs $(LD_AS_NEEDED) $(libelf) $(libdw)
+       @$(textrel_check)
+ libebl_i386.so: $(cpu_i386)
+--- elfutils/backends/Makefile.in
++++ elfutils/backends/Makefile.in
+@@ -83,6 +83,7 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ subdir = backends
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -285,6 +286,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -316,6 +318,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -378,11 +381,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
+       -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(foreach m,$(modules), libebl_$(m).map \
+       libebl_$(m).so $(am_libebl_$(m)_pic_a_OBJECTS))
+@@ -888,7 +891,7 @@ libebl_%.so libebl_%.map: libebl_%_pic.a
+       $(LINK) -shared -o $(@:.map=.so) \
+               -Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
+               -Wl,--version-script,$(@:.so=.map) \
+-              -Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw)
++              -Wl,-z,defs $(LD_AS_NEEDED) $(libelf) $(libdw)
+       @$(textrel_check)
+ libebl_i386.so: $(cpu_i386)
+--- elfutils/ChangeLog
++++ elfutils/ChangeLog
+@@ -187,6 +187,8 @@
+ 2012-01-24  Mark Wielaard  <mjw@redhat.com>
++      * configure.ac: Wrap AC_COMPILE_IFELSE sources in AC_LANG_SOURCE.
++
+       * COPYING: Fix address. Updated version from gnulib.
+ 2012-01-23  Mark Wielaard  <mjw@redhat.com>
+@@ -205,6 +207,9 @@
+ 2011-10-08  Mike Frysinger  <vapier@gentoo.org>
++      * configure.ac (--disable-werror): Handle it, controlling BUILD_WERROR
++      automake option.
++
+       * configure.ac: Fix use of AC_ARG_ENABLE to handle $enableval correctly.
+ 2011-10-02  Ulrich Drepper  <drepper@gmail.com>
+@@ -226,6 +231,10 @@
+       * configure.ac (LOCALEDIR, DATADIRNAME): Removed.
++2009-11-22  Roland McGrath  <roland@redhat.com>
++
++      * configure.ac: Use sed and expr instead of modern bash extensions.
++
+ 2009-09-21  Ulrich Drepper  <drepper@redhat.com>
+       * configure.ac: Update for more modern autoconf.
+@@ -234,6 +243,10 @@
+       * configure.ac (zip_LIBS): Check for liblzma too.
++2009-08-17  Roland McGrath  <roland@redhat.com>
++
++      * configure.ac: Check for -fgnu89-inline; add it to WEXTRA if it works.
++
+ 2009-04-19  Roland McGrath  <roland@redhat.com>
+       * configure.ac (eu_version): Round down here, not in version.h macros.
+@@ -245,6 +258,8 @@
+ 2009-01-23  Roland McGrath  <roland@redhat.com>
++      * configure.ac: Check for __builtin_popcount.
++
+       * configure.ac (zlib check): Check for gzdirect, need zlib >= 1.2.2.3.
+       * configure.ac (__thread check): Use AC_LINK_IFELSE, in case of
+@@ -325,6 +340,10 @@
+       * configure.ac: Add dummy automake conditional to get dependencies
+       for non-generic linker right.  See src/Makefile.am.
++2005-11-22  Roland McGrath  <roland@redhat.com>
++
++      * configure.ac: Check for --as-needed linker option.
++
+ 2005-11-18  Roland McGrath  <roland@redhat.com>
+       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): New variable.
+@@ -372,6 +391,17 @@
+       * Makefile.am (all_SUBDIRS): Add libdwfl.
+       * configure.ac: Write libdwfl/Makefile.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * configure.ac (WEXTRA): Check for -Wextra and set this substitution.
++
++      * configure.ac: Check for struct stat st_?tim members.
++      * src/strip.c (process_file): Use st_?time if st_?tim are not there.
++
++      * configure.ac: Check for futimes function.
++      * src/strip.c (handle_elf) [! HAVE_FUTIMES]: Use utimes instead.
++      (handle_ar) [! HAVE_FUTIMES]: Likewise.
++
+ 2005-05-19  Roland McGrath  <roland@redhat.com>
+       * configure.ac [AH_BOTTOM] (INTDECL, _INTDECL): New macros.
+--- elfutils/config/ChangeLog
++++ elfutils/config/ChangeLog
+@@ -71,6 +71,10 @@
+       * known-dwarf.awk: Use gawk.
++2011-10-08  Mike Frysinger  <vapier@gentoo.org>
++
++      * eu.am [BUILD_WERROR]: Conditionalize -Werror use on this.
++
+ 2010-07-02  Ulrich Drepper  <drepper@redhat.com>
+       * elfutils.spec.in: Add more BuildRequires.
+--- elfutils/config/eu.am
++++ elfutils/config/eu.am
+@@ -1,6 +1,6 @@
+ ## Common automake fragments for elfutils subdirectory makefiles.
+ ##
+-## Copyright (C) 2010, 2014 Red Hat, Inc.
++## Copyright (C) 2010-2011, 2014 Red Hat, Inc.
+ ##
+ ## This file is part of elfutils.
+ ##
+@@ -29,13 +29,21 @@
+ ## not, see <http://www.gnu.org/licenses/>.
+ ##
++WEXTRA = @WEXTRA@
++LD_AS_NEEDED = @LD_AS_NEEDED@
++
+ DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"'
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I..
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow \
+           $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
++          $(if $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) \
++          $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2) \
+           $($(*F)_CFLAGS)
++if BUILD_WERROR
++AM_CFLAGS += $(if $($(*F)_no_Werror),,-Werror)
++endif
++
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ %.os: %.c %.o
+--- elfutils/config/Makefile.in
++++ elfutils/config/Makefile.in
+@@ -147,6 +147,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -178,6 +179,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+--- elfutils/config.h.in
++++ elfutils/config.h.in
+@@ -3,6 +3,9 @@
+ /* Should ar and ranlib use -D behavior by default? */
+ #undef DEFAULT_AR_DETERMINISTIC
++/* Have __builtin_popcount. */
++#undef HAVE_BUILTIN_POPCOUNT
++
+ /* Define to 1 if you have the <inttypes.h> header file. */
+ #undef HAVE_INTTYPES_H
+@@ -102,4 +105,7 @@
+ /* Define for large files, on AIX-style hosts. */
+ #undef _LARGE_FILES
++/* Stubbed out if missing compiler support. */
++#undef __thread
++
+ #include <eu-config.h>
+--- elfutils/configure
++++ elfutils/configure
+@@ -663,6 +663,8 @@ ZLIB_TRUE
+ LIBEBL_SUBDIR
+ TESTS_RPATH_FALSE
+ TESTS_RPATH_TRUE
++BUILD_WERROR_FALSE
++BUILD_WERROR_TRUE
+ BUILD_STATIC_FALSE
+ BUILD_STATIC_TRUE
+ USE_VALGRIND_FALSE
+@@ -678,6 +680,8 @@ NEVER_TRUE
+ base_cpu
+ NATIVE_LD_FALSE
+ NATIVE_LD_TRUE
++LD_AS_NEEDED
++WEXTRA
+ NM
+ READELF
+ ac_ct_AR
+@@ -798,6 +802,7 @@ enable_debugpred
+ enable_gprof
+ enable_gcov
+ enable_valgrind
++enable_werror
+ enable_tests_rpath
+ enable_libebl_subdir
+ with_zlib
+@@ -1455,6 +1460,7 @@ Optional Features:
+   --enable-gprof          build binaries with gprof support
+   --enable-gcov           build binaries with gcov support
+   --enable-valgrind       run all tests under valgrind
++  --disable-werror        do not build with -Werror
+   --enable-tests-rpath    build $ORIGIN-using rpath into tests
+   --enable-libebl-subdir=DIR
+                           install libebl_CPU modules in $(libdir)/DIR
+@@ -4843,6 +4849,130 @@ if test "x$ac_cv_c99" != xyes; then :
+   as_fn_error $? "gcc with C99 support required" "$LINENO" 5
+ fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wextra option to $CC" >&5
++$as_echo_n "checking for -Wextra option to $CC... " >&6; }
++if ${ac_cv_cc_wextra+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  old_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -Wextra"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++void foo (void) { }
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_cc_wextra=yes
++else
++  ac_cv_cc_wextra=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++CFLAGS="$old_CFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_wextra" >&5
++$as_echo "$ac_cv_cc_wextra" >&6; }
++
++if test "x$ac_cv_cc_wextra" = xyes; then :
++  WEXTRA=-Wextra
++else
++  WEXTRA=-W
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fgnu89-inline option to $CC" >&5
++$as_echo_n "checking for -fgnu89-inline option to $CC... " >&6; }
++if ${ac_cv_cc_gnu89_inline+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  old_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -fgnu89-inline -Werror"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++void foo (void)
++{
++  inline void bar (void) {}
++  bar ();
++}
++extern inline void baz (void) {}
++
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_cc_gnu89_inline=yes
++else
++  ac_cv_cc_gnu89_inline=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++CFLAGS="$old_CFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_gnu89_inline" >&5
++$as_echo "$ac_cv_cc_gnu89_inline" >&6; }
++if test "x$ac_cv_cc_gnu89_inline" = xyes; then :
++  WEXTRA="${WEXTRA:+$WEXTRA }-fgnu89-inline"
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --as-needed linker option" >&5
++$as_echo_n "checking for --as-needed linker option... " >&6; }
++if ${ac_cv_as_needed+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
++                          -fPIC -shared -o conftest.so conftest.c
++                          -Wl,--as-needed 1>&5'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }
++then
++  ac_cv_as_needed=yes
++else
++  ac_cv_as_needed=no
++fi
++rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_as_needed" >&5
++$as_echo "$ac_cv_as_needed" >&6; }
++if test "x$ac_cv_as_needed" = xyes; then :
++  LD_AS_NEEDED=-Wl,--as-needed
++else
++  LD_AS_NEEDED=
++fi
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_popcount" >&5
++$as_echo_n "checking for __builtin_popcount... " >&6; }
++if ${ac_cv_popcount+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++exit (__builtin_popcount (127));
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_popcount=yes
++else
++  ac_cv_popcount=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_popcount" >&5
++$as_echo "$ac_cv_popcount" >&6; }
++if test "x$ac_cv_popcount" = xyes; then :
++
++$as_echo "#define HAVE_BUILTIN_POPCOUNT 1" >>confdefs.h
++
++fi
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __thread support" >&5
+ $as_echo_n "checking for __thread support... " >&6; }
+ if ${ac_cv_tls+:} false; then :
+@@ -4879,7 +5009,13 @@ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tls" >&5
+ $as_echo "$ac_cv_tls" >&6; }
+ if test "x$ac_cv_tls" != xyes; then :
+-  as_fn_error $? "__thread support required" "$LINENO" 5
++  if test "$use_locks" = yes; then :
++  as_fn_error $? "--enable-thread-safety requires __thread support" "$LINENO" 5
++else
++
++$as_echo "#define __thread /* empty: no multi-thread support */" >>confdefs.h
++
++fi
+ fi
+ # Check whether --enable-largefile was given.
+@@ -5246,6 +5382,22 @@ else
+ fi
++# Check whether --enable-werror was given.
++if test "${enable_werror+set}" = set; then :
++  enableval=$enable_werror; enable_werror=$enableval
++else
++  enable_werror=yes
++fi
++
++ if test "$enable_werror" = yes; then
++  BUILD_WERROR_TRUE=
++  BUILD_WERROR_FALSE='#'
++else
++  BUILD_WERROR_TRUE='#'
++  BUILD_WERROR_FALSE=
++fi
++
++
+ # Check whether --enable-tests-rpath was given.
+ if test "${enable_tests_rpath+set}" = set; then :
+   enableval=$enable_tests_rpath; tests_use_rpath=$enableval
+@@ -5983,7 +6135,7 @@ case "$eu_version" in
+ esac
+ # Round up to the next release API (x.y) version.
+-eu_version=$(( (eu_version + 999) / 1000 ))
++eu_version=`expr \( $eu_version + 999 \) / 1000`
+ ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+@@ -6729,6 +6881,10 @@ if test -z "${BUILD_STATIC_TRUE}" && tes
+   as_fn_error $? "conditional \"BUILD_STATIC\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
++if test -z "${BUILD_WERROR_TRUE}" && test -z "${BUILD_WERROR_FALSE}"; then
++  as_fn_error $? "conditional \"BUILD_WERROR\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+ if test -z "${TESTS_RPATH_TRUE}" && test -z "${TESTS_RPATH_FALSE}"; then
+   as_fn_error $? "conditional \"TESTS_RPATH\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+--- elfutils/configure.ac
++++ elfutils/configure.ac
+@@ -89,6 +89,54 @@ CFLAGS="$old_CFLAGS"])
+ AS_IF([test "x$ac_cv_c99" != xyes],
+       AC_MSG_ERROR([gcc with C99 support required]))
++AC_CACHE_CHECK([for -Wextra option to $CC], ac_cv_cc_wextra, [dnl
++old_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -Wextra"
++AC_COMPILE_IFELSE([AC_LANG_SOURCE([void foo (void) { }])],
++                ac_cv_cc_wextra=yes, ac_cv_cc_wextra=no)
++CFLAGS="$old_CFLAGS"])
++AC_SUBST(WEXTRA)
++AS_IF([test "x$ac_cv_cc_wextra" = xyes], [WEXTRA=-Wextra], [WEXTRA=-W])
++
++AC_CACHE_CHECK([for -fgnu89-inline option to $CC], ac_cv_cc_gnu89_inline, [dnl
++old_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -fgnu89-inline -Werror"
++AC_COMPILE_IFELSE([AC_LANG_SOURCE([
++void foo (void)
++{
++  inline void bar (void) {}
++  bar ();
++}
++extern inline void baz (void) {}
++])], ac_cv_cc_gnu89_inline=yes, ac_cv_cc_gnu89_inline=no)
++CFLAGS="$old_CFLAGS"])
++AS_IF([test "x$ac_cv_cc_gnu89_inline" = xyes],
++      [WEXTRA="${WEXTRA:+$WEXTRA }-fgnu89-inline"])
++
++AC_CACHE_CHECK([for --as-needed linker option],
++             ac_cv_as_needed, [dnl
++cat > conftest.c <<EOF
++int main (void) { return 0; }
++EOF
++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
++                          -fPIC -shared -o conftest.so conftest.c
++                          -Wl,--as-needed 1>&AS_MESSAGE_LOG_FD])
++then
++  ac_cv_as_needed=yes
++else
++  ac_cv_as_needed=no
++fi
++rm -f conftest*])
++AS_IF([test "x$ac_cv_as_needed" = xyes],
++      [LD_AS_NEEDED=-Wl,--as-needed], [LD_AS_NEEDED=])
++AC_SUBST(LD_AS_NEEDED)
++
++AC_CACHE_CHECK([for __builtin_popcount], ac_cv_popcount, [dnl
++AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[exit (__builtin_popcount (127));]])],
++             ac_cv_popcount=yes, ac_cv_popcount=no)])
++AS_IF([test "x$ac_cv_popcount" = xyes],
++      [AC_DEFINE([HAVE_BUILTIN_POPCOUNT], [1], [Have __builtin_popcount.])])
++
+ AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl
+ # Use the same flags that we use for our DSOs, so the test is representative.
+ # Some old compiler/linker/libc combinations fail some ways and not others.
+@@ -104,7 +152,10 @@ static __thread int a; int foo (int b) {
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"])
+ AS_IF([test "x$ac_cv_tls" != xyes],
+-      AC_MSG_ERROR([__thread support required]))
++      [AS_IF([test "$use_locks" = yes],
++           [AC_MSG_ERROR([--enable-thread-safety requires __thread support])],
++           [AC_DEFINE([__thread], [/* empty: no multi-thread support */],
++                      [Stubbed out if missing compiler support.])])])
+ dnl This test must come as early as possible after the compiler configuration
+ dnl tests, because the choice of the file model can (in principle) affect
+@@ -183,6 +234,11 @@ AM_CONDITIONAL(USE_VALGRIND, test "$use_
+ AM_CONDITIONAL(BUILD_STATIC, [dnl
+ test "$use_gprof" = yes -o "$use_gcov" = yes])
++AC_ARG_ENABLE([werror],
++AS_HELP_STRING([--disable-werror],[do not build with -Werror]),
++             [enable_werror=$enableval], [enable_werror=yes])
++AM_CONDITIONAL(BUILD_WERROR, test "$enable_werror" = yes)
++
+ AC_ARG_ENABLE([tests-rpath],
+ AS_HELP_STRING([--enable-tests-rpath],[build $ORIGIN-using rpath into tests]),
+              [tests_use_rpath=$enableval], [tests_use_rpath=no])
+@@ -302,7 +358,7 @@ case "$eu_version" in
+ esac
+ # Round up to the next release API (x.y) version.
+-eu_version=$(( (eu_version + 999) / 1000 ))
++eu_version=`expr \( $eu_version + 999 \) / 1000`
+ AC_CHECK_SIZEOF(long)
+--- elfutils/lib/ChangeLog
++++ elfutils/lib/ChangeLog
+@@ -65,6 +65,9 @@
+ 2009-01-23  Roland McGrath  <roland@redhat.com>
++      * eu-config.h [! HAVE_BUILTIN_POPCOUNT]
++      (__builtin_popcount): New inline function.
++
+       * eu-config.h: Add multiple inclusion protection.
+ 2009-01-17  Ulrich Drepper  <drepper@redhat.com>
+@@ -121,6 +124,11 @@
+       * Makefile.am (libeu_a_SOURCES): Add it.
+       * system.h: Declare crc32_file.
++2005-02-07  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-04-30  Ulrich Drepper  <drepper@redhat.com>
+       * Makefile.am: Use -ffunction-sections for xmalloc.c.
+--- elfutils/lib/eu-config.h
++++ elfutils/lib/eu-config.h
+@@ -162,6 +162,17 @@ asm (".section predict_data, \"aw\"; .pr
+ /* This macro is used by the tests conditionalize for standalone building.  */
+ #define ELFUTILS_HEADER(name) <lib##name.h>
++#ifndef HAVE_BUILTIN_POPCOUNT
++# define __builtin_popcount hakmem_popcount
++static inline unsigned int __attribute__ ((unused))
++hakmem_popcount (unsigned int x)
++{
++  /* HAKMEM 169 */
++  unsigned int n = x - ((x >> 1) & 033333333333) - ((x >> 2) & 011111111111);
++  return ((n + (n >> 3)) & 030707070707) % 63;
++}
++#endif        /* HAVE_BUILTIN_POPCOUNT */
++
+ #ifdef SHARED
+ # define OLD_VERSION(name, version) \
+--- elfutils/lib/Makefile.in
++++ elfutils/lib/Makefile.in
+@@ -82,6 +82,7 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ subdir = lib
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -197,6 +198,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -228,6 +230,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -289,9 +292,11 @@ top_srcdir = @top_srcdir@
+ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(srcdir)/../libelf
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 $(if \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
+       $($(*F)_no_Werror),,-Werror) $(if \
+-      $($(*F)_no_Wunused),,-Wunused -Wextra) $($(*F)_CFLAGS) -fpic
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1) -fpic
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+--- elfutils/libasm/ChangeLog
++++ elfutils/libasm/ChangeLog
+@@ -87,6 +87,11 @@
+       * asm_error.c: Add new error ASM_E_IOERROR.
+       * libasmP.h: Add ASM_E_IOERROR definition.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+       * Makefile.am (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+--- elfutils/libasm/Makefile.in
++++ elfutils/libasm/Makefile.in
+@@ -83,8 +83,9 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ noinst_PROGRAMS = $(am__EXEEXT_1)
+-@USE_LOCKS_TRUE@am__append_1 = -lpthread
++@USE_LOCKS_TRUE@am__append_2 = -lpthread
+ subdir = libasm
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -248,6 +249,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -279,6 +281,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -341,11 +344,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \
+       -I$(top_srcdir)/libdw
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(am_libasm_pic_a_OBJECTS) \
+       libasm.so.$(VERSION)
+@@ -373,7 +376,7 @@ libasm_a_SOURCES = asm_begin.c asm_abort
+ libasm_pic_a_SOURCES = 
+ am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
+-libasm_so_LDLIBS = $(am__append_1)
++libasm_so_LDLIBS = $(am__append_2)
+ libasm_so_SOURCES = 
+ noinst_HEADERS = libasmP.h symbolhash.h
+ EXTRA_DIST = libasm.map
+--- elfutils/libcpu/ChangeLog
++++ elfutils/libcpu/ChangeLog
+@@ -51,6 +51,9 @@
+ 2009-01-23  Roland McGrath  <roland@redhat.com>
++      * i386_disasm.c (i386_disasm): Add abort after assert-constant for old
++      compilers that don't realize it's noreturn.
++
+       * Makefile.am (i386_parse_CFLAGS): Use quotes around command
+       substitution that can produce leading whitespace.
+@@ -380,6 +383,11 @@
+       * defs/i386.doc: New file.
+       * defs/x86_64: New file.
++2005-04-04  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it instead of -Wextra.
++
+ 2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+       * Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+--- elfutils/libcpu/i386_disasm.c
++++ elfutils/libcpu/i386_disasm.c
+@@ -822,6 +822,7 @@ i386_disasm (const uint8_t **startp, con
+                       default:
+                         assert (! "INVALID not handled");
++                        abort ();
+                       }
+                   }
+                 else
+--- elfutils/libcpu/Makefile.in
++++ elfutils/libcpu/Makefile.in
+@@ -84,6 +84,7 @@ DIST_COMMON = $(top_srcdir)/config/eu.am
+       $(srcdir)/Makefile.am i386_lex.c i386_parse.c \
+       $(top_srcdir)/config/depcomp $(top_srcdir)/config/ylwrap \
+       $(am__noinst_HEADERS_DIST) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ @MAINTAINER_MODE_TRUE@noinst_PROGRAMS = i386_gendis$(EXEEXT)
+ subdir = libcpu
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+@@ -223,6 +224,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
+@@ -254,6 +256,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -316,10 +319,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+       -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 $(if \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
+       $($(*F)_no_Werror),,-Werror) $(if \
+-      $($(*F)_no_Wunused),,-Wunused -Wextra) $($(*F)_CFLAGS) -fpic \
+-      -fdollars-in-identifiers
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1) -fpic -fdollars-in-identifiers
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(foreach P,i386 x86_64,$P_defs \
+       $P.mnemonics)
+--- elfutils/libdw/ChangeLog
++++ elfutils/libdw/ChangeLog
+@@ -717,6 +717,10 @@
+       * Makefile.am (known-dwarf.h): Run gawk on config/known-dwarf.awk.
++2011-07-20  Mark Wielaard  <mjw@redhat.com>
++
++      * dwarf_begin_elf.c: Add fallback for be64toh if not defined.
++
+ 2011-07-14  Mark Wielaard  <mjw@redhat.com>
+       * libdw.h (dwarf_offdie): Fix documentation to mention .debug_info.
+@@ -1076,6 +1080,10 @@
+       * dwarf_hasattr_integrate.c: Integrate DW_AT_specification too.
++2009-08-17  Roland McGrath  <roland@redhat.com>
++
++      * libdw.h: Disable extern inlines for GCC 4.2.
++
+ 2009-08-10  Roland McGrath  <roland@redhat.com>
+       * dwarf_getscopevar.c: Use dwarf_diename.
+@@ -1844,6 +1852,11 @@
+ 2005-05-31  Roland McGrath  <roland@redhat.com>
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
+       * dwarf_formref_die.c (dwarf_formref_die): Add CU header offset to
+       formref offset.
+--- elfutils/libdw/dwarf_begin_elf.c
++++ elfutils/libdw/dwarf_begin_elf.c
+@@ -47,6 +47,14 @@
+ #if USE_ZLIB
+ # include <endian.h>
+ # define crc32                loser_crc32
++# ifndef be64toh
++#  include <byteswap.h>
++#  if __BYTE_ORDER == __LITTLE_ENDIAN
++#   define be64toh(x) bswap_64 (x)
++#  else
++#   define be64toh(x) (x)
++#  endif
++# endif
+ # include <zlib.h>
+ # undef crc32
+ #endif
+--- elfutils/libdw/libdw.h
++++ elfutils/libdw/libdw.h
+@@ -1003,7 +1003,7 @@ extern Dwarf_OOM dwarf_new_oom_handler (
+ /* Inline optimizations.  */
+-#ifdef __OPTIMIZE__
++#if defined __OPTIMIZE__ && !(__GNUC__ == 4 && __GNUC_MINOR__ == 2)
+ /* Return attribute code of given attribute.  */
+ __libdw_extern_inline unsigned int
+ dwarf_whatattr (Dwarf_Attribute *attr)
+--- elfutils/libdw/Makefile.in
++++ elfutils/libdw/Makefile.in
+@@ -84,7 +84,8 @@ DIST_COMMON = $(top_srcdir)/config/eu.am
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(include_HEADERS) $(noinst_HEADERS) $(pkginclude_HEADERS) \
+       ChangeLog
+-@BUILD_STATIC_TRUE@am__append_1 = -fpic
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
++@BUILD_STATIC_TRUE@am__append_2 = -fpic
+ noinst_PROGRAMS = $(am__EXEEXT_1)
+ subdir = libdw
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+@@ -298,6 +299,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -329,6 +331,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -390,10 +393,11 @@ top_srcdir = @top_srcdir@
+ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(srcdir)/../libelf
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 $(if \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
+       $($(*F)_no_Werror),,-Werror) $(if \
+-      $($(*F)_no_Wunused),,-Wunused -Wextra) $($(*F)_CFLAGS) \
+-      $(am__append_1)
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1) $(am__append_2)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+--- elfutils/libdwelf/Makefile.in
++++ elfutils/libdwelf/Makefile.in
+@@ -82,6 +82,7 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ subdir = libdwelf
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -227,6 +228,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -258,6 +260,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -320,11 +323,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(srcdir)/../libelf -I$(srcdir)/../libdw \
+       -I$(srcdir)/../libdwfl -I$(srcdir)/../libebl
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(am_libdwelf_pic_a_OBJECTS)
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+--- elfutils/libdwfl/ChangeLog
++++ elfutils/libdwfl/ChangeLog
+@@ -571,6 +571,21 @@
+       (dwfl_module_addrsym) (i_to_symfile): New function.
+       (dwfl_module_addrsym) (search_table): Use it.
++2013-11-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
++
++      Older OS compatibility bits.
++      * linux-core-attach.c (be64toh, le64toh, be32toh, le32toh): Provide
++      fallbacks if not defined by system.
++
++2013-11-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
++
++      Handle T-stopped detach for old kernels.
++      * linux-pid-attach.c (struct pid_arg): New field stopped.
++      (ptrace_attach): New parameter stoppedp.  Set it appropriately.
++      (pid_set_initial_registers): Pass the new field.
++      (pid_thread_detach): Handle the case of STOPPED for old kernels.
++      (__libdwfl_attach_state_for_pid): Initialize STOPPED.
++
+ 2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Mark Wielaard  <mjw@redhat.com>
+@@ -2336,6 +2351,11 @@
+ 2005-07-21  Roland McGrath  <roland@redhat.com>
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
++2005-07-21  Roland McGrath  <roland@redhat.com>
++
+       * Makefile.am (noinst_HEADERS): Add loc2c.c.
+       * test2.c (main): Check sscanf result to quiet warning.
+--- elfutils/libdwfl/linux-core-attach.c
++++ elfutils/libdwfl/linux-core-attach.c
+@@ -29,6 +29,35 @@
+ #include "libdwflP.h"
+ #include <fcntl.h>
+ #include "system.h"
++#include <endian.h>
++#include <byteswap.h>
++#if __BYTE_ORDER == __LITTLE_ENDIAN
++# ifndef be64toh
++#  define be64toh(x) bswap_64 (x)
++# endif
++# ifndef le64toh
++#  define le64toh(x) (x)
++# endif
++# ifndef be32toh
++#  define be32toh(x) bswap_32 (x)
++# endif
++# ifndef le32toh
++#  define le32toh(x) (x)
++# endif
++#else
++# ifndef be64toh
++#  define be64toh(x) (x)
++# endif
++# ifndef le64toh
++#  define le64toh(x) bswap_64 (x)
++# endif
++# ifndef be32toh
++#  define be32toh(x) (x)
++# endif
++# ifndef le32toh
++#  define le32toh(x) bswap_32 (x)
++# endif
++#endif
+ #include "../libdw/memory-access.h"
+--- elfutils/libdwfl/linux-pid-attach.c
++++ elfutils/libdwfl/linux-pid-attach.c
+@@ -255,6 +255,11 @@ void
+ internal_function
+ __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
+ {
++  // Older kernels (tested kernel-2.6.18-348.12.1.el5.x86_64) need special
++  // handling of the detachment to keep the process State: T (stopped).
++  if (tid_was_stopped)
++    syscall (__NR_tkill, tid, SIGSTOP);
++
+   /* This handling is needed only on older Linux kernels such as
+      2.6.32-358.23.2.el6.ppc64.  Later kernels such as
+      3.11.7-200.fc19.x86_64 remember the T (stopped) state
+@@ -262,6 +267,15 @@ __libdwfl_ptrace_detach (pid_t tid, bool
+      PTRACE_DETACH.  */
+   ptrace (PTRACE_DETACH, tid, NULL,
+         (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
++
++  if (tid_was_stopped)
++    {
++      // Wait till the SIGSTOP settles down.
++      int i;
++      for (i = 0; i < 100000; i++)
++      if (linux_proc_pid_is_stopped (tid))
++        break;
++    }
+ }
+ static void
+--- elfutils/libdwfl/Makefile.in
++++ elfutils/libdwfl/Makefile.in
+@@ -82,9 +82,10 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
+-@ZLIB_TRUE@am__append_1 = gzip.c
+-@BZLIB_TRUE@am__append_2 = bzip2.c
+-@LZMA_TRUE@am__append_3 = lzma.c
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
++@ZLIB_TRUE@am__append_2 = gzip.c
++@BZLIB_TRUE@am__append_3 = bzip2.c
++@LZMA_TRUE@am__append_4 = lzma.c
+ subdir = libdwfl
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -286,6 +287,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -317,6 +319,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -379,11 +382,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. -I$(srcdir) \
+       -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+       -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(am_libdwfl_pic_a_OBJECTS)
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+@@ -413,8 +416,8 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_en
+       dwfl_module_register_names.c dwfl_segment_report_module.c \
+       link_map.c core-file.c open.c image-header.c dwfl_frame.c \
+       frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \
+-      linux-core-attach.c dwfl_frame_regs.c $(am__append_1) \
+-      $(am__append_2) $(am__append_3)
++      linux-core-attach.c dwfl_frame_regs.c $(am__append_2) \
++      $(am__append_3) $(am__append_4)
+ libdwfl = $(libdw)
+ libdw = ../libdw/libdw.so
+ libelf = ../libelf/libelf.so
+--- elfutils/libebl/ChangeLog
++++ elfutils/libebl/ChangeLog
+@@ -765,6 +765,11 @@
+       * Makefile.am (libebl_*_so_SOURCES): Set to $(*_SRCS) so dependency
+       tracking works right.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-05-21  Ulrich Drepper  <drepper@redhat.com>
+       * libebl_x86_64.map: Add x86_64_core_note.
+--- elfutils/libebl/Makefile.in
++++ elfutils/libebl/Makefile.in
+@@ -82,6 +82,7 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ subdir = libebl
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -249,6 +250,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -280,6 +282,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -342,9 +345,11 @@ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. \
+       -I$(srcdir)/../libelf -I$(srcdir)/../libdw \
+       -I$(srcdir)/../libasm
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 $(if \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
+       $($(*F)_no_Werror),,-Werror) $(if \
+-      $($(*F)_no_Wunused),,-Wunused -Wextra) $($(*F)_CFLAGS) -fpic
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1) -fpic
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(am_libebl_pic_a_OBJECTS)
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+--- elfutils/libelf/ChangeLog
++++ elfutils/libelf/ChangeLog
+@@ -244,6 +244,11 @@
+       * elf-knowledge.h (SECTION_STRIP_P): Remove < SHT_NUM check.
++2011-03-10  Roland McGrath  <roland@redhat.com>
++
++      * gnuhash_xlate.h (elf_cvt_gnuhash): Avoid post-increment in bswap_32
++      argument, since some implementations are buggy macros.
++
+ 2011-02-26  Mark Wielaard  <mjw@redhat.com>
+       * elf_end.c (elf_end): Call rwlock_unlock before rwlock_fini.
+@@ -921,6 +926,11 @@
+       * elf.h: Update from glibc.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-05-08  Roland McGrath  <roland@redhat.com>
+       * elf_begin.c (read_file) [_MUDFLAP]: Don't use mmap for now.
+--- elfutils/libelf/common.h
++++ elfutils/libelf/common.h
+@@ -139,7 +139,7 @@ libelf_release_all (Elf *elf)
+   (Var) = (sizeof (Var) == 1                                                \
+          ? (unsigned char) (Var)                                            \
+          : (sizeof (Var) == 2                                               \
+-            ? bswap_16 (Var)                                                \
++            ? (unsigned short int) bswap_16 (Var)                           \
+             : (sizeof (Var) == 4                                            \
+                ? bswap_32 (Var)                                             \
+                : bswap_64 (Var))))
+@@ -148,7 +148,7 @@ libelf_release_all (Elf *elf)
+   (Dst) = (sizeof (Var) == 1                                                \
+          ? (unsigned char) (Var)                                            \
+          : (sizeof (Var) == 2                                               \
+-            ? bswap_16 (Var)                                                \
++            ? (unsigned short int) bswap_16 (Var)                           \
+             : (sizeof (Var) == 4                                            \
+                ? bswap_32 (Var)                                             \
+                : bswap_64 (Var))))
+--- elfutils/libelf/gnuhash_xlate.h
++++ elfutils/libelf/gnuhash_xlate.h
+@@ -1,5 +1,5 @@
+ /* Conversion functions for versioning information.
+-   Copyright (C) 2006, 2007 Red Hat, Inc.
++   Copyright (C) 2006-2011 Red Hat, Inc.
+    This file is part of elfutils.
+    Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+@@ -68,7 +68,9 @@ elf_cvt_gnuhash (void *dest, const void
+   dest32 = (Elf32_Word *) &dest64[bitmask_words];
+   while (len >= 4)
+     {
+-      *dest32++ = bswap_32 (*src32++);
++      *dest32 = bswap_32 (*src32);
++      ++dest32;
++      ++src32;
+       len -= 4;
+     }
+ }
+--- elfutils/libelf/Makefile.in
++++ elfutils/libelf/Makefile.in
+@@ -84,9 +84,10 @@ DIST_COMMON = $(top_srcdir)/config/eu.am
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(include_HEADERS) $(noinst_HEADERS) $(pkginclude_HEADERS) \
+       ChangeLog
+-@BUILD_STATIC_TRUE@am__append_1 = -fpic
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
++@BUILD_STATIC_TRUE@am__append_2 = -fpic
+ noinst_PROGRAMS = $(am__EXEEXT_1)
+-@USE_LOCKS_TRUE@am__append_2 = -lpthread
++@USE_LOCKS_TRUE@am__append_3 = -lpthread
+ subdir = libelf
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -291,6 +292,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -322,6 +324,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = 1
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -382,10 +385,11 @@ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ zip_LIBS = @zip_LIBS@
+ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I..
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 $(if \
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
+       $($(*F)_no_Werror),,-Werror) $(if \
+-      $($(*F)_no_Wunused),,-Wunused -Wextra) $($(*F)_CFLAGS) \
+-      $(am__append_1)
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1) $(am__append_2)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda $(am_libelf_pic_a_OBJECTS) \
+       libelf.so.$(VERSION)
+@@ -449,7 +453,7 @@ libelf_a_SOURCES = elf_version.c elf_has
+ libelf_pic_a_SOURCES = 
+ am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
+-libelf_so_LDLIBS = $(am__append_2)
++libelf_so_LDLIBS = $(am__append_3)
+ libelf_so_SOURCES = 
+ noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
+                version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h
+--- elfutils/m4/Makefile.in
++++ elfutils/m4/Makefile.in
+@@ -145,6 +145,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -176,6 +177,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+--- elfutils/Makefile.in
++++ elfutils/Makefile.in
+@@ -263,6 +263,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -294,6 +295,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+--- elfutils/src/addr2line.c
++++ elfutils/src/addr2line.c
+@@ -540,10 +540,10 @@ handle_address (const char *string, Dwfl
+       bool parsed = false;
+       int i, j;
+       char *name = NULL;
+-      if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2
++      if (sscanf (string, "(%a[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2
+         && string[i] == '\0')
+       parsed = adjust_to_section (name, &addr, dwfl);
+-      switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j))
++      switch (sscanf (string, "%a[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j))
+       {
+       default:
+         break;
+--- elfutils/src/ChangeLog
++++ elfutils/src/ChangeLog
+@@ -1371,8 +1371,16 @@
+       * readelf.c (attr_callback): Use print_block only when we don't use
+       print_ops.
++2009-08-17  Roland McGrath  <roland@redhat.com>
++
++      * ld.h: Disable extern inlines for GCC 4.2.
++
+ 2009-08-14  Roland McGrath  <roland@redhat.com>
++      * strings.c (read_block): Conditionalize posix_fadvise use
++      on [POSIX_FADV_SEQUENTIAL].
++      From Petr Salinger <Petr.Salinger@seznam.cz>.
++
+       * ar.c (do_oper_extract): Use pathconf instead of statfs.
+ 2009-08-01  Ulrich Drepper  <drepper@redhat.com>
+@@ -1536,6 +1544,8 @@
+       * readelf.c (print_debug_frame_section): Use t instead of j formats
+       for ptrdiff_t OFFSET.
++      * addr2line.c (handle_address): Use %a instead of %m for compatibility.
++
+ 2009-01-21  Ulrich Drepper  <drepper@redhat.com>
+       * elflint.c (check_program_header): Fix typo in .eh_frame_hdr section
+@@ -1719,6 +1729,11 @@
+       that matches its PT_LOAD's p_flags &~ PF_W.  On sparc, PF_X really
+       is valid in RELRO.
++2008-03-01  Roland McGrath  <roland@redhat.com>
++
++      * readelf.c (dump_archive_index): Tweak portability hack
++      to match [__GNUC__ < 4] too.
++
+ 2008-02-29  Roland McGrath  <roland@redhat.com>
+       * readelf.c (print_attributes): Add a cast.
+@@ -1970,6 +1985,8 @@
+       * readelf.c (hex_dump): Fix rounding error in whitespace calculation.
++      * Makefile.am (readelf_no_Werror): New variable.
++
+ 2007-10-15  Roland McGrath  <roland@redhat.com>
+       * make-debug-archive.in: New file.
+@@ -2409,6 +2426,10 @@
+       * elflint.c (valid_e_machine): Add EM_ALPHA.
+       Reported by Christian Aichinger <Greek0@gmx.net>.
++      * strings.c (map_file): Define POSIX_MADV_SEQUENTIAL to
++      MADV_SEQUENTIAL if undefined.   Don't call posix_madvise
++      if neither is defined.
++
+ 2006-08-08  Ulrich Drepper  <drepper@redhat.com>
+       * elflint.c (check_dynamic): Don't require DT_HASH for DT_SYMTAB.
+@@ -2485,6 +2506,10 @@
+       * Makefile.am: Add hacks to create dependency files for non-generic
+       linker.
++2006-04-05  Roland McGrath  <roland@redhat.com>
++
++      * strings.c (MAP_POPULATE): Define to 0 if undefined.
++
+ 2006-06-12  Ulrich Drepper  <drepper@redhat.com>
+       * ldgeneric.c (ld_generic_generate_sections): Don't create .interp
+@@ -2833,6 +2858,11 @@
+       * readelf.c (print_debug_loc_section): Fix indentation for larger
+       address size.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-05-30  Roland McGrath  <roland@redhat.com>
+       * readelf.c (print_debug_line_section): Print section offset of each
+--- elfutils/src/findtextrel.c
++++ elfutils/src/findtextrel.c
+@@ -502,7 +502,11 @@ ptrcompare (const void *p1, const void *
+ static void
+-check_rel (size_t nsegments, struct segments segments[nsegments],
++check_rel (size_t nsegments, struct segments segments[
++#if __GNUC__ >= 4
++                                                    nsegments
++#endif
++         ],
+          GElf_Addr addr, Elf *elf, Elf_Scn *symscn, Dwarf *dw,
+          const char *fname, bool more_than_one, void **knownsrcs)
+ {
+--- elfutils/src/ld.h
++++ elfutils/src/ld.h
+@@ -1114,6 +1114,7 @@ extern bool dynamically_linked_p (void);
+ /* Checked whether the symbol is undefined and referenced from a DSO.  */
+ extern bool linked_from_dso_p (struct scninfo *scninfo, size_t symidx);
++#if defined __OPTIMIZE__ && !(__GNUC__ == 4 && __GNUC_MINOR__ == 2)
+ #ifdef __GNUC_STDC_INLINE__
+ __attribute__ ((__gnu_inline__))
+ #endif
+@@ -1131,5 +1132,6 @@ linked_from_dso_p (struct scninfo *scnin
+   return sym->defined && sym->in_dso;
+ }
++#endif        /* Optimizing and not GCC 4.2.  */
+ #endif        /* ld.h */
+--- elfutils/src/Makefile.am
++++ elfutils/src/Makefile.am
+@@ -89,6 +89,11 @@ endif
+ # XXX While the file is not finished, don't warn about this
+ ldgeneric_no_Wunused = yes
++# Buggy old compilers or libc headers.
++readelf_no_Werror = yes
++strings_no_Werror = yes
++addr2line_no_Wformat = yes
++
+ readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl
+ nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl \
+          $(demanglelib)
+--- elfutils/src/Makefile.in
++++ elfutils/src/Makefile.in
+@@ -85,6 +85,7 @@ DIST_COMMON = $(top_srcdir)/config/eu.am
+       $(srcdir)/Makefile.am ldlex.c ldscript.c \
+       $(top_srcdir)/config/depcomp $(top_srcdir)/config/ylwrap \
+       $(noinst_HEADERS) ChangeLog
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
+ bin_PROGRAMS = readelf$(EXEEXT) nm$(EXEEXT) size$(EXEEXT) \
+       strip$(EXEEXT) ld$(EXEEXT) elflint$(EXEEXT) \
+       findtextrel$(EXEEXT) addr2line$(EXEEXT) elfcmp$(EXEEXT) \
+@@ -93,9 +94,9 @@ bin_PROGRAMS = readelf$(EXEEXT) nm$(EXEE
+ @NATIVE_LD_FALSE@noinst_PROGRAMS = $(am__EXEEXT_1)
+ # We never build this library but we need to get the dependency files
+ # of all the linker backends that might be used in a non-generic linker.
+-@NEVER_TRUE@am__append_1 = libdummy.a
++@NEVER_TRUE@am__append_2 = libdummy.a
+ # -ldl is always needed for libebl.
+-@NATIVE_LD_TRUE@am__append_2 = libld_elf.a
++@NATIVE_LD_TRUE@am__append_3 = libld_elf.a
+ @NATIVE_LD_TRUE@am_libld_elf_i386_pic_a_OBJECTS =
+ subdir = src
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+@@ -159,7 +160,7 @@ am_ld_OBJECTS = ld.$(OBJEXT) ldgeneric.$
+       ldscript.$(OBJEXT) symbolhash.$(OBJEXT) sectionhash.$(OBJEXT) \
+       versionhash.$(OBJEXT)
+ ld_OBJECTS = $(am_ld_OBJECTS)
+-ld_DEPENDENCIES = $(libebl) $(libelf) $(libeu) $(am__append_2)
++ld_DEPENDENCIES = $(libebl) $(libelf) $(libeu) $(am__append_3)
+ ld_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ld_LDFLAGS) $(LDFLAGS) -o \
+       $@
+ am_libld_elf_i386_so_OBJECTS =
+@@ -340,6 +341,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -371,6 +373,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -434,11 +437,11 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_sr
+       -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+       -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
+       -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda make-debug-archive none_ld.os \
+       $(ld_modules:.c=.os) *.gconv
+@@ -452,8 +455,8 @@ AM_LFLAGS = -Pld -olex.yy.c
+ native_ld = @native_ld@
+ ld_dsos = libld_elf_i386_pic.a
+ @NATIVE_LD_FALSE@noinst_LIBRARIES = libld_elf.a libar.a $(ld_dsos) \
+-@NATIVE_LD_FALSE@     $(am__append_1)
+-@NATIVE_LD_TRUE@noinst_LIBRARIES = libld_elf.a libar.a $(am__append_1)
++@NATIVE_LD_FALSE@     $(am__append_2)
++@NATIVE_LD_TRUE@noinst_LIBRARIES = libld_elf.a libar.a $(am__append_2)
+ @NATIVE_LD_TRUE@native_ld_cflags = -DBASE_ELF_NAME=elf_$(base_cpu)
+ @NEVER_TRUE@libdummy_a_SOURCES = i386_ld.c
+ ld_SOURCES = ld.c ldgeneric.c ldlex.l ldscript.y symbolhash.c sectionhash.c \
+@@ -479,13 +482,18 @@ libeu = ../lib/libeu.a
+ # XXX While the file is not finished, don't warn about this
+ ldgeneric_no_Wunused = yes
++
++# Buggy old compilers or libc headers.
++readelf_no_Werror = yes
++strings_no_Werror = yes
++addr2line_no_Wformat = yes
+ readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl
+ nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl \
+          $(demanglelib)
+ size_LDADD = $(libelf) $(libeu)
+ strip_LDADD = $(libebl) $(libelf) $(libeu) -ldl
+-ld_LDADD = $(libebl) $(libelf) $(libeu) -ldl $(am__append_2)
++ld_LDADD = $(libebl) $(libelf) $(libeu) -ldl $(am__append_3)
+ ld_LDFLAGS = -rdynamic
+ elflint_LDADD = $(libebl) $(libelf) $(libeu) -ldl
+ findtextrel_LDADD = $(libdw) $(libelf)
+--- elfutils/src/readelf.c
++++ elfutils/src/readelf.c
+@@ -4368,10 +4368,12 @@ listptr_base (struct listptr *p)
+   return base;
+ }
++static const char *listptr_name;
++
+ static int
+-compare_listptr (const void *a, const void *b, void *arg)
++compare_listptr (const void *a, const void *b)
+ {
+-  const char *name = arg;
++  const char *const name = listptr_name;
+   struct listptr *p1 = (void *) a;
+   struct listptr *p2 = (void *) b;
+@@ -4467,8 +4469,11 @@ static void
+ sort_listptr (struct listptr_table *table, const char *name)
+ {
+   if (table->n > 0)
+-    qsort_r (table->table, table->n, sizeof table->table[0],
+-           &compare_listptr, (void *) name);
++    {
++      listptr_name = name;
++      qsort (table->table, table->n, sizeof table->table[0],
++           &compare_listptr);
++    }
+ }
+ static bool
+@@ -9539,7 +9544,7 @@ dump_archive_index (Elf *elf, const char
+         if (unlikely (elf_rand (elf, as_off) == 0)
+             || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
+                          == NULL))
+-#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
++#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7) || __GNUC__ < 4
+           while (1)
+ #endif
+             error (EXIT_FAILURE, 0,
+--- elfutils/src/strings.c
++++ elfutils/src/strings.c
+@@ -43,6 +43,10 @@
+ #include <system.h>
++#ifndef MAP_POPULATE
++# define MAP_POPULATE 0
++#endif
++
+ /* Prototypes of local functions.  */
+ static int read_fd (int fd, const char *fname, off64_t fdlen);
+@@ -489,8 +493,13 @@ map_file (int fd, off64_t start_off, off
+                   fd, start_off);
+       if (mem != MAP_FAILED)
+       {
++#if !defined POSIX_MADV_SEQUENTIAL && defined MADV_SEQUENTIAL
++# define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL
++#endif
++#ifdef POSIX_MADV_SEQUENTIAL
+         /* We will go through the mapping sequentially.  */
+         (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL);
++#endif
+         break;
+       }
+       if (errno != EINVAL && errno != ENOMEM)
+@@ -581,9 +590,11 @@ read_block (int fd, const char *fname, o
+       elfmap_off = from & ~(ps - 1);
+       elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size);
++#ifdef POSIX_FADV_SEQUENTIAL
+       if (unlikely (elfmap == MAP_FAILED))
+       /* Let the kernel know we are going to read everything in sequence.  */
+       (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
++#endif
+     }
+   if (unlikely (elfmap == MAP_FAILED))
+--- elfutils/src/strip.c
++++ elfutils/src/strip.c
+@@ -45,6 +45,12 @@
+ #include <libebl.h>
+ #include <system.h>
++#ifdef HAVE_FUTIMES
++# define FUTIMES(fd, fname, tvp) futimes (fd, tvp)
++#else
++# define FUTIMES(fd, fname, tvp) utimes (fname, tvp)
++#endif
++
+ typedef uint8_t GElf_Byte;
+ /* Name and version of program.  */
+@@ -318,8 +324,18 @@ process_file (const char *fname)
+       /* If we have to preserve the timestamp, we need it in the
+        format utimes() understands.  */
++#ifdef HAVE_STRUCT_STAT_ST_ATIM
+       TIMESPEC_TO_TIMEVAL (&tv[0], &pre_st.st_atim);
++#else
++      tv[0].tv_sec = pre_st.st_atime;
++      tv[0].tv_usec = 0;
++#endif
++#ifdef HAVE_STRUCT_STAT_ST_MTIM
+       TIMESPEC_TO_TIMEVAL (&tv[1], &pre_st.st_mtim);
++#else
++      tv[1].tv_sec = pre_st.st_atime;
++      tv[1].tv_usec = 0;
++#endif
+     }
+   /* Open the file.  */
+@@ -2091,7 +2107,7 @@ while computing checksum for debug infor
+   /* If requested, preserve the timestamp.  */
+   if (tvp != NULL)
+     {
+-      if (futimes (fd, tvp) != 0)
++      if (FUTIMES (fd, output_fname, tvp) != 0)
+       {
+         error (0, errno, gettext ("\
+ cannot set access and modification date of '%s'"),
+@@ -2148,7 +2164,7 @@ handle_ar (int fd, Elf *elf, const char
+   if (tvp != NULL)
+     {
+-      if (unlikely (futimes (fd, tvp) != 0))
++      if (unlikely (FUTIMES (fd, fname, tvp) != 0))
+       {
+         error (0, errno, gettext ("\
+ cannot set access and modification date of '%s'"), fname);
+--- elfutils/tests/backtrace.c
++++ elfutils/tests/backtrace.c
+@@ -36,6 +36,7 @@
+ #include <fcntl.h>
+ #include <string.h>
+ #include <argp.h>
++#include <sys/syscall.h>
+ #include ELFUTILS_HEADER(dwfl)
+ #ifndef __linux__
+--- elfutils/tests/ChangeLog
++++ elfutils/tests/ChangeLog
+@@ -421,6 +421,13 @@
+ 2013-12-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
++      Handle T-stopped detach for old kernels.
++      * backtrace.c: Include sys/syscall.h.
++      (linux_proc_pid_is_stopped): New function.
++      (ptrace_detach_stopped): Handle old kernels.
++
++2013-12-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
++
+       * Makefile.am (check_PROGRAMS): Add backtrace, backtrace-child,
+       backtrace-data and backtrace-dwarf.
+       (BUILT_SOURCES, clean-local, backtrace-child-biarch): New.
+@@ -1285,6 +1292,8 @@
+ 2008-01-21  Roland McGrath  <roland@redhat.com>
++      * line2addr.c (main): Revert last change.
++
+       * testfile45.S.bz2: Add tests for cltq, cqto.
+       * testfile45.expect.bz2: Adjust.
+@@ -1993,6 +2002,11 @@
+       * Makefile.am (TESTS): Add run-elflint-test.sh.
+       (EXTRA_DIST): Add run-elflint-test.sh and testfile18.bz2.
++2005-05-31  Roland McGrath  <roland@redhat.com>
++
++      * Makefile.am (WEXTRA): New variable, substituted by configure.
++      (AM_CFLAGS): Use it in place of -Wextra.
++
+ 2005-05-24  Ulrich Drepper  <drepper@redhat.com>
+       * get-files.c (main): Use correct format specifier.
+--- elfutils/tests/line2addr.c
++++ elfutils/tests/line2addr.c
+@@ -124,7 +124,7 @@ main (int argc, char *argv[])
+     {
+       struct args a = { .arg = argv[cnt] };
+-      switch (sscanf (a.arg, "%m[^:]:%d", &a.file, &a.line))
++      switch (sscanf (a.arg, "%a[^:]:%d", &a.file, &a.line))
+       {
+       default:
+       case 0:
+--- elfutils/tests/Makefile.am
++++ elfutils/tests/Makefile.am
+@@ -365,6 +365,7 @@ get_lines_LDADD = $(libdw) $(libelf)
+ get_files_LDADD = $(libdw) $(libelf)
+ get_aranges_LDADD = $(libdw) $(libelf)
+ allfcts_LDADD = $(libdw) $(libelf)
++line2addr_no_Wformat = yes
+ line2addr_LDADD = $(libdw)
+ addrscopes_LDADD = $(libdw)
+ funcscopes_LDADD = $(libdw)
+--- elfutils/tests/Makefile.in
++++ elfutils/tests/Makefile.in
+@@ -80,13 +80,14 @@ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
+       $(top_srcdir)/config/test-driver ChangeLog
+-@STANDALONE_FALSE@am__append_1 = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
++@BUILD_WERROR_TRUE@am__append_1 = $(if $($(*F)_no_Werror),,-Werror)
++@STANDALONE_FALSE@am__append_2 = -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+ @STANDALONE_FALSE@        -I$(top_srcdir)/libdwfl -I$(top_srcdir)/libdwelf \
+ @STANDALONE_FALSE@        -I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \
+ @STANDALONE_FALSE@        -I$(top_srcdir)/lib -I..
+-@STANDALONE_FALSE@am__append_2 = -Wl,-rpath-link,../libasm:../libdw:../libelf
+-@TESTS_RPATH_TRUE@am__append_3 = -Wl,-rpath,$(BUILD_RPATH)
++@STANDALONE_FALSE@am__append_3 = -Wl,-rpath-link,../libasm:../libdw:../libelf
++@TESTS_RPATH_TRUE@am__append_4 = -Wl,-rpath,$(BUILD_RPATH)
+ check_PROGRAMS = arextract$(EXEEXT) arsymtest$(EXEEXT) \
+       newfile$(EXEEXT) saridx$(EXEEXT) scnnames$(EXEEXT) \
+       sectiondump$(EXEEXT) showptable$(EXEEXT) update1$(EXEEXT) \
+@@ -113,7 +114,7 @@ check_PROGRAMS = arextract$(EXEEXT) arsy
+       deleted$(EXEEXT) deleted-lib.so$(EXEEXT) \
+       aggregate_size$(EXEEXT) vdsosyms$(EXEEXT) $(am__EXEEXT_1) \
+       $(am__EXEEXT_2) $(am__EXEEXT_4)
+-@BIARCH_TRUE@am__append_4 = backtrace-child-biarch
++@BIARCH_TRUE@am__append_5 = backtrace-child-biarch
+ TESTS = run-arextract.sh run-arsymtest.sh newfile$(EXEEXT) \
+       test-nlist$(EXEEXT) update1$(EXEEXT) update2$(EXEEXT) \
+       update3$(EXEEXT) update4$(EXEEXT) run-show-die-info.sh \
+@@ -159,14 +160,14 @@ TESTS = run-arextract.sh run-arsymtest.s
+       run-stack-i-test.sh run-readelf-dwz-multi.sh \
+       run-allfcts-multi.sh run-deleted.sh run-linkmap-cut.sh \
+       run-aggregate-size.sh vdsosyms$(EXEEXT) run-readelf-A.sh \
+-      $(am__EXEEXT_2) $(am__append_7) $(am__append_8) \
++      $(am__EXEEXT_2) $(am__append_8) $(am__append_9) \
+       $(am__EXEEXT_4)
+-@STANDALONE_FALSE@am__append_5 = msg_tst md5-sha1-test
+ @STANDALONE_FALSE@am__append_6 = msg_tst md5-sha1-test
+-@LZMA_TRUE@am__append_7 = run-readelf-s.sh run-dwflsyms.sh
+-@ZLIB_TRUE@am__append_8 = run-readelf-zdebug.sh
+-@HAVE_LIBASM_TRUE@am__append_9 = $(asm_TESTS)
++@STANDALONE_FALSE@am__append_7 = msg_tst md5-sha1-test
++@LZMA_TRUE@am__append_8 = run-readelf-s.sh run-dwflsyms.sh
++@ZLIB_TRUE@am__append_9 = run-readelf-zdebug.sh
+ @HAVE_LIBASM_TRUE@am__append_10 = $(asm_TESTS)
++@HAVE_LIBASM_TRUE@am__append_11 = $(asm_TESTS)
+ subdir = tests
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
+@@ -787,6 +788,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LDFLAGS = @LDFLAGS@
++LD_AS_NEEDED = @LD_AS_NEEDED@
+ LEX = @LEX@
+ LEXLIB = @LEXLIB@
+ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+@@ -818,6 +820,7 @@ SHELL = @SHELL@
+ STRIP = @STRIP@
+ USE_NLS = @USE_NLS@
+ VERSION = @VERSION@
++WEXTRA = @WEXTRA@
+ XGETTEXT = @XGETTEXT@
+ XGETTEXT_015 = @XGETTEXT_015@
+ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+@@ -877,12 +880,12 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ zip_LIBS = @zip_LIBS@
+-AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. $(am__append_1)
+-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+-          $(if $($(*F)_no_Werror),,-Werror) \
+-          $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+-          $($(*F)_CFLAGS)
+-
++AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. $(am__append_2)
++AM_CFLAGS = -std=gnu99 -Wall -Wshadow $(if \
++      $($(*F)_no_Werror),,-Werror) $(if \
++      $($(*F)_no_Wunused),,-Wunused $(WEXTRA)) $(if \
++      $($(*F)_no_Wformat),-Wno-format,-Wformat=2) $($(*F)_CFLAGS) \
++      $(am__append_1)
+ COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+ CLEANFILES = *.gcno *.gcda
+ textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+@@ -890,7 +893,7 @@ textrel_msg = echo "WARNING: TEXTREL fou
+ @FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1
+ textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi
+ BUILD_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf
+-AM_LDFLAGS = $(am__append_2) $(am__append_3)
++AM_LDFLAGS = $(am__append_3) $(am__append_4)
+ @TESTS_RPATH_FALSE@tests_rpath = no
+ @TESTS_RPATH_TRUE@tests_rpath = yes
+ asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
+@@ -1106,6 +1109,7 @@ get_lines_LDADD = $(libdw) $(libelf)
+ get_files_LDADD = $(libdw) $(libelf)
+ get_aranges_LDADD = $(libdw) $(libelf)
+ allfcts_LDADD = $(libdw) $(libelf)
++line2addr_no_Wformat = yes
+ line2addr_LDADD = $(libdw)
+ addrscopes_LDADD = $(libdw)
+ funcscopes_LDADD = $(libdw)
diff --git a/libs/elfutils/patches/002-argp_standalone.patch b/libs/elfutils/patches/002-argp_standalone.patch
new file mode 100644 (file)
index 0000000..d1511a9
--- /dev/null
@@ -0,0 +1,14 @@
+--- elfutils-0.160/lib/color.c.old     2014-11-06 03:46:43.584116134 -0200
++++ elfutils-0.160/lib/color.c 2014-11-06 03:47:25.840116128 -0200
+@@ -131,8 +131,10 @@
+   - 'never', 'no', 'none'\n\
+   - 'auto', 'tty', 'if-tty'\n"),
+                    program_invocation_short_name, arg);
++          char program_invocation_short_name_nonconst[sizeof(program_invocation_short_name)];
++          strcpy(program_invocation_short_name_nonconst, program_invocation_short_name);
+             argp_help (&color_argp, stderr, ARGP_HELP_SEE,
+-                       program_invocation_short_name);
++                       program_invocation_short_name_nonconst);
+             exit (EXIT_FAILURE);
+           }
+       }
diff --git a/libs/elfutils/patches/003-libint-stub.patch b/libs/elfutils/patches/003-libint-stub.patch
new file mode 100644 (file)
index 0000000..c9ceb37
--- /dev/null
@@ -0,0 +1,49 @@
+--- elfutils-0.160/libelf/libelfP.h.old        2014-11-06 01:47:55.420116984 -0200
++++ elfutils-0.160/libelf/libelfP.h    2014-11-06 01:48:33.368116980 -0200
+@@ -43,6 +43,9 @@
+ #include <string.h>
++#ifdef _ /* fix libintl-stub */
++#undef _
++#endif
+ /* gettext helper macros.  */
+ #define _(Str) dgettext ("elfutils", Str)
+--- elfutils-0.160/libdw/libdwP.h.old  2014-11-06 02:27:12.628116703 -0200
++++ elfutils-0.160/libdw/libdwP.h      2014-11-06 02:27:39.816116700 -0200
+@@ -36,7 +36,9 @@
+ #include <libdw.h>
+ #include <dwarf.h>
+-
++#ifdef _ /* fix libintl-stub */
++#undef _
++#endif
+ /* gettext helper macros.  */
+ #define _(Str) dgettext ("elfutils", Str)
+--- elfutils-0.160/libdwfl/libdwflP.h.old      2014-11-06 02:31:20.112116673 -0200
++++ elfutils-0.160/libdwfl/libdwflP.h  2014-11-06 02:33:00.548116661 -0200
+@@ -46,6 +46,9 @@
+ typedef struct Dwfl_Process Dwfl_Process;
++#ifdef _ /* fix libintl-stub */
++#undef _
++#endif
+ /* gettext helper macros.  */
+ #define _(Str) dgettext ("elfutils", Str)
+--- elfutils-0.160/libasm/libasmP.h.old        2014-11-06 02:31:32.064116672 -0200
++++ elfutils-0.160/libasm/libasmP.h    2014-11-06 02:33:08.656116660 -0200
+@@ -33,6 +33,9 @@
+ #include <libasm.h>
++#ifdef _ /* fix libintl-stub */
++#undef _
++#endif
+ /* gettext helper macros.  */
+ #define _(Str) dgettext ("elfutils", Str)
diff --git a/libs/elfutils/patches/004-maybe-uninitialized.patch b/libs/elfutils/patches/004-maybe-uninitialized.patch
new file mode 100644 (file)
index 0000000..7d54d71
--- /dev/null
@@ -0,0 +1,11 @@
+--- elfutils-0.160/libelf/elf_getarsym.c.org   2014-11-06 01:56:58.664116919 -0200
++++ elfutils-0.160/libelf/elf_getarsym.c       2014-11-06 01:57:09.396116918 -0200
+@@ -166,7 +166,7 @@
+       /* We have an archive.  The first word in there is the number of
+        entries in the table.  */
+-      uint64_t n;
++      uint64_t n = 0;
+       size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr);
+       if (read_number_entries (&n, elf, &off, index64_p) < 0)
+       {
diff --git a/libs/elfutils/patches/004-memcpy_def.patch b/libs/elfutils/patches/004-memcpy_def.patch
new file mode 100644 (file)
index 0000000..62e4d0c
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/libelf/libelf.h
++++ b/libelf/libelf.h
+@@ -34,6 +34,11 @@
+ /* Get the ELF types.  */
+ #include <elf.h>
++#ifndef _LIBC
++#ifndef __mempcpy
++#define __mempcpy mempcpy
++#endif
++#endif
+ /* Known translation types.  */
+ typedef enum
diff --git a/libs/elfutils/patches/005-build_only_libs.patch b/libs/elfutils/patches/005-build_only_libs.patch
new file mode 100644 (file)
index 0000000..b8b4594
--- /dev/null
@@ -0,0 +1,24 @@
+--- elfutils-0.160/Makefile.in.old     2014-11-06 03:56:04.828116067 -0200
++++ elfutils-0.160/Makefile.in 2014-11-06 03:57:03.380116060 -0200
+@@ -359,8 +359,7 @@
+ pkginclude_HEADERS = version.h
+ # Add doc back when we have some real content.
+-SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libcpu libasm \
+-        backends src po tests
++SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libasm
+ EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
+            COPYING COPYING-GPLV2 COPYING-LGPLV3
+--- elfutils-0.160/Makefile.am.old     2014-11-06 03:58:13.012116051 -0200
++++ elfutils-0.160/Makefile.am 2014-11-06 03:58:25.948116050 -0200
+@@ -23,8 +23,7 @@
+ pkginclude_HEADERS = version.h
+ # Add doc back when we have some real content.
+-SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libcpu libasm \
+-        backends src po tests
++SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libasm
+ EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
+            COPYING COPYING-GPLV2 COPYING-LGPLV3
diff --git a/libs/elfutils/patches/006-libdw_LIBS.patch b/libs/elfutils/patches/006-libdw_LIBS.patch
new file mode 100644 (file)
index 0000000..aaa35f9
--- /dev/null
@@ -0,0 +1,11 @@
+--- elfutils-0.161/libdw/Makefile.in.orig      2015-01-16 03:50:15.311237461 -0200
++++ elfutils-0.161/libdw/Makefile.in   2015-01-16 03:55:35.082090075 -0200
+@@ -969,7 +969,7 @@
+               -Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
+               -Wl,--version-script,$<,--no-undefined \
+               -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
+-              -ldl $(zip_LIBS)
++              -ldl $(zip_LIBS) $(LIBS)
+       @$(textrel_check)
+       ln -fs $@ $@.$(VERSION)
diff --git a/libs/elfutils/patches/100-musl-compat.patch b/libs/elfutils/patches/100-musl-compat.patch
new file mode 100644 (file)
index 0000000..076b9cf
--- /dev/null
@@ -0,0 +1,788 @@
+--- a/lib/system.h
++++ b/lib/system.h
+@@ -68,6 +68,16 @@ extern int crc32_file (int fd, uint32_t
+ #define gettext_noop(Str) Str
++#ifndef TEMP_FAILURE_RETRY
++#define TEMP_FAILURE_RETRY(expression) \
++  (__extension__                                                            \
++    ({ long int __result;                                                   \
++       do __result = (long int) (expression);                               \
++       while (__result == -1L && errno == EINTR);                           \
++       __result; }))
++#endif
++
++#define error(status, errno, ...) err(status, __VA_ARGS__)
+ static inline ssize_t __attribute__ ((unused))
+ pwrite_retry (int fd, const void *buf, size_t len, off_t off)
+--- a/lib/color.c
++++ b/lib/color.c
+@@ -32,7 +32,7 @@
+ #endif
+ #include <argp.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+ #include <string.h>
+--- a/lib/xmalloc.c
++++ b/lib/xmalloc.c
+@@ -30,7 +30,7 @@
+ # include <config.h>
+ #endif
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stddef.h>
+ #include <stdlib.h>
+--- a/src/addr2line.c
++++ b/src/addr2line.c
+@@ -23,7 +23,7 @@
+ #include <argp.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <inttypes.h>
+ #include <libdwfl.h>
+--- a/src/ar.c
++++ b/src/ar.c
+@@ -22,7 +22,7 @@
+ #include <argp.h>
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <libintl.h>
+--- a/src/arlib2.c
++++ b/src/arlib2.c
+@@ -20,7 +20,7 @@
+ # include <config.h>
+ #endif
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <limits.h>
+ #include <string.h>
+--- a/src/arlib.c
++++ b/src/arlib.c
+@@ -21,7 +21,7 @@
+ #endif
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <gelf.h>
+ #include <libintl.h>
+ #include <stdio.h>
+--- a/src/elfcmp.c
++++ b/src/elfcmp.c
+@@ -23,7 +23,7 @@
+ #include <argp.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <locale.h>
+ #include <libintl.h>
+--- a/src/elflint.c
++++ b/src/elflint.c
+@@ -24,7 +24,7 @@
+ #include <assert.h>
+ #include <byteswap.h>
+ #include <endian.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/src/findtextrel.c
++++ b/src/findtextrel.c
+@@ -23,7 +23,7 @@
+ #include <argp.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <libdw.h>
+--- a/src/i386_ld.c
++++ b/src/i386_ld.c
+@@ -20,7 +20,7 @@
+ #endif
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+ #include <string.h>
+--- a/src/ld.c
++++ b/src/ld.c
+@@ -21,7 +21,7 @@
+ #include <argp.h>
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <libelf.h>
+ #include <libintl.h>
+--- a/src/ldgeneric.c
++++ b/src/ldgeneric.c
+@@ -23,7 +23,7 @@
+ #include <ctype.h>
+ #include <dlfcn.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <fnmatch.h>
+ #include <gelf.h>
+--- a/src/ldlex.c
++++ b/src/ldlex.c
+@@ -1099,7 +1099,7 @@ char *ldtext;
+ #include <assert.h>
+ #include <ctype.h>
+ #include <elf.h>
+-#include <error.h>
++#include <err.h>
+ #include <inttypes.h>
+ #include <libintl.h>
+ #include <stdbool.h>
+--- a/src/ldscript.c
++++ b/src/ldscript.c
+@@ -95,7 +95,7 @@
+ #endif
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stdbool.h>
+ #include <stdint.h>
+@@ -106,7 +106,7 @@
+ #include <system.h>
+ #include <ld.h>
+-/* The error handler.  */
++/* The err.handler.  */
+ static void yyerror (const char *s);
+ /* Some helper functions we need to construct the data structures
+--- a/src/nm.c
++++ b/src/nm.c
+@@ -26,7 +26,7 @@
+ #include <ctype.h>
+ #include <dwarf.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/src/objdump.c
++++ b/src/objdump.c
+@@ -21,7 +21,7 @@
+ #endif
+ #include <argp.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <inttypes.h>
+ #include <libintl.h>
+--- a/src/ranlib.c
++++ b/src/ranlib.c
+@@ -24,7 +24,7 @@
+ #include <argp.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <libintl.h>
+--- a/src/readelf.c
++++ b/src/readelf.c
+@@ -25,7 +25,7 @@
+ #include <ctype.h>
+ #include <dwarf.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/src/size.c
++++ b/src/size.c
+@@ -21,7 +21,7 @@
+ #endif
+ #include <argp.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/src/stack.c
++++ b/src/stack.c
+@@ -18,7 +18,7 @@
+ #include <config.h>
+ #include <assert.h>
+ #include <argp.h>
+-#include <error.h>
++#include <err.h>
+ #include <stdlib.h>
+ #include <inttypes.h>
+ #include <stdio.h>
+--- a/src/strings.c
++++ b/src/strings.c
+@@ -25,7 +25,7 @@
+ #include <ctype.h>
+ #include <endian.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/src/strip.c
++++ b/src/strip.c
+@@ -24,7 +24,7 @@
+ #include <assert.h>
+ #include <byteswap.h>
+ #include <endian.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <libelf.h>
+--- a/src/unstrip.c
++++ b/src/unstrip.c
+@@ -31,7 +31,7 @@
+ #include <argp.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <fnmatch.h>
+ #include <libintl.h>
+--- a/tests/addrscopes.c
++++ b/tests/addrscopes.c
+@@ -25,7 +25,7 @@
+ #include <stdio_ext.h>
+ #include <locale.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+--- a/tests/allregs.c
++++ b/tests/allregs.c
+@@ -21,7 +21,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ #include <locale.h>
+ #include <argp.h>
+ #include <assert.h>
+--- a/tests/backtrace.c
++++ b/tests/backtrace.c
+@@ -24,7 +24,7 @@
+ #include <dirent.h>
+ #include <stdlib.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <unistd.h>
+ #include <dwarf.h>
+ #include <sys/resource.h>
+--- a/tests/backtrace-data.c
++++ b/tests/backtrace-data.c
+@@ -27,7 +27,7 @@
+ #include <dirent.h>
+ #include <stdlib.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <unistd.h>
+ #include <dwarf.h>
+ #include <sys/resource.h>
+--- a/tests/buildid.c
++++ b/tests/buildid.c
+@@ -23,7 +23,7 @@
+ #include ELFUTILS_HEADER(elf)
+ #include ELFUTILS_HEADER(dwelf)
+ #include <stdio.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+--- a/tests/debugaltlink.c
++++ b/tests/debugaltlink.c
+@@ -23,7 +23,7 @@
+ #include ELFUTILS_HEADER(dw)
+ #include ELFUTILS_HEADER(dwelf)
+ #include <stdio.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+--- a/tests/debuglink.c
++++ b/tests/debuglink.c
+@@ -21,7 +21,7 @@
+ #include <errno.h>
+ #include ELFUTILS_HEADER(dwelf)
+ #include <stdio.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+--- a/tests/dwfl-addr-sect.c
++++ b/tests/dwfl-addr-sect.c
+@@ -23,7 +23,7 @@
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ #include <locale.h>
+ #include <argp.h>
+ #include ELFUTILS_HEADER(dwfl)
+--- a/tests/dwfl-bug-addr-overflow.c
++++ b/tests/dwfl-bug-addr-overflow.c
+@@ -20,7 +20,7 @@
+ #include <inttypes.h>
+ #include <stdio.h>
+ #include <stdio_ext.h>
+-#include <error.h>
++#include <err.h>
+ #include <locale.h>
+ #include ELFUTILS_HEADER(dwfl)
+--- a/tests/dwfl-bug-fd-leak.c
++++ b/tests/dwfl-bug-fd-leak.c
+@@ -24,7 +24,7 @@
+ #include <dirent.h>
+ #include <stdlib.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <unistd.h>
+ #include <dwarf.h>
+ #include <sys/resource.h>
+--- a/tests/dwfl-bug-getmodules.c
++++ b/tests/dwfl-bug-getmodules.c
+@@ -18,7 +18,7 @@
+ #include <config.h>
+ #include ELFUTILS_HEADER(dwfl)
+-#include <error.h>
++#include <err.h>
+ static const Dwfl_Callbacks callbacks =
+   {
+--- a/tests/dwfllines.c
++++ b/tests/dwfllines.c
+@@ -27,7 +27,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ int
+ main (int argc, char *argv[])
+--- a/tests/dwflmodtest.c
++++ b/tests/dwflmodtest.c
+@@ -23,7 +23,7 @@
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ #include <locale.h>
+ #include <argp.h>
+ #include ELFUTILS_HEADER(dwfl)
+--- a/tests/dwfl-report-elf-align.c
++++ b/tests/dwfl-report-elf-align.c
+@@ -20,7 +20,7 @@
+ #include <inttypes.h>
+ #include <stdio.h>
+ #include <stdio_ext.h>
+-#include <error.h>
++#include <err.h>
+ #include <locale.h>
+ #include <string.h>
+ #include <stdlib.h>
+--- a/tests/dwflsyms.c
++++ b/tests/dwflsyms.c
+@@ -25,7 +25,7 @@
+ #include <stdio.h>
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ static const char *
+--- a/tests/early-offscn.c
++++ b/tests/early-offscn.c
+@@ -19,7 +19,7 @@
+ #endif
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <stdio.h>
+--- a/tests/ecp.c
++++ b/tests/ecp.c
+@@ -16,7 +16,7 @@
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <stdlib.h>
+--- a/tests/find-prologues.c
++++ b/tests/find-prologues.c
+@@ -25,7 +25,7 @@
+ #include <stdio_ext.h>
+ #include <locale.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <fnmatch.h>
+--- a/tests/funcretval.c
++++ b/tests/funcretval.c
+@@ -25,7 +25,7 @@
+ #include <stdio_ext.h>
+ #include <locale.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <fnmatch.h>
+--- a/tests/funcscopes.c
++++ b/tests/funcscopes.c
+@@ -25,7 +25,7 @@
+ #include <stdio_ext.h>
+ #include <locale.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <fnmatch.h>
+--- a/tests/line2addr.c
++++ b/tests/line2addr.c
+@@ -26,7 +26,7 @@
+ #include <locale.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ static void
+--- a/tests/low_high_pc.c
++++ b/tests/low_high_pc.c
+@@ -25,7 +25,7 @@
+ #include <stdio_ext.h>
+ #include <locale.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <fnmatch.h>
+--- a/tests/md5-sha1-test.c
++++ b/tests/md5-sha1-test.c
+@@ -19,7 +19,7 @@
+ #endif
+ #include <string.h>
+-#include <error.h>
++#include <err.h>
+ #include "md5.h"
+ #include "sha1.h"
+--- a/tests/rdwrmmap.c
++++ b/tests/rdwrmmap.c
+@@ -15,7 +15,7 @@
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+--- a/tests/saridx.c
++++ b/tests/saridx.c
+@@ -17,7 +17,7 @@
+ #include <config.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <stdio.h>
+--- a/tests/sectiondump.c
++++ b/tests/sectiondump.c
+@@ -18,7 +18,7 @@
+ #include <config.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <fcntl.h>
+ #include <gelf.h>
+ #include <inttypes.h>
+--- a/tests/varlocs.c
++++ b/tests/varlocs.c
+@@ -25,7 +25,7 @@
+ #include <dwarf.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+-#include <error.h>
++#include <err.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+--- a/libelf/libelf.h
++++ b/libelf/libelf.h
+@@ -29,6 +29,7 @@
+ #ifndef _LIBELF_H
+ #define _LIBELF_H 1
++#include <fcntl.h>
+ #include <sys/types.h>
+ /* Get the ELF types.  */
+--- a/libasm/asm_end.c
++++ b/libasm/asm_end.c
+@@ -32,7 +32,7 @@
+ #endif
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+--- a/libasm/asm_newscn.c
++++ b/libasm/asm_newscn.c
+@@ -32,7 +32,7 @@
+ #endif
+ #include <assert.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+ #include <string.h>
+--- a/libcpu/i386_gendis.c
++++ b/libcpu/i386_gendis.c
+@@ -31,7 +31,7 @@
+ # include <config.h>
+ #endif
+-#include <error.h>
++#include <err.h>
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+--- a/libcpu/i386_lex.c
++++ b/libcpu/i386_lex.c
+@@ -571,7 +571,7 @@ char *i386_text;
+ #endif
+ #include <ctype.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <system.h>
+--- a/libcpu/i386_lex.l
++++ b/libcpu/i386_lex.l
+@@ -31,7 +31,7 @@
+ #endif
+ #include <ctype.h>
+-#include <error.h>
++#include <err.h>
+ #include <libintl.h>
+ #include <system.h>
+--- a/libcpu/i386_parse.c
++++ b/libcpu/i386_parse.c
+@@ -107,7 +107,7 @@
+ #include <assert.h>
+ #include <ctype.h>
+ #include <errno.h>
+-#include <error.h>
++#include <err.h>
+ #include <inttypes.h>
+ #include <libintl.h>
+ #include <math.h>
+--- a/libdw/libdw_alloc.c
++++ b/libdw/libdw_alloc.c
+@@ -31,7 +31,7 @@
+ # include <config.h>
+ #endif
+-#include <error.h>
++#include <err.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/param.h>
+@@ -74,5 +74,5 @@ __attribute ((noreturn, visibility ("hid
+ __libdw_oom (void)
+ {
+   while (1)
+-    error (EXIT_FAILURE, ENOMEM, "libdw");
++    err (EXIT_FAILURE, "libdw: out of memory");
+ }
+--- a/libebl/eblopenbackend.c
++++ b/libebl/eblopenbackend.c
+@@ -32,7 +32,7 @@
+ #include <assert.h>
+ #include <dlfcn.h>
+-#include <error.h>
++#include <err.h>
+ #include <libelfP.h>
+ #include <dwarf.h>
+ #include <stdlib.h>
+--- a/src/ldlex.l
++++ b/src/ldlex.l
+@@ -23,7 +23,7 @@
+ #include <assert.h>
+ #include <ctype.h>
+ #include <elf.h>
+-#include <error.h>
++#include <err.h>
+ #include <inttypes.h>
+ #include <libintl.h>
+ #include <stdbool.h>
+--- a/libebl/eblwstrtab.c
++++ b/libebl/eblwstrtab.c
+@@ -305,7 +305,7 @@ copystrings (struct Ebl_WStrent *nodep,
+   /* Process the current node.  */
+   nodep->offset = *offsetp;
+-  *freep = wmempcpy (*freep, nodep->string, nodep->len);
++  *freep = wmemcpy (*freep, nodep->string, nodep->len) + nodep->len;
+   *offsetp += nodep->len * sizeof (wchar_t);
+   for (subs = nodep->next; subs != NULL; subs = subs->next)
+--- a/libdwfl/dwfl_error.c
++++ b/libdwfl/dwfl_error.c
+@@ -128,6 +128,7 @@ const char *
+ dwfl_errmsg (error)
+      int error;
+ {
++  static __thread char s[64] = "";
+   if (error == 0 || error == -1)
+     {
+       int last_error = global_error;
+@@ -142,7 +143,8 @@ dwfl_errmsg (error)
+   switch (error &~ 0xffff)
+     {
+     case OTHER_ERROR (ERRNO):
+-      return strerror_r (error & 0xffff, "bad", 0);
++      strerror_r (error & 0xffff, s, sizeof(s));
++      return s;
+     case OTHER_ERROR (LIBELF):
+       return elf_errmsg (error & 0xffff);
+     case OTHER_ERROR (LIBDW):
+--- a/libdwfl/libdwfl.h
++++ b/libdwfl/libdwfl.h
+@@ -31,6 +31,27 @@
+ #include "libdw.h"
+ #include <stdio.h>
++#include <unistd.h>
++#include <alloca.h>
++#include <string.h>
++
++#ifndef TEMP_FAILURE_RETRY
++#define TEMP_FAILURE_RETRY(expression) \
++  (__extension__                                                              \
++    ({ long int __result;                                                     \
++       do __result = (long int) (expression);                                 \
++       while (__result == -1L && errno == EINTR);                             \
++       __result; }))
++#endif
++
++#ifndef strndupa
++#define strndupa(s, n) \
++      (__extension__ ({const char *__in = (s); \
++                       size_t __len = strnlen (__in, (n)) + 1; \
++                       char *__out = (char *) alloca (__len); \
++                       __out[__len-1] = '\0'; \
++                       (char *) memcpy (__out, __in, __len-1);}))
++#endif
+ /* Handle for a session using the library.  */
+ typedef struct Dwfl Dwfl;
+--- a/libdwfl/find-debuginfo.c
++++ b/libdwfl/find-debuginfo.c
+@@ -338,7 +338,7 @@ dwfl_standard_find_debuginfo (Dwfl_Modul
+       /* If FILE_NAME is a symlink, the debug file might be associated
+        with the symlink target name instead.  */
+-      char *canon = canonicalize_file_name (file_name);
++      char *canon = realpath (file_name, NULL);
+       if (canon != NULL && strcmp (file_name, canon))
+       fd = find_debuginfo_in_path (mod, canon,
+                                    debuglink_file, debuglink_crc,
+--- a/libdwfl/dwfl_build_id_find_elf.c
++++ b/libdwfl/dwfl_build_id_find_elf.c
+@@ -80,7 +80,7 @@ __libdwfl_open_by_build_id (Dwfl_Module
+       {
+         if (*file_name != NULL)
+           free (*file_name);
+-        *file_name = canonicalize_file_name (name);
++        *file_name = realpath (name, NULL);
+         if (*file_name == NULL)
+           {
+             *file_name = name;
+--- a/libelf/elf_getarsym.c
++++ b/libelf/elf_getarsym.c
+@@ -284,7 +284,7 @@ elf_getarsym (elf, ptr)
+               arsym[cnt].as_off = file_data->u32[cnt];
+             arsym[cnt].as_hash = _dl_elf_hash (str_data);
+-            str_data = rawmemchr (str_data, '\0') + 1;
++            str_data = memchr (str_data, '\0', SIZE_MAX) + 1;
+           }
+         /* At the end a special entry.  */
diff --git a/libs/elfutils/patches/101-no-fts.patch b/libs/elfutils/patches/101-no-fts.patch
new file mode 100644 (file)
index 0000000..9dd7ee2
--- /dev/null
@@ -0,0 +1,109 @@
+--- a/libdwfl/argp-std.c
++++ b/libdwfl/argp-std.c
+@@ -52,9 +52,6 @@ static const struct argp_option options[
+   { "linux-process-map", 'M', "FILE", 0,
+     N_("Find addresses in files mapped as read from FILE"
+        " in Linux /proc/PID/maps format"), 0 },
+-  { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 },
+-  { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL,
+-    N_("Kernel with all modules"), 0 },
+   { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
+     N_("Search path for separate debuginfo files"), 0 },
+   { NULL, 0, NULL, 0, NULL, 0 }
+@@ -81,15 +78,6 @@ static const Dwfl_Callbacks proc_callbac
+     .find_elf = INTUSE(dwfl_linux_proc_find_elf),
+   };
+-static const Dwfl_Callbacks kernel_callbacks =
+-  {
+-    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+-    .debuginfo_path = &debuginfo_path,
+-
+-    .find_elf = INTUSE(dwfl_linux_kernel_find_elf),
+-    .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
+-  };
+-
+ /* Structure held at state->HOOK.  */
+ struct parse_opt
+ {
+@@ -219,43 +207,6 @@ parse_opt (int key, char *arg, struct ar
+       }
+       break;
+-    case 'k':
+-      {
+-      struct parse_opt *opt = state->hook;
+-      if (opt->dwfl == NULL)
+-        {
+-          Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
+-          int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
+-          if (result != 0)
+-            return fail (dwfl, result, _("cannot load kernel symbols"));
+-          result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+-          if (result != 0)
+-            /* Non-fatal to have no modules since we do have the kernel.  */
+-            failure (dwfl, result, _("cannot find kernel modules"));
+-          opt->dwfl = dwfl;
+-        }
+-      else
+-        goto toomany;
+-      }
+-      break;
+-
+-    case 'K':
+-      {
+-      struct parse_opt *opt = state->hook;
+-      if (opt->dwfl == NULL)
+-        {
+-          Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+-          int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
+-                                                                 NULL);
+-          if (result != 0)
+-            return fail (dwfl, result, _("cannot find kernel or modules"));
+-          opt->dwfl = dwfl;
+-        }
+-      else
+-        goto toomany;
+-      }
+-      break;
+-
+     case ARGP_KEY_SUCCESS:
+       {
+       struct parse_opt *opt = state->hook;
+--- a/libdwfl/Makefile.in
++++ b/libdwfl/Makefile.in
+@@ -113,7 +113,7 @@ am__libdwfl_a_SOURCES_DIST = dwfl_begin.
+       dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
+       dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
+       find-debuginfo.c dwfl_build_id_find_elf.c \
+-      dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
++      dwfl_build_id_find_debuginfo.c \
+       linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
+       dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
+       dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
+@@ -142,7 +142,7 @@ am_libdwfl_a_OBJECTS = dwfl_begin.$(OBJE
+       dwfl_validate_address.$(OBJEXT) argp-std.$(OBJEXT) \
+       find-debuginfo.$(OBJEXT) dwfl_build_id_find_elf.$(OBJEXT) \
+       dwfl_build_id_find_debuginfo.$(OBJEXT) \
+-      linux-kernel-modules.$(OBJEXT) linux-proc-maps.$(OBJEXT) \
++      linux-proc-maps.$(OBJEXT) \
+       dwfl_addrmodule.$(OBJEXT) dwfl_addrdwarf.$(OBJEXT) \
+       cu.$(OBJEXT) dwfl_module_nextcu.$(OBJEXT) \
+       dwfl_nextcu.$(OBJEXT) dwfl_cumodule.$(OBJEXT) \
+@@ -402,7 +402,7 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_en
+       dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
+       dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
+       find-debuginfo.c dwfl_build_id_find_elf.c \
+-      dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
++      dwfl_build_id_find_debuginfo.c \
+       linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
+       dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
+       dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
+@@ -540,7 +540,6 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_map.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-core-attach.Po@am__quote@
+-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-kernel-modules.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-pid-attach.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-proc-maps.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzma.Po@am__quote@
index 85f01ba62b906bfdb771cb8fd05605f564a974a2..39bf0bdd7dfc8fb46c044ceb9245b18bfd585e01 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=file
-PKG_VERSION:=5.19
+PKG_VERSION:=5.20
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=ftp://ftp.astron.com/pub/file/
-PKG_MD5SUM:=e3526f59023f3f7d1ffa4d541335edab
+PKG_MD5SUM:=5d5e13eb3e0e13839da869a31790faf2
 
 PKG_LICENSE:=BSD-2c
 PKG_LICENSE_FILES:=COPYING
index edfcb1dcf64b262a23363500cb566fe18101426c..7d94cb63ed28654d441078b048250812f17d0eb4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=flac
-PKG_VERSION:=1.2.1
+PKG_VERSION:=1.3.1
 PKG_RELEASE:=1
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=@SF/flac
-PKG_MD5SUM:=
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/flac/
+PKG_MD5SUM:=b9922c9a0378c88d3e901b234f852698
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_INSTALL:=1
@@ -30,23 +30,21 @@ define Package/libflac
   SECTION:=libs
   CATEGORY:=Libraries
   TITLE:=Free Lossless Audio Codec library
-  URL:=http://flac.sourceforge.net/
+  URL:=https://xiph.org/flac
 endef
 
-define Build/Configure
-       $(call Build/Configure/Default, \
-               --disable-cpplibs \
-               --disable-sse \
-               --disable-3dnow \
-               --disable-altivec \
-               --disable-doxgen-docs \
-               --disable-local-xmms-plugin \
-               --disable-xmms-plugin \
-               --disable-ogg \
-               --disable-oggtest \
-               --disable-debug \
-       )
-endef
+CONFIGURE_ARGS += \
+       --disable-cpplibs \
+       --disable-sse \
+       --disable-3dnow \
+       --disable-altivec \
+       --disable-doxgen-docs \
+       --disable-local-xmms-plugin \
+       --disable-xmms-plugin \
+       --disable-ogg \
+       --disable-oggtest \
+       --disable-debug \
+       --enable-static \
 
 TARGET_CFLAGS += $(FPIC)
 
index cd4e821a4944a70e80d80c476dc92bc2f52cd177..72b26310e3d5ee56800c15b2c558be97bba0cc6a 100644 (file)
@@ -1,73 +1,25 @@
 --- a/Makefile.am
 +++ b/Makefile.am
-@@ -30,7 +30,7 @@
+@@ -31,7 +31,7 @@
  
- AUTOMAKE_OPTIONS = foreign 1.7
+ ACLOCAL_AMFLAGS = -I m4
  
--SUBDIRS = doc include m4 man src examples test build obj
-+SUBDIRS = include m4 src build obj
- DISTCLEANFILES = libtool-disable-static
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -234,7 +234,7 @@ target_alias = @target_alias@
- AUTOMAKE_OPTIONS = foreign 1.7
--SUBDIRS = doc include m4 man src examples test build obj
-+SUBDIRS = include m4 src build obj
- DISTCLEANFILES = libtool-disable-static
+-SUBDIRS = doc include m4 man src examples test build objs
++SUBDIRS = include m4 src build objs
  
+ EXTRA_DIST = \
+       COPYING.FDL \
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
-@@ -30,12 +30,6 @@ SUBDIRS = \
+@@ -30,11 +30,6 @@ SUBDIRS = \
+       flac \
        metaflac \
-       monkeys_audio_utilities \
        $(XMMS_DIRS) \
--      plugin_winamp2 \
 -      test_grabbag \
 -      test_libs_common \
 -      test_libFLAC \
 -      test_seeking \
 -      test_streams \
+       utils \
        $(CPPLIBS_DIRS)
  
- EXTRA_DIST = \
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -221,7 +221,7 @@ target_alias = @target_alias@
- @FLaC__HAS_XMMS_TRUE@XMMS_DIRS = plugin_common plugin_xmms
--@FLaC__WITH_CPPLIBS_TRUE@CPPLIBS_DIRS = libFLAC++ test_libFLAC++
-+@FLaC__WITH_CPPLIBS_TRUE@CPPLIBS_DIRS = libFLAC++
- SUBDIRS = \
-       libFLAC \
-@@ -230,12 +230,6 @@ SUBDIRS = \
-       metaflac \
-       monkeys_audio_utilities \
-       $(XMMS_DIRS) \
--      plugin_winamp2 \
--      test_grabbag \
--      test_libs_common \
--      test_libFLAC \
--      test_seeking \
--      test_streams \
-       $(CPPLIBS_DIRS)
-@@ -256,9 +250,8 @@ RECURSIVE_TARGETS = info-recursive dvi-r
-       check-recursive installcheck-recursive
- DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
- DIST_SUBDIRS = libFLAC share flac metaflac monkeys_audio_utilities \
--      plugin_common plugin_xmms plugin_winamp2 test_grabbag \
--      test_libs_common test_libFLAC test_seeking test_streams \
--      libFLAC++ test_libFLAC++
-+      plugin_common plugin_xmms plugin_winamp2 \
-+      libFLAC++
- all: all-recursive
- .SUFFIXES:
index e6fe1b3ed470f6a5ecad5d6dfb311cf3a867c69a..f74460259caeb6597195aebd755ea6e0c91bcdae 100644 (file)
@@ -1,24 +1,13 @@
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
-@@ -26,9 +26,6 @@ endif
+@@ -27,10 +27,7 @@ endif
  SUBDIRS = \
-       libFLAC \
        share \
--      flac \
--      metaflac \
--      monkeys_audio_utilities \
-       $(XMMS_DIRS) \
-       $(CPPLIBS_DIRS)
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -226,9 +226,6 @@ target_alias = @target_alias@
- SUBDIRS = \
        libFLAC \
-       share \
 -      flac \
 -      metaflac \
--      monkeys_audio_utilities \
        $(XMMS_DIRS) \
+-      utils \
        $(CPPLIBS_DIRS)
  
+ EXTRA_DIST = \
index f8b154679b182b1140926fcfbd2a5602e0054edd..83180480bf9e1f1eb020deacf3de5a6c7f374c88 100644 (file)
@@ -1,8 +1,8 @@
 --- a/Makefile.am
 +++ b/Makefile.am
-@@ -34,6 +34,8 @@ SUBDIRS = include m4 src build obj
+@@ -33,6 +33,8 @@ ACLOCAL_AMFLAGS = -I m4
  
- DISTCLEANFILES = libtool-disable-static
+ SUBDIRS = include m4 src build objs
  
 +ACLOCAL_AMFLAGS = -I m4
 +
diff --git a/libs/flac/patches/020-libFLAC-remove-altivec-options.patch b/libs/flac/patches/020-libFLAC-remove-altivec-options.patch
deleted file mode 100644 (file)
index bc98672..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
---- a/src/libFLAC/Makefile.in
-+++ b/src/libFLAC/Makefile.in
-@@ -66,6 +66,7 @@ NORMAL_UNINSTALL = :
- PRE_UNINSTALL = :
- POST_UNINSTALL = :
- host_triplet = @host@
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@@FLaC__USE_ALTIVEC_TRUE@am__append_1 = -maltivec -mabi=altivec
- ACLOCAL = @ACLOCAL@
- ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
- AMDEP_FALSE = @AMDEP_FALSE@
-@@ -234,13 +235,21 @@ target_alias = @target_alias@
- lib_LTLIBRARIES = libFLAC.la
- @DEBUG_TRUE@DEBUGCFLAGS = -DFLAC__OVERFLOW_DETECT
-+# Linux-gcc for PPC does not have -force_cpusubtype_ALL, it is Darwin-specific
-+#@@@ PPC optimizations temporarily disabled
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@CPUCFLAGS =  \
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@  $(am__append_1) \
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@  -DFLAC__NO_ASM
-+
-+# FIXME: The following logic should be part of configure, not of Makefile.am
-+
- # The -force_cpusubtype_ALL is needed to insert a ppc64 instruction
- # into cpu.c with an asm().
- #@@@ PPC optimizations temporarily disabled
--@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@CPUCFLAGS = -faltivec -force_cpusubtype_ALL -DFLAC__NO_ASM
--# Linux-gcc for PPC does not have -force_cpusubtype_ALL, it is Darwin-specific
--#@@@ PPC optimizations temporarily disabled
--@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_FALSE@CPUCFLAGS = -maltivec -mabi=altivec -DFLAC__NO_ASM
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@CPUCFLAGS = -faltivec \
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@   -force_cpusubtype_ALL \
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@   -DFLAC__NO_ASM \
-+@FLaC__CPU_PPC_TRUE@@FLaC__SYS_DARWIN_TRUE@   $(am__append_1)
- AM_CFLAGS = $(DEBUGCFLAGS) $(CPUCFLAGS) @OGG_CFLAGS@
- @FLaC__CPU_PPC_TRUE@@FLaC__NO_ASM_FALSE@ARCH_SUBDIRS = ppc
---- a/src/libFLAC/Makefile.am
-+++ b/src/libFLAC/Makefile.am
-@@ -32,6 +32,9 @@ lib_LTLIBRARIES = libFLAC.la
- if DEBUG
- DEBUGCFLAGS = -DFLAC__OVERFLOW_DETECT
- endif
-+
-+# FIXME: The following logic should be part of configure, not of Makefile.am
-+
- if FLaC__CPU_PPC
- # The -force_cpusubtype_ALL is needed to insert a ppc64 instruction
- # into cpu.c with an asm().
-@@ -40,8 +43,12 @@ if FLaC__SYS_DARWIN
- CPUCFLAGS = -faltivec -force_cpusubtype_ALL -DFLAC__NO_ASM
- else
- # Linux-gcc for PPC does not have -force_cpusubtype_ALL, it is Darwin-specific
-+CPUCFLAGS =
-+if FLaC__USE_ALTIVEC
-+CPUCFLAGS += -maltivec -mabi=altivec
-+endif
- #@@@ PPC optimizations temporarily disabled
--CPUCFLAGS = -maltivec -mabi=altivec -DFLAC__NO_ASM
-+CPUCFLAGS += -DFLAC__NO_ASM
- endif
- endif
index f6fd7a4bcf4360724783f8d879a00c94cb6562eb..e88d748711aed8752fab0a88eaa5391af89db87b 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=freetype
-PKG_VERSION:=2.5.3
+PKG_VERSION:=2.5.5
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=@SF/freetype
-PKG_MD5SUM:=d6b60f06bfc046e43ab2a6cbfd171d65
+PKG_MD5SUM:=2a7a314927011d5030903179cf183be0
 
 PKG_LICENSE:=FTL GPL-2.0 MIT ZLIB
 PKG_LICENSE_FILES:=docs/LICENSE.TXT docs/FTL.TXT docs/GPLv2.TXT src/bdf/README src/pcf/README src/gzip/zlib.h
index bdb353069fefbdc2b8685b7cfb0fafd09faaa9e9..b4d907aa184e7f925496e9b64298481602580d93 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2012 OpenWrt.org
+# Copyright (C) 2007-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,19 +8,21 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=glib2
-PKG_VERSION:=2.41.1
-PKG_RELEASE:=2
+PKG_VERSION:=2.43.3
+PKG_RELEASE:=1
 
 PKG_SOURCE:=glib-$(PKG_VERSION).tar.xz
 PKG_BUILD_DIR:=$(BUILD_DIR)/glib-$(PKG_VERSION)
-PKG_SOURCE_URL:=@GNOME/glib/2.41
-PKG_MD5SUM:=bae557c87323e8df7ac30fb484b5cba9
+PKG_SOURCE_URL:=@GNOME/glib/2.43
+PKG_MD5SUM:=2727c4dee79c5449f364cd5e27b17099
 
 PKG_BUILD_DEPENDS:=glib2/host libpthread zlib libintl libffi
 HOST_BUILD_DEPENDS:=libintl/host libiconv/host libffi/host
 PKG_INSTALL:=1
 PKG_USE_MIPS16:=0
 
+PKG_FIXUP:=autoreconf
+
 HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/glib-$(PKG_VERSION)
 
 include $(INCLUDE_DIR)/host-build.mk
diff --git a/libs/glib2/patches/001-automake-compat.patch b/libs/glib2/patches/001-automake-compat.patch
new file mode 100644 (file)
index 0000000..8f8ce37
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/gtk-doc.make
++++ b/gtk-doc.make
+@@ -267,7 +267,7 @@ uninstall-local:
+ #
+ # Require gtk-doc when making dist
+ #
+-if HAVE_GTK_DOC
++if ENABLE_GTK_DOC
+ dist-check-gtkdoc: docs
+ else
+ dist-check-gtkdoc:
diff --git a/libs/glib2/patches/100-fix-gio-linking.patch b/libs/glib2/patches/100-fix-gio-linking.patch
new file mode 100644 (file)
index 0000000..22ac62f
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/gio/Makefile.am
++++ b/gio/Makefile.am
+@@ -695,6 +695,7 @@ bin_PROGRAMS = gio-querymodules glib-com
+ glib_compile_resources_LDADD = libgio-2.0.la          \
+       $(top_builddir)/gobject/libgobject-2.0.la       \
++      $(top_builddir)/gmodule/libgmodule-2.0.la       \
+       $(top_builddir)/glib/libglib-2.0.la             \
+       $(NULL)
index 0564876ad5349cbfc5efa462bb972fb68000e970..a7aedf9df31dc551386a76ea32718b868776c662 100644 (file)
@@ -8,19 +8,33 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gnutls
-PKG_VERSION:=3.3.8
+PKG_VERSION:=3.3.12
 PKG_RELEASE:=1
 PKG_USE_MIPS16:=0
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=ftp://ftp.gnutls.org/gcrypt/gnutls/v3.3
-PKG_MD5SUM:=b57e6b7630bdba9ea8eb28ff0eb29c2f
+PKG_MD5SUM:=a37b20b4352a5f542367ded904729c90
 PKG_MAINTAINER:=Nikos Mavrogiannopoulos <nmav@gnutls.org>
 
 PKG_INSTALL:=1
 PKG_LIBTOOL_PATHS:=. lib
 PKG_CHECK_FORMAT_SECURITY:=0
 
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_GNUTLS_ALPN \
+       CONFIG_GNUTLS_ANON \
+       CONFIG_GNUTLS_CRYPTODEV \
+       CONFIG_GNUTLS_DTLS_SRTP \
+       CONFIG_GNUTLS_EXT_LIBTASN1 \
+       CONFIG_GNUTLS_HEARTBEAT \
+       CONFIG_GNUTLS_OCSP \
+       CONFIG_GNUTLS_OPENPGP \
+       CONFIG_GNUTLS_PKCS11 \
+       CONFIG_GNUTLS_PSK \
+       CONFIG_GNUTLS_SRP \
+       CONFIG_LIBNETTLE_MINI \
+
 include $(INCLUDE_DIR)/package.mk
 
 
diff --git a/libs/gperf/Makefile b/libs/gperf/Makefile
new file mode 100644 (file)
index 0000000..4cdd470
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gperf
+PKG_VERSION:=3.0.4
+PKG_RELEASE:=1
+PKG_MD5SUM:=c1f1db32fb6598d6a93e6e88796a8632
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/gperf
+PKG_HOST_ONLY=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/gperf
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU gperf
+  BUILDONLY:=1
+  URL:=http://www.gnu.org/software/gperf
+endef
+
+define Package/gperf/description
+ GNU gperf is a perfect hash function generator. For a given list of strings, it
+ produces a hash function and hash table, in form of C or C++ code, for looking 
+ up a value depending on the input string. The hash function is perfect, which 
+ means that the hash table has no collisions, and the hash table lookup needs a
+ single string comparison only.
+endef
+
+define Host/Install
+       $(MAKE) -C $(HOST_BUILD_DIR) install
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,gperf))
diff --git a/libs/hidapi/Makefile b/libs/hidapi/Makefile
new file mode 100644 (file)
index 0000000..efdbbf5
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hidapi
+PKG_VERSION:=0.8.0-rc1
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/signal11/hidapi.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=hidapi-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_SOURCE_VERSION).tar.gz
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE-bsd.txt
+
+PKG_MAINTAINER:=Paul Fertser <fercerpav@gmail.com>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/hidapi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libusb-1.0 +libiconv +librt
+  TITLE:=Library to talk to HID devices
+  URL:=http://www.signal11.us/oss/hidapi/
+endef
+
+define Package/hidapi/description
+HIDAPI is a multi-platform library which allows an application to interface
+with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and Mac
+OS X.  HIDAPI can be either built as a shared library (.so or .dll) or
+can be embedded directly into a target application by adding a single source
+file (per platform) and a single header.
+endef
+
+define Build/Configure
+endef
+
+MAKE_PATH=libusb
+MAKE_FLAGS+=-f Makefile.linux
+TARGET_CFLAGS+=$(FPIC)
+
+define Build/Compile
+       $(call Build/Compile/Default, libhidapi-libusb.so)
+       mv $(PKG_BUILD_DIR)/libusb/libhidapi-libusb.so \
+               $(PKG_BUILD_DIR)/libusb/libhidapi-libusb.so.0
+       ln -s libhidapi-libusb.so.0 $(PKG_BUILD_DIR)/libusb/libhidapi-libusb.so
+       sed    's^@prefix@^/usr^; \
+               s^@exec_prefix@^/usr^; \
+               s^@libdir@^$$$${exec_prefix}/lib^; \
+               s^@includedir@^$$$${prefix}/include^' \
+               < $(PKG_BUILD_DIR)/pc/hidapi-libusb.pc.in \
+               > $(PKG_BUILD_DIR)/pc/hidapi-libusb.pc
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/hidapi
+       $(CP) $(PKG_BUILD_DIR)/hidapi/hidapi.h $(1)/usr/include/hidapi/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libusb/libhidapi-libusb.so* $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+       $(CP) $(PKG_BUILD_DIR)/pc/hidapi-libusb.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/hidapi/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libusb/libhidapi-libusb.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,hidapi))
diff --git a/libs/hidapi/patches/010-add-iconv-linkage.patch b/libs/hidapi/patches/010-add-iconv-linkage.patch
new file mode 100644 (file)
index 0000000..d942d50
--- /dev/null
@@ -0,0 +1,22 @@
+Index: hidapi-0.8.0-rc1/libusb/Makefile.linux
+===================================================================
+--- hidapi-0.8.0-rc1.orig/libusb/Makefile.linux
++++ hidapi-0.8.0-rc1/libusb/Makefile.linux
+@@ -22,7 +22,7 @@ COBJS_LIBUSB = hid.o
+ COBJS = $(COBJS_LIBUSB)
+ CPPOBJS   = ../hidtest/hidtest.o
+ OBJS      = $(COBJS) $(CPPOBJS)
+-LIBS_USB  = `pkg-config libusb-1.0 --libs` -lrt -lpthread
++LIBS_USB  = `pkg-config libusb-1.0 --libs` -lrt -lpthread -liconv
+ LIBS      = $(LIBS_USB)
+ INCLUDES ?= -I../hidapi `pkg-config libusb-1.0 --cflags`
+@@ -33,7 +33,7 @@ hidtest-libusb: $(COBJS_LIBUSB) $(CPPOBJ
+ # Shared Libs
+ libhidapi-libusb.so: $(COBJS_LIBUSB)
+-      $(CC) $(LDFLAGS) $(LIBS_USB) -shared -fpic -Wl,-soname,$@.0 $^ -o $@
++      $(CC) $(LDFLAGS) $^ $(LIBS_USB) -shared -fpic -Wl,-soname,$@.0 -o $@
+ # Objects
+ $(COBJS): %.o: %.c
index 6fb746518b1cc2ff2164d24d3d6fdf73816d55c5..c574147cab6641650d6487af7ad993a314d778a1 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ibrcommon
-PKG_VERSION:=0.12.1
+PKG_VERSION:=1.0.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
-PKG_MD5SUM:=45681f48138bbbbd17384d25dc91454a
-PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_MD5SUM:=c40e5c8e2ada746c6da7ab2c359c1575
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
 PKG_LICENSE:=Apache-2.0
 
 PKG_INSTALL:=1
index bd54485270b6dfa3759929f2a02afde26aed6a3a..e69b3eeb2574522fc4a53390b4575d0a4c904ad1 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ibrdtn
-PKG_VERSION:=0.12.1
+PKG_VERSION:=1.0.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
-PKG_MD5SUM:=96428dd4af541ea0c52db80776976a65
-PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_MD5SUM:=c30f6164b717132b2c302d965d03c968
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
 PKG_LICENSE:=Apache-2.0
 
 PKG_INSTALL:=1
-PKG_FIXUP:=libtool autoreconf
+PKG_FIXUP:=libtool
 
 include $(INCLUDE_DIR)/package.mk
 
diff --git a/libs/ibrdtn/patches/100-add_configure_options.patch b/libs/ibrdtn/patches/100-add_configure_options.patch
deleted file mode 100644 (file)
index 9a8df8d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -159,12 +159,21 @@ AS_IF([test "x$enable_android" = "xyes"], [
-       dnl -----------------------------------------------
-       dnl check for glib support
-       dnl -----------------------------------------------
--      PKG_CHECK_MODULES([GLIB], [glib-2.0], [
--              AC_SUBST(GLIB_CFLAGS)
--              AC_SUBST(GLIB_LIBS)
--              AC_DEFINE(HAVE_GLIB, [1], ["glib library is available"])
--              REQUIRES_LIBS="$REQUIRES_LIBS glib-2.0"
--      ], [
-+      AC_ARG_WITH([glib], [AS_HELP_STRING([--without-glib], [Disable linking to glib-2.0 library])], [with_glib=no], [with_glib=yes])
-+      AS_IF([test "x$with_glib" != xno],
-+      [
-+              PKG_CHECK_MODULES([GLIB], [glib-2.0], [
-+                      AC_SUBST(GLIB_CFLAGS)
-+                      AC_SUBST(GLIB_LIBS)
-+                      AC_DEFINE(HAVE_GLIB, [1], ["glib library is available"])
-+                      REQUIRES_LIBS="$REQUIRES_LIBS glib-2.0"
-+              ], [
-+                      with_glib=no
-+              ])
-+      ], [])
-+              
-+      AS_IF([test "x$with_glib" = xno],
-+      [
-               AS_IF([test "x$has_endian_h" = "xyes"],[
-                       AC_MSG_NOTICE([use endian.h for endianess conversion])
-               ],[
--- 
-1.9.1
-
diff --git a/libs/jansson/Makefile b/libs/jansson/Makefile
new file mode 100644 (file)
index 0000000..3d18d42
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2011-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=jansson
+PKG_VERSION:=2.7
+PKG_RELEASE:=1
+PKG_LICENSE:=MIT
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.digip.org/jansson/releases/
+PKG_MD5SUM:=3a106a465bbb77637550b422f5b262ef
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/jansson
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Jansson library
+  URL:=http://www.digip.org/jansson/
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+endef
+
+define Package/jansson/description
+  Jansson is a C library for encoding, decoding and manipulating JSON data
+endef
+
+TARGET_CFLAGS += $(FPIC)
+TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib -lm
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/{lib,include}
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjansson* $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+endef
+
+define Package/jansson/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjansson*so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,jansson))
index 7ff1b113b7923ad161c8b93e5b3609a137904461..dbcb59f7fe064943d78c5c963e1425cd751508a9 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2010 OpenWrt.org
+# Copyright (C) 2007-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,13 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libaio
-PKG_VERSION:=0.3.109
+PKG_VERSION:=0.3.110
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
 PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/liba/libaio/
-PKG_MD5SUM:=435a5b16ca6198eaf01155263d855756
+PKG_MD5SUM:=2a35602e43778383e2f4907a4ca39ab8
 PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
+PKG_LICENSE:=LGPL-2.1
 
 PKG_USE_MIPS16:=0
 
diff --git a/libs/libaio/patches/001-arches_from_debian_package_0.3.109-4.patch b/libs/libaio/patches/001-arches_from_debian_package_0.3.109-4.patch
deleted file mode 100644 (file)
index 6c36144..0000000
+++ /dev/null
@@ -1,1098 +0,0 @@
----
- harness/main.c       |   10 ++
- src/libaio.h         |   30 ++++++
- src/syscall-m68k.h   |   78 +++++++++++++++++
- src/syscall-mips.h   |  223 +++++++++++++++++++++++++++++++++++++++++++++++++++
- src/syscall-parisc.h |  146 +++++++++++++++++++++++++++++++++
- src/syscall-sparc.h  |  130 +++++++++++++++++++++++++++++
- src/syscall.h        |    8 +
- 7 files changed, 625 insertions(+)
-
-Index: libaio-0.3.109/src/syscall-m68k.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-m68k.h  2014-06-11 10:40:07.921826651 +0200
-@@ -0,0 +1,78 @@
-+#define __NR_io_setup         241
-+#define __NR_io_destroy               242
-+#define __NR_io_getevents     243
-+#define __NR_io_submit                244
-+#define __NR_io_cancel                245
-+
-+#define io_syscall1(type,fname,sname,atype,a) \
-+type fname(atype a) \
-+{ \
-+register long __res __asm__ ("%d0") = __NR_##sname; \
-+register long __a __asm__ ("%d1") = (long)(a); \
-+__asm__ __volatile__ ("trap  #0" \
-+                    : "+d" (__res) \
-+                    : "d" (__a)  ); \
-+return (type) __res; \
-+}
-+
-+#define io_syscall2(type,fname,sname,atype,a,btype,b) \
-+type fname(atype a,btype b) \
-+{ \
-+register long __res __asm__ ("%d0") = __NR_##sname; \
-+register long __a __asm__ ("%d1") = (long)(a); \
-+register long __b __asm__ ("%d2") = (long)(b); \
-+__asm__ __volatile__ ("trap  #0" \
-+                    : "+d" (__res) \
-+                    : "d" (__a), "d" (__b) \
-+                   ); \
-+return (type) __res; \
-+}
-+
-+#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \
-+type fname(atype a,btype b,ctype c) \
-+{ \
-+register long __res __asm__ ("%d0") = __NR_##sname; \
-+register long __a __asm__ ("%d1") = (long)(a); \
-+register long __b __asm__ ("%d2") = (long)(b); \
-+register long __c __asm__ ("%d3") = (long)(c); \
-+__asm__ __volatile__ ("trap  #0" \
-+                    : "+d" (__res) \
-+                    : "d" (__a), "d" (__b), \
-+                      "d" (__c) \
-+                   ); \
-+return (type) __res; \
-+}
-+
-+#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \
-+type fname (atype a, btype b, ctype c, dtype d) \
-+{ \
-+register long __res __asm__ ("%d0") = __NR_##sname; \
-+register long __a __asm__ ("%d1") = (long)(a); \
-+register long __b __asm__ ("%d2") = (long)(b); \
-+register long __c __asm__ ("%d3") = (long)(c); \
-+register long __d __asm__ ("%d4") = (long)(d); \
-+__asm__ __volatile__ ("trap  #0" \
-+                    : "+d" (__res) \
-+                    : "d" (__a), "d" (__b), \
-+                      "d" (__c), "d" (__d)  \
-+                   ); \
-+return (type) __res; \
-+}
-+
-+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-+type fname (atype a,btype b,ctype c,dtype d,etype e) \
-+{ \
-+register long __res __asm__ ("%d0") = __NR_##sname; \
-+register long __a __asm__ ("%d1") = (long)(a); \
-+register long __b __asm__ ("%d2") = (long)(b); \
-+register long __c __asm__ ("%d3") = (long)(c); \
-+register long __d __asm__ ("%d4") = (long)(d); \
-+register long __e __asm__ ("%d5") = (long)(e); \
-+__asm__ __volatile__ ("trap  #0" \
-+                    : "+d" (__res) \
-+                    : "d" (__a), "d" (__b), \
-+                      "d" (__c), "d" (__d), "d" (__e)  \
-+                   ); \
-+return (type) __res; \
-+}
-+
-Index: libaio-0.3.109/src/syscall-sparc.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-sparc.h 2014-06-11 10:40:07.921826651 +0200
-@@ -0,0 +1,130 @@
-+/* $Id: unistd.h,v 1.74 2002/02/08 03:57:18 davem Exp $ */
-+
-+/*
-+ * System calls under the Sparc.
-+ *
-+ * Don't be scared by the ugly clobbers, it is the only way I can
-+ * think of right now to force the arguments into fixed registers
-+ * before the trap into the system call with gcc 'asm' statements.
-+ *
-+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
-+ *
-+ * SunOS compatibility based upon preliminary work which is:
-+ *
-+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
-+ */
-+
-+
-+#define __NR_io_setup         268
-+#define __NR_io_destroy               269
-+#define __NR_io_submit                270
-+#define __NR_io_cancel                271
-+#define __NR_io_getevents     272
-+
-+
-+#define io_syscall1(type,fname,sname,type1,arg1) \
-+type fname(type1 arg1) \
-+{ \
-+long __res; \
-+register long __g1 __asm__ ("g1") = __NR_##sname; \
-+register long __o0 __asm__ ("o0") = (long)(arg1); \
-+__asm__ __volatile__ ("t 0x10\n\t" \
-+                    "bcc 1f\n\t" \
-+                    "mov %%o0, %0\n\t" \
-+                    "sub %%g0, %%o0, %0\n\t" \
-+                    "1:\n\t" \
-+                    : "=r" (__res), "=&r" (__o0) \
-+                    : "1" (__o0), "r" (__g1) \
-+                    : "cc"); \
-+if (__res < -255 || __res >= 0) \
-+      return (type) __res; \
-+return -1; \
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
-+type fname(type1 arg1,type2 arg2) \
-+{ \
-+long __res; \
-+register long __g1 __asm__ ("g1") = __NR_##sname; \
-+register long __o0 __asm__ ("o0") = (long)(arg1); \
-+register long __o1 __asm__ ("o1") = (long)(arg2); \
-+__asm__ __volatile__ ("t 0x10\n\t" \
-+                    "bcc 1f\n\t" \
-+                    "mov %%o0, %0\n\t" \
-+                    "sub %%g0, %%o0, %0\n\t" \
-+                    "1:\n\t" \
-+                    : "=r" (__res), "=&r" (__o0) \
-+                    : "1" (__o0), "r" (__o1), "r" (__g1) \
-+                    : "cc"); \
-+if (__res < -255 || __res >= 0) \
-+      return (type) __res; \
-+return -1; \
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-+type fname(type1 arg1,type2 arg2,type3 arg3) \
-+{ \
-+long __res; \
-+register long __g1 __asm__ ("g1") = __NR_##sname; \
-+register long __o0 __asm__ ("o0") = (long)(arg1); \
-+register long __o1 __asm__ ("o1") = (long)(arg2); \
-+register long __o2 __asm__ ("o2") = (long)(arg3); \
-+__asm__ __volatile__ ("t 0x10\n\t" \
-+                    "bcc 1f\n\t" \
-+                    "mov %%o0, %0\n\t" \
-+                    "sub %%g0, %%o0, %0\n\t" \
-+                    "1:\n\t" \
-+                    : "=r" (__res), "=&r" (__o0) \
-+                    : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
-+                    : "cc"); \
-+if (__res < -255 || __res>=0) \
-+      return (type) __res; \
-+return -1; \
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-+{ \
-+long __res; \
-+register long __g1 __asm__ ("g1") = __NR_##sname; \
-+register long __o0 __asm__ ("o0") = (long)(arg1); \
-+register long __o1 __asm__ ("o1") = (long)(arg2); \
-+register long __o2 __asm__ ("o2") = (long)(arg3); \
-+register long __o3 __asm__ ("o3") = (long)(arg4); \
-+__asm__ __volatile__ ("t 0x10\n\t" \
-+                    "bcc 1f\n\t" \
-+                    "mov %%o0, %0\n\t" \
-+                    "sub %%g0, %%o0, %0\n\t" \
-+                    "1:\n\t" \
-+                    : "=r" (__res), "=&r" (__o0) \
-+                    : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
-+                    : "cc"); \
-+if (__res < -255 || __res>=0) \
-+      return (type) __res; \
-+return -1; \
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
-+        type5,arg5) \
-+type fname(type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-+{ \
-+long __res; \
-+register long __g1 __asm__ ("g1") = __NR_##sname; \
-+register long __o0 __asm__ ("o0") = (long)(arg1); \
-+register long __o1 __asm__ ("o1") = (long)(arg2); \
-+register long __o2 __asm__ ("o2") = (long)(arg3); \
-+register long __o3 __asm__ ("o3") = (long)(arg4); \
-+register long __o4 __asm__ ("o4") = (long)(arg5); \
-+__asm__ __volatile__ ("t 0x10\n\t" \
-+                    "bcc 1f\n\t" \
-+                    "mov %%o0, %0\n\t" \
-+                    "sub %%g0, %%o0, %0\n\t" \
-+                    "1:\n\t" \
-+                    : "=r" (__res), "=&r" (__o0) \
-+                    : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
-+                    : "cc"); \
-+if (__res < -255 || __res>=0) \
-+      return (type) __res; \
-+return -1; \
-+}
-+
-Index: libaio-0.3.109/src/syscall.h
-===================================================================
---- libaio-0.3.109.orig/src/syscall.h  2014-06-11 10:40:07.929826651 +0200
-+++ libaio-0.3.109/src/syscall.h       2014-06-11 10:40:07.925826651 +0200
-@@ -24,6 +24,20 @@
- #include "syscall-alpha.h"
- #elif defined(__arm__)
- #include "syscall-arm.h"
-+#elif defined(__m68k__)
-+#include "syscall-m68k.h"
-+#elif defined(__sparc__) && defined(__arch64__)
-+#include "syscall-sparc64.h"
-+#elif defined(__sparc__)
-+#include "syscall-sparc.h"
-+#elif defined(__hppa__)
-+#include "syscall-parisc.h"
-+#elif defined(__mips__)
-+#include "syscall-mips.h"
-+#elif defined(__sh__)
-+#include "syscall-sh.h"
-+#elif defined(__aarch64__)
-+#include "syscall-arm64.h"
- #else
- #error "add syscall-arch.h"
- #endif
-Index: libaio-0.3.109/src/syscall-mips.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-mips.h  2014-06-11 10:40:07.921826651 +0200
-@@ -0,0 +1,223 @@
-+/*
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
-+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
-+ *
-+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
-+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
-+ */
-+
-+#ifndef _MIPS_SIM_ABI32
-+#define _MIPS_SIM_ABI32                       1
-+#define _MIPS_SIM_NABI32              2
-+#define _MIPS_SIM_ABI64                       3
-+#endif
-+
-+#if _MIPS_SIM == _MIPS_SIM_ABI32
-+
-+/*
-+ * Linux o32 style syscalls are in the range from 4000 to 4999.
-+ */
-+#define __NR_Linux                    4000
-+#define __NR_io_setup                 (__NR_Linux + 241)
-+#define __NR_io_destroy                       (__NR_Linux + 242)
-+#define __NR_io_getevents             (__NR_Linux + 243)
-+#define __NR_io_submit                        (__NR_Linux + 244)
-+#define __NR_io_cancel                        (__NR_Linux + 245)
-+
-+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
-+
-+#if _MIPS_SIM == _MIPS_SIM_ABI64
-+
-+/*
-+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
-+ */
-+#define __NR_Linux                    5000
-+#define __NR_io_setup                 (__NR_Linux + 200)
-+#define __NR_io_destroy                       (__NR_Linux + 201)
-+#define __NR_io_getevents             (__NR_Linux + 202)
-+#define __NR_io_submit                        (__NR_Linux + 203)
-+#define __NR_io_cancel                        (__NR_Linux + 204)
-+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
-+
-+#if _MIPS_SIM == _MIPS_SIM_NABI32
-+
-+/*
-+ * Linux N32 syscalls are in the range from 6000 to 6999.
-+ */
-+#define __NR_Linux                    6000
-+#define __NR_io_setup                 (__NR_Linux + 200)
-+#define __NR_io_destroy                       (__NR_Linux + 201)
-+#define __NR_io_getevents             (__NR_Linux + 202)
-+#define __NR_io_submit                        (__NR_Linux + 203)
-+#define __NR_io_cancel                        (__NR_Linux + 204)
-+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
-+
-+#define io_syscall1(type,fname,sname,atype,a) \
-+type fname(atype a) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a3 asm("$7"); \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "li\t$2, %3\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "=r" (__a3) \
-+      : "r" (__a0), "i" (__NR_##sname) \
-+      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#define io_syscall2(type,fname,sname,atype,a,btype,b) \
-+type fname(atype a, btype b) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a1 asm("$5") = (unsigned long) b; \
-+      register unsigned long __a3 asm("$7"); \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "li\t$2, %4\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "=r" (__a3) \
-+      : "r" (__a0), "r" (__a1), "i" (__NR_##sname) \
-+      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \
-+type fname(atype a, btype b, ctype c) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a1 asm("$5") = (unsigned long) b; \
-+      register unsigned long __a2 asm("$6") = (unsigned long) c; \
-+      register unsigned long __a3 asm("$7"); \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "li\t$2, %5\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "=r" (__a3) \
-+      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \
-+      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \
-+type fname(atype a, btype b, ctype c, dtype d) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a1 asm("$5") = (unsigned long) b; \
-+      register unsigned long __a2 asm("$6") = (unsigned long) c; \
-+      register unsigned long __a3 asm("$7") = (unsigned long) d; \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "li\t$2, %5\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "+r" (__a3) \
-+      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \
-+      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
-+
-+/*
-+ * Using those means your brain needs more than an oil change ;-)
-+ */
-+
-+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-+type fname(atype a, btype b, ctype c, dtype d, etype e) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a1 asm("$5") = (unsigned long) b; \
-+      register unsigned long __a2 asm("$6") = (unsigned long) c; \
-+      register unsigned long __a3 asm("$7") = (unsigned long) d; \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "lw\t$2, %6\n\t" \
-+      "subu\t$29, 32\n\t" \
-+      "sw\t$2, 16($29)\n\t" \
-+      "li\t$2, %5\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      "addiu\t$29, 32\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "+r" (__a3) \
-+      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname), \
-+        "m" ((unsigned long)e) \
-+      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */
-+
-+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
-+
-+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-+type fname (atype a,btype b,ctype c,dtype d,etype e) \
-+{ \
-+      register unsigned long __a0 asm("$4") = (unsigned long) a; \
-+      register unsigned long __a1 asm("$5") = (unsigned long) b; \
-+      register unsigned long __a2 asm("$6") = (unsigned long) c; \
-+      register unsigned long __a3 asm("$7") = (unsigned long) d; \
-+      register unsigned long __a4 asm("$8") = (unsigned long) e; \
-+      unsigned long __v0; \
-+      \
-+      __asm__ volatile ( \
-+      ".set\tnoreorder\n\t" \
-+      "li\t$2, %6\t\t\t# " #fname "\n\t" \
-+      "syscall\n\t" \
-+      "move\t%0, $2\n\t" \
-+      ".set\treorder" \
-+      : "=&r" (__v0), "+r" (__a3) \
-+      : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##sname) \
-+      : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-+        "memory"); \
-+      \
-+      if (__a3 == 0) \
-+              return (type) __v0; \
-+      return (type) -1; \
-+}
-+
-+#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
-+
-Index: libaio-0.3.109/src/libaio.h
-===================================================================
---- libaio-0.3.109.orig/src/libaio.h   2014-06-11 10:40:07.929826651 +0200
-+++ libaio-0.3.109/src/libaio.h        2014-06-11 10:40:07.925826651 +0200
-@@ -57,7 +57,8 @@
- #define PADDED(x, y)  x, y
- #define PADDEDptr(x, y)       x
- #define PADDEDul(x, y)        unsigned long x
--#elif defined(__powerpc64__) /* big endian, 64 bits */
-+#elif defined(__powerpc64__) || \
-+      (defined(__sparc__) && defined(__arch64__)) /* big endian, 64 bits */
- #define PADDED(x, y)  unsigned y; x
- #define PADDEDptr(x,y)        x
- #define PADDEDul(x, y)        unsigned long x
-@@ -83,6 +84,56 @@
- #define PADDEDptr(x, y)       x; unsigned y
- #define PADDEDul(x, y)        unsigned long x; unsigned y
- #  endif
-+#elif defined(__m68k__) /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x
-+#elif defined(__sparc__) /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x
-+#elif defined(__hppa__)
-+#  if defined(__arch64__) /* big endian, 64 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x,y)        x
-+#define PADDEDul(x, y)        unsigned long x
-+#  else                    /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x
-+#endif
-+#elif defined(__mips__)
-+#  if defined (__MIPSEB__) /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x
-+#  elif defined(__MIPSEL__) /* little endian, 32 bits */
-+#define PADDED(x, y)  x; unsigned y
-+#define PADDEDptr(x, y)       x; unsigned y
-+#define PADDEDul(x, y)        unsigned long x; unsigned y
-+#  else
-+#    error "neither mipseb nor mipsel?"
-+#  endif
-+#elif defined(__sh__) /* sh3/sh4*/
-+#  if defined (__BIG_ENDIAN__) /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x
-+#  elif defined(__LITTLE_ENDIAN__) /* little endian, 32 bits */
-+#define PADDED(x, y)  x; unsigned y
-+#define PADDEDptr(x, y)       x; unsigned y
-+#define PADDEDul(x, y)        unsigned long x; unsigned y
-+#  endif
-+#elif defined(__aarch64__)
-+#  if defined (__AARCH64EB__) /* big endian, 64 bits */
-+#define PADDED(x, y)    unsigned y; x
-+#define PADDEDptr(x,y)  x
-+#define PADDEDul(x, y)  unsigned long x
-+#  elif defined(__AARCH64EL__) /* little endian, 64 bits */
-+#define PADDED(x, y)    x, y
-+#define PADDEDptr(x, y) x
-+#define PADDEDul(x, y)  unsigned long x
-+#  endif
- #else
- #error        endian?
- #endif
-Index: libaio-0.3.109/src/syscall-parisc.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-parisc.h        2014-06-11 10:40:07.921826651 +0200
-@@ -0,0 +1,146 @@
-+/*
-+ * Linux system call numbers.
-+ *
-+ * Cary Coutant says that we should just use another syscall gateway
-+ * page to avoid clashing with the HPUX space, and I think he's right:
-+ * it will would keep a branch out of our syscall entry path, at the
-+ * very least.  If we decide to change it later, we can ``just'' tweak
-+ * the LINUX_GATEWAY_ADDR define at the bottom and make __NR_Linux be
-+ * 1024 or something.  Oh, and recompile libc. =)
-+ *
-+ * 64-bit HPUX binaries get the syscall gateway address passed in a register
-+ * from the kernel at startup, which seems a sane strategy.
-+ */
-+
-+#define __NR_Linux                0
-+#define __NR_io_setup           (__NR_Linux + 215)
-+#define __NR_io_destroy         (__NR_Linux + 216)
-+#define __NR_io_getevents       (__NR_Linux + 217)
-+#define __NR_io_submit          (__NR_Linux + 218)
-+#define __NR_io_cancel          (__NR_Linux + 219)
-+
-+#define SYS_ify(syscall_name)   __NR_##syscall_name
-+
-+/* Assume all syscalls are done from PIC code just to be
-+ * safe. The worst case scenario is that you lose a register
-+ * and save/restore r19 across the syscall. */
-+#define PIC
-+
-+/* Definition taken from glibc 2.3.3
-+ * sysdeps/unix/sysv/linux/hppa/sysdep.h
-+ */
-+
-+#ifdef PIC
-+/* WARNING: CANNOT BE USED IN A NOP! */
-+# define K_STW_ASM_PIC        "       copy %%r19, %%r4\n"
-+# define K_LDW_ASM_PIC        "       copy %%r4, %%r19\n"
-+# define K_USING_GR4  "%r4",
-+#else
-+# define K_STW_ASM_PIC        " \n"
-+# define K_LDW_ASM_PIC        " \n"
-+# define K_USING_GR4
-+#endif
-+
-+/* GCC has to be warned that a syscall may clobber all the ABI
-+   registers listed as "caller-saves", see page 8, Table 2
-+   in section 2.2.6 of the PA-RISC RUN-TIME architecture
-+   document. However! r28 is the result and will conflict with
-+   the clobber list so it is left out. Also the input arguments
-+   registers r20 -> r26 will conflict with the list so they
-+   are treated specially. Although r19 is clobbered by the syscall
-+   we cannot say this because it would violate ABI, thus we say
-+   r4 is clobbered and use that register to save/restore r19
-+   across the syscall. */
-+
-+#define K_CALL_CLOB_REGS "%r1", "%r2", K_USING_GR4 \
-+                       "%r20", "%r29", "%r31"
-+
-+#undef K_INLINE_SYSCALL
-+#define K_INLINE_SYSCALL(name, nr, args...)   ({                      \
-+      long __sys_res;                                                 \
-+      {                                                               \
-+              register unsigned long __res __asm__("r28");            \
-+              K_LOAD_ARGS_##nr(args)                                  \
-+              /* FIXME: HACK stw/ldw r19 around syscall */            \
-+              __asm__ volatile(                                       \
-+                      K_STW_ASM_PIC                                   \
-+                      "       ble  0x100(%%sr2, %%r0)\n"              \
-+                      "       ldi %1, %%r20\n"                        \
-+                      K_LDW_ASM_PIC                                   \
-+                      : "=r" (__res)                                  \
-+                      : "i" (SYS_ify(name)) K_ASM_ARGS_##nr           \
-+                      : "memory", K_CALL_CLOB_REGS K_CLOB_ARGS_##nr   \
-+              );                                                      \
-+              __sys_res = (long)__res;                                \
-+      }                                                               \
-+      __sys_res;                                                      \
-+})
-+
-+#define K_LOAD_ARGS_0()
-+#define K_LOAD_ARGS_1(r26)                                    \
-+      register unsigned long __r26 __asm__("r26") = (unsigned long)(r26);   \
-+      K_LOAD_ARGS_0()
-+#define K_LOAD_ARGS_2(r26,r25)                                        \
-+      register unsigned long __r25 __asm__("r25") = (unsigned long)(r25);   \
-+      K_LOAD_ARGS_1(r26)
-+#define K_LOAD_ARGS_3(r26,r25,r24)                            \
-+      register unsigned long __r24 __asm__("r24") = (unsigned long)(r24);   \
-+      K_LOAD_ARGS_2(r26,r25)
-+#define K_LOAD_ARGS_4(r26,r25,r24,r23)                                \
-+      register unsigned long __r23 __asm__("r23") = (unsigned long)(r23);   \
-+      K_LOAD_ARGS_3(r26,r25,r24)
-+#define K_LOAD_ARGS_5(r26,r25,r24,r23,r22)                    \
-+      register unsigned long __r22 __asm__("r22") = (unsigned long)(r22);   \
-+      K_LOAD_ARGS_4(r26,r25,r24,r23)
-+#define K_LOAD_ARGS_6(r26,r25,r24,r23,r22,r21)                        \
-+      register unsigned long __r21 __asm__("r21") = (unsigned long)(r21);   \
-+      K_LOAD_ARGS_5(r26,r25,r24,r23,r22)
-+
-+/* Even with zero args we use r20 for the syscall number */
-+#define K_ASM_ARGS_0
-+#define K_ASM_ARGS_1 K_ASM_ARGS_0, "r" (__r26)
-+#define K_ASM_ARGS_2 K_ASM_ARGS_1, "r" (__r25)
-+#define K_ASM_ARGS_3 K_ASM_ARGS_2, "r" (__r24)
-+#define K_ASM_ARGS_4 K_ASM_ARGS_3, "r" (__r23)
-+#define K_ASM_ARGS_5 K_ASM_ARGS_4, "r" (__r22)
-+#define K_ASM_ARGS_6 K_ASM_ARGS_5, "r" (__r21)
-+
-+/* The registers not listed as inputs but clobbered */
-+#define K_CLOB_ARGS_6
-+#define K_CLOB_ARGS_5 K_CLOB_ARGS_6, "%r21"
-+#define K_CLOB_ARGS_4 K_CLOB_ARGS_5, "%r22"
-+#define K_CLOB_ARGS_3 K_CLOB_ARGS_4, "%r23"
-+#define K_CLOB_ARGS_2 K_CLOB_ARGS_3, "%r24"
-+#define K_CLOB_ARGS_1 K_CLOB_ARGS_2, "%r25"
-+#define K_CLOB_ARGS_0 K_CLOB_ARGS_1, "%r26"
-+
-+#define io_syscall1(type,fname,sname,type1,arg1)                      \
-+type fname(type1 arg1)                                                        \
-+{                                                                     \
-+    return K_INLINE_SYSCALL(sname, 1, arg1);                          \
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)           \
-+type fname(type1 arg1, type2 arg2)                                    \
-+{                                                                     \
-+    return K_INLINE_SYSCALL(sname, 2, arg1, arg2);                    \
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)        \
-+type fname(type1 arg1, type2 arg2, type3 arg3)                                \
-+{                                                                     \
-+    return K_INLINE_SYSCALL(sname, 3, arg1, arg2, arg3);              \
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
-+{                                                                     \
-+    return K_INLINE_SYSCALL(sname, 4, arg1, arg2, arg3, arg4);                \
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)        \
-+{                                                                     \
-+    return K_INLINE_SYSCALL(sname, 5, arg1, arg2, arg3, arg4, arg5);  \
-+}
-+
-Index: libaio-0.3.109/harness/main.c
-===================================================================
---- libaio-0.3.109.orig/harness/main.c 2014-06-11 10:40:07.929826651 +0200
-+++ libaio-0.3.109/harness/main.c      2014-06-11 10:40:07.925826651 +0200
-@@ -12,7 +12,17 @@
- #include <libaio.h>
- #if __LP64__ == 0
-+#if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
- #define KERNEL_RW_POINTER     ((void *)0xc0010000)
-+#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
-+#define KERNEL_RW_POINTER     ((void *)0x00010000)
-+#elif defined(__hppa__)
-+#define KERNEL_RW_POINTER     ((void *)0x10100000)
-+#elif defined(__sparc__)
-+#define KERNEL_RW_POINTER     ((void *)0xf0010000)
-+#else
-+#error Unknown kernel memory address.
-+#endif
- #else
- //#warning Not really sure where kernel memory is.  Guessing.
- #define KERNEL_RW_POINTER     ((void *)0xffffffff81000000)
-Index: libaio-0.3.109/src/syscall-sh.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-sh.h    2014-06-11 10:40:07.921826651 +0200
-@@ -0,0 +1,78 @@
-+/* Copy from ./arch/sh/include/asm/unistd_32.h */
-+#define __NR_io_setup       245
-+#define __NR_io_destroy     246
-+#define __NR_io_getevents   247
-+#define __NR_io_submit      248
-+#define __NR_io_cancel      249
-+
-+#define io_syscall1(type,fname,sname,type1,arg1) \
-+type fname(type1 arg1) \
-+{ \
-+register long __sc0 __asm__ ("r3") = __NR_##sname; \
-+register long __sc4 __asm__ ("r4") = (long) arg1; \
-+__asm__ __volatile__ ("trapa    #0x11" \
-+      : "=z" (__sc0) \
-+      : "0" (__sc0), "r" (__sc4) \
-+      : "memory"); \
-+      return (type) __sc0;\
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
-+type fname(type1 arg1,type2 arg2) \
-+{ \
-+register long __sc0 __asm__ ("r3") = __NR_##sname; \
-+register long __sc4 __asm__ ("r4") = (long) arg1; \
-+register long __sc5 __asm__ ("r5") = (long) arg2; \
-+      __asm__ __volatile__ ("trapa    #0x12" \
-+      : "=z" (__sc0) \
-+      : "0" (__sc0), "r" (__sc4), "r" (__sc5) \
-+      : "memory"); \
-+      return (type) __sc0;\
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
-+type fname(type1 arg1,type2 arg2,type3 arg3) \
-+{ \
-+register long __sc0 __asm__ ("r3") = __NR_##sname; \
-+register long __sc4 __asm__ ("r4") = (long) arg1; \
-+register long __sc5 __asm__ ("r5") = (long) arg2; \
-+register long __sc6 __asm__ ("r6") = (long) arg3; \
-+      __asm__ __volatile__ ("trapa    #0x13" \
-+      : "=z" (__sc0) \
-+      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \
-+      : "memory"); \
-+      return (type) __sc0;\
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-+{ \
-+register long __sc0 __asm__ ("r3") = __NR_##sname; \
-+register long __sc4 __asm__ ("r4") = (long) arg1; \
-+register long __sc5 __asm__ ("r5") = (long) arg2; \
-+register long __sc6 __asm__ ("r6") = (long) arg3; \
-+register long __sc7 __asm__ ("r7") = (long) arg4; \
-+__asm__ __volatile__ ("trapa    #0x14" \
-+      : "=z" (__sc0) \
-+      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6),  \
-+      "r" (__sc7) \
-+      : "memory" ); \
-+      return (type) __sc0;\
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-+{ \
-+register long __sc3 __asm__ ("r3") = __NR_##sname; \
-+register long __sc4 __asm__ ("r4") = (long) arg1; \
-+register long __sc5 __asm__ ("r5") = (long) arg2; \
-+register long __sc6 __asm__ ("r6") = (long) arg3; \
-+register long __sc7 __asm__ ("r7") = (long) arg4; \
-+register long __sc0 __asm__ ("r0") = (long) arg5; \
-+__asm__ __volatile__ ("trapa    #0x15" \
-+      : "=z" (__sc0) \
-+      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7),  \
-+      "r" (__sc3) \
-+      : "memory" ); \
-+      return (type) __sc0;\
-+}
-Index: libaio-0.3.109/src/syscall-sparc64.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-sparc64.h       2014-06-11 10:40:07.925826651 +0200
-@@ -0,0 +1,98 @@
-+#define __NR_io_setup         268
-+#define __NR_io_destroy               269
-+#define __NR_io_submit                270
-+#define __NR_io_cancel                271
-+#define __NR_io_getevents     272
-+
-+#define io_syscall1(type,fname,sname,type1,arg1)                        \
-+type fname(type1 arg1)                                                          \
-+{                                                                       \
-+      unsigned long __res;                                              \
-+      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
-+      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
-+      __asm__ __volatile__("t         0x6d\n\t"                         \
-+                           "sub       %%g0, %%o0, %0\n\t"               \
-+                           "movcc     %%xcc, %%o0, %0\n"                \
-+                           "1:"                                         \
-+                           : "=r" (__res), "=&r" (__o0)                 \
-+                           : "1" (__o0), "r" (__g1)                     \
-+                           : "cc");                                     \
-+      return (type) __res;                                              \
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)             \
-+type fname(type1 arg1, type2 arg2)                                      \
-+{                                                                       \
-+      unsigned long __res;                                              \
-+      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
-+      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
-+      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
-+      __asm__ __volatile__("t         0x6d\n\t"                         \
-+                           "sub       %%g0, %%o0, %0\n\t"               \
-+                           "movcc     %%xcc, %%o0, %0\n"                \
-+                           "1:"                                         \
-+                           : "=r" (__res), "=&r" (__o0)                 \
-+                           : "1" (__o0), "r" (__o1), "r" (__g1)         \
-+                           : "cc");                                     \
-+      return (type) __res;                                              \
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)          \
-+type fname(type1 arg1, type2 arg2, type3 arg3)                                  \
-+{                                                                       \
-+      unsigned long __res;                                              \
-+      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
-+      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
-+      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
-+      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
-+      __asm__ __volatile__("t         0x6d\n\t"                         \
-+                           "sub       %%g0, %%o0, %0\n\t"               \
-+                           "movcc     %%xcc, %%o0, %0\n"                \
-+                           "1:"                                         \
-+                           : "=r" (__res), "=&r" (__o0)                 \
-+                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
-+                             "r" (__g1)                                 \
-+                           : "cc");                                     \
-+      return (type) __res;                                              \
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)              \
-+{                                                                       \
-+      unsigned long __res;                                              \
-+      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
-+      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
-+      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
-+      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
-+      register unsigned long __o3 __asm__("o3") = (unsigned long) arg4; \
-+      __asm__ __volatile__("t         0x6d\n\t"                         \
-+                           "sub       %%g0, %%o0, %0\n\t"               \
-+                           "movcc     %%xcc, %%o0, %0\n"                \
-+                           "1:"                                         \
-+                           : "=r" (__res), "=&r" (__o0)                 \
-+                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
-+                             "r" (__o3), "r" (__g1)                     \
-+                           : "cc");                                     \
-+      return (type) __res;                                              \
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)          \
-+{                                                                       \
-+      unsigned long __res;                                              \
-+      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
-+      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
-+      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
-+      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
-+      register unsigned long __o3 __asm__("o3") = (unsigned long) arg4; \
-+      register unsigned long __o4 __asm__("o4") = (unsigned long) arg5; \
-+      __asm__ __volatile__("t         0x6d\n\t"                         \
-+                           "sub       %%g0, %%o0, %0\n\t"               \
-+                           "movcc     %%xcc, %%o0, %0\n"                \
-+                           "1:"                                         \
-+                           : "=r" (__res), "=&r" (__o0)                 \
-+                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
-+                             "r" (__o3), "r" (__o4), "r" (__g1)         \
-+                           : "cc");                                     \
-+      return (type) __res;                                              \
-+}
-Index: libaio-0.3.109/src/syscall-x86_64.h
-===================================================================
---- libaio-0.3.109.orig/src/syscall-x86_64.h   2014-06-11 10:40:07.929826651 +0200
-+++ libaio-0.3.109/src/syscall-x86_64.h        2014-06-11 10:40:07.925826651 +0200
-@@ -1,8 +1,18 @@
-+#ifndef __NR_io_setup
- #define __NR_io_setup         206
-+#endif
-+#ifndef __NR_io_destroy
- #define __NR_io_destroy               207
-+#endif
-+#ifndef __NR_io_getevents
- #define __NR_io_getevents     208
-+#endif
-+#ifndef __NR_io_submit
- #define __NR_io_submit                209
-+#endif
-+#ifndef __NR_io_cancel
- #define __NR_io_cancel                210
-+#endif
- #define __syscall_clobber "r11","rcx","memory" 
- #define __syscall "syscall"
-@@ -42,10 +52,11 @@
- type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4)           \
- {                                                                     \
- long __res;                                                           \
--__asm__ volatile ("movq %5,%%r10 ;" __syscall                         \
-+register long __a4 asm ("r10") = (long) arg4;                           \
-+__asm__ volatile (__syscall                                           \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
--        "d" ((long)(arg3)),"g" ((long)(arg4)) : __syscall_clobber,"r10" ); \
-+        "d" ((long)(arg3)),"r" (__a4)); \
- return __res;                                                         \
- } 
-@@ -54,10 +65,11 @@
- type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)   \
- {                                                                     \
- long __res;                                                           \
--__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall         \
-+register long __a4 asm ("r10") = (long) arg4;                         \
-+register long __a5 asm ("r8") = (long) arg5;                            \
-+__asm__ volatile (__syscall                                           \
-       : "=a" (__res)                                                  \
-       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
--        "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) :    \
--      __syscall_clobber,"r8","r10" );                                 \
-+        "d" ((long)(arg3)),"r" (__a4),"r" (__a5)); \
- return __res;                                                         \
- }
-Index: libaio-0.3.109/src/syscall-arm64.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-arm64.h 2014-06-11 10:40:07.925826651 +0200
-@@ -0,0 +1,101 @@
-+/*
-+ *  linux/include/asm-arm/unistd.h
-+ *
-+ *  Copyright (C) 2001-2005 Russell King
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
-+ * no matter what the change is.  Thanks!
-+ */
-+
-+#define __NR_io_setup                 0
-+#define __NR_io_destroy                       1
-+#define __NR_io_submit                        2
-+#define __NR_io_cancel                        3
-+#define __NR_io_getevents             4
-+
-+#define __sys2(x) #x
-+#define __sys1(x) __sys2(x)
-+
-+#define __SYS_REG(name) register long __sysreg __asm__("w8") = __NR_##name;
-+#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs
-+#define __syscall(name) "svc\t#0"
-+
-+#define io_syscall1(type,fname,sname,type1,arg1)                      \
-+type fname(type1 arg1) {                                              \
-+  __SYS_REG(sname)                                                    \
-+  register long __x0 __asm__("x0") = (long)arg1;                      \
-+  register long __res_x0 __asm__("x0");                                       \
-+  __asm__ __volatile__ (                                              \
-+  __syscall(sname)                                                    \
-+      : "=r" (__res_x0)                                               \
-+      : __SYS_REG_LIST( "0" (__x0) )                                  \
-+      : "memory" );                                                   \
-+  return (type) __res_x0;                                             \
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)           \
-+type fname(type1 arg1,type2 arg2) {                                   \
-+  __SYS_REG(sname)                                                    \
-+  register long __x0 __asm__("x0") = (long)arg1;                      \
-+  register long __x1 __asm__("x1") = (long)arg2;                      \
-+  register long __res_x0 __asm__("x0");                                       \
-+  __asm__ __volatile__ (                                              \
-+  __syscall(sname)                                                    \
-+      : "=r" (__res_x0)                                               \
-+      : __SYS_REG_LIST( "0" (__x0), "r" (__x1) )                      \
-+      : "memory" );                                                   \
-+  return (type) __res_x0;                                             \
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)        \
-+type fname(type1 arg1,type2 arg2,type3 arg3) {                                \
-+  __SYS_REG(sname)                                                    \
-+  register long __x0 __asm__("x0") = (long)arg1;                      \
-+  register long __x1 __asm__("x1") = (long)arg2;                      \
-+  register long __x2 __asm__("x2") = (long)arg3;                      \
-+  register long __res_x0 __asm__("x0");                                       \
-+  __asm__ __volatile__ (                                              \
-+  __syscall(sname)                                                    \
-+      : "=r" (__res_x0)                                               \
-+      : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2) )          \
-+      : "memory" );                                                   \
-+  return (type) __res_x0;                                             \
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {          \
-+  __SYS_REG(sname)                                                    \
-+  register long __x0 __asm__("x0") = (long)arg1;                      \
-+  register long __x1 __asm__("x1") = (long)arg2;                      \
-+  register long __x2 __asm__("x2") = (long)arg3;                      \
-+  register long __x3 __asm__("x3") = (long)arg4;                      \
-+  register long __res_x0 __asm__("x0");                                       \
-+  __asm__ __volatile__ (                                              \
-+  __syscall(sname)                                                    \
-+      : "=r" (__res_x0)                                               \
-+      : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2), "r" (__x3) ) \
-+      : "memory" );                                                   \
-+  return (type) __res_x0;                                             \
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)  \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {\
-+  __SYS_REG(sname)                                                    \
-+  register long __x0 __asm__("x0") = (long)arg1;                      \
-+  register long __x1 __asm__("x1") = (long)arg2;                      \
-+  register long __x2 __asm__("x2") = (long)arg3;                      \
-+  register long __x3 __asm__("x3") = (long)arg4;                      \
-+  register long __x4 __asm__("x4") = (long)arg5;                      \
-+  register long __res_x0 __asm__("x0");                                       \
-+  __asm__ __volatile__ (                                              \
-+  __syscall(sname)                                                    \
-+      : "=r" (__res_x0)                                               \
-+      : __SYS_REG_LIST( "0" (__x0), "r" (__x1), "r" (__x2),           \
-+                        "r" (__x3), "r" (__x4) )                      \
-+      : "memory" );                                                   \
-+  return (type) __res_x0;                                             \
-+}
-Index: libaio-0.3.109/harness/cases/16.t
-===================================================================
---- libaio-0.3.109.orig/harness/cases/16.t     2014-06-11 10:40:07.929826651 +0200
-+++ libaio-0.3.109/harness/cases/16.t  2014-06-11 10:40:07.925826651 +0200
-@@ -18,6 +18,12 @@
- #define SYS_eventfd 318
- #elif defined(__alpha__)
- #define SYS_eventfd 478
-+#elif defined(__aarch64__)
-+/* arm64 does not implement eventfd, only eventfd2 */
-+#define USE_EVENTFD2
-+#ifndef SYS_eventfd2
-+#define SYS_eventfd2 19
-+#endif /* __aarch64__ */
- #else
- #error define SYS_eventfd for your arch!
- #endif
-@@ -39,7 +45,11 @@
-       struct timespec notime = { .tv_sec = 0, .tv_nsec = 0 };
-       buf = malloc(SIZE);                             assert(buf);
-+#ifndef USE_EVENTFD2
-       efd = syscall(SYS_eventfd, 0);
-+#else
-+      efd = syscall(SYS_eventfd2, 0, 0);
-+#endif
-       if (efd < 0) {
-               if (errno == ENOSYS) {
-                       printf("No eventfd support.  [SKIPPING]\n");
diff --git a/libs/libaio/patches/001_arches.patch b/libs/libaio/patches/001_arches.patch
new file mode 100644 (file)
index 0000000..4130af3
--- /dev/null
@@ -0,0 +1,566 @@
+---
+ harness/main.c       |   10 ++
+ src/libaio.h         |    1 
+ src/syscall-m68k.h   |   78 +++++++++++++++++
+ src/syscall-mips.h   |  223 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/syscall-parisc.h |  146 +++++++++++++++++++++++++++++++++
+ src/syscall-sparc.h  |   20 +++-
+ src/syscall.h        |    6 +
+ 7 files changed, 479 insertions(+), 5 deletions(-)
+
+--- /dev/null
++++ b/src/syscall-m68k.h
+@@ -0,0 +1,78 @@
++#define __NR_io_setup         241
++#define __NR_io_destroy               242
++#define __NR_io_getevents     243
++#define __NR_io_submit                244
++#define __NR_io_cancel                245
++
++#define io_syscall1(type,fname,sname,atype,a) \
++type fname(atype a) \
++{ \
++register long __res __asm__ ("%d0") = __NR_##sname; \
++register long __a __asm__ ("%d1") = (long)(a); \
++__asm__ __volatile__ ("trap  #0" \
++                    : "+d" (__res) \
++                    : "d" (__a)  ); \
++return (type) __res; \
++}
++
++#define io_syscall2(type,fname,sname,atype,a,btype,b) \
++type fname(atype a,btype b) \
++{ \
++register long __res __asm__ ("%d0") = __NR_##sname; \
++register long __a __asm__ ("%d1") = (long)(a); \
++register long __b __asm__ ("%d2") = (long)(b); \
++__asm__ __volatile__ ("trap  #0" \
++                    : "+d" (__res) \
++                    : "d" (__a), "d" (__b) \
++                   ); \
++return (type) __res; \
++}
++
++#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \
++type fname(atype a,btype b,ctype c) \
++{ \
++register long __res __asm__ ("%d0") = __NR_##sname; \
++register long __a __asm__ ("%d1") = (long)(a); \
++register long __b __asm__ ("%d2") = (long)(b); \
++register long __c __asm__ ("%d3") = (long)(c); \
++__asm__ __volatile__ ("trap  #0" \
++                    : "+d" (__res) \
++                    : "d" (__a), "d" (__b), \
++                      "d" (__c) \
++                   ); \
++return (type) __res; \
++}
++
++#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \
++type fname (atype a, btype b, ctype c, dtype d) \
++{ \
++register long __res __asm__ ("%d0") = __NR_##sname; \
++register long __a __asm__ ("%d1") = (long)(a); \
++register long __b __asm__ ("%d2") = (long)(b); \
++register long __c __asm__ ("%d3") = (long)(c); \
++register long __d __asm__ ("%d4") = (long)(d); \
++__asm__ __volatile__ ("trap  #0" \
++                    : "+d" (__res) \
++                    : "d" (__a), "d" (__b), \
++                      "d" (__c), "d" (__d)  \
++                   ); \
++return (type) __res; \
++}
++
++#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
++type fname (atype a,btype b,ctype c,dtype d,etype e) \
++{ \
++register long __res __asm__ ("%d0") = __NR_##sname; \
++register long __a __asm__ ("%d1") = (long)(a); \
++register long __b __asm__ ("%d2") = (long)(b); \
++register long __c __asm__ ("%d3") = (long)(c); \
++register long __d __asm__ ("%d4") = (long)(d); \
++register long __e __asm__ ("%d5") = (long)(e); \
++__asm__ __volatile__ ("trap  #0" \
++                    : "+d" (__res) \
++                    : "d" (__a), "d" (__b), \
++                      "d" (__c), "d" (__d), "d" (__e)  \
++                   ); \
++return (type) __res; \
++}
++
+--- a/src/syscall.h
++++ b/src/syscall.h
+@@ -28,6 +28,12 @@
+ #include "syscall-sparc.h"
+ #elif defined(__aarch64__)
+ #include "syscall-arm64.h"
++#elif defined(__m68k__)
++#include "syscall-m68k.h"
++#elif defined(__hppa__)
++#include "syscall-parisc.h"
++#elif defined(__mips__)
++#include "syscall-mips.h"
+ #else
+ #warning "using generic syscall method"
+ #include "syscall-generic.h"
+--- /dev/null
++++ b/src/syscall-mips.h
+@@ -0,0 +1,223 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
++ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ *
++ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
++ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
++ */
++
++#ifndef _MIPS_SIM_ABI32
++#define _MIPS_SIM_ABI32                       1
++#define _MIPS_SIM_NABI32              2
++#define _MIPS_SIM_ABI64                       3
++#endif
++
++#if _MIPS_SIM == _MIPS_SIM_ABI32
++
++/*
++ * Linux o32 style syscalls are in the range from 4000 to 4999.
++ */
++#define __NR_Linux                    4000
++#define __NR_io_setup                 (__NR_Linux + 241)
++#define __NR_io_destroy                       (__NR_Linux + 242)
++#define __NR_io_getevents             (__NR_Linux + 243)
++#define __NR_io_submit                        (__NR_Linux + 244)
++#define __NR_io_cancel                        (__NR_Linux + 245)
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
++
++#if _MIPS_SIM == _MIPS_SIM_ABI64
++
++/*
++ * Linux 64-bit syscalls are in the range from 5000 to 5999.
++ */
++#define __NR_Linux                    5000
++#define __NR_io_setup                 (__NR_Linux + 200)
++#define __NR_io_destroy                       (__NR_Linux + 201)
++#define __NR_io_getevents             (__NR_Linux + 202)
++#define __NR_io_submit                        (__NR_Linux + 203)
++#define __NR_io_cancel                        (__NR_Linux + 204)
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
++
++#if _MIPS_SIM == _MIPS_SIM_NABI32
++
++/*
++ * Linux N32 syscalls are in the range from 6000 to 6999.
++ */
++#define __NR_Linux                    6000
++#define __NR_io_setup                 (__NR_Linux + 200)
++#define __NR_io_destroy                       (__NR_Linux + 201)
++#define __NR_io_getevents             (__NR_Linux + 202)
++#define __NR_io_submit                        (__NR_Linux + 203)
++#define __NR_io_cancel                        (__NR_Linux + 204)
++#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
++
++#define io_syscall1(type,fname,sname,atype,a) \
++type fname(atype a) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a3 asm("$7"); \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "li\t$2, %3\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "=r" (__a3) \
++      : "r" (__a0), "i" (__NR_##sname) \
++      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#define io_syscall2(type,fname,sname,atype,a,btype,b) \
++type fname(atype a, btype b) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a1 asm("$5") = (unsigned long) b; \
++      register unsigned long __a3 asm("$7"); \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "li\t$2, %4\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "=r" (__a3) \
++      : "r" (__a0), "r" (__a1), "i" (__NR_##sname) \
++      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \
++type fname(atype a, btype b, ctype c) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a1 asm("$5") = (unsigned long) b; \
++      register unsigned long __a2 asm("$6") = (unsigned long) c; \
++      register unsigned long __a3 asm("$7"); \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "li\t$2, %5\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "=r" (__a3) \
++      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \
++      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \
++type fname(atype a, btype b, ctype c, dtype d) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a1 asm("$5") = (unsigned long) b; \
++      register unsigned long __a2 asm("$6") = (unsigned long) c; \
++      register unsigned long __a3 asm("$7") = (unsigned long) d; \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "li\t$2, %5\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "+r" (__a3) \
++      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \
++      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#if (_MIPS_SIM == _MIPS_SIM_ABI32)
++
++/*
++ * Using those means your brain needs more than an oil change ;-)
++ */
++
++#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
++type fname(atype a, btype b, ctype c, dtype d, etype e) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a1 asm("$5") = (unsigned long) b; \
++      register unsigned long __a2 asm("$6") = (unsigned long) c; \
++      register unsigned long __a3 asm("$7") = (unsigned long) d; \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "lw\t$2, %6\n\t" \
++      "subu\t$29, 32\n\t" \
++      "sw\t$2, 16($29)\n\t" \
++      "li\t$2, %5\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      "addiu\t$29, 32\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "+r" (__a3) \
++      : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname), \
++        "m" ((unsigned long)e) \
++      : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */
++
++#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
++
++#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
++type fname (atype a,btype b,ctype c,dtype d,etype e) \
++{ \
++      register unsigned long __a0 asm("$4") = (unsigned long) a; \
++      register unsigned long __a1 asm("$5") = (unsigned long) b; \
++      register unsigned long __a2 asm("$6") = (unsigned long) c; \
++      register unsigned long __a3 asm("$7") = (unsigned long) d; \
++      register unsigned long __a4 asm("$8") = (unsigned long) e; \
++      unsigned long __v0; \
++      \
++      __asm__ volatile ( \
++      ".set\tnoreorder\n\t" \
++      "li\t$2, %6\t\t\t# " #fname "\n\t" \
++      "syscall\n\t" \
++      "move\t%0, $2\n\t" \
++      ".set\treorder" \
++      : "=&r" (__v0), "+r" (__a3) \
++      : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##sname) \
++      : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
++        "memory"); \
++      \
++      if (__a3 == 0) \
++              return (type) __v0; \
++      return (type) -1; \
++}
++
++#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
++
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -66,6 +66,7 @@ typedef enum io_iocb_cmd {
+ /* big endian, 64 bits */
+ #elif defined(__powerpc64__) || defined(__s390x__) || \
++      (defined(__hppa__) && defined(__arch64__)) || \
+       (defined(__sparc__) && defined(__arch64__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EB__))
+ #define PADDED(x, y)  unsigned y; x
+--- /dev/null
++++ b/src/syscall-parisc.h
+@@ -0,0 +1,146 @@
++/*
++ * Linux system call numbers.
++ *
++ * Cary Coutant says that we should just use another syscall gateway
++ * page to avoid clashing with the HPUX space, and I think he's right:
++ * it will would keep a branch out of our syscall entry path, at the
++ * very least.  If we decide to change it later, we can ``just'' tweak
++ * the LINUX_GATEWAY_ADDR define at the bottom and make __NR_Linux be
++ * 1024 or something.  Oh, and recompile libc. =)
++ *
++ * 64-bit HPUX binaries get the syscall gateway address passed in a register
++ * from the kernel at startup, which seems a sane strategy.
++ */
++
++#define __NR_Linux                0
++#define __NR_io_setup           (__NR_Linux + 215)
++#define __NR_io_destroy         (__NR_Linux + 216)
++#define __NR_io_getevents       (__NR_Linux + 217)
++#define __NR_io_submit          (__NR_Linux + 218)
++#define __NR_io_cancel          (__NR_Linux + 219)
++
++#define SYS_ify(syscall_name)   __NR_##syscall_name
++
++/* Assume all syscalls are done from PIC code just to be
++ * safe. The worst case scenario is that you lose a register
++ * and save/restore r19 across the syscall. */
++#define PIC
++
++/* Definition taken from glibc 2.3.3
++ * sysdeps/unix/sysv/linux/hppa/sysdep.h
++ */
++
++#ifdef PIC
++/* WARNING: CANNOT BE USED IN A NOP! */
++# define K_STW_ASM_PIC        "       copy %%r19, %%r4\n"
++# define K_LDW_ASM_PIC        "       copy %%r4, %%r19\n"
++# define K_USING_GR4  "%r4",
++#else
++# define K_STW_ASM_PIC        " \n"
++# define K_LDW_ASM_PIC        " \n"
++# define K_USING_GR4
++#endif
++
++/* GCC has to be warned that a syscall may clobber all the ABI
++   registers listed as "caller-saves", see page 8, Table 2
++   in section 2.2.6 of the PA-RISC RUN-TIME architecture
++   document. However! r28 is the result and will conflict with
++   the clobber list so it is left out. Also the input arguments
++   registers r20 -> r26 will conflict with the list so they
++   are treated specially. Although r19 is clobbered by the syscall
++   we cannot say this because it would violate ABI, thus we say
++   r4 is clobbered and use that register to save/restore r19
++   across the syscall. */
++
++#define K_CALL_CLOB_REGS "%r1", "%r2", K_USING_GR4 \
++                       "%r20", "%r29", "%r31"
++
++#undef K_INLINE_SYSCALL
++#define K_INLINE_SYSCALL(name, nr, args...)   ({                      \
++      long __sys_res;                                                 \
++      {                                                               \
++              register unsigned long __res __asm__("r28");            \
++              K_LOAD_ARGS_##nr(args)                                  \
++              /* FIXME: HACK stw/ldw r19 around syscall */            \
++              __asm__ volatile(                                       \
++                      K_STW_ASM_PIC                                   \
++                      "       ble  0x100(%%sr2, %%r0)\n"              \
++                      "       ldi %1, %%r20\n"                        \
++                      K_LDW_ASM_PIC                                   \
++                      : "=r" (__res)                                  \
++                      : "i" (SYS_ify(name)) K_ASM_ARGS_##nr           \
++                      : "memory", K_CALL_CLOB_REGS K_CLOB_ARGS_##nr   \
++              );                                                      \
++              __sys_res = (long)__res;                                \
++      }                                                               \
++      __sys_res;                                                      \
++})
++
++#define K_LOAD_ARGS_0()
++#define K_LOAD_ARGS_1(r26)                                    \
++      register unsigned long __r26 __asm__("r26") = (unsigned long)(r26);   \
++      K_LOAD_ARGS_0()
++#define K_LOAD_ARGS_2(r26,r25)                                        \
++      register unsigned long __r25 __asm__("r25") = (unsigned long)(r25);   \
++      K_LOAD_ARGS_1(r26)
++#define K_LOAD_ARGS_3(r26,r25,r24)                            \
++      register unsigned long __r24 __asm__("r24") = (unsigned long)(r24);   \
++      K_LOAD_ARGS_2(r26,r25)
++#define K_LOAD_ARGS_4(r26,r25,r24,r23)                                \
++      register unsigned long __r23 __asm__("r23") = (unsigned long)(r23);   \
++      K_LOAD_ARGS_3(r26,r25,r24)
++#define K_LOAD_ARGS_5(r26,r25,r24,r23,r22)                    \
++      register unsigned long __r22 __asm__("r22") = (unsigned long)(r22);   \
++      K_LOAD_ARGS_4(r26,r25,r24,r23)
++#define K_LOAD_ARGS_6(r26,r25,r24,r23,r22,r21)                        \
++      register unsigned long __r21 __asm__("r21") = (unsigned long)(r21);   \
++      K_LOAD_ARGS_5(r26,r25,r24,r23,r22)
++
++/* Even with zero args we use r20 for the syscall number */
++#define K_ASM_ARGS_0
++#define K_ASM_ARGS_1 K_ASM_ARGS_0, "r" (__r26)
++#define K_ASM_ARGS_2 K_ASM_ARGS_1, "r" (__r25)
++#define K_ASM_ARGS_3 K_ASM_ARGS_2, "r" (__r24)
++#define K_ASM_ARGS_4 K_ASM_ARGS_3, "r" (__r23)
++#define K_ASM_ARGS_5 K_ASM_ARGS_4, "r" (__r22)
++#define K_ASM_ARGS_6 K_ASM_ARGS_5, "r" (__r21)
++
++/* The registers not listed as inputs but clobbered */
++#define K_CLOB_ARGS_6
++#define K_CLOB_ARGS_5 K_CLOB_ARGS_6, "%r21"
++#define K_CLOB_ARGS_4 K_CLOB_ARGS_5, "%r22"
++#define K_CLOB_ARGS_3 K_CLOB_ARGS_4, "%r23"
++#define K_CLOB_ARGS_2 K_CLOB_ARGS_3, "%r24"
++#define K_CLOB_ARGS_1 K_CLOB_ARGS_2, "%r25"
++#define K_CLOB_ARGS_0 K_CLOB_ARGS_1, "%r26"
++
++#define io_syscall1(type,fname,sname,type1,arg1)                      \
++type fname(type1 arg1)                                                        \
++{                                                                     \
++    return K_INLINE_SYSCALL(sname, 1, arg1);                          \
++}
++
++#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)           \
++type fname(type1 arg1, type2 arg2)                                    \
++{                                                                     \
++    return K_INLINE_SYSCALL(sname, 2, arg1, arg2);                    \
++}
++
++#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)        \
++type fname(type1 arg1, type2 arg2, type3 arg3)                                \
++{                                                                     \
++    return K_INLINE_SYSCALL(sname, 3, arg1, arg2, arg3);              \
++}
++
++#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
++{                                                                     \
++    return K_INLINE_SYSCALL(sname, 4, arg1, arg2, arg3, arg4);                \
++}
++
++#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)        \
++{                                                                     \
++    return K_INLINE_SYSCALL(sname, 5, arg1, arg2, arg3, arg4, arg5);  \
++}
++
+--- a/harness/main.c
++++ b/harness/main.c
+@@ -12,7 +12,17 @@
+ #include <libaio.h>
+ #if __LP64__ == 0
++#if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER     ((void *)0xc0010000)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__)
++#define KERNEL_RW_POINTER     ((void *)0x00010000)
++#elif defined(__hppa__)
++#define KERNEL_RW_POINTER     ((void *)0x10100000)
++#elif defined(__sparc__)
++#define KERNEL_RW_POINTER     ((void *)0xf0010000)
++#else
++#error Unknown kernel memory address.
++#endif
+ #else
+ //#warning Not really sure where kernel memory is.  Guessing.
+ #define KERNEL_RW_POINTER     ((void *)0xffffffff81000000)
+--- a/src/syscall-sparc.h
++++ b/src/syscall-sparc.h
+@@ -20,7 +20,9 @@ __asm__ __volatile__ ("t 0x10\n\t" \
+                       : "=r" (__res), "=&r" (__o0) \
+                       : "1" (__o0), "r" (__g1) \
+                       : "cc"); \
+-return (type) __res; \
++if (__res < -255 || __res >= 0) \
++      return (type) __res; \
++return -1; \
+ }
+ #define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
+@@ -38,7 +40,9 @@ __asm__ __volatile__ ("t 0x10\n\t" \
+                       : "=r" (__res), "=&r" (__o0) \
+                       : "1" (__o0), "r" (__o1), "r" (__g1) \
+                       : "cc"); \
+-return (type) __res; \
++if (__res < -255 || __res >= 0) \
++      return (type) __res; \
++return -1; \
+ }
+ #define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
+@@ -57,7 +61,9 @@ __asm__ __volatile__ ("t 0x10\n\t" \
+                       : "=r" (__res), "=&r" (__o0) \
+                       : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
+                       : "cc"); \
+-return (type) __res; \
++if (__res < -255 || __res >= 0) \
++      return (type) __res; \
++return -1; \
+ }
+ #define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+@@ -77,7 +83,9 @@ __asm__ __volatile__ ("t 0x10\n\t" \
+                       : "=r" (__res), "=&r" (__o0) \
+                       : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
+                       : "cc"); \
+-return (type) __res; \
++if (__res < -255 || __res >= 0) \
++      return (type) __res; \
++return -1; \
+ }
+ #define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+@@ -99,5 +107,7 @@ __asm__ __volatile__ ("t 0x10\n\t" \
+                       : "=r" (__res), "=&r" (__o0) \
+                       : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
+                       : "cc"); \
+-return (type) __res; \
++if (__res < -255 || __res >= 0) \
++      return (type) __res; \
++return -1; \
+ }
diff --git a/libs/libaio/patches/002-avr32_support.patch b/libs/libaio/patches/002-avr32_support.patch
deleted file mode 100644 (file)
index a662ede..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-Index: libaio-0.3.109/src/libaio.h
-===================================================================
---- libaio-0.3.109.orig/src/libaio.h   2014-06-11 10:41:12.537824814 +0200
-+++ libaio-0.3.109/src/libaio.h        2014-06-11 10:41:12.537824814 +0200
-@@ -134,6 +134,10 @@
- #define PADDEDptr(x, y) x
- #define PADDEDul(x, y)  unsigned long x
- #  endif
-+#elif defined(__avr32__) /* big endian, 32 bits */
-+#define PADDED(x, y)  unsigned y; x
-+#define PADDEDptr(x, y)       unsigned y; x
-+#define PADDEDul(x, y)        unsigned y; unsigned long x;
- #else
- #error        endian?
- #endif
-Index: libaio-0.3.109/src/syscall-avr32.h
-===================================================================
---- /dev/null  1970-01-01 00:00:00.000000000 +0000
-+++ libaio-0.3.109/src/syscall-avr32.h 2014-06-11 10:41:12.537824814 +0200
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright (C) 2007 Atmel Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define __NR_io_setup         197
-+#define __NR_io_destroy               198
-+#define __NR_io_getevents     199
-+#define __NR_io_submit                200
-+#define __NR_io_cancel                201
-+
-+#define io_syscall1(type,fname,sname,type1,arg1)                      \
-+type fname(type1 arg1)                                                        \
-+{                                                                     \
-+      register long __r12 __asm__("r12") = (long)arg1;                \
-+      register long __res_r12 __asm__("r12");                         \
-+      register long __scno __asm__("r8") = __NR_##sname;              \
-+      __asm__ __volatile__("scall"                                    \
-+                           : "=r"(__res_r12)                          \
-+                           : "0"(__r12), "r"(__scno)                  \
-+                           : "memory");                               \
-+      return (type) __res_r12;                                        \
-+}
-+
-+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)           \
-+type fname(type1 arg1, type2 arg2)                                    \
-+{                                                                     \
-+      register long __r12 __asm__("r12") = (long)arg1;                \
-+      register long __r11 __asm__("r11") = (long)arg2;                \
-+      register long __res_r12 __asm__("r12");                         \
-+      register long __scno __asm__("r8") = __NR_##sname;              \
-+      __asm__ __volatile__("scall"                                    \
-+                           : "=r"(__res_r12)                          \
-+                           : "0"(__r12), "r"(__r11), "r"(__scno)      \
-+                           : "memory");                               \
-+      return (type) __res_r12;                                        \
-+}
-+
-+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)        \
-+type fname(type1 arg1, type2 arg2, type3 arg3)                                \
-+{                                                                     \
-+      register long __r12 __asm__("r12") = (long)arg1;                \
-+      register long __r11 __asm__("r11") = (long)arg2;                \
-+      register long __r10 __asm__("r10") = (long)arg3;                \
-+      register long __res_r12 __asm__("r12");                         \
-+      register long __scno __asm__("r8") = __NR_##sname;              \
-+      __asm__ __volatile__("scall"                                    \
-+                           : "=r"(__res_r12)                          \
-+                           : "0"(__r12), "r"(__r11), "r"(__r10),      \
-+                             "r"(__scno)                              \
-+                           : "memory");                               \
-+      return (type) __res_r12;                                        \
-+}
-+
-+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)            \
-+{                                                                     \
-+      register long __r12 __asm__("r12") = (long)arg1;                \
-+      register long __r11 __asm__("r11") = (long)arg2;                \
-+      register long __r10 __asm__("r10") = (long)arg3;                \
-+      register long __r9 __asm__("r9") = (long)arg4;                  \
-+      register long __res_r12 __asm__("r12");                         \
-+      register long __scno __asm__("r8") = __NR_##sname;              \
-+      __asm__ __volatile__("scall"                                    \
-+                           : "=r"(__res_r12)                          \
-+                           : "0"(__r12), "r"(__r11), "r"(__r10),      \
-+                             "r"(__r9), "r"(__scno)                   \
-+                           : "memory");                               \
-+      return (type) __res_r12;                                        \
-+}
-+
-+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)        \
-+{                                                                     \
-+      register long __r12 __asm__("r12") = (long)arg1;                \
-+      register long __r11 __asm__("r11") = (long)arg2;                \
-+      register long __r10 __asm__("r10") = (long)arg3;                \
-+      register long __r9 __asm__("r9") = (long)arg4;                  \
-+      register long __r5 __asm__("r5") = (long)arg5;                  \
-+      register long __res_r12 __asm__("r12");                         \
-+      register long __scno __asm__("r8") = __NR_##sname;              \
-+      __asm__ __volatile__("scall"                                    \
-+                           : "=r"(__res_r12)                          \
-+                           : "0"(__r12), "r"(__r11), "r"(__r10),      \
-+                             "r"(__r9), "r"(__r5), "r"(__scno)        \
-+                           : "memory");                               \
-+      return (type) __res_r12;                                        \
-+}
-Index: libaio-0.3.109/src/syscall.h
-===================================================================
---- libaio-0.3.109.orig/src/syscall.h  2014-06-11 10:41:12.537824814 +0200
-+++ libaio-0.3.109/src/syscall.h       2014-06-11 10:41:12.537824814 +0200
-@@ -38,6 +38,8 @@
- #include "syscall-sh.h"
- #elif defined(__aarch64__)
- #include "syscall-arm64.h"
-+#elif defined(__avr32__)
-+#include "syscall-avr32.h"
- #else
- #error "add syscall-arch.h"
- #endif
diff --git a/libs/libaio/patches/002_arches_sh.patch b/libs/libaio/patches/002_arches_sh.patch
new file mode 100644 (file)
index 0000000..ddf9a11
--- /dev/null
@@ -0,0 +1,139 @@
+From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Subject: Add SH supprt
+
+The test-suite logs can be found at:
+
+  <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=535288>
+
+
+---
+ harness/main.c   |    2 -
+ src/libaio.h     |    4 ++
+ src/syscall-sh.h |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/syscall.h    |    2 +
+ 4 files changed, 84 insertions(+), 2 deletions(-)
+
+
+--- a/harness/main.c
++++ b/harness/main.c
+@@ -14,7 +14,7 @@
+ #if __LP64__ == 0
+ #if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER     ((void *)0xc0010000)
+-#elif defined(__arm__) || defined(__m68k__) || defined(__s390__)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__)
+ #define KERNEL_RW_POINTER     ((void *)0x00010000)
+ #elif defined(__hppa__)
+ #define KERNEL_RW_POINTER     ((void *)0x10100000)
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -51,7 +51,8 @@ typedef enum io_iocb_cmd {
+ /* little endian, 32 bits */
+ #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
+-    defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
++    (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
++    defined(__bfin__) || defined(__MIPSEL__) || \
+     defined(__cris__)
+ #define PADDED(x, y)  x; unsigned y
+ #define PADDEDptr(x, y)       x; unsigned y
+@@ -76,6 +77,7 @@ typedef enum io_iocb_cmd {
+ /* big endian, 32 bits */
+ #elif defined(__PPC__) || defined(__s390__) || \
+       (defined(__arm__) && defined(__ARMEB__)) || \
++      (defined(__sh__) && defined (__BIG_ENDIAN__)) || \
+       defined(__sparc__) || defined(__MIPSEB__) || defined(__m68k__) || \
+       defined(__hppa__) || defined(__frv__) || defined(__avr32__)
+ #define PADDED(x, y)  unsigned y; x
+--- /dev/null
++++ b/src/syscall-sh.h
+@@ -0,0 +1,78 @@
++/* Copy from ./arch/sh/include/asm/unistd_32.h */
++#define __NR_io_setup       245
++#define __NR_io_destroy     246
++#define __NR_io_getevents   247
++#define __NR_io_submit      248
++#define __NR_io_cancel      249
++
++#define io_syscall1(type,fname,sname,type1,arg1) \
++type fname(type1 arg1) \
++{ \
++register long __sc0 __asm__ ("r3") = __NR_##sname; \
++register long __sc4 __asm__ ("r4") = (long) arg1; \
++__asm__ __volatile__ ("trapa    #0x11" \
++      : "=z" (__sc0) \
++      : "0" (__sc0), "r" (__sc4) \
++      : "memory"); \
++      return (type) __sc0;\
++}
++
++#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \
++type fname(type1 arg1,type2 arg2) \
++{ \
++register long __sc0 __asm__ ("r3") = __NR_##sname; \
++register long __sc4 __asm__ ("r4") = (long) arg1; \
++register long __sc5 __asm__ ("r5") = (long) arg2; \
++      __asm__ __volatile__ ("trapa    #0x12" \
++      : "=z" (__sc0) \
++      : "0" (__sc0), "r" (__sc4), "r" (__sc5) \
++      : "memory"); \
++      return (type) __sc0;\
++}
++
++#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \
++type fname(type1 arg1,type2 arg2,type3 arg3) \
++{ \
++register long __sc0 __asm__ ("r3") = __NR_##sname; \
++register long __sc4 __asm__ ("r4") = (long) arg1; \
++register long __sc5 __asm__ ("r5") = (long) arg2; \
++register long __sc6 __asm__ ("r6") = (long) arg3; \
++      __asm__ __volatile__ ("trapa    #0x13" \
++      : "=z" (__sc0) \
++      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \
++      : "memory"); \
++      return (type) __sc0;\
++}
++
++#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
++{ \
++register long __sc0 __asm__ ("r3") = __NR_##sname; \
++register long __sc4 __asm__ ("r4") = (long) arg1; \
++register long __sc5 __asm__ ("r5") = (long) arg2; \
++register long __sc6 __asm__ ("r6") = (long) arg3; \
++register long __sc7 __asm__ ("r7") = (long) arg4; \
++__asm__ __volatile__ ("trapa    #0x14" \
++      : "=z" (__sc0) \
++      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6),  \
++      "r" (__sc7) \
++      : "memory" ); \
++      return (type) __sc0;\
++}
++
++#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
++{ \
++register long __sc3 __asm__ ("r3") = __NR_##sname; \
++register long __sc4 __asm__ ("r4") = (long) arg1; \
++register long __sc5 __asm__ ("r5") = (long) arg2; \
++register long __sc6 __asm__ ("r6") = (long) arg3; \
++register long __sc7 __asm__ ("r7") = (long) arg4; \
++register long __sc0 __asm__ ("r0") = (long) arg5; \
++__asm__ __volatile__ ("trapa    #0x15" \
++      : "=z" (__sc0) \
++      : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7),  \
++      "r" (__sc3) \
++      : "memory" ); \
++      return (type) __sc0;\
++}
+--- a/src/syscall.h
++++ b/src/syscall.h
+@@ -34,6 +34,8 @@
+ #include "syscall-parisc.h"
+ #elif defined(__mips__)
+ #include "syscall-mips.h"
++#elif defined(__sh__)
++#include "syscall-sh.h"
+ #else
+ #warning "using generic syscall method"
+ #include "syscall-generic.h"
diff --git a/libs/libaio/patches/003_arches_sparc64.patch b/libs/libaio/patches/003_arches_sparc64.patch
new file mode 100644 (file)
index 0000000..c685f5e
--- /dev/null
@@ -0,0 +1,117 @@
+---
+ src/syscall-sparc64.h |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/syscall.h         |    2 +
+ 2 files changed, 100 insertions(+)
+
+--- a/src/syscall.h
++++ b/src/syscall.h
+@@ -24,6 +24,8 @@
+ #include "syscall-alpha.h"
+ #elif defined(__arm__)
+ #include "syscall-arm.h"
++#elif defined(__sparc__) && defined(__arch64__)
++#include "syscall-sparc64.h"
+ #elif defined(__sparc__)
+ #include "syscall-sparc.h"
+ #elif defined(__aarch64__)
+--- /dev/null
++++ b/src/syscall-sparc64.h
+@@ -0,0 +1,98 @@
++#define __NR_io_setup         268
++#define __NR_io_destroy               269
++#define __NR_io_submit                270
++#define __NR_io_cancel                271
++#define __NR_io_getevents     272
++
++#define io_syscall1(type,fname,sname,type1,arg1)                        \
++type fname(type1 arg1)                                                          \
++{                                                                       \
++      unsigned long __res;                                              \
++      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
++      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
++      __asm__ __volatile__("t         0x6d\n\t"                         \
++                           "sub       %%g0, %%o0, %0\n\t"               \
++                           "movcc     %%xcc, %%o0, %0\n"                \
++                           "1:"                                         \
++                           : "=r" (__res), "=&r" (__o0)                 \
++                           : "1" (__o0), "r" (__g1)                     \
++                           : "cc");                                     \
++      return (type) __res;                                              \
++}
++
++#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2)             \
++type fname(type1 arg1, type2 arg2)                                      \
++{                                                                       \
++      unsigned long __res;                                              \
++      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
++      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
++      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
++      __asm__ __volatile__("t         0x6d\n\t"                         \
++                           "sub       %%g0, %%o0, %0\n\t"               \
++                           "movcc     %%xcc, %%o0, %0\n"                \
++                           "1:"                                         \
++                           : "=r" (__res), "=&r" (__o0)                 \
++                           : "1" (__o0), "r" (__o1), "r" (__g1)         \
++                           : "cc");                                     \
++      return (type) __res;                                              \
++}
++
++#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3)          \
++type fname(type1 arg1, type2 arg2, type3 arg3)                                  \
++{                                                                       \
++      unsigned long __res;                                              \
++      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
++      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
++      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
++      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
++      __asm__ __volatile__("t         0x6d\n\t"                         \
++                           "sub       %%g0, %%o0, %0\n\t"               \
++                           "movcc     %%xcc, %%o0, %0\n"                \
++                           "1:"                                         \
++                           : "=r" (__res), "=&r" (__o0)                 \
++                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
++                             "r" (__g1)                                 \
++                           : "cc");                                     \
++      return (type) __res;                                              \
++}
++
++#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4)              \
++{                                                                       \
++      unsigned long __res;                                              \
++      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
++      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
++      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
++      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
++      register unsigned long __o3 __asm__("o3") = (unsigned long) arg4; \
++      __asm__ __volatile__("t         0x6d\n\t"                         \
++                           "sub       %%g0, %%o0, %0\n\t"               \
++                           "movcc     %%xcc, %%o0, %0\n"                \
++                           "1:"                                         \
++                           : "=r" (__res), "=&r" (__o0)                 \
++                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
++                             "r" (__o3), "r" (__g1)                     \
++                           : "cc");                                     \
++      return (type) __res;                                              \
++}
++
++#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
++type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)          \
++{                                                                       \
++      unsigned long __res;                                              \
++      register unsigned long __g1 __asm__("g1") = __NR_##sname;         \
++      register unsigned long __o0 __asm__("o0") = (unsigned long) arg1; \
++      register unsigned long __o1 __asm__("o1") = (unsigned long) arg2; \
++      register unsigned long __o2 __asm__("o2") = (unsigned long) arg3; \
++      register unsigned long __o3 __asm__("o3") = (unsigned long) arg4; \
++      register unsigned long __o4 __asm__("o4") = (unsigned long) arg5; \
++      __asm__ __volatile__("t         0x6d\n\t"                         \
++                           "sub       %%g0, %%o0, %0\n\t"               \
++                           "movcc     %%xcc, %%o0, %0\n"                \
++                           "1:"                                         \
++                           : "=r" (__res), "=&r" (__o0)                 \
++                           : "1" (__o0), "r" (__o1), "r" (__o2),        \
++                             "r" (__o3), "r" (__o4), "r" (__g1)         \
++                           : "cc");                                     \
++      return (type) __res;                                              \
++}
diff --git a/libs/libaio/patches/004_arches_x32.patch b/libs/libaio/patches/004_arches_x32.patch
new file mode 100644 (file)
index 0000000..8d315f2
--- /dev/null
@@ -0,0 +1,65 @@
+Index: libaio-0.3.109/src/syscall-x86_64.h
+===================================================================
+--- libaio-0.3.109.orig/src/syscall-x86_64.h   2009-10-09 11:17:02.000000000 -0700
++++ libaio-0.3.109/src/syscall-x86_64.h        2013-03-03 07:15:13.000000000 -0800
+@@ -1,8 +1,18 @@
++#ifndef __NR_io_setup
+ #define __NR_io_setup         206
++#endif
++#ifndef __NR_io_destroy
+ #define __NR_io_destroy               207
++#endif
++#ifndef __NR_io_getevents
+ #define __NR_io_getevents     208
++#endif
++#ifndef __NR_io_submit
+ #define __NR_io_submit                209
++#endif
++#ifndef __NR_io_cancel
+ #define __NR_io_cancel                210
++#endif
+ #define __syscall_clobber "r11","rcx","memory" 
+ #define __syscall "syscall"
+@@ -42,10 +52,11 @@
+ type fname (type1 arg1, type2 arg2, type3 arg3, type4 arg4)           \
+ {                                                                     \
+ long __res;                                                           \
+-__asm__ volatile ("movq %5,%%r10 ;" __syscall                         \
++register long __a4 asm ("r10") = (long) arg4;                           \
++__asm__ volatile (__syscall                                           \
+       : "=a" (__res)                                                  \
+       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
+-        "d" ((long)(arg3)),"g" ((long)(arg4)) : __syscall_clobber,"r10" ); \
++        "d" ((long)(arg3)),"r" (__a4)); \
+ return __res;                                                         \
+ } 
+@@ -54,10 +65,11 @@
+ type fname (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)   \
+ {                                                                     \
+ long __res;                                                           \
+-__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall         \
++register long __a4 asm ("r10") = (long) arg4;                         \
++register long __a5 asm ("r8") = (long) arg5;                            \
++__asm__ volatile (__syscall                                           \
+       : "=a" (__res)                                                  \
+       : "0" (__NR_##sname),"D" ((long)(arg1)),"S" ((long)(arg2)),     \
+-        "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) :    \
+-      __syscall_clobber,"r8","r10" );                                 \
++        "d" ((long)(arg3)),"r" (__a4),"r" (__a5)); \
+ return __res;                                                         \
+ }
+Index: libaio-0.3.109/harness/main.c
+===================================================================
+--- libaio-0.3.109.orig/harness/main.c 2013-03-03 06:58:51.000000000 -0800
++++ libaio-0.3.109/harness/main.c      2013-03-03 07:23:40.000000000 -0800
+@@ -14,7 +14,7 @@
+ #if __LP64__ == 0
+ #if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER     ((void *)0xc0010000)
+-#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
+ #define KERNEL_RW_POINTER     ((void *)0x00010000)
+ #elif defined(__hppa__)
+ #define KERNEL_RW_POINTER     ((void *)0x10100000)
diff --git a/libs/libaio/patches/005_arches_mips.patch b/libs/libaio/patches/005_arches_mips.patch
new file mode 100644 (file)
index 0000000..1bd0971
--- /dev/null
@@ -0,0 +1,63 @@
+Description: Fix mips/mipsel syscall wrappers to return correct error values.
+Author: Jurica Stanojkovic <Jurica.Stanojkovic@rt-rk.com>
+Forwarded: no
+Last-Update: 2012-09-24
+
+
+diff -upNr a/src/syscall-mips.h b/src/syscall-mips.h
+--- a/src/syscall-mips.h       2012-09-13 11:46:35.652286733 +0200
++++ b/src/syscall-mips.h       2012-09-13 16:09:17.964407909 +0200
+@@ -76,7 +76,7 @@ type fname(atype a) \
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #define io_syscall2(type,fname,sname,atype,a,btype,b) \
+@@ -100,7 +100,7 @@ type fname(atype a, btype b) \
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \
+@@ -125,7 +125,7 @@ type fname(atype a, btype b, ctype c) \
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \
+@@ -150,7 +150,7 @@ type fname(atype a, btype b, ctype c, dt
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #if (_MIPS_SIM == _MIPS_SIM_ABI32)
+@@ -186,7 +186,7 @@ type fname(atype a, btype b, ctype c, dt
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */
+@@ -216,7 +216,7 @@ type fname (atype a,btype b,ctype c,dtyp
+       \
+       if (__a3 == 0) \
+               return (type) __v0; \
+-      return (type) -1; \
++      return (type) 0 - __v0; \
+ }
+ #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
diff --git a/libs/libaio/patches/006_arches_mips_fix_padding.patch b/libs/libaio/patches/006_arches_mips_fix_padding.patch
new file mode 100644 (file)
index 0000000..06bd00f
--- /dev/null
@@ -0,0 +1,37 @@
+Description: Fix structure padding for mips64
+Author: Guillem Jover <guillem@debian.org>
+Forwarded: no
+Last-Update: 2014-07-23
+
+---
+ src/libaio.h |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -52,7 +52,8 @@ typedef enum io_iocb_cmd {
+ /* little endian, 32 bits */
+ #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
+     (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
+-    defined(__bfin__) || defined(__MIPSEL__) || \
++    defined(__bfin__) || \
++    (defined(__MIPSEL__) && !defined(__mips64)) || \
+     defined(__cris__)
+ #define PADDED(x, y)  x; unsigned y
+ #define PADDEDptr(x, y)       x; unsigned y
+@@ -60,6 +61,7 @@ typedef enum io_iocb_cmd {
+ /* little endian, 64 bits */
+ #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
++      (defined(__mips64) && defined(__MIPSEL__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EL__))
+ #define PADDED(x, y)  x, y
+ #define PADDEDptr(x, y)       x
+@@ -69,6 +71,7 @@ typedef enum io_iocb_cmd {
+ #elif defined(__powerpc64__) || defined(__s390x__) || \
+       (defined(__hppa__) && defined(__arch64__)) || \
+       (defined(__sparc__) && defined(__arch64__)) || \
++      (defined(__mips64) && defined(__MIPSEB__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EB__))
+ #define PADDED(x, y)  unsigned y; x
+ #define PADDEDptr(x,y)        x
diff --git a/libs/libantlr3c/Makefile b/libs/libantlr3c/Makefile
new file mode 100644 (file)
index 0000000..bd1e51e
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libantlr3c
+PKG_VERSION:=3.2
+PKG_RELEASE:=1
+PKG_MD5SUM:=674646e1d1bf5c6015435480cead725a
+
+PKG_SOURCE_URL:=http://www.antlr3.org/download/C
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libantlr3c
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libantlr3c
+  URL:=http://www.antlr3.org/
+endef
+
+define Package/libantlr3c/description
+  ANother Tool for Language Recognition, is a language tool that provides a framework for constructing recognizers,
+  interpreters, compilers, and translators from grammatical descriptions containing actions in a variety of target languages.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libantlr3c.{a,so} $(1)/usr/lib/
+endef
+
+define Package/libantlr3c/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libantlr3c.so  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libantlr3c))
index f3a4317ac3d5111342e7ec26b83e6a1c62381a86..690af47ab98a87aabcfc2ec286353b1097e909f7 100644 (file)
@@ -18,7 +18,7 @@ PKG_MD5SUM:=9f5dd20d7e95fd0dd72df5353829f097
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/libs/libartnet/Makefile b/libs/libartnet/Makefile
new file mode 100644 (file)
index 0000000..c5b003e
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2010-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libartnet
+PKG_VERSION:=1.1.2
+PKG_RELEASE:=1.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/OpenLightingProject/libartnet/releases/download/1.1.2
+PKG_MD5SUM:=dcceab3efe3dae4c18fa549dbd198e71
+
+PKG_MAINTAINER:=Martijn Zilverschoon <martijn@friedzombie.com>
+
+PKG_LICENSE:=GPL-2.1
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libartnet
+       SECTION:=libs
+       CATEGORY:=Libraries
+       TITLE:=Libartnet is an implementation of the ArtNet protocol.
+       URL:=http://www.openlighting.org/libartnet-main/
+endef
+
+define Package/libartnet/description
+       Libartnet is an implementation of the ArtNet protocol. ArtNet allows the
+       transmission of DMX and related data over IP networks.
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default)
+endef
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+       DESTDIR="$(PKG_INSTALL_DIR)" \
+       all install
+endef
+
+define Build/InstallDev
+       mkdir -p $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/artnet $(1)/usr/include/
+       mkdir -p $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libartnet.{so,so.1,so.1.0.0} $(1)/usr/lib/
+endef
+
+
+define Package/libartnet/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libartnet.{so,so.1,so.1.0.0} $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libartnet))
diff --git a/libs/libartnet/patches/001-bswap_16.patch b/libs/libartnet/patches/001-bswap_16.patch
new file mode 100644 (file)
index 0000000..9c9be5f
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/artnet/private.h
++++ b/artnet/private.h
+@@ -100,7 +100,9 @@ extern uint16_t HIGH_BYTE;
+ #endif
+ // byte ordering macros
++#ifndef bswap_16
+ #define bswap_16(x)  ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
++#endif
+ // htols : convert short from host to little endian order
+ #ifdef WIN32
diff --git a/libs/libavl/Makefile b/libs/libavl/Makefile
new file mode 100644 (file)
index 0000000..0ff2385
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libavl
+PKG_VERSION:=0.3.5
+PKG_RELEASE:=1
+PKG_MD5SUM:=882c68ea7f71876ca110f3b84d7ab12d
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
+PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/liba/libavl
+PKG_BUILD_DIR:=$(BUILD_DIR)/avl-$(PKG_VERSION)
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=LGPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libavl
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=AVLTree (this is not GNU libavl)
+  URL:=https://packages.debian.org/wheezy/libavl1
+endef
+
+define Package/libavl/description
+  AVLTree is a small implementation of AVL trees for the C programming language.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/avl.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libavl.so* $(1)/usr/lib/
+endef
+
+define Package/libavl/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libavl.so.*  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libavl))
diff --git a/libs/libavl/patches/010-update_GNUmakefile.patch b/libs/libavl/patches/010-update_GNUmakefile.patch
new file mode 100644 (file)
index 0000000..3013949
--- /dev/null
@@ -0,0 +1,45 @@
+--- a/GNUmakefile      2002-11-15 19:57:48.000000000 +0100
++++ a/GNUmakefile      2014-10-02 16:03:02.864803002 +0200
+@@ -6,7 +6,7 @@
+ LDCONFIG ?= /sbin/ldconfig
+ # Some suggestions: (-mcpu= generates i386 compatible code)
+-CFLAGS ?= -O2 -fomit-frame-pointer -pipe -mcpu=i686 -w
++CFLAGS ?= -O2 -pipe -Wall -Werror
+ #CFLAGS = -O2 -fomit-frame-pointer -pipe -march=i586 -Wall -g
+ #CFLAGS = -O6 -fomit-frame-pointer -pipe -march=i586 -Wall -ansi -pedantic
+ #CFLAGS = -O6 -fomit-frame-pointer -pipe -march=i686 -Wall -ansi -pedantic
+@@ -15,10 +15,9 @@
+ #CFLAGS = -g -pg -a -pipe -march=i686 -Wall
+ #LDFLAGS = -s
+-prefix ?= /usr/local
++prefix ?= /usr
+ libdir ?= $(prefix)/lib
+ includedir ?= $(prefix)/include
+-includedir ?= /usr/include
+ PROGRAMS = avlsort setdiff
+ LIBRARY = libavl.so.1.5
+@@ -34,16 +33,17 @@
+       $(CC) $(LDFLAGS) $^ -o $@ $(LIBS)
+ $(LIBRARY): avl.o
+-      $(CC) -nostdlib -shared -Wl,-soname,libavl.so.1 $^ -o $@ -lc
++      $(CC) -shared -Wl,-soname,libavl.so.1 $^ -o $@ -lc
+ clean:
+       $(RM) *.o $(PROGRAMS) libavl.*
+ install: all
+       $(INSTALL) -d $(DESTDIR)$(libdir)
+-      $(INSTALL) avl.h $(DESTDIR)$(includedir)
+-      $(INSTALL) $(LIBRARIES) $(DESTDIR)$(libdir)
+-      for i in $(LIBRARIES); do\
++      $(INSTALL) -d $(DESTDIR)$(includedir)
++      $(INSTALL) -m 644 avl.h $(DESTDIR)$(includedir)
++      $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(libdir)
++      for i in $(LIBRARY); do\
+               $(LN) -sf $$i $(DESTDIR)$(libdir)/$${i%.*};\
+               $(LN) -sf $${i%.*} $(DESTDIR)$(libdir)/$${i%.*.*};\
+       done
index 41a8abac84f2b169e95f7da4800a5bb7ec13b890..958a37d2a4b93ad6a2a3a3c8e1e6b655599180cf 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libdaemon
 PKG_VERSION:=0.14
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://0pointer.de/lennart/projects/libdaemon/
@@ -46,6 +46,7 @@ define Build/Configure
                --enable-shared \
                --enable-static \
                --disable-lynx \
+               --disable-examples \
                , \
                ac_cv_func_setpgrp_void=yes \
        )
diff --git a/libs/libdaq/Makefile b/libs/libdaq/Makefile
new file mode 100644 (file)
index 0000000..fb3585b
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2012-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdaq
+PKG_VERSION:=2.0.4
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://www.snort.org/downloads/snort/
+PKG_SOURCE:=daq-$(PKG_VERSION).tar.gz
+PKG_MD5SUM:=65e51d72e9d5d8b397e192e4e5857eff
+PKG_BUILD_DIR:=$(BUILD_DIR)/daq-$(PKG_VERSION)
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libdaq
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=DAQ library
+  URL:=$(PKG_SOURCE_URL)
+  DEPENDS:=+libdnet +libpcap
+endef
+
+define Package/libdaq/description
+ Data Acquisition library for packet I/O.
+endef
+
+CONFIGURE_ARGS+= \
+       --disable-static \
+       --disable-nfq-module \
+       --with-dnet-includes="$(STAGING_DIR)/usr/include" \
+       --with-dnet-libraries="$(STAGING_DIR)/usr/lib" \
+       --with-libpcap-includes="$(STAGING_DIR)/usr/include" \
+       --with-libpcap-libraries="$(STAGING_DIR)/usr/lib" \
+
+define Build/Compile
+       $(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR)
+endef
+
+define Build/Install
+       $(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) install DESTDIR=$(PKG_INSTALL_DIR)
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(STAGING_DIR)/usr/include/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib* $(STAGING_DIR)/usr/lib/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/lib/daq
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/daq/* $(STAGING_DIR)/usr/lib/daq/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/daq-modules-config $(STAGING_DIR)/usr/bin/
+endef
+
+define Package/libdaq/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/daq
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/daq/*.so* $(1)/usr/lib/daq/
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/daq-modules-config $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libdaq))
diff --git a/libs/libdaq/patches/001-compile.patch b/libs/libdaq/patches/001-compile.patch
new file mode 100644 (file)
index 0000000..6eadb9e
--- /dev/null
@@ -0,0 +1,18 @@
+--- daq-1.1.1/configure        2012-07-10 21:32:51.000000000 +0200
++++ daq-new/configure  2012-08-03 15:47:07.654945651 +0200
+@@ -12717,10 +12717,11 @@
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpcap version >= \"1.0.0\"" >&5
+ $as_echo_n "checking for libpcap version >= \"1.0.0\"... " >&6; }
+     if test "$cross_compiling" = yes; then :
+-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
+-See \`config.log' for more details" "$LINENO" 5; }
++#  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++#$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++#as_fn_error $? "cannot run test program while cross compiling
++#See \`config.log' for more details" "$LINENO" 5; }
++        echo "    No cross compiling test."
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
index 3ff5bae6775cb981b3ea9f88aa4ab7843fb35423..e5a2da7f3175f51ab3e6bb7c33c694d7aee226de 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=@SF/libdbi-drivers
 PKG_MD5SUM:=9f47b960e225eede2cdeaabf7d22f59f
 
 PKG_LICENSE:=LGPL-2.1
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
index aaf15cca47b6811c0d6edb4c381bb472f8e84376..a1079fea462dc8afba134844ec058aa0a00b3b08 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=@SF/libdbi
 PKG_MD5SUM:=05e2ceeac4bc85fbe40de8b4b22d9ab3
 
 PKG_LICENSE:=LGPL-2.1
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
index 3fc5096231753d703e69ff4613aec8b14148f7b7..7a7cbaba7d7da85f711b7ac32369b770e1b20be3 100644 (file)
@@ -15,8 +15,8 @@ PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
-PKG_LICENSE=LGPLv2.1
-PKG_LICENSE_FILE=COPYING
+PKG_LICENSE:=LGPLv2.1
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/libdmapsharing-$(PKG_VERSION)
 PKG_SOURCE:=libdmapsharing-$(PKG_VERSION).tar.gz
diff --git a/libs/libdmapsharing/patches/001-diable_pixbuf.patch b/libs/libdmapsharing/patches/001-diable_pixbuf.patch
deleted file mode 100644 (file)
index 663dd49..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Index: libdmapsharing-2.9.15/configure.ac
-===================================================================
---- libdmapsharing-2.9.15.orig/configure.ac    2012-08-14 21:02:31.861158482 +0200
-+++ libdmapsharing-2.9.15/configure.ac 2012-08-14 21:03:42.448658906 +0200
-@@ -112,18 +112,7 @@
- AC_SUBST(GOBJECT_CFLAGS)
- AC_SUBST(GOBJECT_LIBS)
--dnl Check for gdk-pixbuf, needed for DACP Now Playing Artwork
--PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0,
--  HAVE_GDKPIXBUF=yes,
--  HAVE_GDKPIXBUF=no)
--
--if test x"$HAVE_GDKPIXBUF" = "xyes"; then
--  AC_DEFINE(HAVE_GDKPIXBUF, 1, [Define if gdk-pixbuf support is enabled])
--else
--  AC_WARN(Gdk-pixbuf library not present, Now Playing artwork might be affected.)
--fi
--
--AM_CONDITIONAL(USE_GDKPIXBUF, test x"$HAVE_GDKPIXBUF" = "xyes")
-+HAVE_GDKPIXBUF=no
- AC_SUBST(GDKPIXBUF_CFLAGS)
- AC_SUBST(GDKPIXBUF_LIBS)
diff --git a/libs/libdmapsharing/patches/001-disable_pixbuf.patch b/libs/libdmapsharing/patches/001-disable_pixbuf.patch
new file mode 100644 (file)
index 0000000..fcc8453
--- /dev/null
@@ -0,0 +1,22 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -117,18 +117,7 @@ dnl make GOBJECT_CFLAGS and GOBJECT_LIBS
+ AC_SUBST(GOBJECT_CFLAGS)
+ AC_SUBST(GOBJECT_LIBS)
+-dnl Check for gdk-pixbuf, needed for DACP Now Playing Artwork
+-PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0,
+-  HAVE_GDKPIXBUF=yes,
+-  HAVE_GDKPIXBUF=no)
+-
+-if test x"$HAVE_GDKPIXBUF" = "xyes"; then
+-  AC_DEFINE(HAVE_GDKPIXBUF, 1, [Define if gdk-pixbuf support is enabled])
+-else
+-  AC_WARN(Gdk-pixbuf library not present, Now Playing artwork might be affected.)
+-fi
+-
+-AM_CONDITIONAL(USE_GDKPIXBUF, test x"$HAVE_GDKPIXBUF" = "xyes")
++HAVE_GDKPIXBUF=no
+ AC_SUBST(GDKPIXBUF_CFLAGS)
+ AC_SUBST(GDKPIXBUF_LIBS)
diff --git a/libs/libdmapsharing/patches/002-disable_tests.patch b/libs/libdmapsharing/patches/002-disable_tests.patch
new file mode 100644 (file)
index 0000000..bafc52f
--- /dev/null
@@ -0,0 +1,8 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-SUBDIRS = libdmapsharing vala tests doc
++SUBDIRS = libdmapsharing vala doc
+ DIST_SUBDIRS = $(SUBDIRS) m4 media
+ # pcfiles = libdmapsharing-@LIBDMAPSHARING_MAJORMINOR@.pc
diff --git a/libs/libdnet/Makefile b/libs/libdnet/Makefile
new file mode 100644 (file)
index 0000000..08d3e20
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdnet
+PKG_VERSION:=1.12
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=http://libdnet.googlecode.com/files/
+PKG_MD5SUM:=9253ef6de1b5e28e9c9a62b882e44cc9
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_LICENSE:=BSD
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdnet
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Low-level network library
+  URL:=http://sourceforge.net/projects/libdnet/
+endef
+
+define Package/libdnet/description
+ libdnet is a library of simplified, portable interface to several low-level
+ networking routines.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static \
+       --without-check \
+       --without-python
+
+CONFIGURE_VARS += \
+       ac_cv_dnet_bsd_bpf=no
+
+MAKE_FLAGS += \
+       CFLAGS="$(TARGET_CFLAGS) -D_GNU_SOURCE"
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(2)/bin
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/dnet-config \
+               $(2)/bin/
+       $(SED) \
+               's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+               $(2)/bin/dnet-config
+
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_DATA)\
+               $(PKG_INSTALL_DIR)/usr/include/dnet.h \
+               $(1)/usr/include/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/include/dnet \
+               $(1)/usr/include/
+
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/libdnet.{la,a,so*} \
+               $(1)/usr/lib/
+endef
+
+define Package/libdnet/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/libdnet.so.* \
+               $(1)/usr/lib/
+
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/sbin/dnet \
+               $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libdnet))
diff --git a/libs/libdnet/patches/001-compile.patch b/libs/libdnet/patches/001-compile.patch
new file mode 100644 (file)
index 0000000..54223c9
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/config/config.sub
++++ b/config/config.sub
+@@ -228,7 +228,7 @@ case $basic_machine in
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+-      | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
++      | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+@@ -290,7 +290,7 @@ case $basic_machine in
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+-      | avr-* \
++      | avr-* | avr32-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c54x-* \
+       | clipper-* | cydra-* \
diff --git a/libs/libdnet/patches/002-config.patch b/libs/libdnet/patches/002-config.patch
new file mode 100644 (file)
index 0000000..cde376a
--- /dev/null
@@ -0,0 +1,23 @@
+--- a/dnet-config.in
++++ b/dnet-config.in
+@@ -45,10 +45,18 @@ while test $# -gt 0; do
+ done
+ if test "$echo_cflags" = "yes"; then
+-      echo -I@includedir@
++      includes=
++      if test "@includedir@" != "/usr/include" ; then
++             includes=-I@includedir@
++      fi
++      echo $includes
+ fi
+ if test "$echo_libs" = "yes"; then
+-      echo -L@libdir@ -ldnet @LIBS@
++      libs=
++      if test "@libdir@" != "/usr/lib" ; then
++             libs=-I@libdir@
++      fi
++      echo $libs -ldnet @LIBS@
+ fi      
diff --git a/libs/libesmtp/Makefile b/libs/libesmtp/Makefile
new file mode 100644 (file)
index 0000000..205084f
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2008-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libesmtp
+PKG_VERSION:=1.0.6
+PKG_RELEASE:=1
+PKG_MD5SUM:=c4fedc999b6c3820296b0eb92cc2e252
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=LGPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE_URL:=http://www.stafford.uklinux.net/libesmtp
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_CAT:=zcat
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libesmtp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A Library for Posting Electronic Mail
+  URL:=http://www.stafford.uklinux.net/libesmtp/
+  DEPENDS:=+libpthread
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default,--without-openssl)
+endef
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               all install
+endef
+
+define Build/InstallDev
+       mkdir -p $(STAGING_DIR)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/libesmtp.h $(STAGING_DIR)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/auth-client.h $(STAGING_DIR)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/auth-plugin.h $(STAGING_DIR)/usr/include/
+       mkdir -p $(STAGING_DIR)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libesmtp.{a,so*} $(STAGING_DIR)/usr/lib/
+       $(INSTALL_DIR) $(2)/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libesmtp-config $(2)/bin/
+       $(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(2)/bin/libesmtp-config
+endef
+
+define Build/UninstallDev
+       rm -rf \
+               $(STAGING_DIR)/usr/include/libesmtp.h \
+               $(STAGING_DIR)/usr/include/auth-client.h \
+               $(STAGING_DIR)/usr/include/auth-plugin.h \
+               $(STAGING_DIR)/usr/lib/libesmtp.{a,so*}
+endef
+
+define Package/libesmtp/install
+       mkdir -p $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libesmtp.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libesmtp))
diff --git a/libs/libevhtp/Makefile b/libs/libevhtp/Makefile
new file mode 100644 (file)
index 0000000..5838870
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libevhtp
+PKG_VERSION:=1.2.9
+PKG_RELEASE:=1
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/ellzey/libevhtp/archive/
+PKG_MD5SUM:=428a8d179fcc0cadedd914ed6456e08f
+PKG_CAT:=zcat
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libevhtp
+    SECTION:=libs
+    CATEGORY:=Libraries
+    TITLE:=A more flexible replacement for libevent's httpd API
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=https://github.com/ellzey/libevhtp
+    DEPENDS:=+libevent2 +libevent2-openssl +libevent2-pthreads +libopenssl +libpthread
+endef
+
+define Package/libevhtp/description
+   Libevhtp was created as a replacement API for Libevent's current HTTP API.
+   The reality of libevent's http interface is that it was created as a JIT server,
+   meaning the developer never thought of it being used for creating a full-fledged HTTP service.
+endef
+
+include $(INCLUDE_DIR)/cmake.mk
+
+Hooks/Prepare/Post += delete_source_package
+
+define delete_source_package
+       # deleting source package as its filename is ambiguous
+       rm -f $(DL_DIR)/$(PKG_SOURCE)
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/{include,lib}
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libevhtp.so* $(1)/usr/lib/
+
+endef
+
+define Package/libevhtp/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libevhtp.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libevhtp))
diff --git a/libs/libevhtp/patches/010-enable-shared-object-building.patch b/libs/libevhtp/patches/010-enable-shared-object-building.patch
new file mode 100644 (file)
index 0000000..fa6aa4b
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rupN libevhtp-1.2.9.orig/CMakeLists.txt libevhtp-1.2.9/CMakeLists.txt
+--- libevhtp-1.2.9.orig/CMakeLists.txt 2014-03-23 12:50:50.000000000 +0100
++++ libevhtp-1.2.9/CMakeLists.txt      2014-11-21 11:46:58.644575813 +0100
+@@ -64,7 +64,7 @@ OPTION(EVHTP_DISABLE_EVTHR     "Disable
+ OPTION(EVHTP_DISABLE_REGEX     "Disable regex support"    OFF)
+ # -DEVHTP_BUILD_SHARED:STRING=ON
+-OPTION(EVHTP_BUILD_SHARED      "Build shared library too" OFF)
++OPTION(EVHTP_BUILD_SHARED      "Build shared library too" ON)
+ # -DEVHTP_USE_DEFER_ACCEPT:STRING=ON
+ OPTION(EVHTP_USE_DEFER_ACCEPT  "Enable TCP_DEFER_ACCEPT"  OFF)
diff --git a/libs/libevhtp/patches/020-strcmp-endianness-fix.patch b/libs/libevhtp/patches/020-strcmp-endianness-fix.patch
new file mode 100644 (file)
index 0000000..072b76b
--- /dev/null
@@ -0,0 +1,49 @@
+diff -rupN libevhtp-1.2.9.orig/htparse/htparse.c libevhtp-1.2.9/htparse/htparse.c
+--- libevhtp-1.2.9.orig/htparse/htparse.c      2014-03-23 12:50:50.000000000 +0100
++++ libevhtp-1.2.9/htparse/htparse.c   2014-12-09 01:12:22.242001241 +0100
+@@ -197,6 +197,7 @@ static const char * method_strmap[] = {
+ #define _MIN_READ(a, b) ((a) < (b) ? (a) : (b))
++#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ #define _str3_cmp(m, c0, c1, c2, c3) \
+     *(uint32_t *)m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
+@@ -226,6 +227,37 @@ static const char * method_strmap[] = {
+     *(uint32_t *)m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)        \
+     && ((uint32_t *)m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4) \
+     && m[8] == c8
++#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
++#define _str3_cmp(m, c0, c1, c2, c3) \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3)
++
++#define _str3Ocmp(m, c0, c1, c2, c3) \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3)
++
++#define _str4cmp(m, c0, c1, c2, c3) \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3)
++
++#define _str5cmp(m, c0, c1, c2, c3, c4)                          \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3) \
++    && m[4] == c4
++
++#define _str6cmp(m, c0, c1, c2, c3, c4, c5)                      \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3) \
++    && (((uint32_t *)m)[1] & 0xffff0000) == ((c4 << 24) | c5 << 16)
++
++#define _str7_cmp(m, c0, c1, c2, c3, c4, c5, c6, c7)             \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3) \
++    && ((uint32_t *)m)[1] == ((c4 << 24) | (c5 << 16) | (c6 << 8) | c7)
++
++#define _str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7)              \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3) \
++    && ((uint32_t *)m)[1] == ((c4 << 24) | (c5 << 16) | (c6 << 8) | c7)
++
++#define _str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8)                 \
++    *(uint32_t *)m == ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3)        \
++    && ((uint32_t *)m)[1] == ((c4 << 24) | (c5 << 16) | (c6 << 8) | c7) \
++    && m[8] == c8
++#endif
+ #define __HTPARSE_GENHOOK(__n)                                                    \
+     static inline int hook_ ## __n ## _run(htparser * p, htparse_hooks * hooks) { \
index c146e991845559721a2f7c15cec1c6801e84cd52..7b6ab90d5183bdd3407900a158ee7bba2fa2b77b 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2011-2014 OpenWrt.org
+# Copyright (C) 2011-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libftdi
 PKG_VERSION:=0.20
-PKG_RELEASE:=1
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.intra2net.com/en/developer/libftdi/download/
@@ -43,13 +43,14 @@ define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include/
        $(CP) $(PKG_INSTALL_DIR)/usr/include/ftdi.h $(1)/usr/include/
        $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi.{a,so} $(1)/usr/lib/
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi.{a,so*} $(1)/usr/lib/
        $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libftdi.pc $(1)/usr/lib/pkgconfig/libftdi.pc
 endef
 
 define Package/libftdi/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libftdi-config $(1)/usr/bin/
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi.so.* $(1)/usr/lib/
 endef
index 9a9da9a6cfa934cd53771771323b6dd1ece3c908..2460cb16337c1066955e7e3cfa31fbdff194cb40 100644 (file)
@@ -1,6 +1,6 @@
 --- a/CMakeLists.txt
 +++ b/CMakeLists.txt
-@@ -43,7 +43,7 @@ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+@@ -44,7 +44,7 @@ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
      SET(LIB_SUFFIX "")
      SET(PACK_ARCH "")
    ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
diff --git a/libs/libftdi/patches/101-fix-cmake-version-packagekit.patch b/libs/libftdi/patches/101-fix-cmake-version-packagekit.patch
new file mode 100644 (file)
index 0000000..e6861dc
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,9 +1,12 @@
+ # Project
+ project(libftdi)
++set(PACKAGE libftdi)
+ set(MAJOR_VERSION 0)
+ set(MINOR_VERSION 20)
++set(VERSION ${VERSION_STRING})
+ set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
+-SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
++set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
++set(top_srcdir ${CMAKE_SOURCE_DIR})
+ # CMake
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "")
+@@ -98,12 +101,6 @@ option(DOCUMENTATION "Generate API docum
+ find_package(Doxygen)
+ if(DOCUMENTATION AND DOXYGEN_FOUND)
+-
+-   # Set variables
+-   set(PACKAGE libftdi)
+-   set(VERSION ${VERSION_STRING})
+-   set(top_srcdir ${CMAKE_SOURCE_DIR})
+-
+    # Find doxy config
+    message(STATUS "Doxygen found.")
+    set(DOXY_DIR "${CMAKE_SOURCE_DIR}/doc")
index 5fa7220fbde4fea9241eb6d8c88822390e326160..693cfce50f629a3667ef9ef59b4f623f22b8ee09 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 OpenWrt.org
+# Copyright (C) 2014-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libftdi1
-PKG_VERSION:=1.1
-PKG_RELEASE:=1
+PKG_VERSION:=1.2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://www.intra2net.com/en/developer/libftdi/download/
-PKG_MD5SUM:=b79a6356978aa8e69f8eecc3a720ff79
+PKG_MD5SUM:=89dff802d89c4c0d55d8b4665fd52d0b
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 
 PKG_LICENSE:=LGPL-2.0
@@ -39,19 +39,47 @@ define Package/libftdi1/description
   The library is linked with your program in userspace, no kernel driver required.
 endef
 
+define Package/ftdi_eeprom
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+confuse +libftdi1
+  TITLE:=Tool for reading/erasing/flashing FTDI USB chip eeproms
+  URL:=http://www.intra2net.com/en/developer/libftdi/
+endef
+
+define Package/ftdi_eeprom/description
+  ftdi_eeprom is a small tool for reading/erasing/flashing FTDI USB chip
+  eeproms. It uses libftdi to access the chip, so you will need to have
+  the required permissions on the device.
+
+  The ftdi_sio module should not be loaded.
+
+  You have to unplug and replug your device to get the new values to be
+  read. Otherwise, you will still get the old values.
+endef
+
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include/libftdi1/
        $(CP) $(PKG_INSTALL_DIR)/usr/include/libftdi1/ftdi.h $(1)/usr/include/libftdi1/
        $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi1.{a,so} $(1)/usr/lib/
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi1.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi1.{a,so*} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/cmake/libftdi1
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/libftdi1/* $(1)/usr/lib/cmake/libftdi1/
        $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libftdi1.pc $(1)/usr/lib/pkgconfig/libftdi1.pc
 endef
 
 define Package/libftdi1/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libftdi1-config $(1)/usr/bin/
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi1.so.* $(1)/usr/lib/
 endef
 
+define Package/ftdi_eeprom/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ftdi_eeprom $(1)/usr/bin/
+endef
+
 $(eval $(call BuildPackage,libftdi1))
+$(eval $(call BuildPackage,ftdi_eeprom))
index bf3674eaeaf2c3cd69adf91d109f493ca12c718a..495db1789ada22a977becf4a09cda3e348496ce0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/CMakeLists.txt
 +++ b/CMakeLists.txt
-@@ -43,7 +43,7 @@ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+@@ -55,7 +55,7 @@ if ( NOT DEFINED LIB_SUFFIX )
        AND NOT EXISTS "/etc/debian_version"
        AND NOT EXISTS "/etc/arch-release" )
      if ( "${CMAKE_SIZEOF_VOID_P}" EQUAL "8" )
index cafd775a6863c8226571ca8f3c47ee35374bfbe5..e940de123fb496388fd26634174897fe0a925199 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libgd
 PKG_VERSION:=2.1.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://bitbucket.org/libgd/gd-libgd/downloads
@@ -48,6 +48,7 @@ CONFIGURE_ARGS += \
        --without-freetype \
        --with-jpeg=$(STAGING_DIR)/usr \
        --with-png=$(STAGING_DIR)/usr \
+       --with-vpx=no \
        --without-xpm \
        --without-iconv
 
diff --git a/libs/libhttp-parser/Makefile b/libs/libhttp-parser/Makefile
new file mode 100644 (file)
index 0000000..fe28b4c
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libhttp-parser
+PKG_VERSION:=2.3.0
+PKG_RELEASE=1
+PKG_MAINTAINER:=Ramanathan Sivagurunathan <ramzthecoder@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE-MIT
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://github.com/joyent/http-parser.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=56f7ad0e2e5a80f79d214015c91e1f17d11d109f
+
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libhttp-parser
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library to parse http request and response
+  URL:=https://github.com/joyent/http-parser
+endef
+
+define Package/libhttp-parser/description
+  A parser for HTTP messages written in C. It parses both requests and responses. 
+  The parser is designed to be used in performance HTTP applications. 
+  It does not make any syscalls nor allocations, it does not buffer data, 
+  it can be interrupted at anytime. Depending on your architecture, 
+  it only requires about 40 bytes of data per message stream 
+  (in a web server that is per connection).
+endef
+
+define Build/Compile
+       $(call Build/Compile/Default, library) 
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/http_parser.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/libhttp_parser.so.* $(1)/usr/lib/
+       ( cd $(1)/usr/lib ; ln -s libhttp_parser.so.* libhttp_parser.so )
+endef
+
+define Package/libhttp-parser/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libhttp_parser.so.* $(1)/usr/lib/
+       ( cd $(1)/usr/lib ; ln -s libhttp_parser.so.* libhttp_parser.so )
+endef
+
+$(eval $(call BuildPackage,libhttp-parser))
diff --git a/libs/libical/Makefile b/libs/libical/Makefile
new file mode 100644 (file)
index 0000000..4af4c85
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2009-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libical
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/freeassociation
+PKG_MD5SUM:=
+
+PKG_LICENSE:=LGPL-2.1 MPL-1.0
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_FIXUP:=libtool
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libical
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=iCal (RFC 2445) library
+  URL:=http://www.nabber.org/projects/ical/
+  DEPENDS:=+libpthread
+endef
+
+define Package/libical/description
+ This package provides a a read/write library of classes for object oriented
+ languages (Initial goals of PHP and Python) that implement and enforce the iCal
+ standard (RFC 2445).
+endef
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static \
+       --disable-cxx \
+       --disable-java \
+       --disable-python \
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/{ical.h,libical} $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libical{,ss,vcal}.{a,so*} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libical.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libical/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libical{,ss,vcal}.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libical))
index 69daced326c69dff20b6d73547e6ff212965f8bc..811ebe442840778581068130c6935d05e8d8538f 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009-2014 OpenWrt.org
+# Copyright (C) 2009-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libidn
 PKG_VERSION:=1.29
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@GNU/libidn
@@ -17,7 +17,6 @@ PKG_MD5SUM:=2b67bb507207af379f9461e1307dc84b
 
 PKG_LICENSE:=GPL-2.0+ GPL-3.0+ LGPL-2.1+ LGPL-3.0+ Apache-2.0
 PKG_LICENSE_FILES:=COPYING COPYINGv2 COPYINGv3 COPYING.LESSERv2 COPYING.LESSERv3 java/LICENSE-2.0.txt
-PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
 
 PKG_FIXUP:=autoreconf
 PKG_REMOVE_FILES:=GNUmakefile aclocal.m4
@@ -25,17 +24,45 @@ PKG_INSTALL:=1
 
 include $(INCLUDE_DIR)/package.mk
 
+define Package/idn/Default
+  SECTION:=net
+  CATEGORY:=Network
+  URL:=http://www.gnu.org/software/libidn/
+  MAINTAINER:=Marcel Denia <naoir@gmx.net>
+endef
+
+define Package/idn/Default/description
+  GNU Libidn is a fully documented implementation of the Stringprep,
+  Punycode and IDNA specifications. Libidn's purpose is to encode and
+  decode internationalized domain names.
+endef
+
+define Package/idn
+  $(call Package/idn/Default)
+  SUBMENU:=IP Addresses and Names
+  TITLE:=GNU IDN (Internationalized Domain Name) tool
+  DEPENDS:=+libidn
+endef
+
+define Package/idn/description
+$(call Package/idn/Default/description)
+
+  Command line tool using libidn
+
+endef
+
 define Package/libidn
+  $(call Package/idn/Default)
   SECTION:=libs
   CATEGORY:=Libraries
   TITLE:=Stringprep, Punycode and IDNA implementation
-  URL:=http://www.gnu.org/software/libidn/
 endef
 
 define Package/libidn/description
-  GNU Libidn is a fully documented implementation of the Stringprep,
-  Punycode and IDNA specifications. Libidn's purpose is to encode and
-  decode internationalized domain names.
+$(call Package/idn/Default/description)
+
+  Library only package
+
 endef
 
 TARGET_CFLAGS += $(FPIC)
@@ -54,9 +81,15 @@ define Build/InstallDev
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libidn.{a,so*} $(1)/usr/lib/
 endef
 
+define Package/idn/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
 define Package/libidn/install
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libidn.so.* $(1)/usr/lib/
 endef
 
+$(eval $(call BuildPackage,idn))
 $(eval $(call BuildPackage,libidn))
index 3ec74e652787c272fac17c52f4737e0709dd977c..7cb06224c16eefb27c3217a694c76e25d4023d57 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libimobiledevice
-PKG_VERSION:=1.1.6
+PKG_VERSION:=1.2.0
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Lukasz Baj <l.baj@radytek.com>
 PKG_LICENSE:=LGPL-2.1+
-PKG_LICENSE_FILE:=COPYING.LESSER
+PKG_LICENSE_FILES:=COPYING.LESSER
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/libimobiledevice/libimobiledevice.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=9732d275d00bb1200d2b6180d94814a1a7fb7696
+PKG_SOURCE_VERSION:=53eb963f8e6d607cca6b50381c10820a5e8357f4
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_FIXUP:=autoreconf
index 4ab9ad7ed1706b151db1c54669512645da27d3d5..4e8fa20e238cdccdc4f5f52342253454af44dd78 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=@SF/liblo
 PKG_MD5SUM:=e2a4391a08b49bb316c03e2034e06fa2
 
 PKG_LICENSE:=LGPL-2.1+
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_INSTALL:=1
index 37aeb8d24b61c6839de7fd6f40dfebd0dde0c1b9..f7f3827d4feb31c081ab8510e0cd76600b785e23 100644 (file)
@@ -14,7 +14,7 @@ PKG_RELEASE:=2
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2.1
-PKG_LICENSE_FILE:=COPYING.LIB
+PKG_LICENSE_FILES:=COPYING.LIB
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=@SF/mcrypt
diff --git a/libs/libmicrohttpd/Makefile b/libs/libmicrohttpd/Makefile
new file mode 100644 (file)
index 0000000..3f1608e
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2010-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmicrohttpd
+PKG_VERSION:=0.9.38
+PKG_RELEASE:=1.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/libmicrohttpd
+PKG_MD5SUM:=b72efbfe7f290846015d460aea7091fe
+
+PKG_MAINTAINER:=Martijn Zilverschoon <martijn@friedzombie.com>
+
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmicrohttpd
+       SECTION:=libs
+       CATEGORY:=Libraries
+       TITLE:=GNU libmicrohttpd is a library that runs an HTTP server.
+       URL:=http://www.gnu.org/software/libmicrohttpd/
+       DEPENDS:=+libpthread +libgcrypt +libgnutls +libgpg-error +libcrypto +libopenssl
+endef
+
+define Package/libmicrohttpd/description
+       GNU libmicrohttpd is a small C library that is supposed to make it easy
+       to run an HTTP server as part of another application.
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libmicrohttpd/install
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmicrohttpd))
index 6fda18d6111479d305bca514b0543aae5fa0d8ef..dbf5fe02ca540259ab8e212043ea8d5b01668aed 100644 (file)
@@ -8,13 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libmpdclient
-PKG_VERSION:=2.7
-PKG_RELEASE:=2
+PKG_VERSION:=2.9
+PKG_RELEASE:=3
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://www.musicpd.org/download/libmpdclient/2/
-PKG_MD5SUM:=053a97f1b045646d2d01a68fb2ddb5ef
+PGK_MD5SUM:=4b101a36e5c0cf967dc063391260ddbf
+
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 
@@ -25,7 +28,6 @@ define Package/libmpdclient
     SECTION:=libs
     CATEGORY:=Libraries
     URL:=http://mpd.wikia.com/wiki/ClientLib:libmpdclient
-    DEPENDS:=
 endef
 
 define Package/libmpdclient/description
@@ -34,10 +36,10 @@ endef
 
 TARGET_CFLAGS+="-std=gnu99"
 
-#TARGET_LDFLAGS+=-lpthread
-
 define Build/Configure
-       $(call Build/Configure/Default)
+       $(call Build/Configure/Default, \
+               --disable-documentation \
+       )
 endef
 
 define Build/InstallDev
diff --git a/libs/libmpdclient/patches/001-WIP_musl_compatibility.patch b/libs/libmpdclient/patches/001-WIP_musl_compatibility.patch
new file mode 100644 (file)
index 0000000..02ea652
--- /dev/null
@@ -0,0 +1,22 @@
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -43,6 +43,7 @@
+ #else
+ #  include <netinet/in.h>
+ #  include <arpa/inet.h>
++#  include <sys/select.h>
+ #  include <sys/socket.h>
+ #  include <netdb.h>
+ #  include <sys/un.h>
+--- a/src/sync.c
++++ b/src/sync.c
+@@ -33,6 +33,9 @@
+ #include <assert.h>
+ #include <stdlib.h>
+ #include <stdio.h>
++#ifndef WIN32
++#include <sys/select.h>
++#endif
+ #include <fcntl.h>
+ #include <unistd.h>
index b9e49e206595b29292eedd29845bb308c7986888..f90d9bc8f418c98d11437afaf0070c59091a3487 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=http://miniupnp.free.fr/files
 PKG_MD5SUM:=7c9a7c76e200ead4e6447fe4b105f676
 PKG_MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de>
 PKG_LICENSE:=BSD-3c
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 
 PKG_INSTALL:=1
 
index 028c231562254ff87926b07bcab090fd4028ed51..b54222ac46332a6472fcf9194746702b6e196ab1 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_URL:= \
 PKG_MD5SUM:=2118d9514c079839ebd9cb3144ad2ad7
 
 PKG_LICENSE:=LGPL-2.1
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
index b154988f3192c113c5c5fa331a1704a6b6b13297..97e858c6368bb0dc6bf95f551bfaac218153e3cf 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_URL:= \
 PKG_MD5SUM:=2a4bb0654ae675a52d2e8d1c06090b94
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
index 029fe079ed2bbbcd40dc5597e8440e1571eeb65b..e150ed0d8432f3370290c64cddefe58741f4eab5 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_URL:= \
 PKG_MD5SUM:=df09befac35cb215865b39a36c96a3fa
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
diff --git a/libs/libnfc/Makefile b/libs/libnfc/Makefile
new file mode 100644 (file)
index 0000000..9a144d2
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libnfc
+PKG_VERSION:=1.7.1
+PKG_RELEASE:=1
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://code.google.com/p/libnfc/
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_LICENSE:=LGPL-2.1
+PKG_MAINTAINER:=Sebastian Wendel <packages@sourceindex.de>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnfc/Default
+       TITLE:=A open source library for Near Field Communication (NFC)
+       URL:=http://nfc-tools.org/
+endef
+
+define Package/libnfc
+       $(call Package/libnfc/Default)
+       SECTION:=libs
+       CATEGORY:=Libraries
+       DEPENDS:=+libusb-compat +pcscd +ccid
+endef
+
+define Package/libnfc/description
+       libnfc is the first libre, platform-independent, low level NFC SDK and Programmers API
+
+       * manipulate Jewel Topaz tags using libnfc
+       * manipulate MIFARE Classic and Ultralight tags using libnfc
+
+endef
+
+define Package/nfc-utils
+       $(call Package/libnfc/Default)
+       SECTION:=utils
+       CATEGORY:=Utilities
+       DEPENDS:=+libnfc
+endef
+
+define Package/nfc-utils/description
+       Provide some examples shared functions like print, parity calculation, options parsing
+
+       * Emulates a NFC Forum Tag Type 4 v2.0 (or v1.0)
+       * Jewel dump/restore tool
+       * Lists the first target present of each founded device
+       * MIFARE Classic manipulation example
+       * MIFARE Ultralight dump/restore tool
+       * Extract NDEF Message from a NFC Forum Tag Type 3
+       * Relay example using two PN532 devices
+       * Lists each available NFC device
+
+endef
+
+TARGET_CFLAGS+=$(FPIC)
+CONFIGURE_ARGS+=--without-readline
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/nfc $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnfc.{a,so*} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnfc.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnfc/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnfc.so.* $(1)/usr/lib/
+endef
+
+define Package/nfc-utils/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-emulate-forum-tag4 $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-jewel $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-list $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-mfclassic $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-mfultralight $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-read-forum-tag3 $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-relay-picc $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/nfc-scan-device $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libnfc))
+$(eval $(call BuildPackage,nfc-utils))
index ce844e2d61b940045dac905dba644aa1109015d6..8850c74fdaf7701fdb96c43ce84054e99648cebc 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=http://liboil.freedesktop.org/download/
 PKG_MD5SUM:=47dc734f82faeb2964d97771cfd2e701
 
 PKG_LICENSE:=FREE
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
index f7ed2ae4b826240606532cd984278aefab1c4cf9..173e5dca1737b16aa5e6b82aeece5fac4d982f1e 100644 (file)
@@ -7,7 +7,7 @@
 
 include $(TOPDIR)/rules.mk
 
-LOWFAT_VERSION=0.28
+LOWFAT_VERSION=0.29
 
 PKG_NAME:=libowfat
 PKG_VERSION:=$(LOWFAT_VERSION)
@@ -15,7 +15,7 @@ PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://dl.fefe.de
-PKG_MD5SUM:=6bbee9a86506419657d87123b7a6f2c1
+PKG_MD5SUM:=1187c6acf11429e7adb9ebe180f644bb
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=GPL-2.0
 PKG_LICENSE_FILES:=COPYING
index 3d40835d7b59bbd8024f738d41ea745581a79800..4d7cb9c86ae965a91aa26a585ceac5272a11d21f 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libplist
-PKG_VERSION:=1.11
+PKG_VERSION:=1.13
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Lukasz Baj <l.baj@radytek.com>
 PKG_LICENSE:=LGPL-2.1+
-PKG_LICENSE_FILE:=COPYING.LESSER
+PKG_LICENSE_FILES:=COPYING.LESSER
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/libimobiledevice/libplist.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=063c629baef6028e84838f77fd1401b05e41dc58
+PKG_SOURCE_VERSION:=cc907c0f162ee84e5698b9c27ac6fb0be8bb9bc0
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_FIXUP:=autoreconf
index 2ae5a31ef26ad101272989a0d2cc12657de12b93..404045886ab39b717cf8134bae84453d70395c09 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libpng
-PKG_VERSION:=1.2.51
+PKG_VERSION:=1.2.52
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@SF/libpng
-PKG_MD5SUM:=4efba67fa5aa2b785c6fcec2cc3e90c9
+PKG_MD5SUM:=49d5c71929bf69a172147c47b9309fbe
 PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
 
 PKG_LICENSE:=Libpng GPL-2.0+ BSD-3-Clause
index 1a6af67905683e80a056f6664d8011f7ac678d00..a7619148c67337e52cbc5de81cdddcb6fb61080d 100644 (file)
@@ -18,7 +18,7 @@ PKG_MD5SUM:=1c7fb25191b4e6e3628d198a66a84f47
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 
diff --git a/libs/libsearpc/Makefile b/libs/libsearpc/Makefile
new file mode 100644 (file)
index 0000000..4ec9e93
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libsearpc
+PKG_VERSION:=3.1.7
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_LICENSE:=GPL-3.0
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/haiwen/libsearpc.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=8998e7b2c5587f0b94c48db24e2952d08def5add
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libsearpc
+    SECTION:=libs
+    CATEGORY:=Libraries
+    TITLE:=Seafile RPC Library
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=http://seafile.com/
+    DEPENDS:=+glib2 +jansson +python $(ICONV_DEPENDS)
+endef
+
+define Package/libsearpc/description
+    Searpc is a simple C language RPC framework based on GObject system.
+    Searpc handles the serialization/deserialization part of RPC,
+    the transport part is left to users.
+endef
+
+CONFIGURE_ARGS += --enable-compile-demo=no \
+                   --disable-server-pkg
+
+TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib -liconv
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Configure
+endef
+
+define Host/Compile
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+       $(INSTALL_BIN) $(HOST_BUILD_DIR)/lib/searpc-codegen.py $(STAGING_DIR_HOST)/bin/
+endef
+
+$(eval $(call HostBuild))
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/{bin,include}
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsearpc.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/searpc* $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsearpc.pc $(1)/usr/lib/pkgconfig/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/searpc-codegen.py $(1)/usr/bin/
+endef
+
+define Package/libsearpc/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/python2.7/site-packages
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsearpc.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/pysearpc $(1)/usr/lib/python2.7/site-packages/
+endef
+
+$(eval $(call BuildPackage,libsearpc))
index 0082c88b5206692b9e4b32a0f35fb9aa91f15f71..a666afb17231508cb903930764f071a7a444a911 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libsodium
-PKG_VERSION:=0.7.1
+PKG_VERSION:=1.0.2
 PKG_RELEASE:=1
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://download.libsodium.org/libsodium/releases
-PKG_MD5SUM:=c224fe3923d1dcfe418c65c8a7246316
+PKG_MD5SUM:=dc40eb23e293448c6fc908757738003f
 PKG_CAT:=zcat
 
 PKG_FIXUP:=libtool autoreconf
@@ -62,6 +62,8 @@ define Build/InstallDev
        $(CP) $(PKG_INSTALL_DIR)/usr/include/sodium/*.h $(1)/usr/include/sodium
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsodium.{a,so*} $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsodium.pc $(1)/usr/lib/pkgconfig/
 endef
 
 define Package/libsodium/install
index 85a48286d6ce08c54ef6ab7dae4aff5407016847..a482b5ed4e99d669a48492a830961dfd907961e1 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=@GNOME/$(PKG_NAME)/2.44
 PKG_MD5SUM:=92aa3667357157e8f3489bcca287f2fa
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
index ce203731ff83a5b6224032d7ad0d47832b05d58f..8f69803f8e7ec631016e7bde21033b090fbffa1b 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_LICENSE:=LGPL-2.1
-PKG_LICENSE_FILE:=LICENCE
+PKG_LICENSE_FILES:=LICENCE
 
 PKG_FIXUP:=libtool
 PKG_REMOVE_FILES:=autogen.sh
index ae258868d636a228a6f8ded28d7f34f67910b619..d5db86c70ba7d52db2a2dfdb21fcfc0f26febca9 100644 (file)
@@ -13,8 +13,11 @@ PKG_RELEASE:=1
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://downloads.xiph.org/releases/theora/
 PKG_MD5SUM:=292ab65cedd5021d6b7ddd117e07cd8e
-PKG_FIXUP:=autoreconf
 
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING LICENSE
+
+PKG_FIXUP:=autoreconf
 PKG_BUILD_DEPENDS:=libvorbis
 
 include $(INCLUDE_DIR)/package.mk
index 76cf04773b54853ab1b85e519d2c1c481e597ea3..1d6fd10d341da36ff016303d6c1d02fbf3e7c763 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libtorrent
-PKG_VERSION:=0.13.4-git
-PKG_RELEASE=$(PKG_SOURCE_VERSION)-1
+PKG_VERSION:=0.13.4-git-0
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/rakshasa/libtorrent.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=51cd5ea8913a5f5062813d9f5b6256c76d41ea11
+PKG_SOURCE_VERSION:=72e908707f01ee01a9b4918436c64348878b63f7
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_FIXUP:=autoreconf
@@ -48,7 +48,8 @@ CONFIGURE_ARGS+= \
        --enable-aligned \
        --disable-debug \
        --enable-openssl \
-       --disable-instrumentation
+       --disable-instrumentation \
+       --with-zlib=$(STAGING_DIR)/usr
 
 define Build/Configure
        ( cd $(PKG_BUILD_DIR); ./autogen.sh );
index 202ee00334c08674b8304c1c4c64d5ced1983302..a0969465a44d5aad7cbf02ac1b427f57cd8e9d20 100644 (file)
@@ -21,7 +21,7 @@
        #include <unistd.h>
 --- a/scripts/common.m4
 +++ b/scripts/common.m4
-@@ -223,7 +223,7 @@ dnl   Need to fix this so that it uses t
+@@ -153,7 +153,7 @@ dnl   Need to fix this so that it uses t
  AC_DEFUN([TORRENT_CHECK_EXECINFO], [
    AC_MSG_CHECKING(for execinfo.h)
  
@@ -30,7 +30,7 @@
        #include <execinfo.h>
        int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
        ])],
-@@ -238,7 +238,7 @@ AC_DEFUN([TORRENT_CHECK_EXECINFO], [
+@@ -168,7 +168,7 @@ AC_DEFUN([TORRENT_CHECK_EXECINFO], [
  AC_DEFUN([TORRENT_CHECK_ALIGNED], [
    AC_MSG_CHECKING(the byte alignment)
  
index 6147948a1530011b510df6be2f498890ed250165..63b6ebe217fc2ff105a1a223807c610c31158eb8 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 OpenWrt.org
+# Copyright (C) 2012-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libuecc
-PKG_VERSION:=4
+PKG_VERSION:=5
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/71
-PKG_MD5SUM:=7f44df5dc69cb8686947562e2a11eea9
+PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/80
+PKG_MD5SUM:=cd03c947931c2f4b0eea0bf45654bd34
 
 PKG_LICENSE:=BSD-2-Clause
-PKG_LICENSE_FILE:=COPYRIGHT
+PKG_LICENSE_FILES:=COPYRIGHT
 
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/cmake.mk
diff --git a/libs/libunistring/Makefile b/libs/libunistring/Makefile
new file mode 100644 (file)
index 0000000..6d69b57
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libunistring
+PKG_VERSION:=0.9.4
+PKG_RELEASE:=1
+PKG_MD5SUM:=c24a6a3838d9ad4a41a62549312c4226
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://ftp.gnu.org/gnu/libunistring
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libunistring
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libunistring
+  URL:=http://www.gnu.org/software/libunistring/
+endef
+
+define Package/libunistring/description
+  This library provides functions for manipulating Unicode strings and for manipulating C strings according to the Unicode standard.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static \
+       --without-libiconv-prefix \
+       --without-libpth-prefix
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/include/unistring
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/unistring/*.h $(1)/usr/include/unistring/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libunistring.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libunistring/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libunistring.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libunistring))
diff --git a/libs/libupnpp/Makefile b/libs/libupnpp/Makefile
new file mode 100644 (file)
index 0000000..58a3222
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libupnpp
+PKG_VERSION:=0.9.0
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.lesbonscomptes.com/upmpdcli/downloads
+PKG_MD5SUM:=ff218bbe2df6cf70b73843d951ef838e
+PKG_MAINTAINER:=Petko Bordjukov <bordjukov@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libupnpp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://www.lesbonscomptes.com/upmpdcli
+  DEPENDS+= +libstdcpp +libexpat +librt +libcurl +libupnp
+  TITLE:=The libupnpp C++ library wraps libupnp for easier use by upmpdcli and upplay
+endef
+
+define Package/libupnpp/description
+libupnpp defines useful objects over libupnp and can be used to create both devices
+and control points. It is shared by upmpdcli and upplay.
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/libupnpp $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp-$(PKG_VERSION).so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp.{so,la} $(1)/usr/lib/
+endef
+
+define Package/libupnpp/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp-$(PKG_VERSION).so.* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libupnpp))
index 8f48e9266af72a1651948d7f7fd96b5b53200749..ec15bc2d2a37e9169f6b971e835120402e42d9cc 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libusbmuxd
-PKG_VERSION:=1.0.9
+PKG_VERSION:=1.1.0
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Lukasz Baj <l.baj@radytek.com>
 PKG_LICENSE:=LGPL-2.1+
-PKG_LICENSE_FILE:=COPYING.LGPLv2.1
+PKG_LICENSE_FILES:=COPYING.LGPLv2.1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/libimobiledevice/libusbmuxd.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=ca68e3c287a8410fbef5280948a6d1d2255e0a89
+PKG_SOURCE_VERSION:=f347085157006523622b0a7160be68d14f037c00
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_FIXUP:=autoreconf
diff --git a/libs/libuvc/Makefile b/libs/libuvc/Makefile
new file mode 100644 (file)
index 0000000..3c9b8b9
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libuvc
+
+PKG_VERSION=0.0.5-20140812-$(PKG_SOURCE_VERSION)
+PKG_RELEASE:=1
+PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/ktossell/libuvc.git
+PKG_SOURCE_VERSION:=2c6403405872aa865999b95ba15944295adf6c38
+
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_LICENSE:=BSD
+
+PKG_INSTALL:=1
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuvc
+       SECTION:=libs
+       CATEGORY:=Libraries
+       TITLE:=libuvc
+       DEPENDS:=+libusb-1.0 +libjpeg
+       URL:=https://int80k.com/libuvc
+endef
+
+define Package/libuvc/description
+ This package contains libuvc is a cross-platform library for USB video devices, 
+ built atop libusb.
+endef
+
+define Package/libuvc/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libuvc.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/{include,lib}
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libuvc.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libuvc))
index 86121dc17f38d8cc0c9fc014f77c7edae40c40ac..4fb41ed1b72867ec422424a77b48e36921803e10 100644 (file)
@@ -11,6 +11,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=v4l-utils
 PKG_VERSION:=1.2.1
 PKG_RELEASE:=2
+PKG_USE_MIPS16:=0
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://www.linuxtv.org/downloads/v4l-utils
@@ -19,7 +20,7 @@ PKG_MD5SUM:=4cc0fb4ded302ea9e89e5e1b56a7252b
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0 LGPL-2.1
-PKG_LICENSE_FILE:=COPYING COPYING.libv4l
+PKG_LICENSE_FILES:=COPYING COPYING.libv4l
 
 PKG_BUILD_DEPENDS:=argp-standalone
 
index cb87ee91a40aa89642df8f4c5dd13822f896bb57..5a026d701f8876e8ac3d068abb9e7bd8192743f4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libvorbisidec
-PKG_VERSION:=1.0.2+svn18153
-PKG_RELEASE:=2
+PKG_REV:=20150104
+PKG_VERSION:=1.0.3-$(PKG_REV)
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://git.xiph.org/tremor.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=b56ffce0c0773ec5ca04c466bc00b1bbcaf65aef
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 
-PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
-PKG_SOURCE_URL:=http://ftp.de.debian.org/debian/pool/main/libv/libvorbisidec/
-PKG_MD5SUM:=4190859414c5d6760e316b5cf00fe7c5
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=BSD-3-Clause
@@ -21,6 +27,7 @@ PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
+PKG_USE_MIPS16:=0
 
 include $(INCLUDE_DIR)/package.mk
 
diff --git a/libs/libvpx/Makefile b/libs/libvpx/Makefile
new file mode 100644 (file)
index 0000000..4d8bb46
--- /dev/null
@@ -0,0 +1,80 @@
+#
+# Copyright (C) 2008-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libvpx
+PKG_VERSION:=1.3.0
+PKG_RELEASE:=1
+
+PKG_REV:=v$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REV).tar.gz
+PKG_SOURCE_URL:=https://chromium.googlesource.com/webm/libvpx
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Luiz Angelo Daros de Luca <luizluca@gmail.com>
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libvpx
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libvpx
+  URL:=http://www.webmproject.org/
+  DEPENDS:=+libpthread
+endef
+
+define Package/libvpx/description
+   libvpx is a VP8/VP9 Codec SDK.
+endef
+
+CONFIGURE_ARGS = \
+               --target=generic-gnu \
+               --prefix=$(CONFIGURE_PREFIX) \
+               --libdir=/usr/lib \
+               --enable-static \
+               --enable-shared \
+        --disable-examples \
+        --disable-docs \
+        --disable-unit-tests \
+
+# Add --enable-small as openwrt gcc flags are overwritten
+ifneq ($(findstring -Os,$(TARGET_CFLAGS)),)
+CONFIGURE_ARGS += --enable-small
+endif
+
+# libvpx expects gcc as linker but uses $LD if provided
+# However, OpenWRT defines LD as *-uclibc-ld and not *-gcc
+CONFIGURE_VARS += \
+    CROSS=$(GNU_TARGET_NAME) \
+       LD="$(TARGET_CC)" \
+
+MAKE_FLAGS += \
+       LD="$(TARGET_CC)" \
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/vpx/
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/vpx/* $(1)/usr/include/vpx/
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libvpx/install
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libvpx))
diff --git a/libs/libwebsockets/Makefile b/libs/libwebsockets/Makefile
new file mode 100644 (file)
index 0000000..e82e072
--- /dev/null
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libwebsockets
+
+PKG_VERSION:=1.3-chrome37-firefox30
+PKG_RELEASE:=1
+PKG_SOURCE:=v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/warmcat/$(PKG_NAME)/archive/
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_SOURCE_SUBDIR)
+PKG_LICENSE:=LGPL-2.1+exception
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += $(if $(CONFIG_PACKAGE_kmod-ipv6),,-DLWS_IPV6=)
+
+CMAKE_OPTIONS += -DLWS_WITHOUT_TESTAPPS=ON
+
+# other options worth noting
+# CMAKE_OPTIONS += -DLWS_WITHOUT_EXTENSIONS=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_DAEMONIZE=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_SERVER=ON
+# CMAKE_OPTIONS += -DLWS_WITHOUT_DEBUG=ON
+
+
+define Package/$(PKG_NAME)/Default
+       SECTION:=libs
+       CATEGORY:=Libraries
+       TITLE:=libwebsockets
+       DEPENDS:=+zlib
+endef
+
+define Package/libwebsockets-openssl
+       $(call Package/$(PKG_NAME)/Default)
+       TITLE += (OpenSSL)
+       DEPENDS += +libopenssl
+       VARIANT:=openssl
+endef
+
+define Package/libwebsockets-cyassl
+       $(call Package/$(PKG_NAME)/Default)
+       TITLE += (CyaSSL)
+       DEPENDS += +libcyassl
+       VARIANT:=cyassl
+endef
+
+ifeq ($(BUILD_VARIANT),openssl)
+    CMAKE_OPTIONS += -DLWS_OPENSSL_CLIENT_CERTS=/etc/ssl/certs
+    CMAKE_OPTIONS += -DLWS_OPENSSL_SUPPORT=ON
+    CMAKE_OPTIONS += -DLWS_WITH_SSL=ON
+endif
+
+ifeq ($(BUILD_VARIANT),cyassl)
+    CMAKE_OPTIONS += -DLWS_OPENSSL_CLIENT_CERTS=/etc/ssl/certs
+    CMAKE_OPTIONS += -DLWS_OPENSSL_SUPPORT=ON
+    CMAKE_OPTIONS += -DLWS_WITH_SSL=ON
+# for cyassl, edit package/libs/cyassl/Makefile to include --enable-opensslextra
+# NOTE: it will compile without it, untested whether it it's needed?!
+    CMAKE_OPTIONS += -DLWS_USE_CYASSL=ON
+    CMAKE_OPTIONS += -DLWS_CYASSL_LIB=$(STAGING_DIR)/usr/lib/libcyassl.so
+    CMAKE_OPTIONS += -DLWS_CYASSL_INCLUDE_DIRS=$(STAGING_DIR)/usr/include
+endif
+
+define Package/libwebsockets/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libwebsockets.so* $(1)/usr/lib/
+endef
+
+Package/$(PKG_NAME)-cyassl/install = $(Package/$(PKG_NAME)/install)
+Package/$(PKG_NAME)-openssl/install = $(Package/$(PKG_NAME)/install)
+
+$(eval $(call BuildPackage,libwebsockets-openssl))
+$(eval $(call BuildPackage,libwebsockets-cyassl))
diff --git a/libs/libwebsockets/patches/0001-cyassl-correct-include-path-for-3.1.x.patch b/libs/libwebsockets/patches/0001-cyassl-correct-include-path-for-3.1.x.patch
new file mode 100644 (file)
index 0000000..4413ac9
--- /dev/null
@@ -0,0 +1,25 @@
+From 4fb4a2353db521667d1ec61480bf8179bf585d5f Mon Sep 17 00:00:00 2001
+From: Karl Palsson <karlp@remake.is>
+Date: Thu, 14 Aug 2014 16:30:48 +0000
+Subject: [PATCH] cyassl: correct include path for 3.1.x
+
+---
+ lib/private-libwebsockets.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
+index 4194498..fbd22b5 100755
+--- a/lib/private-libwebsockets.h
++++ b/lib/private-libwebsockets.h
+@@ -155,7 +155,7 @@
+ #ifdef LWS_OPENSSL_SUPPORT
+ #ifdef USE_CYASSL
+ #include <cyassl/openssl/ssl.h>
+-#include <cyassl/error.h>
++#include <cyassl/error-ssl.h>
+ unsigned char *
+ SHA1(const unsigned char *d, size_t n, unsigned char *md);
+ #else
+-- 
+1.8.3.1
+
diff --git a/libs/libxerces-c/Makefile b/libs/libxerces-c/Makefile
new file mode 100644 (file)
index 0000000..c2dd097
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libxerces-c
+PKG_VERSION:=3.1.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://git.apache.org/xerces-c.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=Xerces-C_3_1_1
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=libtool
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_ARGS += \
+       --disable-pretty-make \
+       --enable-transcoder-iconv \
+       --enable-netaccessor-socket \
+       --enable-msgloader-inmemory
+
+TARGET_CFLAGS += \
+       -I$(STAGING_DIR)/usr/lib/libiconv-full/include
+
+TARGET_CPPFLAGS += \
+       -I$(STAGING_DIR)/usr/lib/libiconv-full/include
+
+TARGET_LDFLAGS += \
+       -L$(STAGING_DIR)/usr/lib/libiconv-full/lib \
+       -lm
+
+define Package/libxerces-c
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Validating XML parser library for C++
+  URL:=http://xerces.apache.org/
+  DEPENDS:=$(CXX_DEPENDS) +libc +libiconv +libpthread
+endef
+
+define Package/libxerces-c-samples
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Validating XML parser library for C++ (samples)
+  URL:=http://xerces.apache.org/
+  DEPENDS:=+libxerces-c
+endef
+
+define Build/Configure
+       (cd $(PKG_BUILD_DIR)/$(CONFIGURE_PATH); \
+       ./reconf;)
+       $(call Build/Configure/Default)
+endef
+
+define Package/libxerces-c/description
+  Xerces-C++ is a validating XML parser written in a portable subset of
+  C++. Xerces-C++ makes it easy to give your application the ability
+  to read and write XML data. A shared library is provided for parsing,
+  generating, manipulating, and validating XML documents. Xerces-C++ is
+  faithful to the XML 1.0 recommendation and associated standards (DOM
+  1.0, DOM 2.0, SAX 1.0, SAX 2.0, Namespaces, XML Schema Part 1 and
+  Part 2). It also provides experimental implementations of XML 1.1
+  and DOM Level 3.0. The parser provides high performance, modularity,
+  and scalability.
+endef
+
+define Package/libxerces-c-samples/description
+  Validating XML parser library for C++ (samples)
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/xercesc/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/xercesc/* $(1)/usr/include/xercesc/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/{libxerces-c.a,libxerces-c-3.1.so,libxerces-c.so} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/xerces-c.pc $(1)/usr/lib/pkgconfig/xerces-c.pc
+endef
+
+define Package/libxerces-c/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/{libxerces-c-3.1.so,libxerces-c.so} $(1)/usr/lib/
+endef
+
+define Package/libxerces-c-samples/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libxerces-c))
+$(eval $(call BuildPackage,libxerces-c-samples))
index d7accab5fb4505cda9dcb6564c973696721b0e7d..c83b7c02d9c1c235a7b72d0518c20ccb04d4241b 100644 (file)
@@ -8,14 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libxml2
-PKG_VERSION:=2.9.1
-PKG_RELEASE:=1
+PKG_VERSION:=2.9.2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://gd.tuwien.ac.at/languages/libxml/ \
        http://xmlsoft.org/sources/ \
        ftp://fr.rpmfind.net/pub/libxml/
-PKG_MD5SUM:=9c0cfef285d5c4a5c80d00904ddab380
+PKG_MD5SUM:=9e6a9aca9d155737868b3dc5fd82f788
 
 PKG_LICENSE:=MIT
 PKG_LICENSE_FILES:=COPYING
@@ -26,6 +26,7 @@ PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
 
+include $(INCLUDE_DIR)/host-build.mk
 include $(INCLUDE_DIR)/package.mk
 
 define Package/libxml2
@@ -43,6 +44,38 @@ endef
 TARGET_CFLAGS += $(FPIC)
 
 CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static \
+       --with-c14n \
+       --without-catalog \
+       --with-debug \
+       --without-docbook \
+       --with-html \
+       --without-ftp \
+       --without-http \
+       --without-iconv \
+       --without-iso8859x \
+       --without-legacy \
+       --with-output \
+       --without-pattern \
+       --without-push \
+       --without-python \
+       --with-reader \
+       --without-readline \
+       --without-regexps \
+       --with-sax1 \
+       --with-schemas \
+       --with-threads \
+       --with-tree \
+       --with-valid \
+       --with-writer \
+       --with-xinclude \
+       --with-xpath \
+       --with-xptr \
+       --with-zlib=$(STAGING_DIR)/usr \
+       --without-lzma
+
+HOST_CONFIGURE_ARGS += \
        --enable-shared \
        --enable-static \
        --with-c14n \
@@ -97,4 +130,5 @@ define Package/libxml2/install
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/libxml2.so* $(1)/usr/lib/
 endef
 
+$(eval $(call HostBuild))
 $(eval $(call BuildPackage,libxml2))
diff --git a/libs/libxml2/patches/0001-threads-use-forward-declarations-only-for-glibc-fixe.patch b/libs/libxml2/patches/0001-threads-use-forward-declarations-only-for-glibc-fixe.patch
new file mode 100644 (file)
index 0000000..e6c3fbe
--- /dev/null
@@ -0,0 +1,42 @@
+From e3e04d254fb6bac49a285775b729e28b0500476c Mon Sep 17 00:00:00 2001
+From: Michael Heimpold <mhei@heimpold.de>
+Date: Sun, 21 Dec 2014 01:03:49 +0100
+Subject: [PATCH] threads: use forward declarations only for glibc (fixes
+ #704908)
+
+The declarations of pthread functions, used to generate weak references
+to them, fail to suppress macros. Thus, if any pthread function has
+been provided as a macro, compiling threads.c will fail.
+This breaks on musl libc, which defines pthread_equal as a macro (in
+addition to providing the function, as required).
+
+Prevent the declarations for e.g. musl libc by refining the condition.
+
+The idea for this solution was borrowed from the alpine linux guys, see
+http://git.alpinelinux.org/cgit/aports/tree/main/libxml2/libxml2-pthread.patch
+
+Signed-off-by: Michael Heimpold <mhei@heimpold.de>
+---
+ threads.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/threads.c
++++ b/threads.c
+@@ -47,7 +47,7 @@
+ #ifdef HAVE_PTHREAD_H
+ static int libxml_is_threaded = -1;
+-#ifdef __GNUC__
++#if defined(__GNUC__) && defined(__GLIBC__)
+ #ifdef linux
+ #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
+ extern int pthread_once (pthread_once_t *__once_control,
+@@ -89,7 +89,7 @@ extern int pthread_cond_signal ()
+          __attribute((weak));
+ #endif
+ #endif /* linux */
+-#endif /* __GNUC__ */
++#endif /* defined(__GNUC__) && defined(__GLIBC__) */
+ #endif /* HAVE_PTHREAD_H */
+ /*
diff --git a/libs/libzdb/Makefile b/libs/libzdb/Makefile
new file mode 100644 (file)
index 0000000..09beff3
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libzdb
+PKG_VERSION:=3.0
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-3.0
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.tildeslash.com/libzdb/dist/
+PKG_MD5SUM:=3bb9efff10a1f3ebc5b76c1055c48635
+PKG_CAT:=zcat
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_BUILD_DEPENDS:=libzdb/host
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libzdb
+    SECTION:=libs
+    CATEGORY:=Libraries
+    TITLE:=A thread-safe multi database connection pool library
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=http://www.tildeslash.com/libzdb/
+    DEPENDS:=+libsqlite3 +libpq +libmysqlclient +zlib +libpthread +libopenssl
+endef
+
+define Package/libzdb/description
+   zdb is a database library with thread-safe connection pooling. The library can connect
+   transparently to multiple database systems. It has zero runtime configuration and connections
+   are specified via a URL scheme. A modern object-oriented API is provided.
+   zdb supports MySQL, PostgreSQL, SQLite, and Oracle.
+   NOTE: This package does not include Oracle support.
+endef
+
+CONFIGURE_ARGS += --disable-profiling \
+                   --enable-optimized \
+                   --with-mysql \
+                   --with-postgresql \
+                   --with-sqlite \
+                   --enable-sqliteunlock \
+                   --enable-openssl
+
+TARGET_CPPFLAGS += -std=c99
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Hooks/HostConfigure/Pre
+endef
+
+define Host/Configure
+endef
+
+define Host/Compile
+       $(HOSTCC) $(HOST_BUILD_DIR)/tools/filterh/lex.yy.c -o $(HOST_BUILD_DIR)/tools/bin/filterh
+endef
+
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+       $(CP) $(HOST_BUILD_DIR)/tools/bin/filterh $(STAGING_DIR_HOST)/bin/
+endef
+
+$(eval $(call HostBuild))
+
+define Build/Compile
+       $(call Build/Compile/Default)
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include/zdb
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/zdb/ $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libzdb* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/zdb.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libzdb/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libzdb.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libzdb))
diff --git a/libs/libzdb/patches/010-cross-compile-fixes.patch b/libs/libzdb/patches/010-cross-compile-fixes.patch
new file mode 100644 (file)
index 0000000..18507da
--- /dev/null
@@ -0,0 +1,186 @@
+diff -rupN libzdb-3.0.orig/configure.ac libzdb-3.0/configure.ac
+--- libzdb-3.0.orig/configure.ac       2014-01-06 22:17:57.000000000 +0100
++++ libzdb-3.0/configure.ac    2014-11-20 13:59:27.456957651 +0100
+@@ -196,15 +196,6 @@ AC_SEARCH_LIBS([pthread_create], [pthrea
+ # Database Libraries 
+ mysql="yes"
+-check_mysql_config() 
+-{
+-        AC_PATH_PROG([MYSQLCONFIG], [mysql_config], [no], [$PATH:/usr/local/bin:/usr/local/mysql/bin])
+-        if test "x$MYSQLCONFIG" = "xno" 
+-        then
+-                AC_MSG_WARN([mysql_config is required to build libzdb with mysql])
+-                mysql="no"
+-        fi
+-}
+ AC_MSG_CHECKING(for mysql)
+ AC_ARG_WITH([mysql], 
+         AS_HELP_STRING([--with-mysql(=<path>)], 
+@@ -216,22 +207,20 @@ AC_ARG_WITH([mysql],
+                         mysql="no"
+                 else
+                         AC_MSG_RESULT([yes])
+-                        AC_CHECK_FILE([$with_mysql], [MYSQLCONFIG=$with_mysql], [check_mysql_config])        
+                 fi
+         ],
+         [
+                 AC_MSG_RESULT([yes])
+-                check_mysql_config
+         ])
+ if test "xyes" = "x$mysql"; then
+         svd_CPPFLAGS=$CPPFLAGS
+         svd_LDFLAGS=$LDFLAGS
+-        CPPFLAGS="`$MYSQLCONFIG --include` $CPPFLAGS"
+-        LDFLAGS="`$MYSQLCONFIG --libs` $LDFLAGS"
++        CPPFLAGS="-I$STAGING_DIR/usr/include/mysql $CPPFLAGS"
++        LDFLAGS="-L$STAGING_DIR/usr/lib/mysql -L$STAGING_DIR/usr/lib $LDFLAGS"
+         AC_CHECK_HEADERS([mysql.h], [], [mysql="no"])
+         if test "xyes" = "x$mysql"; then
+-                DBCPPFLAGS="$DBCPPFLAGS `$MYSQLCONFIG --include`"
+-                DBLDFLAGS="$DBLDFLAGS `$MYSQLCONFIG --libs`"
++                DBCPPFLAGS="$DBCPPFLAGS -I$STAGING_DIR/usr/include/mysql"
++                DBLDFLAGS="$DBLDFLAGS -L$STAGING_DIR/usr/lib/mysql -L$STAGING_DIR/usr/lib -lmysqlclient -lz -lcrypt -lnsl -lm"
+                 AC_DEFINE([HAVE_LIBMYSQLCLIENT], 1, [Define to 1 to enable mysql])
+         else
+                 CPPFLAGS=$svd_CPPFLAGS
+@@ -241,15 +230,6 @@ fi
+ AM_CONDITIONAL([WITH_MYSQL], test "xyes" = "x$mysql")
+ postgresql="yes"
+-check_postgres_config() 
+-{
+-        AC_PATH_PROG([PGCONFIG], [pg_config], [no], [$PATH:/usr/local/bin:/usr/local/pgsql/bin])
+-        if test "x$PGCONFIG" = "xno"
+-        then
+-                AC_MSG_WARN([pg_config is required to build libzdb with postgresql])
+-                postgresql="no"
+-        fi
+-}
+ AC_MSG_CHECKING(for postgresql)
+ AC_ARG_WITH([postgresql], 
+         AS_HELP_STRING([--with-postgresql(=<path>)], 
+@@ -261,22 +241,20 @@ AC_ARG_WITH([postgresql],
+                         postgresql="no"
+                 else
+                         AC_MSG_RESULT([yes])
+-                        AC_CHECK_FILE([$with_postgresql], [PGCONFIG=$with_postgresql],[check_postgres_config])
+                 fi
+         ],
+         [
+                 AC_MSG_RESULT([yes])
+-                check_postgres_config
+         ])
+ if test "xyes" = "x$postgresql"; then
+         svd_CPPFLAGS=$CPPFLAGS
+         svd_LDFLAGS=$LDFLAGS
+-        CPPFLAGS="-I`$PGCONFIG --includedir` $CPPFLAGS"
+-        LDFLAGS="-L`$PGCONFIG --libdir` $LDFLAGS"
++        CPPFLAGS="-I$STAGING_DIR/usr/include/postgresql -I$STAGING_DIR/usr/include $CPPFLAGS"
++        LDFLAGS="-L$STAGING_DIR/usr/lib $LDFLAGS"
+         AC_CHECK_HEADERS([libpq-fe.h], [], [postgresql="no"])
+         if test "xyes" = "x$postgresql"; then
+-                DBCPPFLAGS="$DBCPPFLAGS -I`$PGCONFIG --includedir`"
+-                DBLDFLAGS="$DBLDFLAGS -L`$PGCONFIG --libdir` -lpq"
++                DBCPPFLAGS="$DBCPPFLAGS -I$STAGING_DIR/usr/include/postgresql -I$STAGING_DIR/usr/include"
++                DBLDFLAGS="$DBLDFLAGS -L$STAGING_DIR/usr/lib -lpq"
+                 AC_DEFINE([HAVE_LIBPQ], 1, [Define to 1 to enable postgresql])
+         else
+                 CPPFLAGS=$svd_CPPFLAGS
+@@ -298,22 +276,7 @@ AC_ARG_WITH([sqlite],
+                         sqlite="no"
+                 else
+                         AC_MSG_RESULT([yes])
+-                        AC_CHECK_FILE([$with_sqlite],
+-                        [
+-                                svd_LDFLAGS=$LDFLAGS
+-                                svd_CPPFLAGS=$CPPFLAGS
+-                                LDFLAGS="-L$with_sqlite/lib $LDFLAGS -lsqlite3"
+-                                CPPFLAGS="-I$with_sqlite/include $CPPFLAGS"
+-                                AC_SEARCH_LIBS([sqlite3_open], [sqlite3],
+-                                [
+-                                        DBCPPFLAGS="$DBCPPFLAGS -I$with_sqlite/include"
+-                                        DBLDFLAGS="$DBLDFLAGS -L$with_sqlite/lib/ -lsqlite3"
+-                                ],[sqlite="no"])
+-                                LDFLAGS=$svd_LDFLAGS
+-                                CPPFLAGS=$svd_CPPFLAGS
+-   
+-                        ],
+-                        AC_SEARCH_LIBS([sqlite3_open], [sqlite3], [], [sqlite="no"]))
++                        AC_SEARCH_LIBS([sqlite3_open], [sqlite3], [], [sqlite="no"])
+                 fi
+         ], 
+         [
+@@ -328,20 +291,8 @@ if test "xyes" = "x$sqlite"; then
+ fi
+ AM_CONDITIONAL([WITH_SQLITE], test "xyes" = "x$sqlite")
+-oracle="yes"
+-AC_MSG_CHECKING(for oracle)
+-AX_LIB_ORACLE_OCI
+-if test -n "$ORACLE_OCI_CFLAGS" -a -n "$ORACLE_OCI_LDFLAGS"; then
+-        DBCPPFLAGS="$DBCPPFLAGS $ORACLE_OCI_CFLAGS"
+-        DBLDFLAGS="$DBLDFLAGS $ORACLE_OCI_LDFLAGS"
+-        AC_DEFINE([HAVE_ORACLE], 1, [Define to 1 to enable oracle])
+-else
+-        oracle="no"
+-fi
+-AM_CONDITIONAL([WITH_ORACLE], test "xyes" = "x$oracle")
+-
+ # Test if any database system was found
+-if test "xno" = "x$postgresql" -a "xno" = "x$mysql" -a "xno" = "x$sqlite" -a "xno" = "x$oracle"; then
++if test "xno" = "x$postgresql" -a "xno" = "x$mysql" -a "xno" = "x$sqlite"; then
+         AC_MSG_ERROR([No available database found or selected. Try configure --help])
+ fi
+@@ -358,23 +309,6 @@ AC_HEADER_STDC
+ # Functions 
+ # ------------------------------------------------------------------------
+-# Require a working setjmp
+-AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+-        #include <setjmp.h>
+-        ]],
+-        [[jmp_buf env; setjmp(env);]])], 
+-        [], [AC_MSG_FAILURE([setjmp is required])]
+-)
+-
+-# Require that we have vsnprintf that conforms to c99. I.e. does bounds check
+-AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+-        #include <stdarg.h> 
+-        #include <stdio.h>
+-        ]],
+-        [[char t[1]; va_list ap; int n = vsnprintf(t, 1, "hello", ap); if(n == 5) return 0;return 1;]])], 
+-        [], [AC_MSG_FAILURE([vsnprintf does not conform to c99])]
+-)
+-
+ AC_CHECK_FUNCS([timegm])
+@@ -487,11 +421,6 @@ echo "|   PostgreSQL:
+ else
+ echo "|   PostgreSQL:                                   DISABLED   |"
+ fi
+-if test "xyes" = "x$oracle"; then
+-echo "|   Oracle:                                       ENABLED    |"
+-else
+-echo "|   Oracle:                                       DISABLED   |"
+-fi
+ echo "+------------------------------------------------------------+"
+diff -rupN libzdb-3.0.orig/Makefile.am libzdb-3.0/Makefile.am
+--- libzdb-3.0.orig/Makefile.am        2014-01-06 22:34:08.000000000 +0100
++++ libzdb-3.0/Makefile.am     2014-11-20 13:51:22.508204689 +0100
+@@ -45,11 +45,6 @@ libzdb_la_SOURCES += src/db/sqlite/SQLit
+                      src/db/sqlite/SQLiteResultSet.c \
+                      src/db/sqlite/SQLitePreparedStatement.c
+ endif
+-if WITH_ORACLE
+-libzdb_la_SOURCES += src/db/oracle/OracleConnection.c \
+-                     src/db/oracle/OracleResultSet.c \
+-                     src/db/oracle/OraclePreparedStatement.c
+-endif
+ API_INTERFACES  = src/zdb.h src/db/ConnectionPool.h src/db/Connection.h \
+                   src/db/ResultSet.h src/net/URL.h src/db/PreparedStatement.h \
diff --git a/libs/libzdb/patches/020-filterh-use-host-built-version.patch b/libs/libzdb/patches/020-filterh-use-host-built-version.patch
new file mode 100644 (file)
index 0000000..74c166a
--- /dev/null
@@ -0,0 +1,20 @@
+diff -rupN libzdb-3.0.orig/Makefile.am libzdb-3.0/Makefile.am
+--- libzdb-3.0.orig/Makefile.am        2014-01-06 22:34:08.000000000 +0100
++++ libzdb-3.0/Makefile.am     2014-11-19 20:26:20.588547729 +0100
+@@ -1,5 +1,7 @@
+ # Copyright (C) Tildeslash Ltd. All rights reserved.
++include $(TOPDIR)/rules.mk
++
+ AUTOMAKE_OPTIONS = foreign no-dependencies subdir-objects
+ ACLOCAL_AMFLAGS  = -I m4
+@@ -12,7 +14,7 @@ LIBRARY_NAME    = zdb
+ RE2C          = @RE2C@
+ RE2CFLAGS       = -b
+-FILTERH         = ./tools/bin/filterh
++FILTERH         = $(STAGING_DIR_HOST)/bin/filterh
+ AM_CPPFLAGS     = $(CPPFLAGS) $(DBCPPFLAGS)
+ AM_CPPFLAGS     += -Isrc -Isrc/util -Isrc/net -Isrc/db -Isrc/exceptions
diff --git a/libs/mxml/Makefile b/libs/mxml/Makefile
new file mode 100644 (file)
index 0000000..74cff41
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mxml
+PKG_VERSION:=2.8
+PKG_RELEASE:=1
+PKG_MD5SUM:=d85ee6d30de053581242c4a86e79a5d2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.msweet.org/files/project3/
+PKG_FIXUP:=autoreconf
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mxml
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Mini-XML
+  URL:=http://www.minixml.org/
+endef
+
+define Package/mxml/description
+  A small xml library.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+       --enable-shared \
+       --enable-static
+
+define Build/InstallDev
+       mkdir -p $(1)/usr/include
+       $(CP) $(PKG_BUILD_DIR)/mxml.h $(1)/usr/include/
+       mkdir -p $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libmxml.so* $(1)/usr/lib/
+       mkdir -p $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_BUILD_DIR)/mxml.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/mxml/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/libmxml.so.*  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,mxml))
diff --git a/libs/mxml/patches/001-targets.patch b/libs/mxml/patches/001-targets.patch
new file mode 100644 (file)
index 0000000..86379f0
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -88,7 +88,7 @@ PUBLIBOBJS   =       mxml-attr.o mxml-entity.o m
+                       mxml-index.o mxml-node.o mxml-search.o mxml-set.o
+ LIBOBJS               =       $(PUBLIBOBJS) mxml-private.o mxml-string.o
+ OBJS          =       mxmldoc.o testmxml.o $(LIBOBJS)
+-TARGETS               =       $(LIBMXML) mxmldoc testmxml mxml.xml doc/mxml.man
++TARGETS               =       $(LIBMXML)
+ #
index 7c9fe5037088ec2c494fbbe7cb8445f583e1f487..d14d086078d433da8c9eac370fde6ba4ddbf707e 100644 (file)
@@ -8,12 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=nspr
-PKG_VERSION:=3.16.4
+PKG_VERSION:=3.16.6
 PKG_RELEASE:=1
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/nss-$(PKG_VERSION)
 PKG_SOURCE:=nss-$(PKG_VERSION)-with-nspr-4.10.6.tar.gz
-PKG_SOURCE_URL:=ftp://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_16_4_RTM/src/
+PKG_SOURCE_URL:=ftp://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_16_6_RTM/src/
+PKG_MD5SUM:=4722706ea101948712b5ad003629679f
 PKG_INSTALL:=1
 
 include $(INCLUDE_DIR)/package.mk
diff --git a/libs/opencv/Makefile b/libs/opencv/Makefile
new file mode 100644 (file)
index 0000000..20ba20c
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2013-2014 wrtnode.com
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=opencv
+PKG_VERSION:=2.4.10
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
+PKG_SOURCE_URL:=http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.10/
+PKG_MD5SUM:=ec63952d3a3dff965d5fdde765926821
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+
+define Package/opencv/Default/description
+ OpenCV (Open Source Computer Vision Library) is an open source computer
+ vision and machine learning software library. OpenCV was built to provide
+ a common infrastructure for computer vision applications and to accelerate
+ the use of machine perception in the commercial products. Being a
+ BSD-licensed product, OpenCV makes it easy for businesses to utilize
+ and modify the code.
+endef
+
+define Package/opencv
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=opencv-2.4.10
+  URL:=http://opencv.org/
+  MAINTAINER:=WRTnode Team <pub@wrtnode.com>
+  DEPENDS:=+libpthread +librt +libstdcpp +zlib +libjpeg
+endef
+
+
+PKG_INSTALL:=1
+
+CMAKE_OPTIONS += -DBUILD_opencv_gpu:BOOL=OFF \
+        -DWITH_1394:BOOL=OFF -DBUILD_opencv_stitching:BOOL=OFF \
+        -DBUILD_opencv_superres:BOOL=OFF -DBUILD_opencv_ts:BOOL=OFF
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/opencv $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/opencv2 $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libopencv* $(1)/usr/lib/
+endef
+
+define Package/opencv/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libopencv* $(1)/usr/lib/
+
+endef
+
+$(eval $(call BuildPackage,opencv))
diff --git a/libs/opencv/README.md b/libs/opencv/README.md
new file mode 100644 (file)
index 0000000..a5cdcdd
--- /dev/null
@@ -0,0 +1,23 @@
+Introduction
+===
+
+#### OpenCV: Open Source Computer Vision Library.OpenCV is based on (open source) issued cross-platform computer vision library, you can run on Linux, Windows and Mac OS operating systems.
+
+#### Resources
+
+* Homepage: <http://opencv.org>
+* Docs: <http://docs.opencv.org>
+* Q&A forum: <http://answers.opencv.org>
+* Issue tracking: <http://code.opencv.org>
+
+#### Contributing
+
+Please read before starting work on a pull request: <http://code.opencv.org/projects/opencv/wiki/How_to_contribute>
+
+Summary of guidelines:
+
+* One pull request per issue;
+* Choose the right base branch;
+* Include tests and documentation;
+* Clean up "oops" commits before submitting;
+* Follow the coding style guide.
index 5344080da8b263faba31ff66df8a6c7edb4111c7..dcc9d988a7a7ac3cea73e07eaf12b851625fc14b 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=openldap
 PKG_VERSION:=2.4.39
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
 PKG_SOURCE_URL:=ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/ \
@@ -97,7 +97,6 @@ CONFIGURE_ARGS += \
        --with-yielding_select="yes" \
        --without-cyrus-sasl \
        --without-threads \
-       --without-tls \
        --enable-null \
        --disable-bdb \
        --disable-hdb \
index b30bbf1953ae45936680bce31b485f79a7d2adc8..2209e76b485b11f8cecc5e2ca1c6f0ec0201af8b 100644 (file)
@@ -7,7 +7,7 @@ SERVICE_USE_PID=1
 
 start() {
        mkdir -m 0755 -p /var/openldap-data
-       service_start /usr/sbin/slapd
+       service_start /usr/sbin/slapd -h "ldap://localhost/ ldaps:///"
 }
 
 stop() {
index cbc273eeb9e0afd0d87d2c51d3d0f401189e87f2..dbcb4dd95b1f55b50eb2dfaec130c3556f6cdb8e 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=http://downloads.xiph.org/releases/opus/
 PKG_MD5SUM:=c5a8cf7c0b066759542bc4ca46817ac6
 
 PKG_LICENSE:=BSD-3-Clause
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_INSTALL:=1
index e93475e1ed48d5e62d63d0272dd8c7d7d9b231c1..2c708ec861fd5f83af41df46288c4ffaf3eacb7f 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pcre
-PKG_VERSION:=8.35
-PKG_RELEASE:=3
+PKG_VERSION:=8.36
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=@SF/pcre
-PKG_MD5SUM:=6aacb23986adccd9b3bc626c00979958
+PKG_MD5SUM:=b767bc9af0c20bc9c1fe403b0d41ad97
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
 
 PKG_LICENSE:=BSD-3-Clause
index fa29ff04f7b7c75229ece5137404c55347af6ea3..e3b5ceebfb6f3ef9f89c64fbe7b0f9dffb63d158 100644 (file)
@@ -28,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk
 define Package/libpq
   SECTION:=libs
   CATEGORY:=Libraries
-  DEPENDS:=+zlib +libreadline +libpthread +libncurses +shadow-su
+  DEPENDS:=+zlib +libreadline +libpthread +libncurses +shadow-utils +shadow-su
   TITLE:=PostgreSQL client library
   URL:=http://www.postgresql.org/
   SUBMENU:=database
index 49aa9f468cca6cae232c9dee201650b0c2411daa..f4af211a8a2d00de1aa19abe0bff915bd007bb00 100644 (file)
@@ -18,6 +18,7 @@ PKG_SOURCE_PROTO:=git
 PKG_SOURCE_VERSION:=$(PKG_VERSION)
 
 PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
 
 PKG_LICENSE:=BSD-2c
 
@@ -44,11 +45,6 @@ CONFIGURE_ARGS += \
        --enable-static \
        --disable-protoc
 
-define Build/Configure
-       cd $(PKG_BUILD_DIR) && ./autogen.sh
-       $(call Build/Configure/Default)
-endef
-
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include/
        $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
index 1553a7edc529a60b30925d9bb2d60c0d6ecbca0d..e1d99f67a782288c245706348ba8ebf1143f81e4 100644 (file)
@@ -43,6 +43,7 @@ define Host/Compile
 endef
 
 define Host/Install
+       $(MAKE) -C $(HOST_BUILD_DIR) install
 endef
 
 CONFIGURE_ARGS += --with-protoc=$(HOST_BUILD_DIR)/src/protoc
diff --git a/libs/pthsem/Makefile b/libs/pthsem/Makefile
new file mode 100644 (file)
index 0000000..0dee689
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2008-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=pthsem
+PKG_VERSION:=2.0.8
+PKG_RELEASE:=2
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=LGPL-2.1+
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.auto.tuwien.ac.at/~mkoegler/pth/
+PKG_MD5SUM:=9144b26dcc27e67498d63dd5456f934c
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/pthsem
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU pth extended with semaphore support
+  URL:=http://www.auto.tuwien.ac.at/~mkoegler/index.php/pth
+endef
+
+define Package/pthsem/description
+  GNU pth is a user mode multi threading library.
+  pthsem is an extend version, with support for semaphores added. It can be installed parallel to a normal pth.
+endef
+
+MAKE_FLAGS += \
+       OPTIM="$(TARGET_CFLAGS)" \
+       CFLAGS="$(TARGET_CFLAGS)" \
+       DESTDIR="$(PKG_INSTALL_DIR)"
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(2)/bin
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/pthsem-config \
+               $(2)/bin/
+       $(SED) \
+               's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+               $(2)/bin/pthsem-config
+
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP)   $(PKG_INSTALL_DIR)/usr/include/*.h \
+               $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP)   $(PKG_INSTALL_DIR)/usr/lib/libpthsem.{a,la,so*} \
+               $(1)/usr/lib/
+endef
+
+define Package/pthsem/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpthsem.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,pthsem))
diff --git a/libs/pthsem/patches/001-linux3x-fix.patch b/libs/pthsem/patches/001-linux3x-fix.patch
new file mode 100644 (file)
index 0000000..3b968f7
--- /dev/null
@@ -0,0 +1,12 @@
+--- pthsem-2.0.8/acinclude.m4
++++ pthsem-2.0.8/acinclude.m4
+@@ -892,6 +892,8 @@
+         case "x`uname -r`" in
+ changequote(, )dnl
+             x2.[23456789]* ) ;;
++changequote(, )dnl
++            x3.* ) ;;
+ changequote([, ])
+             * ) braindead=yes ;;
+         esac
+
index 8796dc56cb38ae87a2bf11bbabbd50572911e45b..37a4cc760c06441993c2dd5687ce80a219652242 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sqlite
-PKG_VERSION:=3080600
+PKG_VERSION:=3080801
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-autoconf-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://www.sqlite.org/2014/
-PKG_MD5SUM:=f7e4a156b583abeba349629e2364224b
+PKG_SOURCE_URL:=http://www.sqlite.org/2015/
+PKG_MD5SUM:=a6381941ffe8817ba19669ec0c0ede6f
 
 PKG_LICENSE:=PUBLICDOMAIN
 PKG_LICENSE_FILES:=
diff --git a/libs/tdb/Makefile b/libs/tdb/Makefile
new file mode 100644 (file)
index 0000000..2fce3dc
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=tdb
+PKG_VERSION:=1.0.6
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/tdb
+PKG_MD5SUM:=6b643fdeb48304010dcd5f675e458b58
+
+PKG_INSTALL:=1
+PKG_BUILD_DEPENDS:=+libgdbm
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/tdb
+  SUBMENU:=database
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Trivial Database
+  URL:=http://sourceforge.net/projects/tdb/
+  MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
+#  DEPENDS:=+libgdbm
+endef
+
+define Package/tdb/description
+  TDB is a Trivial Database. In concept, it is very much like GDBM,
+  and BSD's DB except that it allows multiple simultaneous writers
+  and uses locking internally to keep writers from trampling on
+  each other. TDB is also extremely small.
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/tdb.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/tdb/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,tdb))
+
diff --git a/libs/tdb/patches/001-printf-fix.patch b/libs/tdb/patches/001-printf-fix.patch
new file mode 100644 (file)
index 0000000..f88d942
--- /dev/null
@@ -0,0 +1,41 @@
+--- a/tdbtool.c        2001-12-11 06:45:47.000000000 +0300
++++ b/tdbtool.c        2014-11-14 15:14:00.401164300 +0300
+@@ -169,23 +169,21 @@ static void print_data(unsigned char *bu
+ static void help(void)
+ {
+-      printf("
+-tdbtool: 
+-  create    dbname     : create a database
+-  open      dbname     : open an existing database
+-  erase                : erase the database
+-  dump      dumpname   : dump the database as strings
+-  insert    key  data  : insert a record
+-  store     key  data  : store a record (replace)
+-  show      key        : show a record by key
+-  delete    key        : delete a record by key
+-  list                 : print the database hash table and freelist
+-  free                 : print the database freelist
+-  1 | first            : print the first record
+-  n | next             : print the next record
+-  q | quit             : terminate
+-  \\n                   : repeat 'next' command
+-");
++      printf("tdbtool:\n");
++      printf("  create    dbname     : create a database\n");
++      printf("  open      dbname     : open an existing database\n");
++      printf("  erase                : erase the database\n");
++      printf("  dump      dumpname   : dump the database as strings\n");
++      printf("  insert    key  data  : insert a record\n");
++      printf("  store     key  data  : store a record (replace)\n");
++      printf("  show      key        : show a record by key\n");
++      printf("  delete    key        : delete a record by key\n");
++      printf("  list                 : print the database hash table and freelist\n");
++      printf("  free                 : print the database freelist\n");
++      printf("  1 | first            : print the first record\n");
++      printf("  n | next             : print the next record\n");
++      printf("  q | quit             : terminate\n");
++      printf("  \\n                   : repeat 'next' command\n\n");
+ }
+ static void terror(char *why)
index 6476c46d94cae085de809dd5dc96e0fae08eaf15..bccab8bf49535199618a7eb8f793c001feaa39aa 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tiff
 PKG_VERSION:=4.0.3
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://download.osgeo.org/libtiff
diff --git a/libs/tiff/patches/017-CVE-2014-9330.patch b/libs/tiff/patches/017-CVE-2014-9330.patch
new file mode 100644 (file)
index 0000000..acd0a33
--- /dev/null
@@ -0,0 +1,45 @@
+Description: CVE-2014-9330
+ Integer overflow in bmp2tiff
+Origin: upstream, http://bugzilla.maptools.org/show_bug.cgi?id=2494
+Bug: http://bugzilla.maptools.org/show_bug.cgi?id=2494
+Bug-Debian: http://bugs.debian.org/773987
+
+Index: tiff/tools/bmp2tiff.c
+===================================================================
+--- tiff.orig/tools/bmp2tiff.c
++++ tiff/tools/bmp2tiff.c
+@@ -1,4 +1,4 @@
+-/* $Id: bmp2tiff.c,v 1.23 2010-03-10 18:56:49 bfriesen Exp $
++/* $Id: bmp2tiff.c,v 1.24 2014-12-21 15:15:32 erouault Exp $
+  *
+  * Project:  libtiff tools
+  * Purpose:  Convert Windows BMP files in TIFF.
+@@ -403,6 +403,13 @@ main(int argc, char* argv[])
+               width = info_hdr.iWidth;
+               length = (info_hdr.iHeight > 0) ? info_hdr.iHeight : -info_hdr.iHeight;
++        if( width <= 0 || length <= 0 )
++        {
++            TIFFError(infilename,
++                  "Invalid dimensions of BMP file" );
++            close(fd);
++            return -1;
++        }
+               switch (info_hdr.iBitCount)
+               {
+@@ -593,6 +600,14 @@ main(int argc, char* argv[])
+                       compr_size = file_hdr.iSize - file_hdr.iOffBits;
+                       uncompr_size = width * length;
++            /* Detect int overflow */
++            if( uncompr_size / width != length )
++            {
++                TIFFError(infilename,
++                    "Invalid dimensions of BMP file" );
++                close(fd);
++                return -1;
++            }
+                       comprbuf = (unsigned char *) _TIFFmalloc( compr_size );
+                       if (!comprbuf) {
+                               TIFFError(infilename,
index 5c6f4e1161b8b779da0e25abb3d089c9fc91bbe3..eeb6fc96bc63b7c2699d257f98ef4d9b77ed0ad8 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012 OpenWrt.org
+# Copyright (C) 2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -11,7 +11,7 @@ PKG_NAME:=unixodbc
 PKG_VERSION:=2.3.2
 PKG_RELEASE:=1
 
-PKG_SOURCE_URL:=ftp://ftp.unixodbc.org/pub/unixODBC/
+PKG_SOURCE_URL:=@SF/unixodbc
 PKG_SOURCE:=unixODBC-$(PKG_VERSION).tar.gz
 PKG_MD5SUM:=5e4528851eda5d3d4aed249b669bd05b
 PKG_BUILD_DIR:=$(BUILD_DIR)/unixODBC-$(PKG_VERSION)
index d832aa7e945fde19b7ece26a1a0cf8753abccf33..501f987e69559123ba822d4044779b63d29af3f5 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=vips
-PKG_VERSION:=7.38.5
+PKG_VERSION:=7.42.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://www.vips.ecs.soton.ac.uk/supported/7.38/
-PKG_MD5SUM:=768d1c0f50c5b2794bcab68383af33ee
+PKG_SOURCE_URL:=http://www.vips.ecs.soton.ac.uk/supported/7.42/
+PKG_MD5SUM:=33a4590924b3120ce309982ec85a7c16
 PKG_FIXUP:=autoreconf
 PKG_CHECK_FORMAT_SECURITY:=0
 
index 9f01d8d31f7005682ebc9784d675ec0015ad4072..72e841c5bbfce05cd31a2b5a9492c8ab42f005f0 100644 (file)
@@ -1,7 +1,7 @@
-diff -u --recursive --new-file vips-7.38.5-vanilla/configure.ac vips-7.38.5/configure.ac
---- vips-7.38.5-vanilla/configure.ac   2014-07-17 23:48:36.205794473 -0400
-+++ vips-7.38.5/configure.ac   2014-07-17 23:49:32.773792981 -0400
-@@ -184,7 +184,6 @@
+diff -u --recursive --new-file vips-7.42.1-vanilla/configure.ac vips-7.42.1/configure.ac
+--- vips-7.42.1-vanilla/configure.ac   2014-12-29 17:45:59.576995574 -0500
++++ vips-7.42.1/configure.ac   2014-12-29 17:59:03.698808601 -0500
+@@ -264,7 +264,6 @@
  AC_PROG_AWK
  AC_PROG_CC
  AC_PROG_CC_STDC
@@ -9,7 +9,7 @@ diff -u --recursive --new-file vips-7.38.5-vanilla/configure.ac vips-7.38.5/conf
  AC_C_CONST
  AC_C_RESTRICT
  AC_PROG_RANLIB
-@@ -192,19 +191,6 @@
+@@ -272,19 +271,6 @@
  AC_PROG_LN_S
  AM_WITH_DMALLOC
  
@@ -29,7 +29,7 @@ diff -u --recursive --new-file vips-7.38.5-vanilla/configure.ac vips-7.38.5/conf
  # option to build without C++
  # handy for some embedded applications
  # also, including C++ source causes link problems on some
-@@ -212,22 +198,8 @@
+@@ -292,24 +278,8 @@
  AC_ARG_ENABLE(cxx, 
    AS_HELP_STRING([--enable-cxx], [build C++ components (default: test)]))
  
@@ -41,7 +41,9 @@ diff -u --recursive --new-file vips-7.38.5-vanilla/configure.ac vips-7.38.5/conf
 -    # need -lstdc++ for (eg.) the C++ format loaders
 -    # this gets added to vips.pc to help mingw and friends link programs
 -    # using libvips
--    VIPS_CXX_LIBS="-lstdc++"
+-    if test x"$vips_needs_stdcpp" != x"no"; then
+-      VIPS_CXX_LIBS="-lstdc++"
+-    fi
 -    enable_cxx=yes
 -  fi
 -fi
@@ -52,91177 +54,101 @@ diff -u --recursive --new-file vips-7.38.5-vanilla/configure.ac vips-7.38.5/conf
    enable_cxx=no
  fi
  
-@@ -688,7 +660,6 @@
+@@ -817,7 +787,6 @@
  AC_SUBST(VIPS_CFLAGS)
  AC_SUBST(VIPS_INCLUDES)
  AC_SUBST(VIPS_LIBS)
 -AC_SUBST(VIPS_CXX_LIBS)
  AC_SUBST(PACKAGES_USED)
+ AC_SUBST(EXTRA_LIBS_USED)
  
- AC_OUTPUT([
-@@ -700,7 +671,6 @@
-       libvips/include/vips/Makefile 
-       libvips/Makefile 
-       libvips/arithmetic/Makefile 
--      libvips/cimg/Makefile 
-       libvips/colour/Makefile 
-       libvips/conversion/Makefile 
-       libvips/convolution/Makefile 
-@@ -715,9 +685,6 @@
+@@ -850,12 +819,6 @@
        libvips/create/Makefile 
        libvips/resample/Makefile 
        libvips/video/Makefile 
 -      libvipsCC/include/Makefile 
 -      libvipsCC/include/vips/Makefile 
 -      libvipsCC/Makefile 
+-      cplusplus/include/Makefile 
+-      cplusplus/include/vips/Makefile 
+-      cplusplus/Makefile 
        tools/Makefile 
        tools/batch_crop 
        tools/batch_image_convert 
-@@ -725,7 +692,6 @@
-       tools/light_correct 
-       tools/shrink_width 
+@@ -866,7 +829,6 @@
+       test/Makefile 
+       test/variables.sh
        swig/Makefile 
 -      swig/vipsCC/Makefile 
-       swig/python/setup.py 
        man/Makefile
        doc/Makefile
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/cimg.cpp vips-7.38.5/libvips/cimg/cimg.cpp
---- vips-7.38.5-vanilla/libvips/cimg/cimg.cpp  2014-07-17 23:48:36.231794473 -0400
-+++ vips-7.38.5/libvips/cimg/cimg.cpp  1969-12-31 19:00:00.000000000 -0500
-@@ -1,300 +0,0 @@
--/* Pass VIPS images through CImg
-- *
-- * JC, 15/10/07
-- * 29/4/10
-- *    - oop, should be smalltile, probably
-- *    - tiny cleanups
-- *    - gtkdoc
-- */
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--/* CImg needs to call pthread directly, this is the preproc magic they
-- * prefer.
-- */
--#if defined(sun)         || defined(__sun)      || defined(linux)       || defined(__linux) \
-- || defined(__linux__)   || defined(__CYGWIN__) || defined(BSD)         || defined(__FreeBSD__) \
-- || defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__)   || defined(sgi) \
-- || defined(__sgi)
--  #include <pthread.h>
--#endif
--
--#include "CImg.h"
--using namespace cimg_library;
--
--/* Save params here.
-- */
--struct Greyc {
--      IMAGE *in;
--      IMAGE *out;
--      IMAGE *mask;
--      IMAGE **arry;
--
--        int iterations;
--      float amplitude; 
--      float sharpness; 
--      float anisotropy;
--      float alpha; 
--      float sigma; 
--      float dl; 
--      float da; 
--      float gauss_prec; 
--      int interpolation; 
--      bool fast_approx;
--};
--
--// copy part of a vips region into a cimg
--template<typename T> static CImg<T> *
--vips_to_cimg( REGION *in, Rect *area )
--{
--      IMAGE *im = in->im;
--      CImg<T> *img = new CImg<T>( area->width, area->height, 1, im->Bands );
--
--      for( int y = 0; y < area->height; y++ ) {
--              T *p = (T *) IM_REGION_ADDR( in, area->left, area->top + y );
--
--              for( int x = 0; x < area->width; x++ ) {
--                      for( int z = 0; z < im->Bands; z++ )
--                              (*img)( x, y, z ) = p[z];
--
--                      p += im->Bands;
--              }
--      }
--
--      return( img );
--}
--
--// write a CImg to a vips region
--// fill out->valid, img has pixels in img_rect
--template<typename T> static void 
--cimg_to_vips( CImg<T> *img, Rect *img_rect, REGION *out )
--{
--      IMAGE *im = out->im;
--      Rect *valid = &out->valid;
--
--      g_assert( im_rect_includesrect( img_rect, valid ) );
--      
--      int x_off = valid->left - img_rect->left;
--      int y_off = valid->top - img_rect->top;
--
--      for( int y = 0; y < valid->height; y++ ) {
--              T *p = (T *) IM_REGION_ADDR( out, valid->left, valid->top + y );
--
--              for( int x = 0; x < valid->width; x++ ) {
--                      for( int z = 0; z < im->Bands; z++ )
--                              p[z] = static_cast<T>( (*img)( 
--                                      x + x_off, y + y_off, z ) );
--
--                      p += im->Bands;
--              }
--      }
--}
--
--template<typename T> static int
--greyc_gen( REGION *out, REGION **in, IMAGE **arry, Greyc *greyc )
--{
--      static const float gfact = (sizeof( T ) == 2) ? 1.0 / 256 : 1.0;
--      static const int tile_border = 4;
--
--      Rect *ir = &out->valid;
--      Rect need;
--      Rect image;
--
--      CImg<T> *img;
--      CImg<unsigned char> *msk;
--
--      need = *ir;
--      im_rect_marginadjust( &need, tile_border );
--      image.left = 0;
--      image.top = 0;
--      image.width = in[0]->im->Xsize;
--      image.height = in[0]->im->Ysize;
--      im_rect_intersectrect( &need, &image, &need );
--      if( im_prepare( in[0], &need ) )
--              return( -1 );
--      if( in[1] && im_prepare( in[1], &need ) )
--              return( -1 );
--
--      img = NULL;
--      msk = NULL;
--
--      try {
--              img = vips_to_cimg<T>( in[0], &need );
--              if( in[1] )
--                      msk = vips_to_cimg<unsigned char>( in[1], &need );
--              else
--                      // empty mask
--                      msk = new CImg<unsigned char>();
--
--              for( int i = 0; i < greyc->iterations; i++ ) 
--                      img->blur_anisotropic( *msk,
--                              greyc->amplitude, greyc->sharpness, 
--                              greyc->anisotropy,
--                              greyc->alpha, greyc->sigma, greyc->dl, 
--                              greyc->da, greyc->gauss_prec, 
--                              greyc->interpolation, greyc->fast_approx, 
--                              gfact );
--
--              cimg_to_vips<T>( img, &need, out );
--      }
--      catch( CImgException e ) { 
--              if( img )
--                      delete( img );
--              if( msk )
--                      delete( msk );
--
--              im_error( "GREYCstoration", "%s", e.message );
--
--              return( -1 );
--      }
--
--      if( img )
--              delete( img );
--      if( msk )
--              delete( msk );
--
--      return( 0 );
--}
--
--// Hmm, strange double-cast needed
--typedef int (*generate_fn)( REGION *out, REGION **in, 
--      IMAGE **im, Greyc *greyc );
--
--// as a plain C function
--/**
-- * im_greyc_mask:
-- * @in: input image 
-- * @out: output image
-- * @mask: input mask 
-- * @iterations: number of iterations to perform (eg. 1)
-- * @amplitude: scaling factor (eg. 40)
-- * @sharpness: degree of sharpening to apply (eg. 0.9)
-- * @anisotropy: how much to blur along lines (eg. 0.15)
-- * @alpha: blur by this much before calculating geometry (eg. 0.6)
-- * @sigma: blur geometry by this much (eg. 1.1)
-- * @dl: spatial integration step (eg. 0.8)
-- * @da: angular integration step (eg. 30)
-- * @gauss_prec: precision (eg. 2)
-- * @interpolation: interpolation (eg. 0 for nearest-neighbour)
-- *
-- * This operation calls the blur_anisotropic() method of the CImag image
-- * processing library. It is handy for denoising images and for upscaling.
-- *
-- * See also: im_conv().
-- *
-- * Returns: 0 on success, -1 on error
-- */
--int
--im_greyc_mask( IMAGE *in, IMAGE *out, IMAGE *mask,
--        int iterations,
--      float amplitude, float sharpness, float anisotropy,
--      float alpha, float sigma, 
--      float dl, float da, float gauss_prec, 
--      int interpolation, int fast_approx )
--{
--      IMAGE **arry;
--      Greyc *greyc;
--
--      if( im_piocheck( in, out ) ||
--              im_check_uncoded( "im_greyc_mask", in ) ||
--              im_check_u8or16orf( "im_greyc_mask", in ) )
--              return( -1 );
--      if( mask ) {
--              if( im_pincheck( mask ) ||
--                      im_check_uncoded( "im_greyc_mask", mask ) ||
--                      im_check_size_same( "im_greyc_mask", in, mask ) ||
--                      im_check_format( "im_greyc_mask", 
--                              mask, IM_BANDFMT_UCHAR ) )
--                      return( -1 );
--      }
--      if( im_cp_desc( out, in ) ||
--              !(arry = im_allocate_input_array( out, in, mask, NULL )) ||
--              !(greyc = IM_NEW( out, Greyc )) ||
--              im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
--              return( -1 );
--
--      greyc->in = in;
--      greyc->out = out;
--      greyc->mask = mask;
--      greyc->arry = arry;
--      greyc->iterations = iterations;
--      greyc->amplitude = amplitude;
--      greyc->sharpness = sharpness;
--      greyc->anisotropy = anisotropy;
--      greyc->alpha = alpha;
--      greyc->sigma = sigma;
--      greyc->dl = dl;
--      greyc->da = da;
--      greyc->gauss_prec = gauss_prec;
--      greyc->interpolation = interpolation;
--      greyc->fast_approx = fast_approx;
--
--      switch( in->BandFmt ) {
--      case IM_BANDFMT_UCHAR:
--              if( im_generate( out, 
--                      im_start_many, 
--                      // double-cast to give g++ enough context to expand the
--                      // template correctly
--                      (im_generate_fn) (
--                              (generate_fn) greyc_gen<unsigned char>),
--                      im_stop_many, arry, greyc ) )
--                      return( -1 );
--              break;
--
--      case IM_BANDFMT_USHORT:
--              if( im_generate( out, 
--                      im_start_many, 
--                      (im_generate_fn) (
--                              (generate_fn) greyc_gen<unsigned short>),
--                      im_stop_many, arry, greyc ) )
--                      return( -1 );
--              break;
--
--      case IM_BANDFMT_FLOAT:
--              if( im_generate( out, 
--                      im_start_many, 
--                      (im_generate_fn) (
--                              (generate_fn) greyc_gen<float>),
--                      im_stop_many, arry, greyc ) )
--                      return( -1 );
--              break;
--
--      default:
--              g_assert( 0 );
--      }
--
--      return( 0 );
--}
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/cimg_dispatch.c vips-7.38.5/libvips/cimg/cimg_dispatch.c
---- vips-7.38.5-vanilla/libvips/cimg/cimg_dispatch.c   2014-07-17 23:48:36.230794473 -0400
-+++ vips-7.38.5/libvips/cimg/cimg_dispatch.c   1969-12-31 19:00:00.000000000 -0500
-@@ -1,171 +0,0 @@
--/* Function dispatch tables for cimg wrappers.
-- */
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <stdio.h>
--
--#include <vips/vips.h>
--
--/** 
-- * SECTION: cimg_funcs
-- * @short_description: expose operations from the CImg library, mostly noise
-- * removal
-- * @stability: Stable
-- * @include: vips/vips.h
-- *
-- * The GREYCstoration filter.
-- */
--
--static int
--greyc_vec( im_object *argv )
--{
--        IMAGE *src = (IMAGE *) argv[0];
--        IMAGE *dst = (IMAGE *) argv[1];
--
--        int iterations = *((int *) argv[2]); 
--      double amplitude = *((double *) argv[3]);   
--      double sharpness = *((double *) argv[4]); 
--      double anisotropy = *((double *) argv[5]); 
--      double alpha = *((double *) argv[6]); 
--      double sigma = *((double *) argv[7]);
--      double dl = *((double *) argv[8]); 
--      double da = *((double *) argv[9]); 
--      double gauss_prec = *((double *) argv[10]); 
--      int interpolation = *((int *) argv[11]); 
--      int fast_approx = *((int *) argv[12]); 
--
--        if( im_greyc_mask( src, dst, NULL,
--              iterations,
--              amplitude, sharpness, anisotropy,
--              alpha, sigma, 
--              dl, da, gauss_prec, 
--              interpolation, fast_approx ) )
--              return( -1 );
--
--        return( 0 );
--}
--
--static im_arg_desc greyc_arg_types[] = {
--        IM_INPUT_IMAGE( "src" ),
--        IM_OUTPUT_IMAGE( "dst" ),
--        IM_INPUT_INT( "iterations" ),
--      IM_INPUT_DOUBLE( "amplitude" ),
--      IM_INPUT_DOUBLE( "sharpness" ),
--      IM_INPUT_DOUBLE( "anisotropy" ),
--      IM_INPUT_DOUBLE( "alpha" ),
--      IM_INPUT_DOUBLE( "sigma" ),
--      IM_INPUT_DOUBLE( "dl" ),
--      IM_INPUT_DOUBLE( "da" ),
--      IM_INPUT_DOUBLE( "gauss_prec" ),
--      IM_INPUT_INT( "interpolation" ),
--      IM_INPUT_INT( "fast_approx" )
--};
--
--static im_function greyc_desc = {
--        "im_greyc",                   /* Name */
--        "noise-removing filter",              /* Description */
--        (im_fn_flags) (IM_FN_TRANSFORM | IM_FN_PIO),/* Flags */
--        greyc_vec,                    /* Dispatch function */
--        IM_NUMBER( greyc_arg_types ), /* Size of arg list */
--        greyc_arg_types                       /* Arg list */
--};
--
--static int
--greyc_mask_vec( im_object *argv )
--{
--        IMAGE *src = (IMAGE *) argv[0];
--        IMAGE *dst = (IMAGE *) argv[1];
--        IMAGE *mask = (IMAGE *) argv[2];
--
--        int iterations = *((int *) argv[3]); 
--      double amplitude = *((double *) argv[4]);   
--      double sharpness = *((double *) argv[5]); 
--      double anisotropy = *((double *) argv[6]); 
--      double alpha = *((double *) argv[7]); 
--      double sigma = *((double *) argv[8]);
--      double dl = *((double *) argv[9]); 
--      double da = *((double *) argv[10]); 
--      double gauss_prec = *((double *) argv[11]); 
--      int interpolation = *((int *) argv[12]); 
--      int fast_approx = *((int *) argv[13]); 
--
--        if( im_greyc_mask( src, dst, mask,
--              iterations,
--              amplitude, sharpness, anisotropy,
--              alpha, sigma, 
--              dl, da, gauss_prec, 
--              interpolation, fast_approx ) )
--              return( -1 );
--
--        return( 0 );
--}
--
--static im_arg_desc greyc_mask_arg_types[] = {
--        IM_INPUT_IMAGE( "src" ),
--        IM_OUTPUT_IMAGE( "dst" ),
--        IM_INPUT_IMAGE( "mask" ),
--        IM_INPUT_INT( "iterations" ),
--      IM_INPUT_DOUBLE( "amplitude" ),
--      IM_INPUT_DOUBLE( "sharpness" ),
--      IM_INPUT_DOUBLE( "anisotropy" ),
--      IM_INPUT_DOUBLE( "alpha" ),
--      IM_INPUT_DOUBLE( "sigma" ),
--      IM_INPUT_DOUBLE( "dl" ),
--      IM_INPUT_DOUBLE( "da" ),
--      IM_INPUT_DOUBLE( "gauss_prec" ),
--      IM_INPUT_INT( "interpolation" ),
--      IM_INPUT_INT( "fast_approx" )
--};
--
--static im_function greyc_mask_desc = {
--        "im_greyc_mask",              /* Name */
--        "noise-removing filter, with a mask", /* Description */
--        (im_fn_flags) (IM_FN_TRANSFORM | IM_FN_PIO),/* Flags */
--        greyc_mask_vec,               /* Dispatch function */
--        IM_NUMBER( greyc_mask_arg_types ),/* Size of arg list */
--        greyc_mask_arg_types          /* Arg list */
--};
--
--static im_function *function_list[] = {
--      &greyc_desc,
--      &greyc_mask_desc
--};
--
--/* Package of functions.
-- */
--im_package im__cimg = {
--      "cimg",
--      IM_NUMBER( function_list ),
--      function_list
--};
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/CImg.h vips-7.38.5/libvips/cimg/CImg.h
---- vips-7.38.5-vanilla/libvips/cimg/CImg.h    2014-07-17 23:48:36.230794473 -0400
-+++ vips-7.38.5/libvips/cimg/CImg.h    1969-12-31 19:00:00.000000000 -0500
-@@ -1,22228 +0,0 @@
--/*
-- #
-- #  File        : CImg.h
-- #
-- #  Description : The C++ Template Image Processing Library
-- #                ( http://cimg.sourceforge.net )
-- #
-- #  Copyright   : David Tschumperle
-- #                ( http://www.greyc.ensicaen.fr/~dtschump/ )
-- #
-- #  License     : CeCILL-C
-- #
-- #  This software is governed by the CeCILL-C license under French law and
-- #  abiding by the rules of distribution of free software.  You can  use,
-- #  modify and or redistribute the software under the terms of the CeCILL-C
-- #  license as circulated by CEA, CNRS and INRIA at the following URL
-- #  "http://www.cecill.info".
-- #
-- #  As a counterpart to the access to the source code and  rights to copy,
-- #  modify and redistribute granted by the license, users are provided only
-- #  with a limited warranty  and the software's author,  the holder of the
-- #  economic rights,  and the successive licensors  have only  limited
-- #  liability.
-- #
-- #  In this respect, the user's attention is drawn to the risks associated
-- #  with loading,  using,  modifying and/or developing or reproducing the
-- #  software by the user in light of its specific status of free software,
-- #  that may mean  that it is complicated to manipulate,  and  that  also
-- #  therefore means  that it is reserved for developers  and  experienced
-- #  professionals having in-depth computer knowledge. Users are therefore
-- #  encouraged to load and test the software's suitability as regards their
-- #  requirements in conditions enabling the security of their systems and/or
-- #  data to be ensured and,  more generally, to use and operate it in the
-- #  same conditions as regards security.
-- #
-- #  The fact that you are presently reading this means that you have had
-- #  knowledge of the CeCILL-C license and that you accept its terms.
-- #
-- */
--#ifndef cimg_version
--#define cimg_version 1.20
--
--// Detect Microsoft VC++ 6.0 compiler to get some workarounds afterwards.
--#if defined(_MSC_VER) && _MSC_VER<1300
--#define cimg_use_visualcpp6
--#endif
--
--// Avoid strange 'deprecated' warning messages with Visual C++ .NET.
--#if defined(_MSC_VER) && _MSC_VER>=1300
--#define _CRT_SECURE_NO_DEPRECATE 1
--#define _CRT_NONSTDC_NO_DEPRECATE 1
--#endif
--
--// Standard C++ includes.
--#include <cstdio>
--#include <cstdlib>
--#include <cstdarg>
--#include <cstring>
--#include <cmath>
--#include <ctime>
--
--// Overcome VisualC++ 6.0 compilers namespace 'std::' bug.
--#ifdef cimg_use_visualcpp6
--#define std
--#endif
--
--/*
-- #
-- # Set CImg configuration flags.
-- #
-- # If compilation flags are not adapted to your system,
-- # you may override their values, before including
-- # the header file "CImg.h" (use the #define directive).
-- #
-- */
--
--// Try to detect the current system and set value of 'cimg_OS'.
--#ifndef cimg_OS
--#if defined(sun)         || defined(__sun)      || defined(linux)       || defined(__linux) \
-- || defined(__linux__)   || defined(__CYGWIN__) || defined(BSD)         || defined(__FreeBSD__) \
-- || defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__)   || defined(sgi) \
-- || defined(__sgi)
--// Unix-like (Linux, Solaris, BSD, MacOSX, Irix,...).
--#define cimg_OS            1
--#ifndef cimg_display_type
--#define cimg_display_type  1
--#endif
--#ifndef cimg_color_terminal
--#define cimg_color_terminal
--#endif
--#elif defined(_WIN32) || defined(__WIN32__)
--// Windows.
--#define cimg_OS            2
--#ifndef cimg_display_type
--#define cimg_display_type  2
--#endif
--#else
--// Unknown configuration : ask for minimal dependencies (no display).
--#define cimg_OS            0
--#ifndef cimg_display_type
--#define cimg_display_type  0
--#endif
--#endif
--#endif
--
--// Debug configuration.
--//
--// Set 'cimg_debug' to : 0 to remove debug messages (exceptions are still thrown anyway).
--//                       1 to display debug messages on standard error output (console).
--//                       2 to display debug messages with modal windows (default behavior).
--//                       3 to do as 2 + add extra memory access warnings (may slow down the code)
--#ifndef cimg_debug
--#define cimg_debug         2
--#endif
--
--// Allow compatibility with older CImg versions.
--//
--// Define 'cimg_strict' to avoid keeping the compatibility with older code
--#ifndef cimg_strict
--#define CImgl CImgList
--#define cimgl_map cimglist_for
--#define cimglist_map cimglist_for
--#define cimg_map cimg_for
--#define cimg_mapoff cimg_foroff
--#define cimg_mapX cimg_forX
--#define cimg_mapY cimg_forY
--#define cimg_mapZ cimg_forZ
--#define cimg_mapV cimg_forV
--#define cimg_mapXY cimg_forXY
--#define cimg_mapXZ cimg_forXZ
--#define cimg_mapXV cimg_forXV
--#define cimg_mapYZ cimg_forYZ
--#define cimg_mapYV cimg_forYV
--#define cimg_mapZV cimg_forZV
--#define cimg_mapXYZ cimg_forXYZ
--#define cimg_mapXYV cimg_forXYV
--#define cimg_mapXZV cimg_forXZV
--#define cimg_mapYZV cimg_forYZV
--#define cimg_mapXYZV cimg_forXYZV
--#define cimg_imapX cimg_for_insideX
--#define cimg_imapY cimg_for_insideY
--#define cimg_imapZ cimg_for_insideZ
--#define cimg_imapV cimg_for_insideV
--#define cimg_imapXY cimg_for_insideXY
--#define cimg_imapXYZ cimg_for_insideXYZ
--#define cimg_bmapX cimg_for_borderX
--#define cimg_bmapY cimg_for_borderY
--#define cimg_bmapZ cimg_for_borderZ
--#define cimg_bmapV cimg_for_borderV
--#define cimg_bmapXY cimg_for_borderXY
--#define cimg_bmapXYZ cimg_for_borderXYZ
--#define cimg_2mapX cimg_for2X
--#define cimg_2mapY cimg_for2Y
--#define cimg_2mapZ cimg_for2Z
--#define cimg_2mapXY cimg_for2XY
--#define cimg_2mapXZ cimg_for2XZ
--#define cimg_2mapYZ cimg_for2YZ
--#define cimg_2mapXYZ cimg_for2XYZ
--#define cimg_3mapX cimg_for3X
--#define cimg_3mapY cimg_for3Y
--#define cimg_3mapZ cimg_for3Z
--#define cimg_3mapXY cimg_for3XY
--#define cimg_3mapXZ cimg_for3XZ
--#define cimg_3mapYZ cimg_for3YZ
--#define cimg_3mapXYZ cimg_for3XYZ
--#define cimg_4mapX cimg_for4X
--#define cimg_4mapY cimg_for4Y
--#define cimg_4mapZ cimg_for4Z
--#define cimg_4mapXY cimg_for4XY
--#define cimg_4mapXZ cimg_for4XZ
--#define cimg_4mapYZ cimg_for4YZ
--#define cimg_4mapXYZ cimg_for4XYZ
--#define cimg_5mapX cimg_for5X
--#define cimg_5mapY cimg_for5Y
--#define cimg_5mapZ cimg_for5Z
--#define cimg_5mapXY cimg_for5XY
--#define cimg_5mapXZ cimg_for5XZ
--#define cimg_5mapYZ cimg_for5YZ
--#define cimg_5mapXYZ cimg_for5XYZ
--#define cimg_map2x2x1 cimg_for2x2
--#define cimg_map3x3x1 cimg_for3x3
--#define cimg_map4x4x1 cimg_for4x4
--#define cimg_map5x5x1 cimg_for5x5
--#define cimg_map2x2 cimg_for2x2
--#define cimg_map3x3 cimg_for3x3
--#define cimg_map4x4 cimg_for4x4
--#define cimg_map5x5 cimg_for5x5
--#define cimg_map3x3x3 cimg_for3x3x3
--#define cimg_map2x2x2 cimg_for2x2x2
--#define CImg_2x2x1 CImg_2x2
--#define CImg_3x3x1 CImg_3x3
--#define CImg_4x4x1 CImg_4x4
--#define CImg_5x5x1 CImg_5x5
--#define scroll translate
--#define cimg_convert_path cimg_imagemagick_path
--#define load_convert load_imagemagick
--#define save_convert save_imagemagick
--#endif
--
--// Architecture-dependent includes.
--#if cimg_OS==1
--#include <sys/time.h>
--#include <unistd.h>
--#elif cimg_OS==2
--#include <windows.h>
--// Discard unuseful macros in windows.h
--// to allow compilation with VC++ 6.0.
--#ifdef min
--#undef min
--#undef max
--#undef abs
--#endif
--#endif
--// Display-dependent includes.
--#if cimg_display_type==1
--#include <X11/Xlib.h>
--#include <X11/Xutil.h>
--#include <X11/keysym.h>
--#include <pthread.h>
--#ifdef cimg_use_xshm
--#include <sys/ipc.h>
--#include <sys/shm.h>
--#include <X11/extensions/XShm.h>
--#endif
--#ifdef cimg_use_xrandr
--#include <X11/extensions/Xrandr.h>
--#endif
--#endif
--
--// Configuration for native PNG and JPEG support
--//
--// Define 'cimg_use_png', 'cimg_use_jpeg' or 'cimg_use_tiff' to enable native PNG, JPEG or TIFF files support.
--// This requires you link your code with the zlib/png, jpeg or tiff libraries.
--// Without these libraries, PNG,JPEG and TIFF support will be done by the Image Magick's 'convert' tool,
--// or byt the GraphicsMagick 'gm' tool if installed
--// (this is the case on most unix plateforms).
--#ifdef cimg_use_png
--extern "C" {
--#include "png.h"
--}
--#endif
--#ifdef cimg_use_jpeg
--extern "C" {
--#include "jpeglib.h"
--}
--#endif
--#ifdef cimg_use_tiff
--extern "C" {
--#include "tiffio.h"
--}
--#endif
--#ifdef cimg_use_magick
--#include "Magick++.h"
--#endif
--#ifdef cimg_use_fftw3
--extern "C" {
--#include "fftw3.h"
--}
--#endif
--
--/*
-- #
-- #
-- # Define some useful macros. Macros of the CImg Library are prefixed by 'cimg_'
-- # Documented macros below may be safely used in your own code
-- # (particularly useful for option parsing, image loops and neighborhoods).
-- #
-- #
-- */
--
--// Macros used to describe the program usage, and retrieve command line arguments
--// (See corresponding module 'Retrieving command line arguments' in the generated documentation).
--#define cimg_usage(usage) cimg_library::cimg::option((char*)0,argc,argv,(char*)0,usage)
--#define cimg_help(str)    cimg_library::cimg::option((char*)0,argc,argv,str,(char*)0)
--#define cimg_option(name,defaut,usage) cimg_library::cimg::option(name,argc,argv,defaut,usage)
--
--// Macros used for neighborhood definitions and manipulations.
--// (see module 'Using Image Loops' in the generated documentation).
--#define CImg_2(I,T)   T   I##cc,I##nc=0
--#define CImg_2x2(I,T) T   I##cc,I##nc=0,I##cn,I##nn=0
--#define CImg_3(I,T)   T   I##pp,I##cp,I##np=0
--#define CImg_3x3(I,T) T   I##pp,I##cp,I##np=0,I##pc,I##cc,I##nc=0,I##pn,I##cn,I##nn=0
--#define CImg_4(I,T)   T   I##pp,I##cp,I##np=0,I##ap=0
--#define CImg_4x4(I,T) T   I##pp,I##cp,I##np=0,I##ap=0, \
--                          I##pc,I##cc,I##nc=0,I##ac=0, \
--                          I##pn,I##cn,I##nn=0,I##an=0, \
--                          I##pa,I##ca,I##na=0,I##aa=0
--#define CImg_5(I,T)   T   I##bb,I##pb,I##cb,I##nb=0,I##ab=0
--#define CImg_5x5(I,T) T   I##bb,I##pb,I##cb,I##nb=0,I##ab=0, \
--                          I##bp,I##pp,I##cp,I##np=0,I##ap=0, \
--                          I##bc,I##pc,I##cc,I##nc=0,I##ac=0, \
--                          I##bn,I##pn,I##cn,I##nn=0,I##an=0, \
--                          I##ba,I##pa,I##ca,I##na=0,I##aa=0
--#define CImg_2x2x2(I,T) T I##ccc,I##ncc=0,I##cnc,I##nnc=0, \
--                          I##ccn,I##ncn=0,I##cnn,I##nnn=0
--#define CImg_3x3x3(I,T) T I##ppp,I##cpp,I##npp=0,I##pcp,I##ccp,I##ncp=0,I##pnp,I##cnp,I##nnp=0, \
--                          I##ppc,I##cpc,I##npc=0,I##pcc,I##ccc,I##ncc=0,I##pnc,I##cnc,I##nnc=0, \
--                          I##ppn,I##cpn,I##npn=0,I##pcn,I##ccn,I##ncn=0,I##pnn,I##cnn,I##nnn=0
--
--#define CImg_2x2_ref(I,T,tab)   T &I##cc=(tab)[0],&I##nc=(tab)[1],&I##cn=(tab)[2],&I##nn=(tab)[3]
--#define CImg_3x3_ref(I,T,tab)   T &I##pp=(tab)[0],&I##cp=(tab)[1],&I##np=(tab)[2], \
--                                  &I##pc=(tab)[3],&I##cc=(tab)[4],&I##nc=(tab)[5], \
--                                  &I##pn=(tab)[6],&I##cn=(tab)[7],&I##nn=(tab)[8]
--#define CImg_4x4_ref(I,T,tab)   T &I##pp=(tab)[0],&I##cp=(tab)[1],&I##np=(tab)[2],&I##ap=(tab)[3], \
--                                  &I##pc=(tab)[4],&I##cc=(tab)[5],&I##nc=(tab)[6],&I##ap=(tab)[7], \
--                                  &I##pn=(tab)[8],&I##cn=(tab)[9],&I##nn=(tab)[10],&I##aa=(tab)[11], \
--                                  &I##pa=(tab)[12],&I##ca=(tab)[13],&I##na=(tab)[14],&I##aa=(tab)[15]
--#define CImg_5x5_ref(I,T,tab)   T &I##bb=(tab)[0],&I##pb=(tab)[1],&I##cb=(tab)[2],&I##nb=(tab)[3],&I##ab=(tab)[4], \
--                                  &I##bp=(tab)[5],&I##pp=(tab)[6],&I##cp=(tab)[7],&I##np=(tab)[8],&I##ap=(tab)[9], \
--                                  &I##bc=(tab)[10],&I##pc=(tab)[11],&I##cc=(tab)[12],&I##nc=(tab)[13],&I##ac=(tab)[14], \
--                                  &I##bn=(tab)[15],&I##pn=(tab)[16],&I##cn=(tab)[17],&I##nn=(tab)[18],&I##an=(tab)[19], \
--                                  &I##ba=(tab)[20],&I##pa=(tab)[21],&I##ca=(tab)[22],&I##na=(tab)[23],&I##aa=(tab)[24]
--#define CImg_2x2x2_ref(I,T,tab) T &I##ccc=(tab)[0],&I##ncc=(tab)[1],&I##cnc=(tab)[2],&I##nnc=(tab)[3], \
--                                  &I##ccn=(tab)[4],&I##ncn=(tab)[5],&I##cnn=(tab)[6],&I##nnn=(tab)[7]
--#define CImg_3x3x3_ref(I,T,tab) T &I##ppp=(tab)[0],&I##cpp=(tab)[1],&I##npp=(tab)[2], \
--                                  &I##pcp=(tab)[3],&I##ccp=(tab)[4],&I##ncp=(tab)[5], \
--                                  &I##pnp=(tab)[6],&I##cnp=(tab)[7],&I##nnp=(tab)[8], \
--                                  &I##ppc=(tab)[9],&I##cpc=(tab)[10],&I##npc=(tab)[11], \
--                                  &I##pcc=(tab)[12],&I##ccc=(tab)[13],&I##ncc=(tab)[14], \
--                                  &I##pnc=(tab)[15],&I##cnc=(tab)[16],&I##nnc=(tab)[17], \
--                                  &I##ppn=(tab)[18],&I##cpn=(tab)[19],&I##npn=(tab)[20], \
--                                  &I##pcn=(tab)[21],&I##ccn=(tab)[22],&I##ncn=(tab)[23], \
--                                  &I##pnn=(tab)[24],&I##cnn=(tab)[25],&I##nnn=(tab)[26]
--
--#define cimg_copy2x2(J,I)   I##cc=J##cc, I##nc=J##nc, I##cn=J##cn, I##nn=J##nn
--#define cimg_copy3x3(J,I)   I##pp=J##pp, I##cp=J##cp, I##np=J##np, \
--                            I##pc=J##pc, I##cc=J##cc, I##nc=J##nc, \
--                            I##pn=J##pn, I##cn=J##cn, I##nn=J##nn
--#define cimg_copy5x5(J,I)   I##bb=J##bb, I##pb=J##pb, I##cb=J##cb, I##nb=J##nb, I##ab=J##ab, \
--                            I##bp=J##bp, I##pp=J##pp, I##cp=J##cp, I##np=J##np, I##ap=J##ap, \
--                            I##bc=J##bc, I##pc=J##pc, I##cc=J##cc, I##nc=J##nc, I##ac=J##ac, \
--                            I##bn=J##bn, I##pn=J##pn, I##cn=J##cn, I##nn=J##nn, I##an=J##an, \
--                            I##ba=J##ba, I##pa=J##pa, I##ca=J##ca, I##na=J##na, I##aa=J##aa
--
--#define cimg_squaresum2x2(I)   ( I##cc*I##cc + I##nc*I##nc + I##cn*I##cn + I##nn*I##nn )
--#define cimg_squaresum3x3(I)   ( I##pp*I##pp + I##cp*I##cp + I##np*I##np + \
--                                 I##pc*I##pc + I##cc*I##cc + I##nc*I##nc + \
--                                 I##pn*I##pn + I##cn*I##cn + I##nn*I##nn )
--#define cimg_squaresum4x4(I)   ( I##pp*I##pp + I##cp*I##cp + I##np*I##np + I##ap*I##ap + \
--                                 I##pc*I##pc + I##cc*I##cc + I##nc*I##nc + I##ac*I##ac + \
--                                 I##pn*I##pn + I##cn*I##cn + I##nn*I##nn + I##an*I##an + \
--                                 I##pa*I##pa + I##ca*I##ca + I##na*I##na + I##aa*I##aa )
--#define cimg_squaresum5x5(I)   ( I##bb*I##bb + I##pb*I##pb + I##cb*I##cb + I##nb*I##nb + I##ab*I##ab + \
--                                 I##bp*I##bp + I##pp*I##pp + I##cp*I##cp + I##np*I##np + I##ap*I##ap + \
--                                 I##bc*I##bc + I##pc*I##pc + I##cc*I##cc + I##nc*I##nc + I##ac*I##ac + \
--                                 I##bn*I##bn + I##pn*I##pn + I##cn*I##cn + I##nn*I##nn + I##an*I##an + \
--                                 I##ba*I##ba + I##pa*I##pa + I##ca*I##ca + I##na*I##na + I##aa*I##aa )
--#define cimg_squaresum2x2x2(I) ( I##ccc*I##ccc + I##ncc*I##ncc + I##cnc*I##cnc + I##nnc*I##nnc + \
--                                 I##ccn*I##ccn + I##ncn*I##ncn + I##cnn*I##cnn + I##nnn*I##nnn )
--#define cimg_squaresum3x3x3(I) ( I##ppp*I##ppp + I##cpp*I##cpp + I##npp*I##npp + \
--                                 I##pcp*I##pcp + I##ccp*I##ccp + I##ncp*I##ncp + \
--                                 I##pnp*I##pnp + I##cnp*I##cnp + I##nnp*I##nnp + \
--                                 I##ppc*I##ppc + I##cpc*I##cpc + I##npc*I##npc + \
--                                 I##pcc*I##pcc + I##ccc*I##ccc + I##ncc*I##ncc + \
--                                 I##pnc*I##pnc + I##cnc*I##cnc + I##nnc*I##nnc + \
--                                 I##ppn*I##ppn + I##cpn*I##cpn + I##npn*I##npn + \
--                                 I##pcn*I##pcn + I##ccn*I##ccn + I##ncn*I##ncn + \
--                                 I##pnn*I##pnn + I##cnn*I##cnn + I##nnn*I##nnn )
--
--#define cimg_corr2x2(I,m)   ( I##cc*(m)(0,0)+I##nc*(m)(1,0)+I##cn*(m)(0,1)+I##nn*(m)(1,1) )
--#define cimg_corr3x3(I,m)   ( I##pp*(m)(0,0)+I##cp*(m)(1,0)+I##np*(m)(2,0) + \
--                              I##pc*(m)(0,1)+I##cc*(m)(1,1)+I##nc*(m)(2,1) + \
--                              I##pn*(m)(0,2)+I##cn*(m)(1,2)+I##nn*(m)(2,2) )
--#define cimg_corr4x4(I,m)   ( I##pp*(m)(0,0)+I##cp*(m)(1,0)+I##np*(m)(2,0)+I##ap*(m)(3,0) + \
--                              I##pc*(m)(0,1)+I##cc*(m)(1,1)+I##nc*(m)(2,1)+I##ac*(m)(3,1) + \
--                              I##pn*(m)(0,2)+I##cn*(m)(1,2)+I##nn*(m)(2,2)+I##an*(m)(3,2) + \
--                              I##pa*(m)(0,3)+I##ca*(m)(1,3)+I##na*(m)(2,3)+I##aa*(m)(3,3) )
--#define cimg_corr5x5(I,m)   ( I##bb*(m)(0,0)+I##pb*(m)(1,0)+I##cb*(m)(2,0)+I##nb*(m)(3,0)+I##ab*(m)(4,0) + \
--                              I##bp*(m)(0,1)+I##pp*(m)(1,1)+I##cp*(m)(2,1)+I##np*(m)(3,1)+I##ap*(m)(4,1) + \
--                              I##bc*(m)(0,2)+I##pc*(m)(1,2)+I##cc*(m)(2,2)+I##nc*(m)(3,2)+I##ac*(m)(4,2) + \
--                              I##bn*(m)(0,3)+I##pn*(m)(1,3)+I##cn*(m)(2,3)+I##nn*(m)(3,3)+I##an*(m)(4,3) + \
--                              I##ba*(m)(0,4)+I##pa*(m)(1,4)+I##ca*(m)(2,4)+I##na*(m)(3,4)+I##aa*(m)(4,4) )
--#define cimg_corr2x2x2(I,m) ( I##ccc*(m)(0,0,0)+I##ncc*(m)(1,0,0)+I##cnc*(m)(0,1,0)+I##nnc*(m)(1,1,0) + \
--                              I##ccn*(m)(0,0,1)+I##ncn*(m)(1,0,1)+I##cnn*(m)(0,1,1)+I##nnn*(m)(1,1,1) )
--#define cimg_corr3x3x3(I,m) ( I##ppp*(m)(0,0,0)+I##cpp*(m)(1,0,0)+I##npp*(m)(2,0,0) + \
--                              I##pcp*(m)(0,1,0)+I##ccp*(m)(1,1,0)+I##ncp*(m)(2,1,0) + \
--                              I##pnp*(m)(0,2,0)+I##cnp*(m)(1,2,0)+I##nnp*(m)(2,2,0) + \
--                              I##ppc*(m)(0,0,1)+I##cpc*(m)(1,0,1)+I##npc*(m)(2,0,1) + \
--                              I##pcc*(m)(0,1,1)+I##ccc*(m)(1,1,1)+I##ncc*(m)(2,1,1) + \
--                              I##pnc*(m)(0,2,1)+I##cnc*(m)(1,2,1)+I##nnc*(m)(2,2,1) + \
--                              I##ppn*(m)(0,0,2)+I##cpn*(m)(1,0,2)+I##npn*(m)(2,0,2) + \
--                              I##pcn*(m)(0,1,2)+I##ccn*(m)(1,1,2)+I##ncn*(m)(2,1,2) + \
--                              I##pnn*(m)(0,2,2)+I##cnn*(m)(1,2,2)+I##nnn*(m)(2,2,2) )
--
--#define cimg_conv2x2(I,m)   ( I##cc*(m)(1,1)+I##nc*(m)(0,1)+I##cn*(m)(1,0)+I##nn*(m)(0,0) )
--#define cimg_conv3x3(I,m)   ( I##pp*(m)(2,2)+I##cp*(m)(1,2)+I##np*(m)(0,2) + \
--                              I##pc*(m)(2,1)+I##cc*(m)(1,1)+I##nc*(m)(0,1) + \
--                              I##pn*(m)(2,0)+I##cn*(m)(1,0)+I##nn*(m)(0,0) )
--#define cimg_conv4x4(I,m)   ( I##pp*(m)(3,3)+I##cp*(m)(2,3)+I##np*(m)(1,3)+I##ap*(m)(0,3) + \
--                              I##pc*(m)(3,2)+I##cc*(m)(2,2)+I##nc*(m)(1,2)+I##ac*(m)(0,2) + \
--                              I##pn*(m)(3,1)+I##cn*(m)(2,1)+I##nn*(m)(1,1)+I##an*(m)(0,1) + \
--                              I##pa*(m)(3,0)+I##ca*(m)(2,0)+I##na*(m)(1,0)+I##aa*(m)(0,0) )
--#define cimg_conv5x5(I,m)   ( I##bb*(m)(4,4)+I##pb*(m)(3,4)+I##cb*(m)(2,4)+I##nb*(m)(1,4)+I##ab*(m)(0,4) + \
--                              I##bp*(m)(4,3)+I##pp*(m)(3,3)+I##cp*(m)(2,3)+I##np*(m)(1,3)+I##ap*(m)(0,3) + \
--                              I##bc*(m)(4,2)+I##pc*(m)(3,2)+I##cc*(m)(2,2)+I##nc*(m)(1,2)+I##ac*(m)(0,2) + \
--                              I##bn*(m)(4,1)+I##pn*(m)(3,1)+I##cn*(m)(2,1)+I##nn*(m)(1,1)+I##an*(m)(0,1) + \
--                              I##ba*(m)(4,0)+I##pa*(m)(3,0)+I##ca*(m)(2,0)+I##na*(m)(1,0)+I##aa*(m)(0,0) )
--#define cimg_conv2x2x2(I,m) ( I##ccc*(m)(1,1,1)+I##ncc*(m)(0,1,1)+I##cnc*(m)(1,0,1)+I##nnc*(m)(0,0,1) + \
--                              I##ccn*(m)(1,1,0)+I##ncn*(m)(0,1,0)+I##cnn*(m)(1,0,0)+I##nnn*(m)(0,0,0) )
--#define cimg_conv3x3x3(I,m) ( I##ppp*(m)(2,2,2)+I##cpp*(m)(1,2,2)+I##npp*(m)(0,2,2) + \
--                              I##pcp*(m)(2,1,2)+I##ccp*(m)(1,1,2)+I##ncp*(m)(0,1,2) + \
--                              I##pnp*(m)(2,0,2)+I##cnp*(m)(1,0,2)+I##nnp*(m)(0,0,2) + \
--                              I##ppc*(m)(2,2,1)+I##cpc*(m)(1,2,1)+I##npc*(m)(0,2,1) + \
--                              I##pcc*(m)(2,1,1)+I##ccc*(m)(1,1,1)+I##ncc*(m)(0,1,1) + \
--                              I##pnc*(m)(2,0,1)+I##cnc*(m)(1,0,1)+I##nnc*(m)(0,0,1) + \
--                              I##ppn*(m)(2,2,0)+I##cpn*(m)(1,2,0)+I##npn*(m)(0,2,0) + \
--                              I##pcn*(m)(2,1,0)+I##ccn*(m)(1,1,0)+I##ncn*(m)(0,1,0) + \
--                              I##pnn*(m)(2,0,0)+I##cnn*(m)(1,0,0)+I##nnn*(m)(0,0,0) )
--
--#define cimg_get2x2(img,x,y,z,v,I) \
--   I##cc=(img)(x,    y,z,v), I##nc=(img)(_n##x,    y,z,v), \
--   I##cn=(img)(x,_n##y,z,v), I##nn=(img)(_n##x,_n##y,z,v)
--#define cimg_get3x3(img,x,y,z,v,I) \
--  I##pp=(img)(_p##x,_p##y,z,v), I##cp=(img)(x,_p##y,z,v), I##np=(img)(_n##x,_p##y,z,v), \
--  I##pc=(img)(_p##x,    y,z,v), I##cc=(img)(x,    y,z,v), I##nc=(img)(_n##x,    y,z,v), \
--  I##pn=(img)(_p##x,_n##y,z,v), I##cn=(img)(x,_n##y,z,v), I##nn=(img)(_n##x,_n##y,z,v)
--#define cimg_get4x4(img,x,y,z,v,I) \
--  I##pp=(img)(_p##x,_p##y,z,v), I##cp=(img)(x,_p##y,z,v), I##np=(img)(_n##x,_p##y,z,v), I##ap=(img)(_a##x,_p##y,z,v), \
--  I##pc=(img)(_p##x,    y,z,v), I##cc=(img)(x,    y,z,v), I##nc=(img)(_n##x,    y,z,v), I##ac=(img)(_a##x,    y,z,v), \
--  I##pn=(img)(_p##x,_n##y,z,v), I##cn=(img)(x,_n##y,z,v), I##nn=(img)(_n##x,_n##y,z,v), I##an=(img)(_a##x,_n##y,z,v), \
--  I##pa=(img)(_p##x,_a##y,z,v), I##ca=(img)(x,_a##y,z,v), I##na=(img)(_n##x,_a##y,z,v), I##aa=(img)(_a##x,_a##y,z,v)
--#define cimg_get5x5(img,x,y,z,v,I) \
--  I##bb=(img)(_b##x,_b##y,z,v), I##pb=(img)(_p##x,_b##y,z,v), I##cb=(img)(x,_b##y,z,v), I##nb=(img)(_n##x,_b##y,z,v), I##ab=(img)(_a##x,_b##y,z,v), \
--  I##bp=(img)(_b##x,_p##y,z,v), I##pp=(img)(_p##x,_p##y,z,v), I##cp=(img)(x,_p##y,z,v), I##np=(img)(_n##x,_p##y,z,v), I##ap=(img)(_a##x,_p##y,z,v), \
--  I##bc=(img)(_b##x,    y,z,v), I##pc=(img)(_p##x,    y,z,v), I##cc=(img)(x,    y,z,v), I##nc=(img)(_n##x,    y,z,v), I##ac=(img)(_a##x,    y,z,v), \
--  I##bn=(img)(_b##x,_n##y,z,v), I##pn=(img)(_p##x,_n##y,z,v), I##cn=(img)(x,_n##y,z,v), I##nn=(img)(_n##x,_n##y,z,v), I##an=(img)(_a##x,_n##y,z,v), \
--  I##ba=(img)(_b##x,_a##y,z,v), I##pa=(img)(_p##x,_a##y,z,v), I##ca=(img)(x,_a##y,z,v), I##na=(img)(_n##x,_a##y,z,v), I##aa=(img)(_a##x,_a##y,z,v)
--#define cimg_get2x2x2(img,x,y,z,v,I) \
--  I##ccc=(img)(x,y,    z,v), I##ncc=(img)(_n##x,y,    z,v), I##cnc=(img)(x,_n##y,    z,v), I##nnc=(img)(_n##x,_n##y,    z,v), \
--  I##ccc=(img)(x,y,_n##z,v), I##ncc=(img)(_n##x,y,_n##z,v), I##cnc=(img)(x,_n##y,_n##z,v), I##nnc=(img)(_n##x,_n##y,_n##z,v)
--#define cimg_get3x3x3(img,x,y,z,v,I) \
--  I##ppp=(img)(_p##x,_p##y,_p##z,v), I##cpp=(img)(x,_p##y,_p##z,v), I##npp=(img)(_n##x,_p##y,_p##z,v), \
--  I##pcp=(img)(_p##x,    y,_p##z,v), I##ccp=(img)(x,    y,_p##z,v), I##ncp=(img)(_n##x,    y,_p##z,v), \
--  I##pnp=(img)(_p##x,_n##y,_p##z,v), I##cnp=(img)(x,_n##y,_p##z,v), I##nnp=(img)(_n##x,_n##y,_p##z,v), \
--  I##ppc=(img)(_p##x,_p##y,    z,v), I##cpc=(img)(x,_p##y,    z,v), I##npc=(img)(_n##x,_p##y,    z,v), \
--  I##pcc=(img)(_p##x,    y,    z,v), I##ccc=(img)(x,    y,    z,v), I##ncc=(img)(_n##x,    y,    z,v), \
--  I##pnc=(img)(_p##x,_n##y,    z,v), I##cnc=(img)(x,_n##y,    z,v), I##nnc=(img)(_n##x,_n##y,    z,v), \
--  I##ppn=(img)(_p##x,_p##y,_n##z,v), I##cpn=(img)(x,_p##y,_n##z,v), I##npn=(img)(_n##x,_p##y,_n##z,v), \
--  I##pcn=(img)(_p##x,    y,_n##z,v), I##ccn=(img)(x,    y,_n##z,v), I##ncn=(img)(_n##x,    y,_n##z,v), \
--  I##pnn=(img)(_p##x,_n##y,_n##z,v), I##cnn=(img)(x,_n##y,_n##z,v), I##nnn=(img)(_n##x,_n##y,_n##z,v)
--
--// Macros used to define special image loops.
--// (see module 'Using Image Loops' in the generated documentation).
--#define cimg_for(img,ptr,T_ptr)   for (T_ptr *ptr=(img).data+(img).size(); (ptr--)>(img).data; )
--#define cimglist_for(list,l)      for (unsigned int l=0; l<(list).size; l++)
--#define cimglist_apply(list,fn)   cimglist_for(list,__##fn) (list)[__##fn].fn
--#define cimg_foroff(img,off)      for (unsigned int off=0; off<(img).size(); off++)
--#define cimg_forX(img,x)          for (int x=0; x<(int)((img).width); x++)
--#define cimg_forY(img,y)          for (int y=0; y<(int)((img).height);y++)
--#define cimg_forZ(img,z)          for (int z=0; z<(int)((img).depth); z++)
--#define cimg_forV(img,v)          for (int v=0; v<(int)((img).dim);   v++)
--#define cimg_forXY(img,x,y)       cimg_forY(img,y) cimg_forX(img,x)
--#define cimg_forXZ(img,x,z)       cimg_forZ(img,z) cimg_forX(img,x)
--#define cimg_forYZ(img,y,z)       cimg_forZ(img,z) cimg_forY(img,y)
--#define cimg_forXV(img,x,v)       cimg_forV(img,v) cimg_forX(img,x)
--#define cimg_forYV(img,y,v)       cimg_forV(img,v) cimg_forY(img,y)
--#define cimg_forZV(img,z,v)       cimg_forV(img,v) cimg_forZ(img,z)
--#define cimg_forXYZ(img,x,y,z)    cimg_forZ(img,z) cimg_forXY(img,x,y)
--#define cimg_forXYV(img,x,y,v)    cimg_forV(img,v) cimg_forXY(img,x,y)
--#define cimg_forXZV(img,x,z,v)    cimg_forV(img,v) cimg_forXZ(img,x,z)
--#define cimg_forYZV(img,y,z,v)    cimg_forV(img,v) cimg_forYZ(img,y,z)
--#define cimg_forXYZV(img,x,y,z,v) cimg_forV(img,v) cimg_forXYZ(img,x,y,z)
--#define cimg_for_insideX(img,x,n)       for (int x=(n); x<(int)((img).width-(n)); x++)
--#define cimg_for_insideY(img,y,n)       for (int y=(n); y<(int)((img).height-(n)); y++)
--#define cimg_for_insideZ(img,z,n)       for (int z=(n); z<(int)((img).depth-(n)); z++)
--#define cimg_for_insideV(img,v,n)       for (int v=(n); v<(int)((img).dim-(n)); v++)
--#define cimg_for_insideXY(img,x,y,n)    cimg_for_insideY(img,y,n) cimg_for_insideX(img,x,n)
--#define cimg_for_insideXYZ(img,x,y,z,n) cimg_for_insideZ(img,z,n) cimg_for_insideXY(img,x,y,n)
--#define cimg_for_borderX(img,x,n)       for (int x=0; x<(int)((img).width);  x==(n)-1?(x=(img).width-(n)): x++)
--#define cimg_for_borderY(img,y,n)       for (int y=0; y<(int)((img).height); y==(n)-1?(x=(img).height-(n)):y++)
--#define cimg_for_borderZ(img,z,n)       for (int z=0; z<(int)((img).depth);  z==(n)-1?(x=(img).depth-(n)): z++)
--#define cimg_for_borderV(img,v,n)       for (int v=0; v<(int)((img).dim);    v==(n)-1?(x=(img).dim-(n)):   v++)
--#define cimg_for_borderXY(img,x,y,n)    cimg_forY(img,y) for (int x=0; x<(int)((img).width); (y<(n) || y>=(int)((img).height)-(n))?x++: \
--                                                          ((x<(n)-1 || x>=(int)((img).width)-(n))?x++:(x=(img).width-(n))))
--#define cimg_for_borderXYZ(img,x,y,z,n) cimg_forYZ(img,y,z) for (int x=0; x<(int)((img).width); (y<(n) || y>=(int)((img).height)-(n) || z<(n) || z>=(int)((img).depth)-(n))?x++: \
--                                                             ((x<(n)-1 || x>=(int)((img).width)-(n))?x++:(x=(img).width-(n))))
--#define cimg_for2X(img,x)         for (int x=0,_n##x=1; _n##x<(int)((img).width)   || x==--_n##x; x++, _n##x++)
--#define cimg_for2Y(img,y)         for (int y=0,_n##y=1; _n##y<(int)((img).height)  || y==--_n##y; y++, _n##y++)
--#define cimg_for2Z(img,z)         for (int z=0,_n##z=1; _n##z<(int)((img).depth)   || z==--_n##z; z++, _n##z++)
--#define cimg_for2XY(img,x,y)      cimg_for2Y(img,y) cimg_for2X(img,x)
--#define cimg_for2XZ(img,x,z)      cimg_for2Z(img,z) cimg_for2X(img,x)
--#define cimg_for2YZ(img,y,z)      cimg_for2Z(img,z) cimg_for2Y(img,y)
--#define cimg_for2XYZ(img,x,y,z)   cimg_for2Z(img,z) cimg_for2XY(img,x,y)
--#define cimg_for3X(img,x)         for (int x=0,_p##x=0,_n##x=1; _n##x<(int)((img).width)  || x==--_n##x;  _p##x=x++,_n##x++)
--#define cimg_for3Y(img,y)         for (int y=0,_p##y=0,_n##y=1; _n##y<(int)((img).height) || y==--_n##y;  _p##y=y++,_n##y++)
--#define cimg_for3Z(img,z)         for (int z=0,_p##z=0,_n##z=1; _n##z<(int)((img).depth)  || z==--_n##z;  _p##z=z++,_n##z++)
--#define cimg_for3XY(img,x,y)      cimg_for3Y(img,y) cimg_for3X(img,x)
--#define cimg_for3XZ(img,x,z)      cimg_for3Z(img,z) cimg_for3X(img,x)
--#define cimg_for3YZ(img,y,z)      cimg_for3Z(img,z) cimg_for3Y(img,y)
--#define cimg_for3XYZ(img,x,y,z)   cimg_for3Z(img,z) cimg_for3XY(img,x,y)
--#define cimg_for4X(img,x)         for (int _p##x=0,x=0,_n##x=1,_a##x=2; \
--                                       _a##x<(int)((img).width)  || _n##x==--_a##x || x==(_a##x=--_n##x); \
--                                       _p##x=x++,_n##x++,_a##x++)
--#define cimg_for4Y(img,y)         for (int _p##y=0,y=0,_n##y=1,_a##y=2; \
--                                       _a##y<(int)((img).height) || _n##y==--_a##y || y==(_a##y=--_n##y); \
--                                       _p##y=y++,_n##y++,_a##y++)
--#define cimg_for4Z(img,z)         for (int _p##z=0,z=0,_n##z=1,_a##z=2; \
--                                       _a##z<(int)((img).depth)  || _n##z==--_a##z || z==(_a##z=--_n##z); \
--                                       _p##z=z++,_n##z++,_a##z++)
--#define cimg_for4XY(img,x,y)      cimg_for4Y(img,y) cimg_for4X(img,x)
--#define cimg_for4XZ(img,x,z)      cimg_for4Z(img,z) cimg_for4X(img,x)
--#define cimg_for4YZ(img,y,z)      cimg_for4Z(img,z) cimg_for4Y(img,y)
--#define cimg_for4XYZ(img,x,y,z)   cimg_for4Z(img,z) cimg_for4XY(img,x,y)
--#define cimg_for5X(img,x)         for (int _b##x=0,_p##x=0,x=0,_n##x=1,_a##x=2; \
--                                       _a##x<(int)((img).width)  || _n##x==--_a##x || x==(_a##x=--_n##x); \
--                                       _b##x=_p##x,_p##x=x++,_n##x++,_a##x++)
--#define cimg_for5Y(img,y)         for (int _b##y=0,_p##y=0,y=0,_n##y=1,_a##y=2; \
--                                       _a##y<(int)((img).height) || _n##y==--_a##y || y==(_a##y=--_n##y); \
--                                       _b##y=_p##y,_p##y=y++,_n##y++,_a##y++)
--#define cimg_for5Z(img,z)         for (int _b##z=0,_p##z=0,z=0,_n##z=1,_a##z=2; \
--                                       _a##z<(int)((img).depth)  || _n##z==--_a##z || z==(_a##z=--_n##z); \
--                                       _b##z=_p##z,_p##z=z++,_n##z++,_a##z++)
--#define cimg_for5XY(img,x,y)      cimg_for5Y(img,y) cimg_for5X(img,x)
--#define cimg_for5XZ(img,x,z)      cimg_for5Z(img,z) cimg_for5X(img,x)
--#define cimg_for5YZ(img,y,z)      cimg_for5Z(img,z) cimg_for5Y(img,y)
--#define cimg_for5XYZ(img,x,y,z)   cimg_for5Z(img,z) cimg_for5XY(img,x,y)
--
--#define cimg_for2x2(img,x,y,z,v,I) cimg_for2Y(img,y) \
--       for (int _n##x=1, x=(int)((I##cc=(img)(0,    y,z,v)), \
--                                 (I##cn=(img)(0,_n##y,z,v)), \
--                                 0); \
--            (_n##x<(int)((img).width) && ((I##nc=(img)(_n##x,    y,z,v)), \
--                                          (I##nn=(img)(_n##x,_n##y,z,v)), \
--                                          1)) || x==--_n##x; \
--            I##cc=I##nc, I##cn=I##nn, \
--            x++,_n##x++ )
--
--#define cimg_for3x3(img,x,y,z,v,I) cimg_for3Y(img,y) \
--       for (int _n##x=1, _p##x=(int)((I##cp=I##pp=(img)(0,_p##y,z,v)), \
--                                     (I##cc=I##pc=(img)(0,  y,z,v)), \
--                                     (I##cn=I##pn=(img)(0,_n##y,z,v))), \
--                                     x=_p##x=0; \
--            (_n##x<(int)((img).width) && ((I##np=(img)(_n##x,_p##y,z,v)), \
--                                          (I##nc=(img)(_n##x,    y,z,v)), \
--                                          (I##nn=(img)(_n##x,_n##y,z,v)), \
--                                          1)) || x==--_n##x; \
--              I##pp=I##cp, I##pc=I##cc, I##pn=I##cn, \
--              I##cp=I##np, I##cc=I##nc, I##cn=I##nn, \
--              _p##x=x++,_n##x++ )
--
--
--#define cimg_for4x4(img,x,y,z,v,I) cimg_for4Y(img,y) \
--       for (int _a##x=2, _n##x=1, x=(int)((I##cp=I##pp=(img)(0,_p##y,z,v)), \
--                                          (I##cc=I##pc=(img)(0,    y,z,v)), \
--                                          (I##cn=I##pn=(img)(0,_n##y,z,v)), \
--                                          (I##ca=I##pa=(img)(0,_a##y,z,v)), \
--                                          (I##np=(img)(_n##x,_p##y,z,v)), \
--                                          (I##nc=(img)(_n##x,    y,z,v)), \
--                                          (I##nn=(img)(_n##x,_n##y,z,v)), \
--                                          (I##na=(img)(_n##x,_a##y,z,v)), \
--                                          0), _p##x=0; \
--            (_a##x<(int)((img).width) && ((I##ap=(img)(_a##x,_p##y,z,v)), \
--                                          (I##ac=(img)(_a##x,    y,z,v)), \
--                                          (I##an=(img)(_a##x,_n##y,z,v)), \
--                                          (I##aa=(img)(_a##x,_a##y,z,v)), \
--                                          1)) || _n##x==--_a##x || x==(_a##x=--_n##x); \
--              I##pp=I##cp, I##pc=I##cc, I##pn=I##cn, I##pa=I##ca, \
--              I##cp=I##np, I##cc=I##nc, I##cn=I##nn, I##ca=I##na, \
--              I##np=I##ap, I##nc=I##ac, I##nn=I##an, I##na=I##aa, \
--              _p##x=x++, _n##x++, _a##x++ )
--
--#define cimg_for5x5(img,x,y,z,v,I) cimg_for5Y(img,y) \
--       for (int _a##x=2, _n##x=1, _b##x=(int)((I##cb=I##pb=I##bb=(img)(0,_b##y,z,v)), \
--                                              (I##cp=I##pp=I##bp=(img)(0,_p##y,z,v)), \
--                                              (I##cc=I##pc=I##bc=(img)(0,    y,z,v)), \
--                                              (I##cn=I##pn=I##bn=(img)(0,_n##y,z,v)), \
--                                              (I##ca=I##pa=I##ba=(img)(0,_a##y,z,v)), \
--                                              (I##nb=(img)(_n##x,_b##y,z,v)), \
--                                              (I##np=(img)(_n##x,_p##y,z,v)), \
--                                              (I##nc=(img)(_n##x,   y,z,v)), \
--                                              (I##nn=(img)(_n##x,_n##y,z,v)), \
--                                              (I##na=(img)(_n##x,_a##y,z,v))), \
--                                              x=0, _p##x=_b##x=0; \
--            (_a##x<(int)((img).width) && ((I##ab=(img)(_a##x,_b##y,z,v)), \
--                                          (I##ap=(img)(_a##x,_p##y,z,v)), \
--                                          (I##ac=(img)(_a##x,    y,z,v)), \
--                                          (I##an=(img)(_a##x,_n##y,z,v)), \
--                                          (I##aa=(img)(_a##x,_a##y,z,v)), \
--                                          1)) || _n##x==--_a##x || x==(_a##x=--_n##x); \
--              I##bb=I##pb, I##bp=I##pp, I##bc=I##pc, I##bn=I##pn, I##ba=I##pa, \
--              I##pb=I##cb, I##pp=I##cp, I##pc=I##cc, I##pn=I##cn, I##pa=I##ca, \
--              I##cb=I##nb, I##cp=I##np, I##cc=I##nc, I##cn=I##nn, I##ca=I##na, \
--              I##nb=I##ab, I##np=I##ap, I##nc=I##ac, I##nn=I##an, I##na=I##aa, \
--              _b##x=_p##x, _p##x=x++, _n##x++, _a##x++ )
--
--#define cimg_for2x2x2(img,x,y,z,v,I) cimg_for2YZ(img,y,z) \
--       for (int _n##x=1, x=(int)((I##ccc=(img)(0,    y,    z,v)), \
--                                 (I##cnc=(img)(0,_n##y,    z,v)), \
--                                 (I##ccn=(img)(0,    y,_n##z,v)), \
--                                 (I##cnn=(img)(0,_n##y,_n##z,v)), \
--                                 0); \
--            (_n##x<(int)((img).width) && ((I##ncc=(img)(_n##x,    y,    z,v)), \
--                                          (I##nnc=(img)(_n##x,_n##y,    z,v)), \
--                                          (I##ncn=(img)(_n##x,    y,_n##z,v)), \
--                                          (I##nnn=(img)(_n##x,_n##y,_n##z,v)), \
--                                          1)) || x==--_n##x; \
--              I##ccc=I##ncc, I##cnc=I##nnc, \
--              I##ccn=I##ncn, I##cnn=I##nnn, \
--              x++, _n##x++ )
--
--#define cimg_for3x3x3(img,x,y,z,v,I) cimg_for3YZ(img,y,z) \
--       for (int _n##x=1, _p##x=(int)((I##cpp=I##ppp=(img)(0,_p##y,_p##z,v)), \
--                                     (I##ccp=I##pcp=(img)(0,    y,_p##z,v)), \
--                                     (I##cnp=I##pnp=(img)(0,_n##y,_p##z,v)), \
--                                     (I##cpc=I##ppc=(img)(0,_p##y,    z,v)), \
--                                     (I##ccc=I##pcc=(img)(0,    y,    z,v)), \
--                                     (I##cnc=I##pnc=(img)(0,_n##y,    z,v)), \
--                                     (I##cpn=I##ppn=(img)(0,_p##y,_n##z,v)), \
--                                     (I##ccn=I##pcn=(img)(0,    y,_n##z,v)), \
--                                     (I##cnn=I##pnn=(img)(0,_n##y,_n##z,v))),\
--                                     x=_p##x=0; \
--            (_n##x<(int)((img).width) && ((I##npp=(img)(_n##x,_p##y,_p##z,v)), \
--                                          (I##ncp=(img)(_n##x,    y,_p##z,v)), \
--                                          (I##nnp=(img)(_n##x,_n##y,_p##z,v)), \
--                                          (I##npc=(img)(_n##x,_p##y,    z,v)), \
--                                          (I##ncc=(img)(_n##x,    y,    z,v)), \
--                                          (I##nnc=(img)(_n##x,_n##y,    z,v)), \
--                                          (I##npn=(img)(_n##x,_p##y,_n##z,v)), \
--                                          (I##ncn=(img)(_n##x,    y,_n##z,v)), \
--                                          (I##nnn=(img)(_n##x,_n##y,_n##z,v)), \
--                                          1)) || x==--_n##x; \
--              I##ppp=I##cpp, I##pcp=I##ccp, I##pnp=I##cnp, \
--              I##cpp=I##npp, I##ccp=I##ncp, I##cnp=I##nnp, \
--              I##ppc=I##cpc, I##pcc=I##ccc, I##pnc=I##cnc, \
--              I##cpc=I##npc, I##ccc=I##ncc, I##cnc=I##nnc, \
--              I##ppn=I##cpn, I##pcn=I##ccn, I##pnn=I##cnn, \
--              I##cpn=I##npn, I##ccn=I##ncn, I##cnn=I##nnn, \
--              _p##x=x++, _n##x++ )
--
--/*
-- #------------------------------------------------
-- #
-- #
-- #  Definition of the cimg_library:: namespace
-- #
-- #
-- #------------------------------------------------
-- */
--
--//! Namespace that encompasses all classes and functions of the %CImg library.
--/**
--   This namespace is defined to avoid class names collisions that could happen
--   with the include of other C++ header files. Anyway, it should not happen
--   very often and you may start most of your programs with
--   \code
--   #include "CImg.h"
--   using namespace cimg_library;
--   \endcode
--   to simplify the declaration of %CImg Library objects variables afterwards.
--**/
--
--namespace cimg_library {
--
--  // Define the CImg classes.
--  template<typename T=float> struct CImg;
--  template<typename T=float> struct CImgList;
--  struct CImgStats;
--  struct CImgDisplay;
--  struct CImgException;
--
--  namespace cimg {
--
--    // The bodies of the functions below are defined afterwards
--    inline void info();
--
--    inline unsigned int& exception_mode();
--
--    inline int dialog(const char *title,const char *msg,const char *button1_txt="OK",
--                      const char *button2_txt=0,const char *button3_txt=0,
--                      const char *button4_txt=0,const char *button5_txt=0,
--                      const char *button6_txt=0,const bool centering = false);
--
--    template<typename tfunc, typename tp, typename tf>
--    inline void marching_cubes(const tfunc& func, const float isovalue,
--                               const float x0,const float y0,const float z0,
--                               const float x1,const float y1,const float z1,
--                               const float resx,const float resy,const float resz,
--                               CImgList<tp>& points, CImgList<tf>& primitives,
--                               const bool invert_faces = false);
--
--    template<typename tfunc, typename tp, typename tf>
--    inline void marching_squares(const tfunc& func, const float isovalue,
--                                 const float x0,const float y0,
--                                 const float x1,const float y1,
--                                 const float resx,const float resy,
--                                 CImgList<tp>& points, CImgList<tf>& primitives);
--  }
--
--  /*
--   #----------------------------------------------
--   #
--   #
--   # Definition of the CImgException structures
--   #
--   #
--   #----------------------------------------------
--   */
--
--  // Never use the following macro in your own code !
--#define cimg_exception_err(etype,disp_flag) \
--  if (cimg::exception_mode()>=1) { \
--    std::va_list ap; \
--    va_start(ap,format); \
--    std::vsprintf(message,format,ap); \
--    va_end(ap); \
--    if (cimg::exception_mode()>=2 && disp_flag) { \
--      try { cimg::dialog(etype,message,"Abort"); } \
--      catch (CImgException&) { std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); } \
--    } else std::fprintf(stderr,"\n# %s :\n%s\n\n",etype,message); \
--  } \
--  if (cimg::exception_mode()>=3) cimg_library::cimg::info(); \
--
--  //! Class which is thrown when an error occured during a %CImg library function call.
--  /**
--
--      \section ex1 Overview
--
--      CImgException is the base class of %CImg exceptions.
--      Exceptions are thrown by the %CImg Library when an error occured in a %CImg library function call.
--      CImgException is seldom thrown itself. Children classes that specify the kind of error encountered
--      are generally used instead. These sub-classes are :
--
--      - \b CImgInstanceException : Thrown when the instance associated to the called %CImg function is not
--      correctly defined. Generally, this exception is thrown when one tries to process \a empty images. The example
--      below will throw a \a CImgInstanceException.
--      \code
--      CImg<float> img;        // Construct an empty image.
--      img.blur(10);           // Try to blur the image.
--      \endcode
--
--      - \b CImgArgumentException : Thrown when one of the arguments given to the called %CImg function is not correct.
--      Generally, this exception is thrown when arguments passed to the function are outside an admissible range of values.
--      The example below will throw a \a CImgArgumentException.
--      \code
--      CImg<float> img(100,100,1,3);   // Define a 100x100 color image with float pixels.
--      img = 0;                     // Try to fill pixels from the 0 pointer (invalid argument to operator=() ).
--      \endcode
--
--      - \b CImgIOException : Thrown when an error occured when trying to load or save image files.
--      The example below will throw a \a CImgIOException.
--      \code
--      CImg<float> img("file_doesnt_exist.jpg");    // Try to load a file that doesn't exist.
--      \endcode
--
--      - \b CImgDisplayException : Thrown when an error occured when trying to display an image in a window.
--      This exception is thrown when image display request cannot be satisfied.
--
--      The parent class CImgException may be thrown itself when errors that cannot be classified in one of
--      the above type occur. It is recommended not to throw CImgExceptions yourself, since there are normally
--      reserved to %CImg Library functions.
--      \b CImgInstanceException, \b CImgArgumentException, \b CImgIOException and \b CImgDisplayException are simple
--      subclasses of CImgException and are thus not detailled more in this reference documentation.
--
--      \section ex2 Exception handling
--
--      When an error occurs, the %CImg Library first displays the error in a modal window.
--      Then, it throws an instance of the corresponding exception class, generally leading the program to stop
--      (this is the default behavior).
--      You can bypass this default behavior by handling the exceptions yourself,
--      using a code block <tt>try { ... } catch() { ... }</tt>.
--      In this case, you can avoid the apparition of the modal window, by
--      defining the environment variable <tt>cimg_debug</tt> to 0 before including the %CImg header file.
--      The example below shows how to cleanly handle %CImg Library exceptions :
--      \code
--      #define cimg_debug 0     // Disable modal window in CImg exceptions.
--      #define "CImg.h"
--      int main() {
--        try {
--          ...; // Here, do what you want.
--        }
--        catch (CImgInstanceException &e) {
--          std::fprintf(stderr,"CImg Library Error : %s",e.message);  // Display your own error message
--          ...                                                        // Do what you want now.
--        }
--      }
--      \endcode
--  **/
--  struct CImgException {
--    char message[1024]; //!< Message associated with the error that thrown the exception.
--    CImgException() { message[0]='\0'; }
--    CImgException(const char *format,...) { cimg_exception_err("CImgException",true); }
--  };
--
--  // The \ref CImgInstanceException class is used to throw an exception related
--  // to a non suitable instance encountered in a library function call.
--  struct CImgInstanceException : CImgException {
--    CImgInstanceException(const char *format,...) { cimg_exception_err("CImgInstanceException",true); }
--  };
--
--  // The \ref CImgArgumentException class is used to throw an exception related
--  // to invalid arguments encountered in a library function call.
--  struct CImgArgumentException : CImgException {
--    CImgArgumentException(const char *format,...) { cimg_exception_err("CImgArgumentException",true); }
--  };
--
--  // The \ref CImgIOException class is used to throw an exception related
--  // to Input/Output file problems encountered in a library function call.
--  struct CImgIOException : CImgException {
--    CImgIOException(const char *format,...) { cimg_exception_err("CImgIOException",true); }
--  };
--
--  // The CImgDisplayException class is used to throw an exception related to display problems
--  // encountered in a library function call.
--  struct CImgDisplayException : CImgException {
--    CImgDisplayException(const char *format,...) { cimg_exception_err("CImgDisplayException",false); }
--  };
--
--  /*
--   #-------------------------------------
--   #
--   #
--   # Definition of the namespace 'cimg'
--   #
--   #
--   #-------------------------------------
--   */
--
--  //! Namespace that encompasses \a low-level functions and variables of the %CImg Library.
--  /**
--     Most of the functions and variables within this namespace are used by the library for low-level processing.
--     Nevertheless, documented variables and functions of this namespace may be used safely in your own source code.
--
--     \warning Never write <tt>using namespace cimg_library::cimg;</tt> in your source code, since a lot of functions of the
--     <tt>cimg::</tt> namespace have prototypes similar to standard C functions defined in the global namespace <tt>::</tt>.
--  **/
--  namespace cimg {
--
--    // Define the trait that will be used to determine the best data type to work with.
--    // Considered types are : bool, uchar, char, short, ushort, int, uint, long, ulong, float and double.
--    // Two rules applies there :
--    // - largest of two integer types is an integer type.
--    // - largest of integer/float type is a float type.
--    template<typename T,typename t> struct largest          { typedef t type; };
--    template<> struct largest<unsigned char,bool>           { typedef unsigned char type; };
--    template<> struct largest<unsigned char,char>           { typedef short type; };
--    template<> struct largest<char,bool>                    { typedef char type; };
--    template<> struct largest<char,unsigned char>           { typedef short type; };
--    template<> struct largest<char,unsigned short>          { typedef int type; };
--    template<> struct largest<char,unsigned int>            { typedef unsigned int type; };
--    template<> struct largest<char,unsigned long>           { typedef unsigned long type; };
--    template<> struct largest<unsigned short,bool>          { typedef unsigned short type; };
--    template<> struct largest<unsigned short,unsigned char> { typedef unsigned short type; };
--    template<> struct largest<unsigned short,char>          { typedef int type; };
--    template<> struct largest<unsigned short,short>         { typedef int type; };
--    template<> struct largest<short,bool>                   { typedef short type; };
--    template<> struct largest<short,unsigned char>          { typedef short type; };
--    template<> struct largest<short,char>                   { typedef short type; };
--    template<> struct largest<short,unsigned short>         { typedef int type; };
--    template<> struct largest<short,unsigned int>           { typedef unsigned int type; };
--    template<> struct largest<short,unsigned long>          { typedef unsigned long type; };
--    template<> struct largest<unsigned int,bool>            { typedef unsigned int type; };
--    template<> struct largest<unsigned int,unsigned char>   { typedef unsigned int type; };
--    template<> struct largest<unsigned int,char>            { typedef unsigned int type; };
--    template<> struct largest<unsigned int,unsigned short>  { typedef unsigned int type; };
--    template<> struct largest<unsigned int,short>           { typedef unsigned int type; };
--    template<> struct largest<unsigned int,int>             { typedef unsigned int type; };
--    template<> struct largest<int,bool>                     { typedef int type; };
--    template<> struct largest<int,unsigned char>            { typedef int type; };
--    template<> struct largest<int,char>                     { typedef int type; };
--    template<> struct largest<int,unsigned short>           { typedef int type; };
--    template<> struct largest<int,short>                    { typedef int type; };
--    template<> struct largest<int,unsigned int>             { typedef unsigned int type; };
--    template<> struct largest<int,unsigned long>            { typedef unsigned long type; };
--    template<> struct largest<float,bool>                   { typedef float type; };
--    template<> struct largest<float,unsigned char>          { typedef float type; };
--    template<> struct largest<float,char>                   { typedef float type; };
--    template<> struct largest<float,unsigned short>         { typedef float type; };
--    template<> struct largest<float,short>                  { typedef float type; };
--    template<> struct largest<float,unsigned int>           { typedef float type; };
--    template<> struct largest<float,int>                    { typedef float type; };
--    template<> struct largest<float,unsigned long>          { typedef float type; };
--    template<> struct largest<float,long>                   { typedef float type; };
--    template<> struct largest<double,bool>                  { typedef double type; };
--    template<> struct largest<double,unsigned char>         { typedef double type; };
--    template<> struct largest<double,char>                  { typedef double type; };
--    template<> struct largest<double,unsigned short>        { typedef double type; };
--    template<> struct largest<double,short>                 { typedef double type; };
--    template<> struct largest<double,unsigned int>          { typedef double type; };
--    template<> struct largest<double,int>                   { typedef double type; };
--    template<> struct largest<double,unsigned long>         { typedef double type; };
--    template<> struct largest<double,long>                  { typedef double type; };
--    template<> struct largest<double,float>                 { typedef double type; };
--
--    template<typename T> struct type {
--      static T min()  { return (T)-1>0?(T)0:(T)-1<<(8*sizeof(T)-1); }
--      static T max()  { return (T)-1>0?(T)-1:~((T)-1<<(8*sizeof(T)-1)); }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "unknown"; return s; }
--    };
--    template<> struct type<bool> {
--      static bool min() { return false; }
--      static bool max() { return true; }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "bool"; return s; }
--    };
--    template<> struct type<unsigned char> {
--      static unsigned char min() { return 0; }
--      static unsigned char max() { return (unsigned char)~0U; }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "unsigned char"; return s; }
--    };
--    template<> struct type<char> {
--      static char min() { return (char)-1<<(8*sizeof(char)-1); }
--      static char max() { return ~((char)-1<<(8*sizeof(char)-1)); }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "char"; return s; }
--    };
--    template<> struct type<unsigned short> {
--      static unsigned short min() { return 0; }
--      static unsigned short max() { return (unsigned short)~0U; }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "unsigned short"; return s; }
--    };
--    template<> struct type<short> {
--      static short min() { return (short)-1<<(8*sizeof(short)-1); }
--      static short max() { return ~((short)-1<<(8*sizeof(short)-1)); }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "short"; return s; }
--    };
--    template<> struct type<unsigned int> {
--      static unsigned int min() { return 0; }
--      static unsigned int max() { return (unsigned int)~0U; }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "unsigned int"; return s; }
--    };
--    template<> struct type<int> {
--      static int min() { return (int)-1<<(8*sizeof(int)-1); }
--      static int max() { return ~((int)-1<<(8*sizeof(int)-1)); }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "int"; return s; }
--    };
--    template<> struct type<unsigned long> {
--      static unsigned long min() { return 0; }
--      static unsigned long max() { return (unsigned long)~0UL; }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "unsigned long"; return s; }
--    };
--    template<> struct type<long> {
--      static long min() { return (long)-1<<(8*sizeof(long)-1); }
--      static long max() { return ~((long)-1<<(8*sizeof(long)-1)); }
--      static bool is_float() { return false; }
--      static const char* id() { static const char *const s = "long"; return s; }
--    };
--    template<> struct type<float> {
--      static float min() { return -3.4E38f; }
--      static float max() { return  3.4E38f; }
--      static bool is_float() { return true; }
--      static const char* id() { static const char *const s = "float"; return s; }
--    };
--    template<> struct type<double> {
--      static double min() { return -1.7E308; }
--      static double max() { return  1.7E308; }
--      static bool is_float() { return true; }
--      static const char* id() { static const char *const s = "double"; return s; }
--    };
--
--    // Define internal library variables.
--#if cimg_display_type==1
--    struct X11info {
--      volatile unsigned int nb_wins;
--      pthread_mutex_t* mutex;
--      pthread_t*       event_thread;
--      CImgDisplay*     wins[1024];
--      Display*         display;
--      unsigned int     nb_bits;
--      GC*              gc;
--      bool             blue_first;
--      bool             byte_order;
--      bool             shm_enabled;
--#ifdef cimg_use_xrandr
--      XRRScreenSize *resolutions;
--      Rotation curr_rotation;
--      unsigned int curr_resolution;
--      unsigned int nb_resolutions;
--#endif
--      X11info():nb_wins(0),mutex(0),event_thread(0),display(0),
--                nb_bits(0),gc(0),blue_first(false),byte_order(false),shm_enabled(false) {
--#ifdef cimg_use_xrandr
--        resolutions = 0;
--        curr_rotation = 0;
--        curr_resolution = nb_resolutions = 0;
--#endif
--      }
--    };
--#if defined(cimg_module)
--    X11info& X11attr();
--#elif defined(cimg_main)
--    X11info& X11attr() { static X11info val; return val; }
--#else
--    inline X11info& X11attr() { static X11info val; return val; }
--#endif
--
--#elif cimg_display_type==2
--    struct Win32info {
--      HANDLE wait_event;
--      Win32info() { wait_event = CreateEvent(0,FALSE,FALSE,0); }
--    };
--#if defined(cimg_module)
--    Win32info& Win32attr();
--#elif defined(cimg_main)
--    Win32info& Win32attr() { static Win32info val; return val; }
--#else
--    inline Win32info& Win32attr() { static Win32info val; return val; }
--#endif
--#endif
--
--    inline unsigned int& exception_mode() { static unsigned int mode=cimg_debug; return mode; }
--
--#ifdef cimg_color_terminal
--    const char t_normal[9]  = {0x1b,'[','0',';','0',';','0','m','\0'};
--    const char t_red[11]    = {0x1b,'[','4',';','3','1',';','5','9','m','\0'};
--    const char t_bold[5]    = {0x1b,'[','1','m','\0'};
--    const char t_purple[11] = {0x1b,'[','0',';','3','5',';','5','9','m','\0'};
--#else
--    const char t_normal[1]  = {'\0'};
--    const char *const t_red = cimg::t_normal, *const t_bold = cimg::t_normal, *const t_purple = cimg::t_normal;
--#endif
--
--#if cimg_display_type==1
--    // Keycodes for X11-based graphical systems
--    const unsigned int keyESC        = XK_Escape;
--    const unsigned int keyF1         = XK_F1;
--    const unsigned int keyF2         = XK_F2;
--    const unsigned int keyF3         = XK_F3;
--    const unsigned int keyF4         = XK_F4;
--    const unsigned int keyF5         = XK_F5;
--    const unsigned int keyF6         = XK_F6;
--    const unsigned int keyF7         = XK_F7;
--    const unsigned int keyF8         = XK_F8;
--    const unsigned int keyF9         = XK_F9;
--    const unsigned int keyF10        = XK_F10;
--    const unsigned int keyF11        = XK_F11;
--    const unsigned int keyF12        = XK_F12;
--    const unsigned int keyPAUSE      = XK_Pause;
--    const unsigned int key1          = XK_1;
--    const unsigned int key2          = XK_2;
--    const unsigned int key3          = XK_3;
--    const unsigned int key4          = XK_4;
--    const unsigned int key5          = XK_5;
--    const unsigned int key6          = XK_6;
--    const unsigned int key7          = XK_7;
--    const unsigned int key8          = XK_8;
--    const unsigned int key9          = XK_9;
--    const unsigned int key0          = XK_0;
--    const unsigned int keyBACKSPACE  = XK_BackSpace;
--    const unsigned int keyINSERT     = XK_Insert;
--    const unsigned int keyHOME       = XK_Home;
--    const unsigned int keyPAGEUP     = XK_Page_Up;
--    const unsigned int keyTAB        = XK_Tab;
--    const unsigned int keyQ          = XK_q;
--    const unsigned int keyW          = XK_w;
--    const unsigned int keyE          = XK_e;
--    const unsigned int keyR          = XK_r;
--    const unsigned int keyT          = XK_t;
--    const unsigned int keyY          = XK_y;
--    const unsigned int keyU          = XK_u;
--    const unsigned int keyI          = XK_i;
--    const unsigned int keyO          = XK_o;
--    const unsigned int keyP          = XK_p;
--    const unsigned int keyDELETE     = XK_Delete;
--    const unsigned int keyEND        = XK_End;
--    const unsigned int keyPAGEDOWN   = XK_Page_Down;
--    const unsigned int keyCAPSLOCK   = XK_Caps_Lock;
--    const unsigned int keyA          = XK_a;
--    const unsigned int keyS          = XK_s;
--    const unsigned int keyD          = XK_d;
--    const unsigned int keyF          = XK_f;
--    const unsigned int keyG          = XK_g;
--    const unsigned int keyH          = XK_h;
--    const unsigned int keyJ          = XK_j;
--    const unsigned int keyK          = XK_k;
--    const unsigned int keyL          = XK_l;
--    const unsigned int keyENTER      = XK_Return;
--    const unsigned int keySHIFTLEFT  = XK_Shift_L;
--    const unsigned int keyZ          = XK_z;
--    const unsigned int keyX          = XK_x;
--    const unsigned int keyC          = XK_c;
--    const unsigned int keyV          = XK_v;
--    const unsigned int keyB          = XK_b;
--    const unsigned int keyN          = XK_n;
--    const unsigned int keyM          = XK_m;
--    const unsigned int keySHIFTRIGHT = XK_Shift_R;
--    const unsigned int keyARROWUP    = XK_Up;
--    const unsigned int keyCTRLLEFT   = XK_Control_L;
--    const unsigned int keyAPPLEFT    = XK_Super_L;
--    const unsigned int keySPACE      = XK_space;
--    const unsigned int keyALTGR      = XK_Alt_R;
--    const unsigned int keyAPPRIGHT   = XK_Super_R;
--    const unsigned int keyMENU       = XK_Menu;
--    const unsigned int keyCTRLRIGHT  = XK_Control_R;
--    const unsigned int keyARROWLEFT  = XK_Left;
--    const unsigned int keyARROWDOWN  = XK_Down;
--    const unsigned int keyARROWRIGHT = XK_Right;
--    const unsigned int keyPAD0       = XK_KP_0;
--    const unsigned int keyPAD1       = XK_KP_1;
--    const unsigned int keyPAD2       = XK_KP_2;
--    const unsigned int keyPAD3       = XK_KP_3;
--    const unsigned int keyPAD4       = XK_KP_4;
--    const unsigned int keyPAD5       = XK_KP_5;
--    const unsigned int keyPAD6       = XK_KP_6;
--    const unsigned int keyPAD7       = XK_KP_7;
--    const unsigned int keyPAD8       = XK_KP_8;
--    const unsigned int keyPAD9       = XK_KP_9;
--    const unsigned int keyPADADD     = XK_KP_Add;
--    const unsigned int keyPADSUB     = XK_KP_Subtract;
--    const unsigned int keyPADMUL     = XK_KP_Multiply;
--    const unsigned int keyPADDIV     = XK_KP_Divide;
--
--#elif (cimg_display_type==2 && cimg_OS==2)
--    // Keycodes for Windows-OS
--    const unsigned int keyESC        = VK_ESCAPE;
--    const unsigned int keyF1         = VK_F1;
--    const unsigned int keyF2         = VK_F2;
--    const unsigned int keyF3         = VK_F3;
--    const unsigned int keyF4         = VK_F4;
--    const unsigned int keyF5         = VK_F5;
--    const unsigned int keyF6         = VK_F6;
--    const unsigned int keyF7         = VK_F7;
--    const unsigned int keyF8         = VK_F8;
--    const unsigned int keyF9         = VK_F9;
--    const unsigned int keyF10        = VK_F10;
--    const unsigned int keyF11        = VK_F11;
--    const unsigned int keyF12        = VK_F12;
--    const unsigned int keyPAUSE      = VK_PAUSE;
--    const unsigned int key1          = '1';
--    const unsigned int key2          = '2';
--    const unsigned int key3          = '3';
--    const unsigned int key4          = '4';
--    const unsigned int key5          = '5';
--    const unsigned int key6          = '6';
--    const unsigned int key7          = '7';
--    const unsigned int key8          = '8';
--    const unsigned int key9          = '9';
--    const unsigned int key0          = '0';
--    const unsigned int keyBACKSPACE  = VK_BACK;
--    const unsigned int keyINSERT     = VK_INSERT;
--    const unsigned int keyHOME       = VK_HOME;
--    const unsigned int keyPAGEUP     = VK_PRIOR;
--    const unsigned int keyTAB        = VK_TAB;
--    const unsigned int keyQ          = 'Q';
--    const unsigned int keyW          = 'W';
--    const unsigned int keyE          = 'E';
--    const unsigned int keyR          = 'R';
--    const unsigned int keyT          = 'T';
--    const unsigned int keyY          = 'Y';
--    const unsigned int keyU          = 'U';
--    const unsigned int keyI          = 'I';
--    const unsigned int keyO          = 'O';
--    const unsigned int keyP          = 'P';
--    const unsigned int keyDELETE     = VK_DELETE;
--    const unsigned int keyEND        = VK_END;
--    const unsigned int keyPAGEDOWN   = VK_NEXT;
--    const unsigned int keyCAPSLOCK   = VK_CAPITAL;
--    const unsigned int keyA          = 'A';
--    const unsigned int keyS          = 'S';
--    const unsigned int keyD          = 'D';
--    const unsigned int keyF          = 'F';
--    const unsigned int keyG          = 'G';
--    const unsigned int keyH          = 'H';
--    const unsigned int keyJ          = 'J';
--    const unsigned int keyK          = 'K';
--    const unsigned int keyL          = 'L';
--    const unsigned int keyENTER      = VK_RETURN;
--    const unsigned int keySHIFTLEFT  = VK_SHIFT;
--    const unsigned int keyZ          = 'Z';
--    const unsigned int keyX          = 'X';
--    const unsigned int keyC          = 'C';
--    const unsigned int keyV          = 'V';
--    const unsigned int keyB          = 'B';
--    const unsigned int keyN          = 'N';
--    const unsigned int keyM          = 'M';
--    const unsigned int keySHIFTRIGHT = VK_SHIFT;
--    const unsigned int keyARROWUP    = VK_UP;
--    const unsigned int keyCTRLLEFT   = VK_CONTROL;
--    const unsigned int keyAPPLEFT    = VK_LWIN;
--    const unsigned int keySPACE      = VK_SPACE;
--    const unsigned int keyALTGR      = VK_CONTROL;
--    const unsigned int keyAPPRIGHT   = VK_RWIN;
--    const unsigned int keyMENU       = VK_APPS;
--    const unsigned int keyCTRLRIGHT  = VK_CONTROL;
--    const unsigned int keyARROWLEFT  = VK_LEFT;
--    const unsigned int keyARROWDOWN  = VK_DOWN;
--    const unsigned int keyARROWRIGHT = VK_RIGHT;
--    const unsigned int keyPAD0       = 0x60;
--    const unsigned int keyPAD1       = 0x61;
--    const unsigned int keyPAD2       = 0x62;
--    const unsigned int keyPAD3       = 0x63;
--    const unsigned int keyPAD4       = 0x64;
--    const unsigned int keyPAD5       = 0x65;
--    const unsigned int keyPAD6       = 0x66;
--    const unsigned int keyPAD7       = 0x67;
--    const unsigned int keyPAD8       = 0x68;
--    const unsigned int keyPAD9       = 0x69;
--    const unsigned int keyPADADD     = VK_ADD;
--    const unsigned int keyPADSUB     = VK_SUBTRACT;
--    const unsigned int keyPADMUL     = VK_MULTIPLY;
--    const unsigned int keyPADDIV     = VK_DIVIDE;
--#else
--    // Define unknow keycodes when no display
--    const unsigned int keyESC        = 1U;
--    const unsigned int keyF1         = 2U;
--    const unsigned int keyF2         = 3U;
--    const unsigned int keyF3         = 4U;
--    const unsigned int keyF4         = 5U;
--    const unsigned int keyF5         = 6U;
--    const unsigned int keyF6         = 7U;
--    const unsigned int keyF7         = 8U;
--    const unsigned int keyF8         = 9U;
--    const unsigned int keyF9         = 10U;
--    const unsigned int keyF10        = 11U;
--    const unsigned int keyF11        = 12U;
--    const unsigned int keyF12        = 13U;
--    const unsigned int keyPAUSE      = 14U;
--    const unsigned int key1          = 15U;
--    const unsigned int key2          = 16U;
--    const unsigned int key3          = 17U;
--    const unsigned int key4          = 18U;
--    const unsigned int key5          = 19U;
--    const unsigned int key6          = 20U;
--    const unsigned int key7          = 21U;
--    const unsigned int key8          = 22U;
--    const unsigned int key9          = 23U;
--    const unsigned int key0          = 24U;
--    const unsigned int keyBACKSPACE  = 25U;
--    const unsigned int keyINSERT     = 26U;
--    const unsigned int keyHOME       = 27U;
--    const unsigned int keyPAGEUP     = 28U;
--    const unsigned int keyTAB        = 29U;
--    const unsigned int keyQ          = 30U;
--    const unsigned int keyW          = 31U;
--    const unsigned int keyE          = 32U;
--    const unsigned int keyR          = 33U;
--    const unsigned int keyT          = 34U;
--    const unsigned int keyY          = 35U;
--    const unsigned int keyU          = 36U;
--    const unsigned int keyI          = 37U;
--    const unsigned int keyO          = 38U;
--    const unsigned int keyP          = 39U;
--    const unsigned int keyDELETE     = 40U;
--    const unsigned int keyEND        = 41U;
--    const unsigned int keyPAGEDOWN   = 42U;
--    const unsigned int keyCAPSLOCK   = 43U;
--    const unsigned int keyA          = 44U;
--    const unsigned int keyS          = 45U;
--    const unsigned int keyD          = 46U;
--    const unsigned int keyF          = 47U;
--    const unsigned int keyG          = 48U;
--    const unsigned int keyH          = 49U;
--    const unsigned int keyJ          = 50U;
--    const unsigned int keyK          = 51U;
--    const unsigned int keyL          = 52U;
--    const unsigned int keyENTER      = 53U;
--    const unsigned int keySHIFTLEFT  = 54U;
--    const unsigned int keyZ          = 55U;
--    const unsigned int keyX          = 56U;
--    const unsigned int keyC          = 57U;
--    const unsigned int keyV          = 58U;
--    const unsigned int keyB          = 59U;
--    const unsigned int keyN          = 60U;
--    const unsigned int keyM          = 61U;
--    const unsigned int keySHIFTRIGHT = 62U;
--    const unsigned int keyARROWUP    = 63U;
--    const unsigned int keyCTRLLEFT   = 64U;
--    const unsigned int keyAPPLEFT    = 65U;
--    const unsigned int keySPACE      = 66U;
--    const unsigned int keyALTGR      = 67U;
--    const unsigned int keyAPPRIGHT   = 68U;
--    const unsigned int keyMENU       = 69U;
--    const unsigned int keyCTRLRIGHT  = 70U;
--    const unsigned int keyARROWLEFT  = 71U;
--    const unsigned int keyARROWDOWN  = 72U;
--    const unsigned int keyARROWRIGHT = 73U;
--    const unsigned int keyPAD0       = 74U;
--    const unsigned int keyPAD1       = 75U;
--    const unsigned int keyPAD2       = 76U;
--    const unsigned int keyPAD3       = 77U;
--    const unsigned int keyPAD4       = 78U;
--    const unsigned int keyPAD5       = 79U;
--    const unsigned int keyPAD6       = 80U;
--    const unsigned int keyPAD7       = 81U;
--    const unsigned int keyPAD8       = 82U;
--    const unsigned int keyPAD9       = 83U;
--    const unsigned int keyPADADD     = 84U;
--    const unsigned int keyPADSUB     = 85U;
--    const unsigned int keyPADMUL     = 86U;
--    const unsigned int keyPADDIV     = 87U;
--#endif
--
--#ifdef PI
--#undef PI
--#endif
--    const double PI = 3.14159265358979323846;   //!< Definition of the mathematical constant PI
--
--    // Definition of a 7x11 font, used to return a default font for drawing text.
--    const unsigned int font7x11[7*11*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x7f0000,0x40000,0x0,0x0,0x4010c0a4,0x82000040,0x11848402,0x18480050,0x80430292,0x8023,0x9008000,
--      0x40218140,0x4000040,0x21800402,0x18000051,0x1060500,0x8083,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x24002,0x4031,0x80000000,0x10000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c0400,0x40020000,0x80070080,0x40440e00,0x0,0x0,0x1,0x88180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x200000,0x0,0x0,0x80000,0x0,0x0,0x20212140,0x5000020,0x22400204,0x240000a0,0x40848500,0x4044,0x80010038,0x20424285,0xa000020,
--      0x42428204,0x2428e0a0,0x82090a14,0x4104,0x85022014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10240a7,0x88484040,0x40800000,0x270c3,0x87811e0e,
--      0x7c70e000,0x78,0x3c23c1ef,0x1f3e1e89,0xf1c44819,0xa23cf0f3,0xc3cff120,0xc18307f4,0x4040400,0x20000,0x80080080,0x40200,0x0,
--      0x40000,0x2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8188,0x50603800,0xf3c00000,0x1c004003,0xc700003e,0x18180,0xc993880,0x10204081,
--      0x2071ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x7d1224,0x48906048,0x0,0x4000000,0x0,0x9000,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x10240aa,0x14944080,0x23610000,0x68940,0x40831010,0x8891306,0x802044,0x44522208,0x90202088,0x40448819,0xb242890a,0x24011111,
--      0x49448814,0x4040a00,0xe2c3c7,0x8e3f3cb9,0xc1c44216,0xee38b0f2,0xe78f9120,0xc18507e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x101c207,0x88a04001,0x9c00000,0x2200a041,0x8200113a,0x8240,0x50a3110,0x2850a142,0x850c2081,0x2040204,0x8104592,0x142850a1,
--      0x42cd1224,0x4888bc48,0x70e1c387,0xe3b3c70,0xe1c38e1c,0x38707171,0xc3870e1c,0x10791224,0x48906c41,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x10003ee,0x15140080,0x21810000,0x48840,0x40851020,0x8911306,0x31fd804,0x9c522408,0x90204088,0x4045081a,0xba42890a,0x24011111,
--      0x49285024,0x2041b00,0x132408,0x910844c8,0x4044821b,0x7244c913,0x24041111,0x49488822,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x28204,0x85006001,0x6a414000,0x3a004043,0xc700113a,0x8245,0x50a3a00,0x2850a142,0x850c4081,0x2040204,0x81045d2,0x142850a1,
--      0x24951224,0x48852250,0x8102040,0x81054089,0x12244204,0x8108992,0x24489122,0x991224,0x4888b222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x1000143,0xa988080,0x2147c01f,0x88840,0x83091c2c,0x1070f000,0xc000608,0xa48bc408,0x9e3c46f8,0x40460816,0xaa42f10b,0xc3811111,
--      0x35102044,0x1041100,0xf22408,0x9f084488,0x40470212,0x62448912,0x6041111,0x55308846,0x8061c80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x1028704,0x8f805801,0x4be28fdf,0x220001f0,0x111a,0x60000182,0x82c5c710,0x44891224,0x489640f1,0xe3c78204,0x810e552,0x142850a1,
--      0x18a51224,0x48822250,0x78f1e3c7,0x8f1f40f9,0xf3e7c204,0x8108912,0x24489122,0x7ea91224,0x4888a222,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x10007e2,0x85648080,0x20010000,0x88841,0x8f8232,0x20881000,0xc1fc610,0xbefa2408,0x90204288,0x40450816,0xa642810a,0x4041110a,
--      0x36282084,0x1042080,0x1122408,0x90084488,0x40450212,0x62448912,0x184110a,0x55305082,0x8042700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x1028207,0x82004801,0x68050040,0x1c000040,0x110a,0x60000001,0x45484d10,0x7cf9f3e7,0xcf944081,0x2040204,0x8104532,0x142850a1,
--      0x18a51224,0x48822248,0x89122448,0x91244081,0x2040204,0x8108912,0x24489122,0xc91224,0x48852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x282,
--      0x89630080,0x20010c00,0x30108842,0x810222,0x20882306,0x3001800,0x408a2208,0x90202288,0x40448814,0xa642810a,0x2041110a,0x26442104,
--      0x840000,0x1122408,0x90084488,0x40448212,0x62448912,0x84130a,0x36485102,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x101c208,0x4f802801,
--      0x8028040,0x40,0x130a,0x2,0x85e897a0,0x44891224,0x489c2081,0x2040204,0x8104532,0x142850a1,0x24cd1224,0x48823c44,0x89122448,
--      0x91244081,0x2040204,0x8108912,0x24489122,0xc93264,0xc9852214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100028f,0x109f0080,0x20010c00,
--      0x303071f3,0xc7011c1c,0x4071c306,0x802010,0x3907c1ef,0x1f201e89,0xf3844f90,0xa23c80f2,0x17810e04,0x228223f4,0x840000,0xfbc3c7,
--      0x8f083c88,0x40444212,0x6238f0f2,0x7039d04,0x228423e2,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1008780,0x2201800,0xf0014000,0x1f0,
--      0x1d0a,0x5,0x851e140,0x83060c18,0x30671ef9,0xf3e7cf9f,0x3e7c7911,0xe3c78f1e,0x42f8e1c3,0x8702205c,0x7cf9f3e7,0xcf9b3c78,0xf1e3c204,
--      0x8107111,0xc3870e1c,0x10f1d3a7,0x4e823c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x40,0x40000400,0x200000,0x0,0x2,0x0,0x0,0x0,0x0,0x18,
--      0x0,0x4,0x44007f,0x0,0x400,0x400000,0x8010,0x0,0x6002,0x8040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x200800,0x0,0x0,0x100a,
--      0x400000,0x44,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x0,0x62018,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x80000800,
--      0x400000,0x0,0x4,0x0,0x0,0x0,0x0,0xc,0x0,0x7,0x3c0000,0x0,0x3800,0x3800000,0x8010,0x0,0x1c001,0x881c0000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x207000,0x0,0x0,0x100a,0xc00000,0x3c,0x0,0xc00,0x0,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x0,0x1c2070
--    };
--
--    // Definition of a 10x13 font (used in dialog boxes).
--    const unsigned int font10x13[256*10*13/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80100c0,
--      0x68000300,0x801,0xc00010,0x100c000,0x68100,0x100c0680,0x2,0x403000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x4020120,
--      0x58120480,0x402,0x1205008,0x2012050,0x58080,0x20120581,0x40000001,0x804812,0x2000000,0x0,0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140,0x80000,0x200402,0x800000,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x7010,0x7000000,0x8000200,0x20000,0xc0002000,0x8008,0x0,0x0,0x0,0x0,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x80000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x80100c0,0x68000480,0x1001,
--      0xc00010,0x1018000,0x68100,0x100c0680,0x4,0x403000,0x1020000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,0x28081883,0x200801,
--      0x2a00000,0x10,0x1c0201c0,0x70040f80,0xc0f81c07,0x0,0x70,0x3e0303c0,0x3c3c0f83,0xe03c2107,0xe08810,0x18c31070,0x3c0703c0,
--      0x783e0842,0x22222208,0x83e04010,0x1008000,0x4000200,0x20001,0x2002,0x408008,0x0,0x0,0x100000,0x0,0x1008,0x2000000,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080,0x38000880,0x8078140f,0x81c00000,0x3e000,0xc020180,0x60080001,0xe0000002,0xc00042,0x108e2010,
--      0xc0300c0,0x300c0303,0xf83c3e0f,0x83e0f81c,0x701c070,0x3c0c41c0,0x701c0701,0xc0001d08,0x42108421,0x8820088,0x4020120,0x58140480,
--      0x802,0x1205008,0x3014050,0xc058080,0x20120581,0x40000002,0x804814,0x2020050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,
--      0x281e2484,0x80200801,0x1c02000,0x10,0x22060220,0x880c0801,0x82208,0x80000001,0x20008,0x41030220,0x40220802,0x402102,0x209010,
--      0x18c31088,0x22088220,0x80080842,0x22222208,0x80204010,0x1014000,0x200,0x20001,0x2000,0x8008,0x0,0x0,0x100000,0x0,0x1008,
--      0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40000500,0x80800010,0x40200000,0x41000,0x12020040,0x10000003,0xa0000006,
--      0x12000c4,0x31014000,0xc0300c0,0x300c0302,0x80402008,0x2008008,0x2008020,0x220c4220,0x88220882,0x20002208,0x42108421,0x8820088,
--      0x0,0x300,0x0,0x0,0x0,0x14000000,0x0,0x200200,0x0,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xfc282504,0x80001000,
--      0x82a02000,0x20,0x22020020,0x8140802,0x102208,0x80801006,0x18008,0x9c848220,0x80210802,0x802102,0x20a010,0x15429104,0x22104220,
--      0x80080842,0x22221405,0x404008,0x1022000,0x703c0,0x381e0701,0xc0783c02,0xc09008,0x1d83c070,0x3c078140,0x381c0882,0x21242208,
--      0x81e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,0x40220500,0x80800027,0x20e02800,0x9c800,0x12020040,
--      0x20000883,0xa0200002,0x120a044,0x11064010,0x12048120,0x48120484,0x80802008,0x2008008,0x2008020,0x210a4411,0x4411044,0x10884508,
--      0x42108421,0x503c0b0,0x1c0701c0,0x701c0707,0x70381c07,0x1c07008,0x2008020,0x20f01c0,0x701c0701,0xc0201c08,0x82208822,0x883c088,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x50281903,0x20001000,0x80802000,0x20,0x22020040,0x30240f03,0xc0101c08,0x80801018,
--      0x1fc06010,0xa48483c0,0x80210f03,0xe0803f02,0x20c010,0x15429104,0x22104220,0x70080841,0x41540805,0x804008,0x1041000,0x8220,
--      0x40220881,0x882202,0x40a008,0x12422088,0x22088180,0x40100882,0x21241408,0x80201008,0x2031000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x20280,0x401c0200,0x700028,0x21205000,0x92800,0xc1fc080,0x10000883,0xa0200002,0x1205049,0x12c19010,0x12048120,0x48120484,
--      0xf0803c0f,0x3c0f008,0x2008020,0x790a4411,0x4411044,0x10504908,0x42108421,0x5022088,0x2008020,0x8020080,0x88402208,0x82208808,
--      0x2008020,0x1e088220,0x88220882,0x20002608,0x82208822,0x8822088,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x501c0264,
--      0xa0001000,0x8001fc00,0x7000020,0x22020080,0x83e0082,0x20202207,0x80000020,0x1020,0xa4848220,0x80210802,0x9c2102,0x20c010,
--      0x12425104,0x3c1043c0,0x8080841,0x41540802,0x804008,0x1000000,0x78220,0x40220f81,0x882202,0x40c008,0x12422088,0x22088100,
--      0x60100881,0x41540805,0x406008,0x1849000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0xf0140200,0x880028,0x20e0a03f,0x709c800,
--      0x201c0,0x60000881,0xa0000007,0xc0284b,0x122eb020,0x12048120,0x48120487,0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,
--      0x10204908,0x42108421,0x2022088,0x1e0781e0,0x781e0787,0xf8403e0f,0x83e0f808,0x2008020,0x22088220,0x88220882,0x21fc2a08,0x82208822,
--      0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xf80a0294,0x40001000,0x80002000,0x20,0x22020100,0x8040082,0x20202200,
--      0x80000018,0x1fc06020,0xa48fc220,0x80210802,0x842102,0x20a010,0x12425104,0x20104240,0x8080841,0x41541402,0x1004008,0x1000000,
--      0x88220,0x40220801,0x882202,0x40a008,0x12422088,0x22088100,0x18100881,0x41540805,0x801008,0x2046000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x20280,0x401c0f80,0x80880028,0x20005001,0x94800,0x20000,0x880,0xa0000000,0x5015,0x4215040,0x3f0fc3f0,0xfc3f0fc8,
--      0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,0x10505108,0x42108421,0x203c088,0x22088220,0x88220888,0x80402008,0x2008008,
--      0x2008020,0x22088220,0x88220882,0x20002a08,0x82208822,0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa00a0494,0x60001000,
--      0x80002004,0x8020,0x22020200,0x88040882,0x20402201,0x801006,0x18000,0x9f084220,0x40220802,0x442102,0x209010,0x10423088,0x20088220,
--      0x8080840,0x80882202,0x2004008,0x1000000,0x88220,0x40220881,0x882202,0x409008,0x12422088,0x22088100,0x8100880,0x80881402,
--      0x1001008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0x40220200,0x80700027,0x20002801,0x92800,0x1fc000,0x980,
--      0xa0000000,0xa017,0x84417840,0x21084210,0x84210848,0x80402008,0x2008008,0x2008020,0x2208c220,0x88220882,0x20882208,0x42108421,
--      0x2020088,0x22088220,0x88220888,0xc8402208,0x82208808,0x2008020,0x22088220,0x88220882,0x20203208,0x82208822,0x2022020,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xa03c0463,0x90000801,0x2004,0x8040,0x1c0703e0,0x70040701,0xc0401c06,0x801001,0x20020,
--      0x400843c0,0x3c3c0f82,0x3c2107,0x1c0881e,0x10423070,0x20070210,0xf0080780,0x80882202,0x3e04004,0x1000000,0x783c0,0x381e0701,
--      0x782202,0x408808,0x12422070,0x3c078100,0x700c0780,0x80882202,0x1e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,
--      0xf8000200,0x80080010,0x40000001,0x41000,0x0,0xe80,0xa0000000,0x21,0x8e21038,0x21084210,0x84210848,0xf83c3e0f,0x83e0f81c,
--      0x701c070,0x3c08c1c0,0x701c0701,0xc0005c07,0x81e0781e,0x20200b0,0x1e0781e0,0x781e0787,0x30381c07,0x1c07008,0x2008020,0x1c0881c0,
--      0x701c0701,0xc0201c07,0x81e0781e,0x203c020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x801,0x4,0x40,0x0,0x0,0x0,0x1000,
--      0x0,0x3c000000,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x4004,0x1000000,0x0,0x0,0x80000,0x400000,0x0,0x20008000,0x0,0x4,0x1008,0x2000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x8008000f,0x80000000,0x3e000,0x0,0x800,0xa0000400,0x0,0x0,0x0,0x0,0x80000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100000,0x0,0x0,0x0,0x0,0x2000,0x0,0x4020040,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,
--      0x402,0x8,0x40,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x7004,0x70000fc,0x0,0x0,0x700000,0x800000,0x0,0x20008000,
--      0x0,0x4,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80f00000,0x0,0x0,0x0,0x800,0xa0001800,0x0,0x0,0x0,0x0,
--      0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x4020040
--    };
--
--    // Definition of a 8x17 font
--    const unsigned int font8x17[8*17*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x2400,0x2400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20081834,0x1c0000,0x20081800,0x20081800,0x342008,
--      0x18340000,0x200818,0x80000,0x0,0x180000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4200000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x380000,0x4000,0x2000c00,0x40100840,0x70000000,0x0,0x0,0x1c,0x10700000,0x7,0x0,
--      0x1800,0x1800,0x0,0x0,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1010242c,0x14140000,0x10102414,0x10102414,0x2c1010,0x242c1400,
--      0x101024,0x14100038,0x0,0x240000,0x0,0x0,0x30000000,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x8100000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x80000,0x10004000,0x2001000,0x40000040,0x10000000,0x0,0x0,0x10,0x10100000,0x4,
--      0x0,0x18000000,0x0,0x0,0x0,0x34002400,0x2400,0x0,0x0,0x0,0x3c,0x0,0x8000000,0x0,0x60607800,0x0,0x140000,0x0,0x0,0x0,0x0,0x0,
--      0x44,0x10081834,0x240000,0x10081800,0x10081800,0x1c341008,0x18340000,0x100818,0x84000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102812,
--      0x8601c10,0x8100800,0x2,0x1c383e3e,0x67e1e7f,0x3e3c0000,0x38,0x1e087e1e,0x7c7f7f1e,0x417c1c42,0x4063611c,0x7e1c7e3e,0xfe414181,
--      0x63827f10,0x40081000,0x8004000,0x2001000,0x40000040,0x10000000,0x0,0x10000000,0x10,0x10100000,0x3c000008,0x0,0x24003e00,
--      0x3f007f00,0x0,0x0,0x2ce91800,0x1882,0x10101c,0xc2103c,0x143c3c00,0x3c00,0x18003c3c,0x10001f00,0x181c00,0x20200810,0x8080808,
--      0x8083e1e,0x7f7f7f7f,0x7c7c7c7c,0x7c611c1c,0x1c1c1c00,0x1e414141,0x41824044,0x810242c,0x14180000,0x8102414,0x8102414,0x382c0810,
--      0x242c1400,0x81024,0x14104014,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102816,0x3e902010,0x10084910,0x4,0x22084343,0xa402102,0x41620000,
--      0x44,0x33144121,0x42404021,0x41100444,0x40636122,0x43224361,0x10416381,0x22440310,0x20082800,0x4000,0x2001000,0x40000040,
--      0x10000000,0x0,0x10000000,0x10,0x10100000,0x24000008,0x0,0x606100,0x68000300,0x8106c,0x34000000,0x4f0000,0x44,0x101020,0x441040,
--      0x420200,0x4200,0x24000404,0x7d00,0x82200,0x20203010,0x14141414,0x14082821,0x40404040,0x10101010,0x42612222,0x22222200,0x23414141,
--      0x41447e48,0x0,0x0,0x0,0x0,0x4000000,0x18,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10287f,0x49902010,0x10083e10,0x4,0x41080101,
--      0x1a404002,0x41411818,0x1004004,0x21144140,0x41404040,0x41100448,0x40555141,0x41414140,0x10412281,0x14280610,0x20084400,0x1c7c1c,
--      0x3e3c7c3a,0x5c703844,0x107f5c3c,0x7c3e3c3c,0x7e424281,0x66427e10,0x10100000,0x40100008,0x1010,0xa04000,0x48100610,0x100c3024,
--      0x24000000,0x4f3c00,0x2c107e28,0x3820,0x42281060,0x9d1e12,0xbd00,0x24100818,0x427d00,0x82248,0x20200800,0x14141414,0x14142840,
--      0x40404040,0x10101010,0x41514141,0x41414142,0x43414141,0x41284350,0x1c1c1c1c,0x1c1c6c1c,0x3c3c3c3c,0x70707070,0x3c5c3c3c,
--      0x3c3c3c18,0x3e424242,0x42427c42,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x102824,0x48623010,0x10081c10,0x8,0x41080103,0x127c5e04,
--      0x41411818,0xe7f3808,0x4f144140,0x41404040,0x41100450,0x40555141,0x41414160,0x1041225a,0x1c280410,0x1008c600,0x226622,0x66661066,
--      0x62100848,0x10496266,0x66663242,0x10426681,0x24220260,0x100c0000,0xf8280008,0x1010,0x606000,0x48280428,0x28042014,0x48000000,
--      0x494200,0x52280228,0x105420,0x3cee1058,0xa12236,0xa500,0x18101004,0x427d00,0x8226c,0x76767e10,0x14141414,0x14142840,0x40404040,
--      0x10101010,0x41514141,0x41414124,0x45414141,0x41284150,0x22222222,0x22221222,0x66666666,0x10101010,0x66626666,0x66666600,
--      0x66424242,0x42226622,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100024,0x381c4900,0x10086bfe,0x8,0x4908021c,0x22036304,0x3e630000,
--      0x70000710,0x51227e40,0x417f7f43,0x7f100470,0x40554941,0x43417e3e,0x1041225a,0x8100810,0x10080000,0x24240,0x42421042,0x42100850,
--      0x10494242,0x42422040,0x1042245a,0x18240410,0x10103900,0x407c003e,0x1818,0x1c3e10,0x4f7c087c,0x7c002010,0x48000000,0x4008,
--      0x527c0410,0x105078,0x2410104c,0xa13e6c,0x7f00b900,0xfe3c3c,0x421d18,0x1c1c36,0x38383810,0x22222222,0x22144e40,0x7f7f7f7f,
--      0x10101010,0xf1494141,0x41414118,0x49414141,0x4110435c,0x2020202,0x2021240,0x42424242,0x10101010,0x42424242,0x424242ff,0x4e424242,
--      0x42244224,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000fe,0xe664d00,0x10080810,0x380010,0x41080c03,0x42014108,0x633d0000,0x70000710,
--      0x51224140,0x41404041,0x41100448,0x40494541,0x7e414203,0x1041145a,0x14101010,0x10080000,0x3e4240,0x427e1042,0x42100870,0x10494242,
--      0x4242203c,0x1042245a,0x18241810,0x10104600,0xf8f60008,0x1010,0x600320,0x48f610f6,0xf6000000,0x187eff,0x3c04,0x5ef61810,0x105020,
--      0x24fe0064,0x9d006c,0x138ad00,0x100000,0x420518,0x36,0xc0c0c020,0x22222222,0x22224840,0x40404040,0x10101010,0x41454141,0x41414118,
--      0x51414141,0x41107e46,0x3e3e3e3e,0x3e3e7e40,0x7e7e7e7e,0x10101010,0x42424242,0x42424200,0x5a424242,0x42244224,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x28,0x9094500,0x10080010,0x10,0x41081801,0x7f014118,0x41010000,0xe7f3800,0x513e4140,0x41404041,0x41100444,
--      0x40414541,0x40414101,0x10411466,0x36103010,0x8080000,0x424240,0x42401042,0x42100848,0x10494242,0x42422002,0x10423c5a,0x18142010,
--      0x10100000,0x407c0010,0x1010,0x260140,0x487c307c,0x7c000000,0x180000,0x202,0x507c2010,0x105020,0x3c10003c,0x423e36,0x1004200,
--      0x100000,0x420500,0x3e6c,0x41e0440,0x3e3e3e3e,0x3e3e7840,0x40404040,0x10101010,0x41454141,0x41414124,0x61414141,0x41104042,
--      0x42424242,0x42425040,0x40404040,0x10101010,0x42424242,0x42424218,0x72424242,0x42144214,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,
--      0x49096200,0x8100010,0x18001810,0x22082043,0x2432310,0x61421818,0x1004010,0x4f634121,0x42404021,0x41104444,0x40414322,0x40234143,
--      0x10411466,0x22106010,0x8080000,0x466622,0x66621066,0x42100844,0x10494266,0x66662042,0x10461824,0x24184010,0x10100000,0x24381010,
--      0x34001018,0xda4320,0x68386038,0x38000000,0x0,0x4204,0x50384010,0x105420,0x4210100c,0x3c0012,0x3c00,0x0,0x460500,0x48,0xc020c44,
--      0x63636363,0x63228821,0x40404040,0x10101010,0x42432222,0x22222242,0x62414141,0x41104042,0x46464646,0x46465022,0x62626262,
--      0x10101010,0x66426666,0x66666618,0x66464646,0x46186618,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100048,0x3e063d00,0x8100000,0x18001820,
--      0x1c3e7f3e,0x23c1e20,0x3e3c1818,0x10,0x20417e1e,0x7c7f401e,0x417c3842,0x7f41431c,0x401e40be,0x103e0866,0x41107f10,0x4080000,
--      0x3a5c1c,0x3a3c103a,0x427c0842,0xe49423c,0x7c3e203c,0xe3a1824,0x66087e10,0x10100000,0x3c103010,0x245a1010,0x5a3e10,0x3f107f10,
--      0x10000000,0x0,0x3c08,0x2e107e10,0x1038fc,0x101004,0x0,0x0,0xfe0000,0x7f0500,0x0,0x14041438,0x41414141,0x41418e1e,0x7f7f7f7f,
--      0x7c7c7c7c,0x7c431c1c,0x1c1c1c00,0xbc3e3e3e,0x3e10405c,0x3a3a3a3a,0x3a3a6e1c,0x3c3c3c3c,0x7c7c7c7c,0x3c423c3c,0x3c3c3c00,
--      0x7c3a3a3a,0x3a087c08,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x4200000,0x10000020,0x0,0x0,0x10,0x0,0x30000000,0x0,
--      0x0,0x0,0x60000,0x0,0x1c,0x4380000,0x0,0x2,0x800,0x0,0x40020000,0x0,0x8000c,0x10600000,0x2010,0x48000000,0x240000,0x0,0x0,
--      0x0,0x0,0x0,0x1000,0x1078,0x0,0x0,0x0,0x400500,0x0,0x1e081e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x84008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8000000,0x0,0x20000040,0x0,0x0,0x20,0x0,0x1e000000,0x0,0x0,0x0,0x20000,0x0,
--      0x0,0x2000000,0x0,0x26,0x800,0x0,0x40020000,0x0,0x100000,0x10000000,0x2030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x1000,0x0,
--      0x0,0x0,0x400000,0x8000000,0x41e0400,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x104010,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x1c,0x7000,0x0,0x40020000,0x0,0x300000,
--      0x0,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x400000,0x38000000,0x0,0x0,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x1c,0x0,0x0,0x0,0x0,0x0,0x304030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 10x19 font
--    const unsigned int font10x19[10*19*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3600000,0x36000,0x0,0x0,0x0,0x0,0x6c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x180181c0,0xe81b0300,0x1801,0x81c06c18,0x181c06c,0xe8180,0x181c0e81,0xb0000006,0x60701b,0x1800000,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x1c000,0x0,0x0,0x0,0x0,0x6c,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0xc030360,0xb81b0480,0xc03,0x3606c0c,0x303606c,0xb80c0,0x30360b81,0xb0000003,0xc0d81b,0x3000000,0x0,
--      0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x2200000,
--      0x22000,0x0,0x0,0x0,0x0,0x0,0x0,0x30000,0x0,0xe0,0x38078000,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000c080,0x480,0x3000,
--      0xc0800030,0xc08000,0x300,0xc080000,0xc,0x302000,0xc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x41c01,0xe020060c,
--      0x800000,0x4,0x1e0703e0,0xf8060fc1,0xe1fe1e07,0x80000000,0x78,0x307e0,0x3c7c1fe7,0xf83c408f,0x80f10440,0x18660878,0x7e0787e0,
--      0x78ff9024,0xa0140a0,0x27f83840,0x700e000,0x18000400,0x8000,0x70004002,0x410078,0x0,0x0,0x0,0x0,0x1808,0xc000000,0xf000000,
--      0xe000000,0x1400,0x1e0001f,0x8007f800,0x0,0x0,0x3a3b,0x61400000,0x14202,0x20000,0x38002020,0x3c1b00,0x3e00000,0xf8,0x1c0001c0,
--      0x78060001,0xf800000e,0x1e00020,0x8004020,0xc0300c0,0x300c0301,0xf83c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1821e0,0x781e0781,0xe0001f10,
--      0x24090240,0xa02400f8,0x18018140,0xe81b0480,0x1801,0x81406c18,0x181406c,0x190e8180,0x18140e81,0xb0000006,0x60501b,0x184006c,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x26042202,0x200c06,0x800000,0x8,0x210d0611,0x40e0803,0x10026188,0x40000000,
--      0x8c,0xf030418,0xc6431004,0xc64082,0x110840,0x18660884,0x41084410,0x8c081024,0xa012110,0x40082020,0x101b000,0xc000400,0x8000,
--      0x80004002,0x410008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x18800000,0x10000000,0x2200,0x2300024,0x800,0x0,0x0,0x2e13,0x60800000,
--      0x8104,0x20040,0x64001040,0x80401b07,0x80100000,0x1e000,0x22000020,0x40c0003,0xc8000002,0x3300020,0x8004020,0xc0300c0,0x300c0301,
--      0x40c64010,0x4010008,0x2008020,0x43182210,0x84210842,0x10002190,0x24090240,0x9044018c,0xc030220,0xb81b0300,0xc03,0x2206c0c,
--      0x302206c,0x1e0b80c0,0x30220b81,0xb0000003,0xc0881b,0x304006c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x241f2202,
--      0x200802,0x4900000,0x8,0x21010408,0x20a0802,0x44090,0x20000000,0x4,0x11878408,0x80411004,0x804082,0x111040,0x1ce50986,0x40986409,
--      0x81022,0x12012108,0x80102020,0x1031800,0x400,0x8000,0x80004000,0x10008,0x0,0x0,0x100000,0x0,0x2008,0x2000000,0x10000000,
--      0x10000000,0x18,0x4000044,0x1000,0x30180,0xd81b0000,0x13,0xe0000000,0x88,0x40,0x400018c0,0x80400018,0x61f00000,0x61800,0x22020020,
--      0x4000007,0xc8000002,0x2100020,0x8038000,0x1e0781e0,0x781e0301,0x40804010,0x4010008,0x2008020,0x41142619,0x86619866,0x18002190,
--      0x24090240,0x8887e104,0x0,0x0,0x0,0x0,0x0,0x2000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20120,0x2434a202,
--      0x200802,0x3e00000,0x10,0x40810008,0x21a0804,0x44090,0x20000000,0x80040004,0x20848409,0x409004,0x1004082,0x112040,0x14a50902,
--      0x40902409,0x81022,0x11321208,0x80202010,0x1060c00,0x7c5e0,0x781e8783,0xf07a5f0e,0x1c10808,0xfc5f078,0x5e07a170,0x7c7e1024,
--      0xa016190,0x27f82008,0x2000000,0x20000000,0x10000000,0x80200024,0x4000044,0x2000,0x18180,0xc8320000,0x12,0xa1f00037,0x7f888,
--      0x1e0,0x40410880,0x80600017,0xa2100000,0x5e800,0x22020040,0x38001027,0xc8000002,0x2100020,0x8004020,0x12048120,0x48120482,
--      0x41004010,0x4010008,0x2008020,0x40942409,0x2409024,0x9044390,0x24090240,0x88841918,0x1f07c1f0,0x7c1f07c3,0x70781e07,0x81e07838,
--      0xe0380e0,0x1f17c1e0,0x781e0781,0xe0001f90,0x24090240,0x9025e102,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xff241c41,
--      0x1001,0x1c02000,0x10,0x40810008,0x6120f85,0xe0086190,0x20c03007,0x8007800c,0x27848419,0x409004,0x1004082,0x114040,0x14a48902,
--      0x40902409,0x81022,0x11321205,0x602010,0x1000000,0x86610,0x84218840,0x80866182,0x411008,0x9261884,0x61086189,0x82101022,0x12012108,
--      0x40082008,0x2000000,0x20030000,0x20000000,0x80200024,0x4000044,0x3006030,0xc018100,0x4c260000,0x12,0x26080048,0x83000850,
--      0x20250,0x403e0500,0x8078002c,0x12302200,0x92400,0x1c0200c0,0x4001027,0xc8000002,0x3308820,0x8004020,0x12048120,0x48120482,
--      0x41004010,0x4010008,0x2008020,0x40922409,0x2409024,0x8884690,0x24090240,0x85040920,0x21886218,0x86218860,0x88842108,0x42108408,
--      0x2008020,0x21186210,0x84210842,0x10302190,0x24090240,0x88461084,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x4c240182,
--      0x80001001,0x6b02000,0x20,0x4c810010,0x78220846,0x10081e10,0x20c0301c,0x1fe0e018,0x4d8487e1,0x409fe7,0xf9007f82,0x11a040,
--      0x13248902,0x41102418,0xe0081022,0x11320c05,0x402008,0x1000000,0x2409,0x409020,0x81024082,0x412008,0x9240902,0x40902101,0x101022,
--      0x11321208,0x40102008,0x2000000,0x7e0c8000,0xfc000003,0xf0fc0018,0x43802047,0x8c8040c8,0x32008300,0x44240000,0x0,0x4000048,
--      0x8c801050,0x20440,0x40221dc0,0x808c0028,0x11d0667f,0x8009c400,0x1fc180,0x4001023,0xc8300002,0x1e0ccfb,0x3ec7b020,0x12048120,
--      0x48120482,0x79007f9f,0xe7f9fe08,0x2008020,0xf0922409,0x2409024,0x8504490,0x24090240,0x85040920,0x802008,0x2008020,0x89004090,
--      0x24090208,0x2008020,0x40902409,0x2409024,0x8304390,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
--      0x481c0606,0xc8001001,0x802000,0x20,0x4c810020,0x4220024,0x8102108,0x60000070,0x3820,0x48884419,0x409004,0x10e4082,0x112040,
--      0x13244902,0x7e1027e0,0x3c081021,0x21320c02,0x802008,0x1000000,0x7e409,0x409020,0x81024082,0x414008,0x9240902,0x40902101,
--      0x80101022,0x11320c08,0x40202008,0x2038800,0x200bc000,0x20000000,0x80200003,0x80f04044,0xbc080bc,0x2f000200,0x0,0x0,0x6001048,
--      0x8bc02020,0x20441,0xf8220200,0x80820028,0x1000cc00,0x80094400,0x201e0,0x78001021,0xc830000f,0x8000663c,0xf03c0c0,0x21084210,
--      0x84210846,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8204890,0x24090240,0x82040930,0x1f87e1f8,0x7e1f87e0,0x89004090,
--      0x24090208,0x2008020,0x40902409,0x2409024,0x8004690,0x24090240,0x88440884,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,
--      0x480719c4,0x48001001,0x81fc00,0x7800020,0x40810040,0x2420024,0x8104087,0xa0000070,0x3820,0x48884409,0x409004,0x1024082,0x111040,
--      0x13244902,0x40102410,0x2081021,0x214a1202,0x1802008,0x1000000,0x182409,0x409fe0,0x81024082,0x41a008,0x9240902,0x40902100,
--      0xf8101021,0x214a0c04,0x80c0c008,0x1847000,0x7c1ee000,0x20000000,0x8020000c,0x8c044,0x1ee181ee,0x7b800000,0x707,0xf3ff0000,
--      0x3e0084f,0x9ee0c020,0x20440,0x40221fc0,0xc2002c,0x13f11000,0x87892400,0x20000,0x1020,0x48000000,0x3f011c6,0x31cc6180,0x21084210,
--      0x84210844,0x41004010,0x4010008,0x2008020,0x40912409,0x2409024,0x8505090,0x24090240,0x8204191c,0x60982609,0x82609823,0xf9007f9f,
--      0xe7f9fe08,0x2008020,0x40902409,0x2409024,0x9fe4c90,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xfe048224,
--      0x28001001,0x2000,0x40,0x40810080,0x27f8024,0x8104080,0x2000001c,0x1fe0e020,0x488fc409,0x409004,0x1024082,0x110840,0x10242902,
--      0x40102408,0x2081021,0x214a1202,0x1002004,0x1000000,0x102409,0x409000,0x81024082,0x411008,0x9240902,0x40902100,0x6101021,
--      0x214a0c04,0x81002008,0x2000000,0x201dc000,0x20000000,0x80200000,0x98044,0x1dc101dc,0x77000000,0x700,0x0,0x180448,0x1dc10020,
--      0x20440,0x403e0200,0x620017,0xa000cc00,0x80052800,0x20000,0x1020,0x48000000,0x6606,0x206100,0x3f0fc3f0,0xfc3f0fc7,0xc1004010,
--      0x4010008,0x2008020,0x4090a409,0x2409024,0x8886090,0x24090240,0x8207e106,0x40902409,0x2409024,0x81004010,0x4010008,0x2008020,
--      0x40902409,0x2409024,0x8005890,0x24090240,0x84840848,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98048224,0x30001001,0x2000,
--      0x40,0x21010100,0x2020024,0x8204080,0x40000007,0x80078000,0x48884408,0x80411004,0x824082,0x110840,0x10242986,0x40086409,0x2081021,
--      0xe14a2102,0x2002004,0x1000000,0x106409,0x409000,0x81024082,0x410808,0x9240902,0x40902100,0x2101021,0x214a1202,0x82002008,
--      0x2000000,0x300f8000,0x20000000,0x80fc001d,0xe4088044,0xf8200f8,0x3e000000,0x300,0x0,0x80c48,0xf820020,0x20640,0x40410200,
--      0x803c0018,0x60006600,0x61800,0x0,0x1020,0x48000000,0xcc0a,0x20a100,0x21084210,0x84210844,0x40804010,0x4010008,0x2008020,
--      0x4110a619,0x86619866,0x19046110,0x24090240,0x82040102,0x41906419,0x6419064,0x81004010,0x4010008,0x2008020,0x40902409,0x2409024,
--      0x8307090,0x24090240,0x82840828,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x90248222,0x30000802,0x200c,0xc080,0x21010301,
--      0x4021042,0x10202108,0xc0c03000,0x80040020,0x4d902418,0xc6431004,0xc24082,0x6210440,0x10241884,0x40084409,0x86080840,0xc0842102,
--      0x4002002,0x1000000,0x18e610,0x84218820,0x80864082,0x410408,0x9240884,0x61086101,0x6101860,0xc0842103,0x4002008,0x2000000,
--      0x10850180,0x20330000,0x80200013,0x26184024,0x5040050,0x14000000,0x0,0x0,0x4180848,0x85040020,0x20350,0x40000200,0x800c0007,
--      0x80002200,0x1e000,0x0,0x1860,0x48000000,0x880a,0x40a188,0x40902409,0x2409028,0x40c64010,0x4010008,0x2008020,0x43106210,0x84210842,
--      0x10006108,0x42108421,0x2040102,0x6398e639,0x8e6398e4,0x88842088,0x22088208,0x2008020,0x21102210,0x84210842,0x10306118,0x66198661,
--      0x83061030,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0x901f01c1,0xe8000802,0xc,0xc080,0x1e07c7f8,0xf8020f81,0xe0401e07,
--      0x80c03000,0x20,0x279027e0,0x3c7c1fe4,0x3c408f,0x83c1027f,0x90241878,0x4007c404,0xf8080780,0xc0844082,0x7f82002,0x1000000,
--      0xfa5e0,0x781e87c0,0x807a409f,0xc0410207,0x9240878,0x5e07a100,0xf80e0fa0,0xc0846183,0x7f82008,0x2000000,0xf020100,0x40321360,
--      0x80200014,0xa3e0201f,0x8207f820,0x8000000,0x0,0x0,0x3e01037,0x207f820,0x201e1,0xfc000200,0x80040000,0x0,0x0,0x1fc000,0x17b0,
--      0x48000000,0x12,0xc120f0,0x40902409,0x2409028,0x783c7f9f,0xe7f9fe3e,0xf83e0f8,0x7c1061e0,0x781e0781,0xe000be07,0x81e0781e,
--      0x204017c,0x3e8fa3e8,0xfa3e8fa3,0x70781f07,0xc1f07c7f,0x1fc7f1fc,0x1e1021e0,0x781e0781,0xe0007e0f,0xa3e8fa3e,0x8305e030,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0xc06,0xc,0x100,0x0,0x0,0x0,0x3000,0x0,0x20000000,0x0,0x0,0x0,0x0,0xc000,
--      0x0,0x0,0x2001,0x1000000,0x0,0x0,0x20000,0x400000,0x0,0x40002000,0x0,0x1,0x2008,0x2000000,0x100,0x40240000,0x80200008,0x40000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80040000,0x0,0x0,0x0,0x1000,0x48000000,0x1f,0x181f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1040010,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000,0x60c,0x18,0x0,
--      0x0,0x0,0x0,0x6000,0x0,0x10000000,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x3800,0x7000000,0x0,0x0,0x840000,0x400000,0x0,0x40002000,
--      0x0,0x2,0x2008,0x2000000,0x200,0x40440000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x80780000,0x0,0x0,0x0,0x1000,0x48000400,
--      0x2,0x1e02000,0x0,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x2040020,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x4000,0x0,0xf000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x780000,0x3800000,0x0,0x40002000,0x0,0xe,0x1808,0xc000000,0x3,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,
--      0x0,0x0,0x0,0x1000,0x1c00,0x0,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0xe0400e0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fc,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 12x24 font
--     const unsigned int font12x24[12*24*256/32] = {
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x80000000,0x198000,0x0,0x0,0x0,0x0,
--       0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc001806,0xc81980,0x60000000,0xc001806,0x1980c00,0x18060198,0xc80c,
--       0x180600,0xc8198000,0xc001,0x80601980,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x600300f,0x1301980,0x90000000,0x600300f,0x1980600,0x300f0198,0x13006,0x300f01,0x30198000,0x6003,
--       0xf01980,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x60000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7007,0x3c0000,0x3006019,
--       0x80000000,0x90000000,0x3006019,0x80000300,0x60198000,0x3,0x601980,0x0,0x3006,0x1980000,0x60000000,0x0,0x0,0xe0000000,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000000,
--       0x0,0x0,0x0,0x0,0x0,0xc800019,0x80000000,0x198000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x1001,0x420000,0x0,0x0,0x90000000,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000c06,0xc80001,0x10000000,0x18000c06,0x1800,0xc060000,0xc818,0xc0600,0xc8000000,
--       0x18000,0xc0600000,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80660207,0x800f8060,0x300c004,0x0,0x6,
--       0xe00703f,0x3f00383,0xf80f07fc,0x1f01f000,0x0,0xf8,0x607f,0x7c7e07,0xfe7fe0f8,0x6063fc1f,0x86066007,0xe7060f0,0x7f80f07f,
--       0x81f8fff6,0x6606c03,0x70ee077f,0xe0786000,0xf0070000,0xc000060,0xc0,0x3e000,0x60006003,0x600fc00,0x0,0x0,0x0,0x0,0x0,0x3c0603,
--       0xc0000000,0x7800000,0xf0000,0x0,0xf00001f,0x80001fe0,0x7fe000,0x0,0x0,0x0,0x168fe609,0x0,0x90e07,0x6000,0x3c000e,0x70000f8,
--       0x1980001f,0x0,0x1f8,0xf00000f,0xf00180,0xfe000,0xe00e,0x1001,0x20060,0x6006006,0x600600,0x600fe07c,0x7fe7fe7f,0xe7fe3fc3,
--       0xfc3fc3fc,0x7e07060f,0xf00f00,0xf00f0000,0xf360660,0x6606606e,0x76001e0,0xc00180f,0x1681981,0x10000000,0xc00180f,0x1980c00,
--       0x180f0198,0x3801680c,0x180f01,0x68198000,0xc001,0x80f01980,0x18600198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,
--       0x8044020c,0xc01f8060,0x2004004,0x0,0xc,0x3f81f07f,0x87f80383,0xf81f87fc,0x3f83f800,0x0,0x1fc,0x780607f,0x81fe7f87,0xfe7fe1fc,
--       0x6063fc1f,0x860c6007,0xe7061f8,0x7fc1f87f,0xc3fcfff6,0x6606c03,0x30c6067f,0xe0783000,0xf00d8000,0x6000060,0xc0,0x7e000,0x60006003,
--       0x600fc00,0x0,0x0,0xc00,0x0,0x0,0x7c0603,0xe0000000,0xfc00000,0x1f0000,0x0,0x900003f,0xc0003fe0,0x7fe000,0x0,0x0,0x0,0x1302660f,
--       0x0,0xf0606,0x6004,0x7e0006,0x60601f8,0x19800001,0x80000000,0x1f8,0x19800010,0x81080300,0x3f2000,0x2011,0x1001,0x1c0060,0x6006006,
--       0x600600,0x601fe1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f87061f,0x81f81f81,0xf81f8000,0x3fa60660,0x66066066,0x66003f0,0x6003009,
--       0x1301981,0x10000000,0x6003009,0x1980600,0x30090198,0x1f013006,0x300901,0x30198000,0x6003,0x901980,0x30600198,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc0f8c,0xc0180060,0x6006044,0x40000000,0xc,0x3181b041,0xc41c0783,0x388018,
--       0x71c71800,0x0,0x106,0x18c0f061,0xc38261c6,0x600384,0x60606001,0x86186007,0xe78630c,0x60e30c60,0xe7040606,0x630cc03,0x39c30c00,
--       0xc0603000,0x3018c000,0x3000060,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,0x60000000,0x18400000,0x180000,
--       0x0,0x19800070,0x40003600,0xc000,0x0,0x0,0x0,0x25a06,0x0,0x6030c,0x4,0xe20007,0xe060180,0xf000,0x80000000,0xf0000,0x10800000,
--       0x80080600,0x7f2000,0x2020,0x80001001,0x20000,0xf00f00f,0xf00f00,0x601b0382,0x60060060,0x6000600,0x60060060,0x61c78630,0xc30c30c3,
--       0xc30c000,0x30e60660,0x66066063,0xc600738,0x3006019,0x80000000,0xe0000000,0x3006019,0x80000300,0x60198000,0x3e000003,0x601980,
--       0x0,0x3006,0x1980000,0x60600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc1fcc,0xc0180060,0x6006035,0x80000000,
--       0x18,0x71c03000,0xc00c0583,0x300018,0x60c60c00,0x0,0x6,0x3060f060,0xc30060c6,0x600300,0x60606001,0x86306007,0x9e78670e,0x60670e60,
--       0x66000606,0x630c606,0x19830c01,0xc0601800,0x30306000,0x60,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,
--       0x60000000,0x18000000,0x300000,0x0,0x78060,0x6600,0x1c000,0x300c,0x39819c0,0x0,0x25a00,0x0,0x30c,0x4,0xc00003,0xc060180,0x30c1f,
--       0x80000000,0x30c000,0x10800001,0x80700000,0x7f2000,0x2020,0x80001001,0x20060,0xf00f00f,0xf00f00,0xf01b0300,0x60060060,0x6000600,
--       0x60060060,0x60c78670,0xe70e70e7,0xe70e000,0x70c60660,0x66066063,0xc7f8618,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,
--       0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x87ff3a4c,0xc0180060,0x400600e,0x600000,0x18,0x60c03000,
--       0xc00c0d83,0x700018,0x60c60c00,0x20,0x400006,0x3060f060,0xc6006066,0x600600,0x60606001,0x86606006,0x966c6606,0x60660660,0x66000606,
--       0x630c666,0xf019801,0x80601800,0x30603000,0x1f06f,0xf01ec0,0xf03fe1ec,0x6703e01f,0x61c0c06,0xdc6701f0,0x6f01ec0c,0xe1f87fc6,
--       0xc60cc03,0x71c60c7f,0xc0600600,0x60000000,0x30000000,0x300000,0x40040,0x88060,0x6600,0x18000,0x300c,0x1981980,0x0,0x2421f,
--       0x80003ce0,0x7fc198,0x601f,0xc02021,0x980600c0,0x40230,0x80000000,0x402000,0x19806003,0x80006,0xc7f2000,0x2020,0x80001001,
--       0x420060,0xf00f00f,0xf00f00,0xf01b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x6606208,0x60e60660,0x66066061,
--       0x987fc670,0x1f01f01f,0x1f01f01,0xf039c0f0,0xf00f00f,0xf03e03,0xe03e03e0,0x1f06701f,0x1f01f01,0xf01f0060,0x1e660c60,0xc60c60c6,
--       0xc6f060c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x7ff3207,0x8c0c0000,0xc00300e,0x600000,0x30,0x60c03000,
--       0xc01c0983,0xf0600030,0x31860c06,0x6001e0,0x78000e,0x23e1f861,0xc6006066,0x600600,0x60606001,0x86c06006,0x966c6606,0x60660660,
--       0xe7000606,0x630c666,0xf01f803,0x600c00,0x30000000,0x3f87f,0x83f83fc3,0xf83fe3fc,0x7f83e01f,0x6380c07,0xfe7f83f8,0x7f83fc0d,
--       0xf3fc7fc6,0xc71cc03,0x3183187f,0xc0600600,0x60000000,0xff806000,0x300000,0x40040,0x88070,0x6600,0x60030060,0x6001818,0x1883180,
--       0x0,0x2423f,0xc0007ff0,0x607fc1f8,0x603f,0x80c01fc1,0xf80601e0,0x5f220,0x80420000,0x5f2000,0xf006006,0x80006,0xc7f2000,0x2020,
--       0x82107c07,0xc03c0060,0x1f81f81f,0x81f81f80,0xf03b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x660671c,0x61660660,
--       0x66066061,0xf860e6c0,0x3f83f83f,0x83f83f83,0xf87fe3f8,0x3f83f83f,0x83f83e03,0xe03e03e0,0x3f87f83f,0x83f83f83,0xf83f8060,
--       0x3fc60c60,0xc60c60c3,0x187f8318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x883200,0x300c0000,0xc003035,0x80600000,
--       0x30,0x66c03001,0xc0f81983,0xf86f0030,0x1f071c06,0x600787,0xfe1e001c,0x6261987f,0x86006067,0xfe7fc600,0x7fe06001,0x87c06006,
--       0xf6646606,0x60e6067f,0xc3e00606,0x61986f6,0x600f007,0x600c00,0x30000000,0x21c71,0x830831c3,0x1c06031c,0x71c06003,0x6700c06,
--       0x6671c318,0x71831c0f,0x16040c06,0xc318606,0x1b031803,0x80600600,0x60000000,0x30009000,0x300000,0x40040,0x7003e,0x67e0,0x90070090,
--       0x9001818,0x8c3100,0x0,0x60,0x4000e730,0x900380f0,0x6034,0x80c018c7,0xfe060338,0xb0121,0x80c60000,0x909000,0x6008,0x1080006,
--       0xc3f2000,0x2011,0x3180060,0x60060e0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0x60664660,0x66066066,
--       0x66063b8,0x62660660,0x66066060,0xf06066c0,0x21c21c21,0xc21c21c2,0x1c466308,0x31c31c31,0xc31c0600,0x60060060,0x31871c31,0x83183183,
--       0x18318000,0x71860c60,0xc60c60c3,0x18718318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1981a00,0xe03e0000,0xc003044,
--       0x40600000,0x60,0x66c03001,0x80f03182,0x1c7f8030,0x3f83fc06,0x601e07,0xfe078038,0x6661987f,0x86006067,0xfe7fc61e,0x7fe06001,
--       0x87e06006,0x66666606,0x7fc6067f,0x81f80606,0x61986f6,0x6006006,0x600600,0x30000000,0xc60,0xc60060c6,0xc06060c,0x60c06003,
--       0x6e00c06,0x6660c60c,0x60c60c0e,0x6000c06,0xc318666,0x1f031803,0x600600,0x603c2000,0x30016800,0x1fe0000,0x1f81f8,0x1c1f,0x804067e1,
--       0x68060168,0x16800810,0xc42300,0x0,0x60,0x20c331,0x68030060,0x6064,0x3fc1040,0xf006031c,0xa011e,0x818c7fe0,0x909000,0x7fe1f,
--       0x80f00006,0xc0f2060,0xf80e,0x18c0780,0x780781c0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0xfc666660,
--       0x66066066,0x66061f0,0x66660660,0x66066060,0x606066e0,0xc00c00,0xc00c00c0,0xc066600,0x60c60c60,0xc60c0600,0x60060060,0x60c60c60,
--       0xc60c60c6,0xc60c000,0x61c60c60,0xc60c60c3,0x1860c318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1980f81,0x80373000,
--       0xc003004,0x7fe0001,0xf0000060,0x60c03003,0x183180,0xc71c060,0x3181ec00,0x7000,0xe070,0x66619860,0xc6006066,0x60061e,0x60606001,
--       0x87606006,0x66626606,0x7f860661,0xc01c0606,0x6198696,0xf00600e,0x600600,0x30000000,0x1fc60,0xc60060c7,0xfc06060c,0x60c06003,
--       0x7c00c06,0x6660c60c,0x60c60c0c,0x7f00c06,0xc3b8666,0xe01b007,0x3c00600,0x3c7fe000,0xff03ec00,0x1fe0000,0x40040,0xe001,0xc0806603,
--       0xec0e03ec,0x3ec00010,0x0,0x60000000,0x7f,0x10c3f3,0xec070060,0x6064,0x3fc1040,0x6000030c,0xa0100,0x3187fe1,0xf09f1000,0x7fe00,
--       0x6,0xc012060,0x0,0xc63c03,0xc03c0380,0x19819819,0x81981981,0x98330600,0x60060060,0x6000600,0x60060060,0xfc662660,0x66066066,
--       0x66060e0,0x6c660660,0x66066060,0x6060e630,0x1fc1fc1f,0xc1fc1fc1,0xfc3fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
--       0xc60c7fe,0x62c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe02c6,0x3c633000,0xc003004,
--       0x7fe0001,0xf00000c0,0x60c03006,0xc6180,0xc60c060,0x60c00c00,0x7000,0xe060,0x66639c60,0x66006066,0x600606,0x60606001,0x86306006,
--       0x66636606,0x60060660,0xc0060606,0x61f8696,0xf00600c,0x600300,0x30000000,0x3fc60,0xc60060c7,0xfc06060c,0x60c06003,0x7c00c06,
--       0x6660c60c,0x60c60c0c,0x1f80c06,0xc1b0666,0xe01b00e,0x3c00600,0x3c43c000,0x3007de00,0x600000,0x40040,0x30000,0x61006607,0xde0c07de,
--       0x7de00000,0x0,0xf07fefff,0x1f,0x8008c3f7,0xde0e0060,0x6064,0xc01047,0xfe00018c,0xb013f,0x86300061,0xf0911000,0x6000,0x6,
--       0xc012060,0x3f,0x8063c0cc,0x3cc0c700,0x39c39c39,0xc39c39c1,0x98630600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,
--       0x66061f0,0x78660660,0x66066060,0x607fc618,0x3fc3fc3f,0xc3fc3fc3,0xfc7fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
--       0xc60c7fe,0x64c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe0260,0x6661b000,0xc003000,
--       0x600000,0xc0,0x60c0300c,0xc7fe0,0xc60c060,0x60c01c00,0x1e07,0xfe078060,0x6663fc60,0x66006066,0x600606,0x60606001,0x86386006,
--       0x6636606,0x60060660,0xe0060606,0x60f039c,0x1b806018,0x600300,0x30000000,0x70c60,0xc60060c6,0x6060c,0x60c06003,0x7600c06,
--       0x6660c60c,0x60c60c0c,0x1c0c06,0xc1b03fc,0xe01f01c,0xe00600,0x70000000,0x3007fc00,0x600000,0x40040,0x0,0x62006607,0xfc1807fc,
--       0x7fc00000,0x0,0xf0000000,0x1,0xc004c307,0xfc1c0060,0x6064,0xc018c0,0x600000d8,0x5f200,0x3180060,0x50a000,0x6000,0x6,0xc012000,
--       0x0,0xc601c0,0x4201c600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,0x66063b8,
--       0x70660660,0x66066060,0x607f860c,0x70c70c70,0xc70c70c7,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,
--       0x68c60c60,0xc60c60c1,0xf060c1f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3300260,0x6661e000,0xc003000,0x600000,
--       0x180,0x71c03018,0xc7fe0,0xc60c0c0,0x60c01800,0x787,0xfe1e0060,0x6663fc60,0x630060c6,0x600306,0x60606001,0x86186006,0x661e70e,
--       0x60070c60,0x60060606,0x60f039c,0x19806038,0x600180,0x30000000,0x60c60,0xc60060c6,0x6060c,0x60c06003,0x6700c06,0x6660c60c,
--       0x60c60c0c,0xc0c06,0xc1b039c,0x1f00e018,0x600600,0x60000000,0x1803f800,0x600000,0x40040,0x39e00,0x63006603,0xf83803f8,0x3f800000,
--       0x0,0x60000000,0x0,0xc00cc303,0xf8180060,0x6064,0xc01fc0,0x60060070,0x40200,0x18c0060,0x402000,0x6000,0x6,0xc012000,0x0,0x18c0140,
--       0x2014600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0300,0x60060060,0x6000600,0x60060060,0x60c61e70,0xe70e70e7,0xe70e71c,0x60e60660,0x66066060,
--       0x6060060c,0x60c60c60,0xc60c60c6,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,0x70c60c60,0xc60c60c0,
--       0xe060c0e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33022e0,0x6670c000,0xc003000,0x600600,0x60180,0x31803030,
--       0x41c0184,0x1831c0c0,0x71c23806,0x6001e0,0x780000,0x62630c60,0xe38261c6,0x600386,0x60606043,0x860c6006,0x661e30c,0x60030c60,
--       0x740e0607,0xe0f039c,0x31c06030,0x600180,0x30000000,0x61c71,0x830831c3,0x406031c,0x60c06003,0x6300c06,0x6660c318,0x71831c0c,
--       0x41c0c07,0x1c0e039c,0x1b00e030,0x600600,0x60000000,0x1c41b00e,0x601cc0,0x401f8,0x45240,0xe1803601,0xb03001b0,0x1b000000,
--       0x0,0x0,0x41,0xc008e711,0xb0300060,0x6034,0x80c02020,0x60060030,0x30c00,0xc60000,0x30c000,0x0,0x7,0x1c012000,0x0,0x3180240,
--       0x6024608,0x30c30c30,0xc30c30c3,0xc630382,0x60060060,0x6000600,0x60060060,0x61c61e30,0xc30c30c3,0xc30c208,0x70c70e70,0xe70e70e0,
--       0x6060068c,0x61c61c61,0xc61c61c6,0x1cc62308,0x30430430,0x43040600,0x60060060,0x31860c31,0x83183183,0x18318060,0x31c71c71,
--       0xc71c71c0,0xe07180e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2203fc0,0x663f6000,0x6006000,0x600600,0x60300,
--       0x3f81fe7f,0xc7f80187,0xf83f80c0,0x3f83f006,0x600020,0x400060,0x33e6067f,0xc1fe7f87,0xfe6001fe,0x6063fc7f,0x60e7fe6,0x660e3f8,
--       0x6001f860,0x37fc0603,0xfc06030c,0x30c0607f,0xe06000c0,0x30000000,0x7fc7f,0x83f83fc3,0xfc0603fc,0x60c7fe03,0x61807c6,0x6660c3f8,
--       0x7f83fc0c,0x7f80fc3,0xfc0e039c,0x3180607f,0xc0600600,0x60000000,0xfc0e00c,0x601986,0x66040040,0x4527f,0xc0803fe0,0xe07fe0e0,
--       0xe000000,0x0,0x0,0x7f,0x80107ff0,0xe07fc060,0x603f,0x83fe0000,0x60060018,0xf000,0x420000,0xf0000,0x7fe00,0x7,0xfe012000,
--       0x0,0x2100640,0xc0643f8,0x60660660,0x66066067,0xec3e1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f860e3f,0x83f83f83,0xf83f8000,
--       0x5fc3fc3f,0xc3fc3fc0,0x606006fc,0x7fc7fc7f,0xc7fc7fc7,0xfcffe3f8,0x3fc3fc3f,0xc3fc7fe7,0xfe7fe7fe,0x3f860c3f,0x83f83f83,
--       0xf83f8060,0x7f83fc3f,0xc3fc3fc0,0x607f8060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2201f80,0x3c1e7000,0x6006000,
--       0x600,0x60300,0xe01fe7f,0xc3f00183,0xe01f0180,0x1f01e006,0x600000,0x60,0x3006067f,0x807c7e07,0xfe6000f8,0x6063fc3e,0x6067fe6,
--       0x660e0f0,0x6000f060,0x3bf80601,0xf806030c,0x60e0607f,0xe06000c0,0x30000000,0x1ec6f,0xf01ec0,0xf80601ec,0x60c7fe03,0x61c03c6,
--       0x6660c1f0,0x6f01ec0c,0x3f007c1,0xcc0e030c,0x71c0c07f,0xc0600600,0x60000000,0x7804018,0xe01186,0x66040040,0x39e3f,0x80401fe0,
--       0x407fe040,0x4000000,0x0,0x0,0x3f,0x203ce0,0x407fc060,0x601f,0x3fe0000,0x60060018,0x0,0x0,0x0,0x7fe00,0x6,0xe6012000,0x0,
--       0x7e0,0x1807e1f0,0x60660660,0x66066066,0x6c3e07c,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7e060e0f,0xf00f00,0xf00f0000,0x8f01f81f,
--       0x81f81f80,0x60600670,0x1ec1ec1e,0xc1ec1ec1,0xec79c0f0,0xf80f80f,0x80f87fe7,0xfe7fe7fe,0x1f060c1f,0x1f01f01,0xf01f0000,0x4f01cc1c,
--       0xc1cc1cc0,0xc06f00c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x6006000,0x600,0x600,0x0,0x0,0x0,0x0,
--       0x600000,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x600060,0x30000000,0x0,0x0,0xc,0x3,0x0,0x0,0x60000c00,0x0,
--       0x0,0xc000,0x600600,0x60000000,0x18,0xc03100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f8,0x0,0x0,0x0,0x0,0x6,
--       0x12000,0x2000000,0x40,0x20004000,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0xc06000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x2004000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,
--       0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x21c,0x3,0x0,0x0,0x60000c00,0x0,0x0,0xc000,
--       0x7c0603,0xe0000000,0x10,0xc02300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f0,0x0,0x0,0x0,0x0,0x6,0x12000,0x1000000,
--       0x40,0x7e004000,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc06000c0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x300c000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,0x0,0x7800000,0x0,
--       0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x3f8,0x3e,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x3c0603,0xc0000000,
--       0x10,0xfc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x60000,0x0,0x0,0x0,0x0,0x6,0x0,0x1000000,0x0,0x0,0x0,0x0,
--       0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,
--       0x0,0x1f0,0x3c,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x600,0x0,0x0,0xf000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x6,0x0,0xe000000,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--       0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 16x32 font
--    const unsigned int font16x32[16*32*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70000e0,0x3c00730,0xe7001c0,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0x730,0x70000e0,0x3c00730,
--      0xe700000,0x700,0xe003c0,0xe7000e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x18001c0,0x6600ff0,0xe7003e0,0x0,0x18001c0,0x6600e70,0x18001c0,0x6600e70,0xff0,0x18001c0,0x6600ff0,0xe700000,0x180,
--      0x1c00660,0xe7001c0,0x0,0x0,0x0,0x380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,
--      0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00380,
--      0xc300ce0,0xe700630,0x0,0x1c00380,0xc300e70,0x1c00380,0xc300e70,0xce0,0x1c00380,0xc300ce0,0xe700000,0x1c0,0x3800c30,0xe700380,
--      0x0,0x0,0x0,0x7c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x700000,0x0,0x0,0x0,0x7c007c00,0x3e000000,
--      0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000070,0x1800000,0xc60,0x0,0xe000070,0x1800000,0xe000070,
--      0x1800000,0x0,0xe000070,0x1800000,0x0,0xe00,0x700180,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x800000,0x0,0x600600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x3f0,0xfc0,0x0,0x7000000,0x38000000,0x1c0000,0xfc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,
--      0x1801f00,0x0,0x0,0x1c,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7300000,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0xe700000,
--      0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0xc000c00,0x43800000,0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0xf80,0x70000e0,0x3c00730,0xe700c60,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0xe000730,0x70000e0,0x3c00730,0xe700000,0x700,
--      0xe003c0,0xe7000e0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300000,0x803c00,0x7c00180,
--      0xc00300,0x1000000,0x0,0x1c,0x3c007c0,0xfc007e0,0xe01ff8,0x3f03ffc,0x7e007c0,0x0,0x0,0x7c0,0x1c0,0x7f8003f0,0x7f007ff8,0x7ff803f0,
--      0x70381ffc,0xff0700e,0x7000783c,0x783807c0,0x7fc007c0,0x7fc00fc0,0x7fff7038,0x700ee007,0x780f780f,0x7ffc03f0,0x70000fc0,0x3c00000,
--      0x3000000,0x38000000,0x1c0000,0x1fc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x1801f80,0x0,0x1f80000,
--      0x7e,0x0,0x0,0x2400000,0xfc00000,0x7ff0000,0x7ffc0000,0x0,0x0,0x0,0x0,0xf30fb0c,0x2400000,0x0,0x240780f,0x1c0,0xfc,0x780f,
--      0x18003f0,0xe700000,0x7c00000,0x0,0xff0,0x3c00000,0x78007c0,0xc00000,0xff80000,0xf80,0x7c00000,0xc000c00,0x18001c0,0x1c001c0,
--      0x1c001c0,0x1c003e0,0x7fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007838,0x7c007c0,0x7c007c0,0x7c00000,0x7c67038,
--      0x70387038,0x7038780f,0x70001fe0,0x30000c0,0x2400f30,0xe700c60,0x0,0x30000c0,0x2400e70,0x30000c0,0x2400e70,0xf700f30,0x30000c0,
--      0x2400f30,0xe700000,0x300,0xc00240,0xe7000c0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,
--      0x630018c,0x807e00,0xfe00180,0xc00300,0x1000000,0x0,0x38,0xff01fc0,0x3ff01ff0,0x1e01ff8,0x7f83ffc,0x1ff80ff0,0x0,0x0,0xff0,
--      0x1f003e0,0x7fe00ff8,0x7fc07ff8,0x7ff80ff8,0x70381ffc,0xff0701c,0x7000783c,0x78381ff0,0x7fe01ff0,0x7fe01ff0,0x7fff7038,0x781ee007,
--      0x3c1e380e,0x7ffc0380,0x380001c0,0x3c00000,0x1800000,0x38000000,0x1c0000,0x3c00000,0x380001c0,0xe01c00,0x3800000,0x0,0x0,
--      0x0,0x7000000,0x0,0x0,0x1e0,0x18003c0,0x0,0x3fc0000,0x70,0x0,0x0,0x6600000,0x1ff00000,0x1fff0000,0x7ffc0000,0x0,0x0,0x0,0x0,
--      0xcf0239c,0x3c00000,0x0,0x3c0380e,0x1c0,0x2001fe,0x380e,0x18007f8,0xe700000,0x8600000,0x0,0xff0,0x7e00000,0x8c00870,0x1800000,
--      0x1ff80000,0x180,0xc600000,0xc000c00,0x38001c0,0x3e003e0,0x3e003e0,0x3e001c0,0x7fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,
--      0x7fc07838,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x1fec7038,0x70387038,0x7038380e,0x70003ce0,0x1800180,0x6600cf0,0xe7007c0,0x0,
--      0x1800180,0x6600e70,0x1800180,0x6600e70,0x7c00cf0,0x1800180,0x6600cf0,0xe700000,0x180,0x1800660,0xe700180,0x38000e70,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630030c,0x3f0e700,0x1e200180,0x1800180,0x21100000,0x0,
--      0x38,0x1e7819c0,0x38781038,0x1e01c00,0xf080038,0x1c381c38,0x0,0x0,0x1878,0x7fc03e0,0x70e01e18,0x70e07000,0x70001e18,0x703801c0,
--      0x707038,0x70007c7c,0x7c381c70,0x70701c70,0x70703830,0x1c07038,0x381ce007,0x1c1c3c1e,0x3c0380,0x380001c0,0x7e00000,0xc00000,
--      0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,0x70c0000,0xe0,
--      0x0,0x0,0xc300000,0x38300000,0x3c700000,0x3c0000,0x0,0x0,0x0,0x0,0xce022f4,0x1800000,0x0,0x1803c1e,0x1c0,0x2003c2,0x3c1e,
--      0x1800e08,0x7e0,0x300000,0x0,0x7e00000,0xe700000,0x600030,0x3000000,0x3f980000,0x180,0x18200000,0xc000c00,0x1e0001c0,0x3e003e0,
--      0x3e003e0,0x3e003e0,0xfe01e18,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70e07c38,0x1c701c70,0x1c701c70,0x1c700000,0x3c787038,
--      0x70387038,0x70383c1e,0x70003870,0xc00300,0xc300ce0,0x380,0x0,0xc00300,0xc300000,0xc00300,0xc300000,0xfc00ce0,0xc00300,0xc300ce0,
--      0x0,0xc0,0x3000c30,0x300,0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630031c,0xff8c300,
--      0x1c000180,0x1800180,0x39380000,0x0,0x70,0x1c3801c0,0x203c001c,0x3e01c00,0x1c000038,0x381c3838,0x0,0x0,0x1038,0xe0e03e0,0x70703c08,
--      0x70707000,0x70003808,0x703801c0,0x707070,0x70007c7c,0x7c383838,0x70383838,0x70387010,0x1c07038,0x381c700e,0x1e3c1c1c,0x780380,
--      0x1c0001c0,0xe700000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,
--      0x0,0xe000000,0xe0,0x0,0x1000100,0x3800,0x70100000,0x38700000,0x780000,0x1c0,0x7801ce0,0xe380000,0x0,0x2264,0x0,0x0,0x1c1c,
--      0x0,0x200780,0x1c1c,0x1800c00,0x1818,0x7f00000,0x0,0x18180000,0xc300000,0x600070,0x0,0x7f980000,0x180,0x18300000,0xc000c00,
--      0x3000000,0x3e003e0,0x3e003e0,0x3e003e0,0xee03c08,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,
--      0x38380000,0x38387038,0x70387038,0x70381c1c,0x7fc03870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbc00000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0xe88c300,0x1c000180,0x38001c0,
--      0xfe00180,0x0,0x70,0x1c3801c0,0x1c001c,0x6e01c00,0x1c000078,0x381c3818,0x0,0x40000,0x40000038,0x1c0607e0,0x70703800,0x70707000,
--      0x70003800,0x703801c0,0x7070e0,0x70007c7c,0x7c383838,0x70383838,0x70387000,0x1c07038,0x381c700e,0xf780e38,0x700380,0x1c0001c0,
--      0x1c380000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,
--      0xe000000,0xe0,0x0,0x1000100,0x4400,0x70000000,0x38700000,0x700000,0xe0,0x7001c70,0xe380000,0x0,0x2264,0x0,0x0,0xe38,0x0,
--      0x200700,0xe38,0x1800c00,0x300c,0xc300000,0x0,0x300c0000,0xc300180,0x6003c0,0x0,0x7f980000,0x180,0x18300000,0xc000c00,0x1800000,
--      0x7e007e0,0x7e007e0,0x7e003e0,0xee03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,0x38380000,
--      0x38387038,0x70387038,0x70380e38,0x7ff039f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x40000,0x0,0x0,0x38000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0x1c80e700,0x1c000180,0x38001c0,0x3800180,
--      0x0,0xe0,0x381c01c0,0x1c001c,0x6e01c00,0x38000070,0x381c381c,0x0,0x3c0000,0x78000078,0x38030770,0x70707800,0x70387000,0x70007000,
--      0x703801c0,0x7071c0,0x7000745c,0x7638701c,0x7038701c,0x70387000,0x1c07038,0x1c38718e,0x7700f78,0xf00380,0xe0001c0,0x381c0000,
--      0x7e0,0x39e003e0,0x79c03f0,0x3ffc079c,0x39e01fc0,0xfe01c1e,0x3807778,0x39e007e0,0x39e0079c,0x73c07e0,0x7ff83838,0x701ce007,
--      0x783c701c,0x1ffc01c0,0x18001c0,0x0,0x1c000100,0xe0,0x0,0x1000100,0x4200,0x70000000,0x70700100,0xf00100,0x10000e0,0x7000c70,
--      0xc700000,0x0,0x2204,0x7e00000,0x1e380100,0x1ffc0f78,0x0,0xf80700,0xf78,0x1800e00,0x63e6,0x18300000,0x0,0x6fe60000,0xe700180,
--      0xc00060,0x3838,0x7f980000,0x180,0x18300000,0xc000c00,0x18001c0,0x7700770,0x7700770,0x77007f0,0xee07800,0x70007000,0x70007000,
--      0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1008,0x707c7038,0x70387038,0x70380f78,0x707039c0,0x7e007e0,0x7e007e0,
--      0x7e007e0,0x1f3c03e0,0x3f003f0,0x3f003f0,0x1fc01fc0,0x1fc01fc0,0x7f039e0,0x7e007e0,0x7e007e0,0x7e00380,0x7ce3838,0x38383838,
--      0x3838701c,0x39e0701c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6307fff,0x1c807e0c,0xe000180,
--      0x30000c0,0x3800180,0x0,0xe0,0x381c01c0,0x1c001c,0xce01fe0,0x38000070,0x381c381c,0x3800380,0xfc0000,0x7e0000f0,0x30030770,
--      0x70707000,0x70387000,0x70007000,0x703801c0,0x707380,0x700076dc,0x7638701c,0x7038701c,0x70387800,0x1c07038,0x1c3873ce,0x7f00770,
--      0xe00380,0xe0001c0,0x700e0000,0x1ff8,0x3ff00ff0,0xffc0ff8,0x3ffc0ffc,0x3bf01fc0,0xfe01c3c,0x3807f78,0x3bf00ff0,0x3ff00ffc,
--      0x77e0ff0,0x7ff83838,0x3838e007,0x3c783838,0x1ffc01c0,0x18001c0,0x0,0x7ff00380,0x1e0,0x0,0x1000100,0x4200,0x78000000,0x70700380,
--      0xe00380,0x3800060,0xe000e30,0x1c600000,0x0,0x2204,0xff00000,0x7f7c0380,0x1ffc0770,0x1c0,0x3fc0700,0x18040770,0x1800780,0x4e12,
--      0x18300104,0x0,0x4c320000,0x7e00180,0x1c00030,0x3838,0x7f980000,0x180,0x18302080,0xc000c00,0x18001c0,0x7700770,0x7700770,
--      0x7700770,0x1ee07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c381c,0x705c7038,0x70387038,
--      0x70380770,0x70383b80,0x1ff81ff8,0x1ff81ff8,0x1ff81ff8,0x3fbe0ff0,0xff80ff8,0xff80ff8,0x1fc01fc0,0x1fc01fc0,0xff83bf0,0xff00ff0,
--      0xff00ff0,0xff00380,0xffc3838,0x38383838,0x38383838,0x3ff03838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x1c0,0x7fff,0x1c803c38,0xf000000,0x70000e0,0xfe00180,0x0,0x1c0,0x381c01c0,0x3c0078,0xce01ff0,0x39e000f0,0x1c38381c,0x3800380,
--      0x3e07ffc,0xf8001f0,0x307b0770,0x70e07000,0x70387000,0x70007000,0x703801c0,0x707700,0x700076dc,0x7638701c,0x7038701c,0x70387e00,
--      0x1c07038,0x1c3873ce,0x3e007f0,0x1e00380,0x70001c0,0x0,0x1038,0x3c381e18,0x1c7c1e3c,0x3801e3c,0x3c7801c0,0xe01c78,0x380739c,
--      0x3c781c38,0x3c381c3c,0x7c21e10,0x7003838,0x3838700e,0x1ef03838,0x3c01c0,0x18001c0,0x0,0x7fe007c0,0x1c0,0x0,0x1000100,0x6400,
--      0x7e000000,0x707007c0,0x1e007c0,0x7c00070,0xe000638,0x18600000,0x0,0x0,0x1e100000,0x73ce07c0,0x3c07f0,0x1c0,0x7240700,0x1ddc3ffe,
--      0x1800de0,0x8c01,0x1870030c,0x0,0x8c310000,0x3c00180,0x3800030,0x3838,0x7f980000,0x180,0x183030c0,0xc000c00,0x430001c0,0x7700770,
--      0x7700770,0x7700770,0x1ce07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1c38,0x70dc7038,
--      0x70387038,0x703807f0,0x70383b80,0x10381038,0x10381038,0x10381038,0x21e71e18,0x1e3c1e3c,0x1e3c1e3c,0x1c001c0,0x1c001c0,0x1e383c78,
--      0x1c381c38,0x1c381c38,0x1c380380,0x1c383838,0x38383838,0x38383838,0x3c383838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0x1e8000e0,0x1f000000,0x70000e0,0x39380180,0x0,0x1c0,0x3b9c01c0,0x3c07f0,0x18e01078,0x3bf800e0,
--      0x7e0383c,0x3800380,0x1f807ffc,0x3f001c0,0x61ff0e38,0x7fc07000,0x70387ff0,0x7ff07000,0x7ff801c0,0x707f00,0x7000729c,0x7338701c,
--      0x7070701c,0x70703fc0,0x1c07038,0x1e7873ce,0x1c003e0,0x3c00380,0x70001c0,0x0,0x1c,0x3c381c00,0x1c3c1c1c,0x3801c3c,0x383801c0,
--      0xe01cf0,0x380739c,0x38381c38,0x3c381c3c,0x7801c00,0x7003838,0x3838700e,0xfe03c78,0x7801c0,0x18001c0,0x0,0x1c000c20,0xff8,
--      0x0,0x1ff01ff0,0x3818,0x3fc00100,0x707e0c20,0x3c00c20,0xc200030,0xc000618,0x18c00000,0x0,0x0,0x1c000080,0xe1ce0c20,0x7803e0,
--      0x1c0,0xe200700,0xff83ffe,0x1801878,0x9801,0x1cf0071c,0x7ffc0000,0x8c310000,0x7ffe,0x7000030,0x3838,0x3f980380,0x180,0xc6038e0,
--      0x7f9c7f9c,0x3e1c01c0,0xe380e38,0xe380e38,0xe380f78,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,0x1c001c0,0xfe387338,0x701c701c,
--      0x701c701c,0x701c0e70,0x719c7038,0x70387038,0x703803e0,0x70383b80,0x1c001c,0x1c001c,0x1c001c,0xe71c00,0x1c1c1c1c,0x1c1c1c1c,
--      0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380000,0x3c383838,0x38383838,0x38383c78,0x3c383c78,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0xf800380,0x3f830000,0x70000e0,0x31080180,0x0,0x380,0x3b9c01c0,
--      0x7807e0,0x38e00038,0x3c3800e0,0xff01c3c,0x3800380,0x7c000000,0x7c03c0,0x61870e38,0x7fc07000,0x70387ff0,0x7ff070fc,0x7ff801c0,
--      0x707f80,0x7000739c,0x7338701c,0x7ff0701c,0x7fe00ff0,0x1c07038,0xe7073ce,0x1c003e0,0x3800380,0x38001c0,0x0,0x1c,0x381c3800,
--      0x381c380e,0x380381c,0x383801c0,0xe01de0,0x380739c,0x3838381c,0x381c381c,0x7001e00,0x7003838,0x1c70718e,0x7e01c70,0xf00380,
--      0x18001e0,0x1e000000,0x1c001bb0,0xff8,0x0,0x1000100,0xe0,0xff00300,0x707e1bb0,0x3801bb0,0x1bb00010,0x8000308,0x30c00000,0x0,
--      0x0,0x1e0000c0,0xe1ce1bb0,0xf003e0,0x1c0,0x1c203ff8,0x63003e0,0x180181c,0x9801,0xfb00e38,0x7ffc0000,0x8fc10000,0x7ffe,0xe000860,
--      0x3838,0x1f980380,0x180,0x7c01c70,0x1f001f0,0x1f003c0,0xe380e38,0xe380e38,0xe380e38,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,
--      0x1c001c0,0xfe387338,0x701c701c,0x701c701c,0x701c07e0,0x731c7038,0x70387038,0x703803e0,0x70383980,0x1c001c,0x1c001c,0x1c001c,
--      0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x387c3838,0x38383838,0x38381c70,
--      0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc30,0x7f00e00,0x33c30000,0x70000e0,0x1007ffe,
--      0x0,0x380,0x3b9c01c0,0xf00078,0x30e0001c,0x3c1c01c0,0x1c381fdc,0x0,0x70000000,0x1c0380,0x63030e38,0x70707000,0x70387000,0x700070fc,
--      0x703801c0,0x707b80,0x7000739c,0x7338701c,0x7fc0701c,0x7fc001f0,0x1c07038,0xe703e5c,0x3e001c0,0x7800380,0x38001c0,0x0,0x7fc,
--      0x381c3800,0x381c380e,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7001fc0,0x7003838,0x1c70718e,0x7c01c70,
--      0xe01f00,0x180007c,0x7f8c0000,0x7fc03fb8,0x1c0,0x0,0x1000100,0x700,0x1f00600,0x70703fb8,0x7803fb8,0x3fb80000,0x8000000,0x180,
--      0x0,0x0,0x1fc00060,0xe1ce3fb8,0xe001c0,0x1c0,0x1c203ff8,0xc1801c0,0x180c,0x9801,0x1c70,0xc0000,0x8cc10000,0x180,0xfe007c0,
--      0x3838,0x7980380,0xff0,0xe38,0x3e003e00,0x3e000380,0xe380e38,0xe380e38,0xe380e38,0x38e07000,0x70007000,0x70007000,0x1c001c0,
--      0x1c001c0,0x70387338,0x701c701c,0x701c701c,0x701c03c0,0x731c7038,0x70387038,0x703801c0,0x703838e0,0x7fc07fc,0x7fc07fc,0x7fc07fc,
--      0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x38dc3838,0x38383838,0x38381c70,
--      0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc60,0xf83878,0x71e30000,0x70000e0,0x1007ffe,
--      0x7f0,0x380,0x381c01c0,0x1e0003c,0x60e0001c,0x381c01c0,0x381c079c,0x0,0x7c000000,0x7c0380,0x63031c1c,0x70307000,0x70387000,
--      0x7000701c,0x703801c0,0x7071c0,0x7000739c,0x71b8701c,0x7000701c,0x71e00078,0x1c07038,0xe703e7c,0x7e001c0,0xf000380,0x38001c0,
--      0x0,0x1ffc,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fc0,0x380739c,0x3838381c,0x381c381c,0x7000ff0,0x7003838,0x1ef03bdc,
--      0x3800ee0,0x1e01f00,0x180007c,0x61fc0000,0x7fc07f3c,0x1c0,0x0,0x1000100,0x1800,0x780c00,0x70707f3c,0xf007f3c,0x7f3c0000,0x0,
--      0x3c0,0x3ffcffff,0x0,0xff00030,0xe1fe7f3c,0x1e001c0,0x1c0,0x1c200700,0xc183ffe,0xe0c,0x9801,0x1ff038e0,0xc07f0,0x8c610000,
--      0x180,0x0,0x3838,0x1980380,0x0,0x1ff0071c,0xe000e000,0xe0000f80,0x1c1c1c1c,0x1c1c1c1c,0x1c1c1e38,0x38e07000,0x70007000,0x70007000,
--      0x1c001c0,0x1c001c0,0x703871b8,0x701c701c,0x701c701c,0x701c03c0,0x761c7038,0x70387038,0x703801c0,0x70703870,0x1ffc1ffc,0x1ffc1ffc,
--      0x1ffc1ffc,0xfff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x389c3838,0x38383838,
--      0x38380ee0,0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xfffc,0xbc60fc,0x70e30000,0x70000e0,
--      0x180,0x7f0,0x700,0x381c01c0,0x3e0001c,0x7ffc001c,0x381c03c0,0x381c001c,0x0,0x1f807ffc,0x3f00380,0x63031ffc,0x70387000,0x70387000,
--      0x7000701c,0x703801c0,0x7071e0,0x7000701c,0x71b8701c,0x7000701c,0x70f00038,0x1c07038,0x7e03e7c,0x77001c0,0xe000380,0x1c001c0,
--      0x0,0x3c1c,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x70003f8,0x7003838,0xee03bdc,
--      0x3c00ee0,0x3c00380,0x18000e0,0xf00000,0x1c007e7c,0x3c0,0x0,0x1000100,0x0,0x381800,0x70707e7c,0xe007e7c,0x7e7c0000,0x0,0x7c0,
--      0x0,0x0,0x3f80018,0xe1fe7e7c,0x3c001c0,0x1c0,0x1c200700,0xc183ffe,0xf0c,0x8c01,0x38e0,0xc07f0,0x8c710000,0x180,0x0,0x3838,
--      0x1980000,0x0,0x71c,0x7000f0,0x700f00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x3fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
--      0x703871b8,0x701c701c,0x701c701c,0x701c07e0,0x7c1c7038,0x70387038,0x703801c0,0x7ff03838,0x3c1c3c1c,0x3c1c3c1c,0x3c1c3c1c,
--      0x3fff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x391c3838,0x38383838,0x38380ee0,
--      0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffc,0x9c01ce,0x70f60000,0x70000e0,0x180,
--      0x0,0x700,0x381c01c0,0x780001c,0x7ffc001c,0x381c0380,0x381c003c,0x0,0x3e07ffc,0xf800380,0x63031ffc,0x70387000,0x70387000,
--      0x7000701c,0x703801c0,0x7070f0,0x7000701c,0x71b8701c,0x7000701c,0x70700038,0x1c07038,0x7e03e7c,0xf7801c0,0x1e000380,0x1c001c0,
--      0x0,0x381c,0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7000078,0x7003838,0xee03a5c,
--      0x7c00fe0,0x78001c0,0x18001c0,0x0,0x1c003ef8,0x380,0x0,0x1000100,0x810,0x383000,0x70703ef8,0x1e003ef8,0x3ef80000,0x0,0x7c0,
--      0x0,0x0,0x78000c,0xe1c03ef8,0x78001c0,0x1c0,0x1c200700,0x63001c0,0x18003f8,0x4e12,0x1c70,0xc0000,0x4c320000,0x180,0x0,0x3838,
--      0x1980000,0x0,0xe38,0x700118,0x701e00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x7fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
--      0x703871b8,0x701c701c,0x701c701c,0x701c0e70,0x7c1c7038,0x70387038,0x703801c0,0x7fc0381c,0x381c381c,0x381c381c,0x381c381c,
--      0x78e03800,0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x3b1c3838,0x38383838,0x38380fe0,
--      0x381c0fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1860,0x9c0186,0x707e0000,0x30000c0,0x180,
--      0x0,0xe00,0x183801c0,0xf00001c,0xe0001c,0x181c0380,0x381c0038,0x0,0xfc0000,0x7e000000,0x61873c1e,0x70383800,0x70707000,0x7000381c,
--      0x703801c0,0x707070,0x7000701c,0x70f83838,0x70003838,0x70780038,0x1c07038,0x7e03c3c,0xe3801c0,0x1c000380,0xe001c0,0x0,0x381c,
--      0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01ef0,0x380739c,0x3838381c,0x381c381c,0x7000038,0x7003838,0xfe03e7c,0xfe007c0,
--      0x70001c0,0x18001c0,0x0,0xe001ff0,0x380,0x0,0x1000100,0x162c,0x381800,0x30701ff0,0x1c001ff0,0x1ff00000,0x0,0x3c0,0x0,0x0,
--      0x380018,0xe1c01ff0,0x70001c0,0x1c0,0x1c200700,0xff801c0,0x18000f0,0x63e6,0xe38,0x0,0x6c3e0000,0x0,0x0,0x3838,0x1980000,0x0,
--      0x1c70,0xf0000c,0xf01c00,0x3c1e3c1e,0x3c1e3c1e,0x3c1e3c1c,0x70e03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x707070f8,
--      0x38383838,0x38383838,0x38381c38,0x38387038,0x70387038,0x703801c0,0x7000381c,0x381c381c,0x381c381c,0x381c381c,0x70e03800,
--      0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0380,0x3e1c3838,0x38383838,0x383807c0,0x381c07c0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18c0,0x9c0186,0x783c0000,0x38001c0,0x180,0x3800000,
--      0x3800e00,0x1c3801c0,0x1e00003c,0xe00038,0x1c1c0780,0x381c0038,0x3800380,0x3c0000,0x78000000,0x61ff380e,0x70383808,0x70707000,
--      0x7000381c,0x703801c0,0x40707078,0x7000701c,0x70f83838,0x70003838,0x70384038,0x1c07038,0x7e03c3c,0x1e3c01c0,0x3c000380,0xe001c0,
--      0x0,0x383c,0x3c381c00,0x1c3c1c00,0x3801c3c,0x383801c0,0xe01c78,0x380739c,0x38381c38,0x3c381c3c,0x7000038,0x7003878,0x7c01e78,
--      0x1ef007c0,0xf0001c0,0x18001c0,0x0,0xe000ee0,0x7800380,0xe380000,0x1001ff0,0x2242,0x40380c00,0x38700ee0,0x3c000ee0,0xee00000,
--      0x0,0x0,0x0,0x0,0x380030,0xe1c00ee0,0xf0001c0,0x1c0,0xe200700,0xdd801c0,0x1800038,0x300c,0x71c,0x0,0x300c0000,0x0,0x0,0x3838,
--      0x1980000,0x0,0x38e0,0xb0000c,0xb01c08,0x380e380e,0x380e380e,0x380e380e,0x70e03808,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
--      0x707070f8,0x38383838,0x38383838,0x3838381c,0x38387038,0x70387038,0x703801c0,0x7000381c,0x383c383c,0x383c383c,0x383c383c,
--      0x70e01c00,0x1c001c00,0x1c001c00,0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383878,0x38783878,0x387807c0,
--      0x3c3807c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x18c0,0x10b801ce,0x3c3e0000,0x38001c0,0x180,
--      0x3800000,0x3801c00,0x1e7801c0,0x3c002078,0xe02078,0x1c380700,0x1c3810f0,0x3800380,0x40000,0x40000380,0x307b380e,0x70701e18,
--      0x70e07000,0x70001c1c,0x703801c0,0x60e0703c,0x7000701c,0x70f83c78,0x70003c70,0x703c70f0,0x1c03870,0x3c01c3c,0x3c1c01c0,0x78000380,
--      0x7001c0,0x0,0x3c7c,0x3c381e18,0x1c7c1e0c,0x3801c3c,0x383801c0,0xe01c38,0x3c0739c,0x38381c38,0x3c381c3c,0x7001078,0x7803c78,
--      0x7c01c38,0x1c780380,0x1e0001c0,0x18001c0,0x0,0x70c06c0,0x7000380,0xe300000,0x1000100,0x2142,0x70f00600,0x3c7006c0,0x780006c0,
--      0x6c00000,0x0,0x0,0x0,0x0,0x10780060,0x73e206c0,0x1e0001c0,0x1c0,0x7240700,0x180c01c0,0x1800018,0x1818,0x30c,0x0,0x18180000,
--      0x0,0x0,0x3c78,0x1980000,0x0,0x30c0,0x130000c,0x1301c18,0x380e380e,0x380e380e,0x380e380e,0x70e01e18,0x70007000,0x70007000,
--      0x1c001c0,0x1c001c0,0x70e070f8,0x3c783c78,0x3c783c78,0x3c781008,0x7c783870,0x38703870,0x387001c0,0x70003a3c,0x3c7c3c7c,0x3c7c3c7c,
--      0x3c7c3c7c,0x79f11e18,0x1e0c1e0c,0x1e0c1e0c,0x1c001c0,0x1c001c0,0x1c783838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383c78,0x3c783c78,
--      0x3c780380,0x3c380380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x38c0,0x1ff800fc,0x1fee0000,
--      0x1800180,0x180,0x3800000,0x3801c00,0xff01ffc,0x3ffc3ff0,0xe03ff0,0xff00700,0x1ff81fe0,0x3800380,0x0,0x380,0x3000780f,0x7ff00ff8,
--      0x7fc07ff8,0x70000ffc,0x70381ffc,0x7fe0701c,0x7ff8701c,0x70781ff0,0x70001ff0,0x701c7ff0,0x1c01fe0,0x3c01c38,0x380e01c0,0x7ffc0380,
--      0x7001c0,0x0,0x1fdc,0x3ff00ff0,0xffc0ffc,0x3800fdc,0x38383ffe,0xe01c3c,0x1fc739c,0x38380ff0,0x3ff00ffc,0x7001ff0,0x3f81fb8,
--      0x7c01c38,0x3c3c0380,0x1ffc01c0,0x18001c0,0x0,0x3fc0380,0x7000380,0xc70718c,0x1000100,0x2244,0x7ff00200,0x1fff0380,0x7ffc0380,
--      0x3800000,0x0,0x0,0x0,0x0,0x1ff000c0,0x7f7e0380,0x1ffc01c0,0x1c0,0x3fc3ffe,0x1c0,0x1800018,0x7e0,0x104,0x0,0x7e00000,0x7ffe,
--      0x0,0x3fde,0x1980000,0x0,0x2080,0x3300018,0x3300ff0,0x780f780f,0x780f780f,0x780f780e,0xf0fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,
--      0x1ffc1ffc,0x7fc07078,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x7ff01fe0,0x1fe01fe0,0x1fe001c0,0x70003bf8,0x1fdc1fdc,0x1fdc1fdc,
--      0x1fdc1fdc,0x3fbf0ff0,0xffc0ffc,0xffc0ffc,0x3ffe3ffe,0x3ffe3ffe,0xff03838,0xff00ff0,0xff00ff0,0xff00000,0x3ff01fb8,0x1fb81fb8,
--      0x1fb80380,0x3ff00380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x31c0,0x7e00078,0x7cf0000,0x1800180,
--      0x0,0x3800000,0x3803800,0x3c01ffc,0x3ffc0fe0,0xe01fc0,0x3e00e00,0x7e00f80,0x3800380,0x0,0x380,0x18007007,0x7fc003f0,0x7f007ff8,
--      0x700003f0,0x70381ffc,0x3f80701e,0x7ff8701c,0x707807c0,0x700007c0,0x701e1fc0,0x1c00fc0,0x3c01818,0x780f01c0,0x7ffc0380,0x3801c0,
--      0x0,0xf9c,0x39e003e0,0x79c03f0,0x380079c,0x38383ffe,0xe01c1e,0x7c739c,0x383807e0,0x39e0079c,0x7000fc0,0x1f80f38,0x3801c38,
--      0x781e0380,0x1ffc01c0,0x18001c0,0x0,0x1f80100,0xe000700,0x1c60718c,0x1000100,0x1e3c,0x1fc00100,0x7ff0100,0x7ffc0100,0x1000000,
--      0x0,0x0,0x0,0x0,0xfc00080,0x3e3c0100,0x1ffc01c0,0x1c0,0xf83ffe,0x1c0,0x1800838,0x0,0x0,0x0,0x0,0x7ffe,0x0,0x3b9e,0x1980000,
--      0x0,0x0,0x2300038,0x23003e0,0x70077007,0x70077007,0x70077007,0xe0fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007078,
--      0x7c007c0,0x7c007c0,0x7c00000,0xc7c00fc0,0xfc00fc0,0xfc001c0,0x700039f0,0xf9c0f9c,0xf9c0f9c,0xf9c0f9c,0x1f1e03e0,0x3f003f0,
--      0x3f003f0,0x3ffe3ffe,0x3ffe3ffe,0x7e03838,0x7e007e0,0x7e007e0,0x7e00000,0x63e00f38,0xf380f38,0xf380380,0x39e00380,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x3000000,0x3800,0x0,0x0,0x0,0x0,
--      0x0,0x300,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x380,0x3801c0,0x0,0x0,0x0,0x0,0x1c,0x0,0xe00000,
--      0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1c0,0x18001c0,0x0,0x0,0xe000700,0x18600000,0x1000100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800ff0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0x1800000,0x0,0x6300070,0x6300000,0x0,
--      0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,
--      0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x7000000,
--      0x7000,0x0,0x0,0x0,0x0,0x0,0x700,0x0,0x0,0xf040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x3f0,0x1c0fc0,0x0,0x0,
--      0x0,0x0,0x1c,0x0,0xe00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1e0,0x18003c0,0x0,0x0,0xc000700,0x18c00000,0x1000000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x18007e0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
--      0x0,0x7f800e0,0x7f80000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,
--      0x0,0x600600,0x0,0x6000000,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,
--      0x3f0,0xfc0,0x0,0x0,0x0,0x0,0x838,0x0,0x1e00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0xf00,0xfc,0x1801f80,0x0,0x0,0x8008e00,0x30c00000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
--      0x0,0x3001c0,0x300000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0xf00,0x38000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0xff0,0x0,0x1fc00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3e00,0x7c,0x1801f00,0x0,0x0,0x800fe00,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7c00000,0x0,0x3001fc,0x300000,
--      0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x3e00,0x38003e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x7e0,0x0,0x1f000000,
--      0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3c00,0x0,0x1800000,0x0,0x0,0x7800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00,0x38003c00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 19x38 font
--    const unsigned int font19x38[19*38*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c380000,0x0,0x1c380,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800007,0x3c003,0x86000000,
--      0x1e00000,0x3,0x80000700,0x3c00000,0x380000,0x70003c00,0x0,0xe1800e,0x1c00,0xf000e18,0x0,0x0,0x700000e0,0x780000,0x7000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe700000,0x0,0xe700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0000e,0x7e003,0xe60071c0,0x7f80000,0x1,0xc0000e00,0x7e0038e,0x1c0000,
--      0xe0007e00,0x38e00000,0xf98007,0x3800,0x1f800f98,0x1c70000,0x0,0x380001c0,0xfc0071,0xc000e000,0x0,0x0,0x0,0x0,0x3e00000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x7e00000,0x0,0x7e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0001c,0xe7006,0x7c0071c0,0xe180000,0x0,0xe0001c00,0xe70038e,0xe0001,0xc000e700,0x38e00000,
--      0x19f0003,0x80007000,0x39c019f0,0x1c70000,0x0,0x1c000380,0x1ce0071,0xc001c000,0x0,0x0,0x0,0x0,0x7f00000,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,
--      0x0,0x3c00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x700038,0x1c3806,0x3c0071c0,0xc0c0000,0x0,0x70003800,0x1c38038e,0x70003,0x8001c380,0x38e00000,0x18f0001,0xc000e000,
--      0x70e018f0,0x1c70000,0x0,0xe000700,0x3870071,0xc0038000,0x0,0x0,0x0,0x0,0xe380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60000000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c38,0x0,0x1,0xc3800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000003,0x80018000,0x0,0xc180000,
--      0xe,0x380,0x1800000,0xe00000,0x38001800,0x0,0x38,0xe00,0x6000000,0x0,0x1,0xc0000070,0x300000,0x3800,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78c00,0xc30,
--      0x0,0x0,0xc3000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800000,0x0,0x0,0x0,0xe0,0x1c000f,0xc0000000,0x0,0x0,
--      0x0,0xc0c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7000007,0x3c003,0xc6000000,0xc180000,0x7,0x700,
--      0x3c00000,0x700000,0x70003c00,0x0,0xf1801c,0x1c00,0xf000f18,0x0,0x0,0xe00000e0,0x780000,0x7000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x1c007000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x3800000,0x700000,0x38,
--      0x7,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf800e,0x3e0000,0x0,0x0,0x0,0x1e00000,0x0,0x1,
--      0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7cc00,0x660,0x0,0x0,0x66000000,0x0,0x0,0x0,0x0,0x7,0x1c000000,0x0,0x0,0x0,0x3fe00000,
--      0x0,0x0,0x7000000,0x0,0x0,0x0,0x3e0,0x7c001f,0xe0000000,0x0,0x0,0x0,0xe1c0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x1f80,0x380000e,0x7e007,0xe60071c0,0xc180000,0x3,0x80000e00,0x7e0038e,0x380000,0xe0007e00,0x38e00f00,0x1f9800e,
--      0x3800,0x1f801f98,0x1c70000,0x0,0x700001c0,0xfc0071,0xc000e007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61c00600,0x1e00007e,0x70000,0x18003000,0x1800000,0x0,0x0,0x1c01f0,0x7e003f,0xc003f800,
--      0x1e03ffc,0x7f01ff,0xfc03f000,0x7e000000,0x0,0x0,0xfc0,0x1e,0x7fe000,0x7e03fe00,0x3fff07ff,0xe007e038,0x383ffe0,0xff81c01,
--      0xe1c000f8,0xf8f00e0,0xfc01ffc,0x3f00ff,0xc000fe07,0xfffc7007,0x1c007700,0x73c01ef,0x78ffff,0xfe0380,0xfe000,0x38000000,0x1800000,
--      0x700000,0x38,0x1f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0xfc0000,
--      0x0,0x7f00000,0x0,0x1,0x98000000,0x7f00000,0x3ffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0xcf81f,0xee3807e0,0x0,0x0,0x7e03c01e,0x1c,
--      0x0,0x1f800000,0xf0078038,0xfc007,0x1c000000,0xfe00000,0x0,0x0,0x3fe000f0,0xf,0xc001f800,0x6000000,0xffc000,0x0,0x1c0007e0,
--      0x360,0x6c0010,0x70000700,0xf0001e,0x3c000,0x78000f00,0x7f800ff,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,
--      0x7807007,0xe000fc00,0x1f8003f0,0x7e0000,0x1f867,0x70e00e,0x1c01c380,0x38f00787,0x3fe0,0x180000c,0x66006,0x7c0071c0,0xe380000,
--      0x1,0x80000c00,0x660038e,0x180000,0xc0006600,0x38e0078e,0x19f0006,0x3000,0x198019f0,0x1c70000,0x0,0x30000180,0xcc0071,0xc000c007,
--      0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0x61800600,0x7f8001ff,0x70000,
--      0x38003800,0x1800000,0x0,0x0,0x3807fc,0x1fe00ff,0xf00ffe00,0x3e03ffc,0xff81ff,0xfc07fc01,0xff800000,0x0,0x0,0x3fe0,0xfe001e,
--      0x7ff801,0xff83ff80,0x3fff07ff,0xe01ff838,0x383ffe0,0xff81c03,0xc1c000f8,0xf8f80e0,0x3ff01fff,0xffc0ff,0xf003ff87,0xfffc7007,
--      0x1e00f700,0x71c03c7,0x70ffff,0xfe01c0,0xfe000,0x7c000000,0xc00000,0x700000,0x38,0x3f,0xe000001c,0x1c00,0x1c00700,0x7fc0000,
--      0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x3f800e,0x3f8000,0x0,0x3fe0000,0x0,0xff00000,0x0,0x3,0xc000000,0x1ffc0000,0xfffe00,
--      0xffff0,0x0,0x0,0x0,0x0,0x0,0xc781f,0xee3803c0,0x0,0x0,0x3c01c01c,0x1c,0xc000,0x7fc00000,0x70070038,0x3fe007,0x1c000000,0x1ff80000,
--      0x0,0x0,0x3fe003fc,0x1f,0xe003fc00,0xc000000,0x3ffc000,0x0,0x7c000ff0,0x60,0xc0000,0x30000700,0xf0001e,0x3c000,0x78000f00,
--      0x3f000ff,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x7c0701f,0xf803ff00,0x7fe00ffc,0x1ff8000,0x7fe67,
--      0x70e00e,0x1c01c380,0x38700707,0x7ff0,0xc00018,0xc3006,0x3c0071c0,0x7f00000,0x0,0xc0001800,0xc30038e,0xc0001,0x8000c300,0x38e003fc,
--      0x18f0003,0x6000,0x30c018f0,0x1c70000,0x0,0x18000300,0x1860071,0xc0018007,0x38e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe1801fc0,0x618001ff,0x70000,0x30001800,0x21840000,0x0,0x0,0x380ffe,0x1fe00ff,
--      0xfc0fff00,0x3e03ffc,0x1ff81ff,0xfc0ffe03,0xffc00000,0x0,0x0,0x7ff0,0x3ff803f,0x7ffc03,0xffc3ffc0,0x3fff07ff,0xe03ffc38,0x383ffe0,
--      0xff81c07,0x81c000f8,0xf8f80e0,0x7ff81fff,0x81ffe0ff,0xf80fff87,0xfffc7007,0xe00e700,0x70e0387,0x80f0ffff,0xe001c0,0xe000,
--      0xfe000000,0xe00000,0x700000,0x38,0x3c,0x1c,0x1c00,0x1c00700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x78000e,0x3c000,
--      0x0,0x7ff0000,0x0,0xf100000,0x0,0x7,0xe000000,0x7ffc0000,0x1fffe00,0xffff0,0x0,0x0,0x0,0x0,0x0,0x3,0xf780180,0x0,0x0,0x1801e03c,
--      0x1c,0xc000,0xffc00000,0x780f0038,0x786000,0x7f00,0x18380000,0x0,0xfe00,0x30c,0x10,0x70020e00,0x1c000000,0x7f8c000,0x0,0x6c001c38,
--      0x60,0xc0000,0x70000700,0x1f8003f,0x7e000,0xfc001f80,0x3f000ff,0xf03ffc1f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,
--      0x7c0703f,0xfc07ff80,0xfff01ffe,0x3ffc000,0xffec7,0x70e00e,0x1c01c380,0x38780f07,0xf070,0xe00038,0x1c3800,0x0,0x3e00000,0x0,
--      0xe0003800,0x1c380000,0xe0003,0x8001c380,0x3e0,0x3,0x8000e000,0x70e00000,0x0,0x0,0x1c000700,0x3870000,0x38007,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xe3807ff0,0xc0c003c1,0x70000,0x70001c00,
--      0x718e0000,0x0,0x0,0x700f1e,0x1ce00c0,0x3c0c0f80,0x7e03800,0x3e08000,0x381e0f03,0xc1e00000,0x0,0x0,0x7078,0x783c03f,0x701e07,
--      0xc1c383e0,0x38000700,0x7c1c38,0x3801c00,0x381c0f,0x1c000fc,0x1f8f80e0,0x78781c07,0x81e1e0e0,0x780f0180,0xe007007,0xe00e380,
--      0xe0f0783,0x80e0000e,0xe000e0,0xe001,0xef000000,0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,
--      0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xf830000,0x0,0x1e000000,0x0,0x0,0x10000,0x780c0000,0x3e38000,0xe0,0x0,0x0,0x0,0x0,0x0,0x3,
--      0xd580000,0x0,0x0,0xe038,0x1c,0xc000,0xf0400000,0x380e0038,0x702000,0x1ffc0,0xc0000,0x0,0x3ff80,0x606,0x0,0x30000600,0x0,
--      0x7f8c000,0x0,0xc001818,0x60,0xc0003,0xe0000700,0x1f8003f,0x7e000,0xfc001f80,0x73801ee,0x7c1c1c,0x38000,0x70000e00,0xe0001,
--      0xc0003800,0x700383e,0x7c0703c,0x3c078780,0xf0f01e1e,0x3c3c000,0xf0f87,0x70e00e,0x1c01c380,0x38380e07,0xe038,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0xff0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x1c,0x1c7000,0xc380fff0,0xc0c00380,0x70000,0x70001c00,0x3dbc0070,0x0,0x0,0x701e0f,0xe0000,0x1e000380,
--      0x6e03800,0x7800000,0x781c0707,0x80e00000,0x0,0x0,0x4038,0xe00c03f,0x700e07,0x4380f0,0x38000700,0x700438,0x3801c00,0x381c0e,
--      0x1c000ec,0x1b8fc0e0,0xf03c1c03,0xc3c0f0e0,0x3c1e0000,0xe007007,0xe00e380,0xe070703,0xc1e0001e,0xe000e0,0xe001,0xc7000000,
--      0x0,0x700000,0x38,0x38,0x1c,0x0,0x700,0x1c0000,0x0,0x0,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x70000e,0x1c000,0x0,0xe010000,0x0,
--      0x1c000000,0x10,0x20000,0x6c000,0xf0000000,0x3838000,0x1e0,0x0,0xf000f,0xf1e00,0x78f00000,0x0,0x3,0xdd80000,0x0,0x0,0xf078,
--      0x0,0xc001,0xe0000000,0x1c1c0038,0x700000,0x3c1e0,0xc0000,0x0,0x783c0,0x606,0x0,0x30000e00,0x0,0xff8c000,0x0,0xc00300c,0x60,
--      0xc0003,0xe0000000,0x1f8003f,0x7e000,0xfc001f80,0x73801ce,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x7e07078,
--      0x1e0f03c1,0xe0783c0f,0x781e000,0x1c0787,0x70e00e,0x1c01c380,0x383c1e07,0xff00e038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x878,
--      0x0,0x0,0x0,0x7,0x80000080,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,
--      0x1c7000,0xc301e630,0xc0c00380,0x70000,0xe0000e00,0xff00070,0x0,0x0,0xe01c07,0xe0000,0xe000380,0xce03800,0x7000000,0x701c0707,
--      0x600000,0x0,0x4000010,0x38,0x1c00e07f,0x80700e0e,0x38070,0x38000700,0xe00038,0x3801c00,0x381c1c,0x1c000ec,0x1b8ec0e0,0xe01c1c01,
--      0xc38070e0,0x1c1c0000,0xe007007,0x701c380,0xe078e01,0xc1c0003c,0xe00070,0xe003,0x83800000,0x7f,0x71f000,0x3e003e38,0x3f007ff,
--      0xe01f1c1c,0x7801fc00,0x3fc00701,0xe01c0077,0x8f071e00,0xf801c7c,0x7c700e,0x3e01fc03,0xfff8380e,0xe007700,0x73c0787,0x387ffc,
--      0x70000e,0x1c000,0x0,0xe000000,0x0,0x1c000000,0x10,0x20000,0xc2000,0xe0000000,0x3838000,0x3c0,0x0,0xf000f,0x78e00,0x70e00000,
--      0x0,0x3,0xc980fe0,0x1f0,0xf8000007,0xffc07070,0x0,0x3f801,0xc0000000,0x1e3c0038,0x700000,0x70070,0x7fc0000,0x0,0xe00e0,0x606,
--      0x1c0000,0x70007c00,0x380e,0xff8c000,0x0,0xc00300c,0x60,0xc0000,0x70000000,0x3fc007f,0x800ff001,0xfe003fc0,0x73801ce,0xe0001c,
--      0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,0x7607070,0xe0e01c1,0xc0383807,0x700e000,0x1c0387,0x70e00e,0x1c01c380,0x381c1c07,
--      0xffc0e0f8,0x3f8007f,0xfe001,0xfc003f80,0x7f007e3,0xe003e001,0xf8003f00,0x7e000fc,0xfe001f,0xc003f800,0x7f00003c,0x38f0007,
--      0xc000f800,0x1f0003e0,0x7c0007,0x8003f0c3,0x80e0701c,0xe0381c0,0x70700387,0x1f01c00e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0xc0c00380,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03c07,
--      0x800e0000,0xe000380,0x1ce03800,0x7000000,0x701c0707,0x7003c0,0x780000,0x3c00001e,0x38,0x18006073,0x80700e0e,0x38070,0x38000700,
--      0xe00038,0x3801c00,0x381c38,0x1c000ee,0x3b8ee0e1,0xe01e1c01,0xc78078e0,0x1c1c0000,0xe007007,0x701c387,0xe03de00,0xe3800038,
--      0xe00070,0xe007,0x1c00000,0x1ff,0xc077f801,0xff807fb8,0xff807ff,0xe03fdc1d,0xfc01fc00,0x3fc00703,0xc01c007f,0xdf877f00,0x3fe01dfe,
--      0xff700e,0xff07ff03,0xfff8380e,0x700f700,0x71e0f03,0x80707ffc,0x70000e,0x1c000,0x0,0x1c000008,0x0,0x1c000000,0x10,0x20000,
--      0x82000,0xe0000000,0x7038000,0x80000380,0x2000040,0x7000e,0x38700,0xf1e00000,0x0,0x3,0xc183ff8,0x3fd,0xfc008007,0xffc038e0,
--      0x0,0xffc01,0xc0008008,0xe380038,0x380000,0xe3e38,0x1ffc0040,0x80000000,0x1cfc70,0x606,0x1c0000,0xe0007c00,0x380e,0xff8c000,
--      0x0,0xc00300c,0x8100060,0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0x73801ce,0xe0001c,0x38000,0x70000e00,0xe0001,
--      0xc0003800,0x7003807,0x77070f0,0xf1e01e3,0xc03c7807,0x8f00f080,0x83c0787,0x70e00e,0x1c01c380,0x380e3807,0xffe0e1c0,0xffe01ff,
--      0xc03ff807,0xff00ffe0,0x1ffc0ff7,0xf01ff807,0xfc00ff80,0x1ff003fe,0xfe001f,0xc003f800,0x7f0003fc,0x3bf801f,0xf003fe00,0x7fc00ff8,
--      0x1ff0007,0x8007fd83,0x80e0701c,0xe0381c0,0x70380707,0x7f80e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x1c,0x1c701f,0xfff1c600,0x618081c0,0x70000,0xe0000e00,0x3c00070,0x0,0x0,0xe03803,0x800e0000,0xe000380,0x18e03800,
--      0xf000000,0xf01c0707,0x7003c0,0x780000,0xfc00001f,0x80000078,0x301e6073,0x80700e1c,0x38038,0x38000700,0x1c00038,0x3801c00,
--      0x381c70,0x1c000e6,0x338ee0e1,0xc00e1c01,0xc70038e0,0x1c1c0000,0xe007007,0x701c387,0xe01dc00,0xf7800078,0xe00070,0xe00e,0xe00000,
--      0x3ff,0xe07ffc03,0xffc0fff8,0x1ffc07ff,0xe07ffc1d,0xfe01fc00,0x3fc00707,0x801c007f,0xdf877f80,0x7ff01fff,0x1fff00e,0xff07ff03,
--      0xfff8380e,0x700e380,0xe0e0e03,0x80707ffc,0x70000e,0x1c000,0x0,0x7ffc001c,0x0,0x1c000000,0x10,0x20000,0x82000,0xe0000000,
--      0x7038001,0xc0000780,0x70000e0,0x3800e,0x38700,0xe1c00000,0x0,0x3,0xc183ff8,0x7ff,0xfc01c007,0xffc03de0,0x0,0x1ffc01,0xc001c01c,
--      0xf780038,0x3c0000,0xcff18,0x380c00c1,0x80000000,0x18fe30,0x30c,0x1c0001,0xc0000e00,0x380e,0xff8c000,0x0,0xc00300c,0xc180060,
--      0xc0000,0x30000700,0x39c0073,0x800e7001,0xce0039c0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x877070e0,
--      0x71c00e3,0x801c7003,0x8e0071c0,0x1c380fc7,0x70e00e,0x1c01c380,0x380f7807,0x1e0e380,0x1fff03ff,0xe07ffc0f,0xff81fff0,0x3ffe0fff,
--      0xf03ffc0f,0xfe01ffc0,0x3ff807ff,0xfe001f,0xc003f800,0x7f0007fe,0x3bfc03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x800fff83,0x80e0701c,
--      0xe0381c0,0x70380707,0xffc0e01c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1c701f,
--      0xfff1c600,0x7f8381e0,0x70000,0xc0000600,0xff00070,0x0,0x0,0x1c03803,0x800e0000,0xe000f00,0x38e03fe0,0xe000000,0xe00e0e07,
--      0x7003c0,0x780007,0xf0ffff87,0xf00000f0,0x307fe0f3,0xc0703c1c,0x38038,0x38000700,0x1c00038,0x3801c00,0x381ce0,0x1c000e6,0x338e70e1,
--      0xc00e1c01,0xc70038e0,0x3c1e0000,0xe007007,0x783c38f,0x8e01fc00,0x770000f0,0xe00038,0xe01c,0x700000,0x381,0xe07c1e07,0xc0c1e0f8,
--      0x3c1e0038,0xf07c1f,0xe001c00,0x1c0070f,0x1c0079,0xf3c7c380,0xf0781f07,0x83c1f00f,0xc10f0300,0x1c00380e,0x700e380,0xe0f1e03,
--      0xc0f00078,0x70000e,0x1c000,0x0,0xfff8003e,0x0,0x3c000000,0x10,0x20000,0xc6000,0xf0000000,0x7038003,0xe0000f00,0xf8001f0,
--      0x3801c,0x18300,0xe1800000,0x0,0x3,0xc187818,0x70f,0x9e03e000,0x7801dc0,0x1c,0x3cc401,0xc000efb8,0x7f7f0038,0x3f0000,0x1ce11c,
--      0x300c01c3,0x80000000,0x38c638,0x3fc,0x1c0003,0x80000600,0x380e,0xff8c000,0x0,0xc00300c,0xe1c0060,0xc0010,0x70000700,0x79e00f3,
--      0xc01e7803,0xcf0079e0,0xe1c038e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,
--      0x8e0070e0,0x38381dc7,0x70e00e,0x1c01c380,0x38077007,0xf0e700,0x1c0f0381,0xe0703c0e,0x781c0f0,0x381e083e,0x787c0c1e,0xf03c1e0,
--      0x783c0f07,0x800e0001,0xc0003800,0x7000fff,0x3e1c078,0x3c0f0781,0xe0f03c1e,0x783c000,0x1e0f03,0x80e0701c,0xe0381c0,0x70380f07,
--      0xc1e0e03c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x1,0x8701c600,0x1e0f01e0,0x1,
--      0xc0000700,0x3dbc0070,0x0,0x0,0x1c03803,0x800e0000,0x1e01fe00,0x70e03ff8,0xe3e0001,0xe007fc07,0x80f003c0,0x78001f,0xc0ffff81,
--      0xfc0001e0,0x30e1e0e1,0xc07ff81c,0x38038,0x3ffe07ff,0xc1c0003f,0xff801c00,0x381de0,0x1c000e7,0x738e70e1,0xc00e1c03,0xc70038e0,
--      0x780f8000,0xe007007,0x383838d,0x8e00f800,0x7f0000e0,0xe00038,0xe000,0x0,0x200,0xf0780e07,0x8041c078,0x380e0038,0xe03c1e,
--      0xf001c00,0x1c0071e,0x1c0070,0xe1c783c0,0xe0381e03,0x8380f00f,0xe0000,0x1c00380e,0x381c380,0xe07bc01,0xc0e00078,0x70000e,
--      0x1c000,0x0,0x1c000061,0x0,0x38000000,0x10,0x20000,0x7c000,0x7c000000,0x703fc06,0x10000e00,0x18400308,0x1801c,0x1c381,0xc3800000,
--      0x0,0x0,0x7000,0xe0f,0xe061000,0x7801fc0,0x1c,0x38c001,0xc0007ff0,0x7fff0038,0x77c000,0x19c00c,0x301c0387,0x0,0x30c618,0xf0,
--      0x1c0007,0x600,0x380e,0x7f8c007,0x80000000,0xc001818,0x70e03fc,0x387f871f,0xe0e00700,0x70e00e1,0xc01c3803,0x870070e0,0xe1c038f,
--      0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,0xc0003800,0x7003803,0x873870e0,0x71c00e3,0x801c7003,0x8e007070,0x703839c7,0x70e00e,
--      0x1c01c380,0x3807f007,0x70e700,0x10078200,0xf0401e08,0x3c10078,0x200f001c,0x3878041c,0x70380e0,0x701c0e03,0x800e0001,0xc0003800,
--      0x7001e0f,0x3c1e070,0x1c0e0381,0xc070380e,0x701c000,0x1c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80e07038,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600e600,0x7803f0,0x1,0xc0000700,0x718e0070,0x0,0x0,0x38038c3,
--      0x800e0000,0x3c01f800,0x60e03ffc,0xeff8001,0xc001f003,0xc1f003c0,0x7800fe,0xffff80,0x3f8003c0,0x60c0e0e1,0xc07fe01c,0x38038,
--      0x3ffe07ff,0xc1c07e3f,0xff801c00,0x381fe0,0x1c000e3,0x638e30e1,0xc00e1c07,0x870038ff,0xf00ff800,0xe007007,0x38381cd,0x9c007000,
--      0x3e0001e0,0xe0001c,0xe000,0x0,0x0,0x70780f0f,0x3c078,0x70070038,0x1e03c1c,0x7001c00,0x1c0073c,0x1c0070,0xe1c701c1,0xe03c1e03,
--      0xc780f00f,0xe0000,0x1c00380e,0x381c387,0xe03f801,0xc0e000f0,0x70000e,0x1c007,0xe0100000,0x1c0000cd,0x80000003,0xffc00000,
--      0x3ff,0x807ff000,0xe0,0x7fc00060,0x703fc0c,0xd8001e00,0x3360066c,0x1c018,0xc181,0x83000000,0x0,0x0,0x7000,0x300e07,0xe0cd800,
--      0xf000f80,0x1c,0x78c00f,0xff0038e0,0x3e00038,0xe1e000,0x19800c,0x383c070e,0x7fffc00,0x30fc18,0x0,0xffff80e,0x20e00,0x380e,
--      0x7f8c007,0x80000000,0xc001c38,0x38703ff,0xf87fff0f,0xcfe00f00,0x70e00e1,0xc01c3803,0x870070e0,0x1e1e078f,0xe1c0001f,0xff03ffe0,
--      0x7ffc0fff,0x800e0001,0xc0003800,0x700ff83,0x871870e0,0x71c00e3,0x801c7003,0x8e007038,0xe03871c7,0x70e00e,0x1c01c380,0x3803e007,
--      0x70e700,0x38000,0x70000e00,0x1c00038,0x7001c,0x38f00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7001c07,0x380e0f0,0x1e1e03c3,
--      0xc078780f,0xf01e000,0x3c0f03,0x80e0701c,0xe0381c0,0x701c0e07,0x80f07038,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0x8600ff00,0x1e00778,0x38000001,0xc0000700,0x21843fff,0xe0000000,0x0,0x38039e3,0x800e0000,
--      0x7c01fe00,0xe0e0203e,0xeffc001,0xc00ffe03,0xff700000,0x7f0,0x0,0x7f00380,0x618060e1,0xc07ffc1c,0x38038,0x3ffe07ff,0xc1c07e3f,
--      0xff801c00,0x381ff0,0x1c000e3,0x638e38e1,0xc00e1fff,0x870038ff,0xc003fe00,0xe007007,0x38381cd,0x9c00f800,0x3e0003c0,0xe0001c,
--      0xe000,0x0,0x0,0x7070070e,0x38038,0x70070038,0x1c01c1c,0x7001c00,0x1c00778,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0xfc000,
--      0x1c00380e,0x381c3c7,0x1e01f001,0xe1e001e0,0xf0000e,0x1e01f,0xf8300000,0x1c00019c,0xc0000003,0xffc00000,0x10,0x20000,0x700,
--      0x1ff000c0,0x703fc19,0xcc003c00,0x67300ce6,0xc038,0xc181,0x83000000,0x0,0x0,0x7e00,0x180e07,0xe19cc00,0x1e000f80,0x1c,0x70c00f,
--      0xff007070,0x3e00038,0xe0f000,0x19800c,0x1fec0e1c,0x7fffc00,0x30f818,0x0,0xffff81f,0xf003fc00,0x380e,0x3f8c007,0x80000000,
--      0x7f800ff0,0x1c3803f,0xe007fc00,0xff800e00,0x70e00e1,0xc01c3803,0x870070e0,0x1c0e070f,0xe1c0001f,0xff03ffe0,0x7ffc0fff,0x800e0001,
--      0xc0003800,0x700ff83,0x871c70e0,0x71c00e3,0x801c7003,0x8e00701d,0xc038e1c7,0x70e00e,0x1c01c380,0x3803e007,0x70e3c0,0x38000,
--      0x70000e00,0x1c00038,0x7001c,0x38e00038,0x3870070,0xe00e1c01,0xc00e0001,0xc0003800,0x7003c07,0x8380e0e0,0xe1c01c3,0x80387007,
--      0xe00e1ff,0xfe381b83,0x80e0701c,0xe0381c0,0x701e1e07,0x707878,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x1c,0x3,0xe007fe0,0x7800e3c,0x38000001,0xc0000700,0x1803fff,0xe0000000,0x0,0x70039c3,0x800e0000,0xf8000f80,
--      0xc0e0000e,0xf83c003,0xc01e0f01,0xff700000,0x7c0,0x0,0x1f00780,0x618061c0,0xe0701e1c,0x38038,0x38000700,0x1c07e38,0x3801c00,
--      0x381e78,0x1c000e3,0xe38e18e1,0xc00e1fff,0x70038ff,0xe0007f80,0xe007007,0x1c701dd,0x9c00f800,0x1c000780,0xe0000e,0xe000,0x0,
--      0x7f,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x7fc00,0x1c00380e,
--      0x1c381c7,0x1c01f000,0xe1c001c0,0xfe0000e,0xfe1f,0xfff00000,0x7ff003fc,0xe0000003,0xffc00000,0x10,0x20000,0x3800,0x3fc0180,
--      0x703803f,0xce007800,0xff381fe7,0x30,0x0,0xc0,0x0,0x0,0x3fe0,0xc0e07,0xfe3fce00,0x1c000700,0x1c,0x70c00f,0xff006030,0x1c00000,
--      0xe07800,0x19800c,0xfcc1c38,0x7fffc00,0x30d818,0x0,0xffff81f,0xf001f800,0x380e,0xf8c007,0x80000000,0x7f8007e0,0xe1c3fe,0x7fc00f,
--      0xf8001e00,0xe0701c0,0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700ff83,0x870c70e0,
--      0x71c00e3,0x801c7003,0x8e00700f,0x8038c1c7,0x70e00e,0x1c01c380,0x3801c007,0xf0e3e0,0x3ff807f,0xf00ffe01,0xffc03ff8,0x7ff03ff,
--      0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe383383,0x80e0701c,
--      0xe0381c0,0x700e1c07,0x703870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x3,0xc000ff0,
--      0x3c1e1c1c,0x38000001,0xc0000700,0x1803fff,0xe0000007,0xf8000000,0x7003803,0x800e0001,0xf0000381,0xc0e00007,0xf01e003,0x801c0700,
--      0x7c700000,0x7c0,0x0,0x1f00700,0x618061c0,0xe0700e1c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381e38,0x1c000e1,0xc38e1ce1,
--      0xc00e1ffc,0x70038e0,0xf0000780,0xe007007,0x1c701dd,0xdc01fc00,0x1c000780,0xe0000e,0xe000,0x0,0x1ff,0xf070070e,0x38038,0x7fff0038,
--      0x1c01c1c,0x7001c00,0x1c007f8,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3ff00,0x1c00380e,0x1c381cd,0x9c00e000,0xe1c003c0,
--      0xf80000e,0x3e18,0x3ff00000,0xffe007fd,0xf0000000,0x38000000,0x10,0x20000,0x1c000,0x3c0300,0x703807f,0xdf007801,0xff7c3fef,
--      0x80000000,0x0,0x3e0,0x7ffe7ff,0xff000000,0x1ff8,0x60e07,0xfe7fdf00,0x3c000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0xf03800,
--      0x19800c,0x1c38,0x1c07,0xf830cc18,0x0,0x1c0000,0x0,0x380e,0x18c007,0x80000000,0x0,0xe1cfe0,0x1fc003f,0x80003c00,0xe0701c0,
--      0xe0381c07,0x380e070,0x1c0e070e,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,
--      0x8e007007,0x3981c7,0x70e00e,0x1c01c380,0x3801c007,0x1e0e0f8,0xfff81ff,0xf03ffe07,0xffc0fff8,0x1fff07ff,0xf8e0003f,0xff87fff0,
--      0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e1ff,0xfe386383,0x80e0701c,0xe0381c0,0x700e1c07,
--      0x703870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x7f,0xffc00678,0x707f9c1e,0x38000001,
--      0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0003,0xe00001c3,0x80e00007,0xe00e007,0x80380380,0x700000,0x7f0,0x0,0x7f00700,
--      0x618061ff,0xe070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,0x381c3c,0x1c000e1,0xc38e1ce1,0xc00e1c00,0x70038e0,0x700003c0,
--      0xe007007,0x1c701d8,0xdc03dc00,0x1c000f00,0xe00007,0xe000,0x0,0x3ff,0xf070070e,0x38038,0x7fff0038,0x1c01c1c,0x7001c00,0x1c007fc,
--      0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x3f00,0x1c00380e,0x1c381cd,0x9c01f000,0x73800780,0xfe0000e,0xfe10,0x7c00000,0x1c000ffb,
--      0xf8000000,0x38000000,0x10,0x20000,0x20000,0x1e0700,0x70380ff,0xbf80f003,0xfefe7fdf,0xc0000000,0x0,0x3f0,0x7ffe7ff,0xff000000,
--      0x1f8,0x30e07,0xfeffbf80,0x78000700,0x1c,0x70c001,0xc0006030,0x7fff0000,0x783800,0x1ce11c,0xe1c,0x1c07,0xf838ce38,0x0,0x1c0000,
--      0x0,0x380e,0x18c000,0x0,0x0,0x1c38c00,0x1800030,0x7800,0xfff01ff,0xe03ffc07,0xff80fff0,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,
--      0xe0001,0xc0003800,0x7003803,0x870e70e0,0x71c00e3,0x801c7003,0x8e00700f,0x803b81c7,0x70e00e,0x1c01c380,0x3801c007,0xffe0e03c,
--      0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0fff,0xf8e0003f,0xff87fff0,0xfffe1fff,0xc00e0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,
--      0x80387007,0xe00e000,0x38c383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0063c,0x40619c0f,0x30000001,0xc0000700,0x70,0x7,0xf8000000,0xe003803,0x800e0007,0xc00001c3,
--      0xfffc0007,0xe00e007,0x380380,0xf00000,0xfe,0xffff80,0x3f800700,0x618063ff,0xf070071c,0x38038,0x38000700,0x1c00e38,0x3801c00,
--      0x381c1e,0x1c000e0,0x38e0ee1,0xc00e1c00,0x70038e0,0x380001c0,0xe007007,0x1ef01d8,0xdc038e00,0x1c001e00,0xe00007,0xe000,0x0,
--      0x7c0,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0079e,0x1c0070,0xe1c701c1,0xc01c1c01,0xc700700e,0x780,0x1c00380e,
--      0xe701cd,0x9c01f000,0x73800f00,0xe0000e,0xe000,0x0,0x1c0007f7,0xf0000000,0x70000000,0x10,0x20000,0x0,0xe0e00,0x703807f,0x7f01e001,
--      0xfdfc3fbf,0x80000000,0x0,0x7f0,0x0,0x0,0x3c,0x18e07,0x7f7f00,0xf0000700,0x1c,0x70c001,0xc0007070,0x1c00000,0x3e7000,0xcff18,
--      0x3ffc070e,0x1c07,0xf818c630,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x3870000,0xe000fc00,0x380f000,0x1fff83ff,0xf07ffe0f,
--      0xffc1fff8,0x3fff0ffe,0x1c0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003803,0x870770e0,0x71c00e3,0x801c7003,0x8e00701d,
--      0xc03f01c7,0x70e00e,0x1c01c380,0x3801c007,0xffc0e01c,0x3e0387c0,0x70f80e1f,0x1c3e038,0x7c071e1c,0xe00038,0x70000,0xe0001c00,
--      0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x398383,0x80e0701c,0xe0381c0,0x70073807,0x701ce0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0xffc0061c,0xc0dc07,0xf0000001,0xc0000700,
--      0x70,0x0,0x0,0x1c003c07,0x800e000f,0x1c3,0xfffc0007,0xe00e007,0x380380,0xe00000,0x1f,0xc0ffff81,0xfc000700,0x618063ff,0xf070070e,
--      0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0e,0x1c000e0,0x38e0ee1,0xe01e1c00,0x78078e0,0x380001c0,0xe007007,0xee01f8,0xfc078f00,
--      0x1c001c00,0xe00003,0x8000e000,0x0,0x700,0x7070070e,0x38038,0x70000038,0x1c01c1c,0x7001c00,0x1c0070e,0x1c0070,0xe1c701c1,
--      0xc01c1c01,0xc700700e,0x380,0x1c00380e,0xe700ed,0xb803f800,0x77800f00,0x70000e,0x1c000,0x0,0xe0003f7,0xe0000000,0x70000000,
--      0x10,0x20000,0x1c0e0,0xe1c00,0x703803f,0x7e01c000,0xfdf81fbf,0x0,0x0,0x3f0,0x0,0x0,0x1c,0x1ce07,0x3f7e00,0xf0000700,0x1c,
--      0x70c001,0xc00038e0,0x1c00038,0xf7000,0xe3e38,0x3ffc0387,0x1c00,0x1cc770,0x0,0x1c0000,0x0,0x380e,0x18c000,0x0,0x3ffc,0x70e0001,
--      0xe001fe00,0x780e000,0x1fff83ff,0xf07ffe0f,0xffc1fff8,0x3fff0ffe,0xe0001c,0x38000,0x70000e00,0xe0001,0xc0003800,0x7003807,
--      0x70770f0,0xf1e01e3,0xc03c7807,0x8f00f038,0xe03e03c7,0x70e00e,0x1c01c380,0x3801c007,0xff00e00e,0x38038700,0x70e00e1c,0x1c38038,
--      0x70071c1c,0xe00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003803,0x8380e0e0,0xe1c01c3,0x80387007,0xe00e000,0x3b0383,0x80e0701c,
--      0xe0381c0,0x70077807,0x701de0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x1c00061c,
--      0xc0de03,0xe0000001,0xc0000700,0x70,0x0,0x0,0x1c001c07,0xe001e,0x1c3,0xfffc0007,0x600e00e,0x380380,0xe00000,0x7,0xf0ffff87,
--      0xf0000000,0x60c0e380,0x7070070e,0x38070,0x38000700,0xe00e38,0x3801c00,0x381c0f,0x1c000e0,0x38e06e0,0xe01c1c00,0x38070e0,
--      0x1c0001c0,0xe007007,0xee00f8,0xf80f0700,0x1c003c00,0xe00003,0x8000e000,0x0,0x700,0x70780f0f,0x3c078,0x70000038,0x1e03c1c,
--      0x7001c00,0x1c0070f,0x1c0070,0xe1c701c1,0xe03c1e03,0xc780f00e,0x380,0x1c00380e,0xe700f8,0xf807bc00,0x3f001e00,0x70000e,0x1c000,
--      0x0,0xe0001ff,0xc0000000,0x70000000,0x10,0x20000,0x33110,0xe0e00,0x383801f,0xfc03c000,0x7ff00ffe,0x0,0x0,0x3e0,0x0,0x0,0x1c,
--      0x38e07,0x1ffc01,0xe0000700,0x1c,0x78c001,0xc0007ff0,0x1c00038,0x7c000,0x70070,0x1c3,0x80001c00,0xe00e0,0x0,0x1c0000,0x0,
--      0x380e,0x18c000,0x0,0x0,0xe1c0001,0xe0010700,0x780e000,0x1c038380,0x70700e0e,0x1c1c038,0x78070e0e,0xe0001c,0x38000,0x70000e00,
--      0xe0001,0xc0003800,0x7003807,0x7037070,0xe0e01c1,0xc0383807,0x700e070,0x701c0387,0x70e00e,0x1c01c380,0x3801c007,0xe00e,0x38038700,
--      0x70e00e1c,0x1c38038,0x70071c1c,0xf00038,0x70000,0xe0001c00,0xe0001,0xc0003800,0x7003c07,0x8380e0f0,0x1e1e03c3,0xc078780f,
--      0xf01e007,0x803e0783,0x80e0701c,0xe0381c0,0x7003f007,0x80f00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x6,0x1800061c,0xc0de01,0xc0000000,0xc0000e00,0x70,0xf0000,0x3c00,0x38001c0f,0xe003c,0x3c0,0xe0000e,0x701e00e,
--      0x3c0780,0x1e003c0,0x780000,0xfc00001f,0x80000000,0x60e1e780,0x78700f07,0x4380f0,0x38000700,0xf00e38,0x3801c00,0xc0781c07,
--      0x81c000e0,0x38e07e0,0xe03c1c00,0x380f0e0,0x1e0003c0,0xe00780f,0xee00f0,0x780e0780,0x1c007800,0xe00001,0xc000e000,0x0,0x700,
--      0xf0780e07,0x8041c078,0x38020038,0xe03c1c,0x7001c00,0x1c00707,0x801c0070,0xe1c701c0,0xe0381e03,0x8380f00e,0x80380,0x1c003c1e,
--      0x7e00f8,0xf80f1e00,0x3f003c00,0x70000e,0x1c000,0x0,0xf0100f7,0x80078000,0x700078f0,0x10,0x7ff000,0x61208,0x1e0700,0x383800f,
--      0x78078000,0x3de007bc,0x0,0x0,0x0,0x0,0x0,0x401c,0x70e0f,0xf7803,0xc0000700,0x1c,0x38c001,0xc000efb8,0x1c00038,0x1e000,0x3c1e0,
--      0xc1,0x80000000,0x783c0,0x0,0x0,0x0,0x3c1e,0x18c000,0x0,0x0,0xc180003,0x60000300,0xd80e010,0x3c03c780,0x78f00f1e,0x1e3c03c,
--      0x70039c0e,0x70041c,0x38000,0x70000e00,0xe0001,0xc0003800,0x700380f,0x703f070,0x1e0e03c1,0xc078380f,0x701e0e0,0x381c0787,
--      0x80f0f01e,0x1e03c3c0,0x7801c007,0xe00e,0x38078700,0xf0e01e1c,0x3c38078,0x700f1c1c,0x78041c,0x1038020,0x70040e00,0x800e0001,
--      0xc0003800,0x7001c07,0x380e070,0x1c0e0381,0xc070380e,0x701c007,0x801e0703,0xc1e0783c,0xf0781e0,0xf003f007,0x80e00fc0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xe,0x1801867c,0xc0cf83,0xe0000000,0xe0000e00,
--      0x70,0xf0000,0x3c00,0x38000f1e,0xe0070,0x180780,0xe0603e,0x783c01e,0x1e0f01,0x7c003c0,0x780000,0x3c00001e,0x700,0x307fe700,
--      0x38701e07,0xc1c383e0,0x38000700,0x7c1e38,0x3801c00,0xe0f01c03,0x81c000e0,0x38e03e0,0x78781c00,0x1e1e0e0,0xe180780,0xe003c1e,
--      0x7c00f0,0x781e03c0,0x1c007000,0xe00001,0xc000e000,0x0,0x783,0xf07c1e07,0xc0c1e0f8,0x3e0e0038,0xf07c1c,0x7001c00,0x1c00703,
--      0xc01e0070,0xe1c701c0,0xf0781f07,0x83c1f00e,0xe0f80,0x1e003c3e,0x7e00f8,0xf80e0e00,0x3f003800,0x70000e,0x1c000,0x0,0x7830077,
--      0xf0000,0x700078f0,0x10,0x20000,0x41208,0xc03c0380,0x3c38007,0x70070000,0x1dc003b8,0x0,0x0,0x0,0x0,0x0,0x707c,0x6070f,0x86077003,
--      0x80000700,0x1c,0x3ec401,0xc001c01c,0x1c00038,0xf000,0x1ffc0,0x40,0x80000000,0x3ff80,0x0,0x0,0x0,0x3e3e,0x18c000,0x0,0x0,
--      0x8100006,0x60000300,0x1980f070,0x3801c700,0x38e0071c,0xe3801c,0x70039c0e,0x7c1c1c,0x38000,0x70000e00,0xe0001,0xc0003800,
--      0x700383e,0x701f03c,0x3c078780,0xf0f01e1e,0x3c3c1c0,0x1c3f0f03,0xc1e0783c,0xf0781e0,0xf001c007,0xe81e,0x3c1f8783,0xf0f07e1e,
--      0xfc3c1f8,0x783f1e3e,0x187c0c1f,0x703e0e0,0x7c1c0f83,0x800e0001,0xc0003800,0x7001e0f,0x380e078,0x3c0f0781,0xe0f03c1e,0x783c007,
--      0x801e0f03,0xc3e0787c,0xf0f81e1,0xf003f007,0xc1e00fc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x1c,0xe,0x3801fff8,0x6187ff,0xe0000000,0xe0000e00,0x70,0xf0000,0x3c00,0x38000ffe,0x1fff0ff,0xfe1fff80,0xe07ffc,0x3ffc01c,
--      0x1fff01,0xff8003c0,0x780000,0x4000010,0x700,0x301e6700,0x387ffe03,0xffc3ffc0,0x3fff0700,0x3ffe38,0x383ffe0,0xfff01c03,0xc1fff8e0,
--      0x38e03e0,0x7ff81c00,0x1ffe0e0,0xf1fff80,0xe003ffe,0x7c00f0,0x781c01c0,0x1c00ffff,0xe00001,0xc000e000,0x0,0x3ff,0x707ffc03,
--      0xffc0fff8,0x1ffe0038,0x7ffc1c,0x707fff0,0x1c00701,0xc00ff070,0xe1c701c0,0x7ff01fff,0x1fff00e,0xfff00,0xff81fee,0x7e00f0,
--      0x781e0f00,0x1e007ffc,0x70000e,0x1c000,0x0,0x3ff003e,0xf0000,0xe00070e0,0x60830010,0x20000,0x41208,0xfffc01c0,0x1fffe03,0xe00ffff0,
--      0xf8001f0,0x0,0x0,0x0,0x0,0x0,0x7ff8,0xc07fd,0xfe03e007,0xffc00700,0x1c,0x1ffc1f,0xffc08008,0x1c00038,0x7000,0x7f00,0x0,0x0,
--      0xfe00,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0x6,0x60000700,0x19807ff0,0x3801c700,0x38e0071c,0xe3801c,0x70039c0f,0xf03ffc1f,
--      0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ffc,0x701f03f,0xfc07ff80,0xfff01ffe,0x3ffc080,0x83fff03,0xffe07ffc,0xfff81ff,
--      0xf001c007,0xeffc,0x1ffb83ff,0x707fee0f,0xfdc1ffb8,0x3ff70ff7,0xf83ffc0f,0xff01ffe0,0x3ffc07ff,0x83fff87f,0xff0fffe1,0xfffc0ffe,
--      0x380e03f,0xf807ff00,0xffe01ffc,0x3ff8007,0x803ffe01,0xfee03fdc,0x7fb80ff,0x7001e007,0xffc00780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x3801fff0,0x7f83fe,0x70000000,0xe0000e00,0x0,0xf0000,0x3c00,0x700007fc,
--      0x1fff0ff,0xfe1ffe00,0xe07ff8,0x1ff801c,0xffe01,0xff0003c0,0x780000,0x0,0x700,0x38000f00,0x3c7ffc01,0xff83ff80,0x3fff0700,
--      0x1ffc38,0x383ffe0,0x7fe01c01,0xe1fff8e0,0x38e03e0,0x3ff01c00,0xffc0e0,0x71fff00,0xe001ffc,0x7c00f0,0x783c01e0,0x1c00ffff,
--      0xe00000,0xe000e000,0x0,0x1ff,0x7077f801,0xff807fb8,0xffc0038,0x3fdc1c,0x707fff0,0x1c00701,0xe007f070,0xe1c701c0,0x3fe01dfe,
--      0xff700e,0x7fe00,0xff80fee,0x3c0070,0x703c0780,0x1e007ffc,0x70000e,0x1c000,0x0,0x1fe001c,0xe0000,0xe000e1c0,0x71c78010,0x20000,
--      0x21318,0xfff800c0,0xfffe01,0xc00ffff0,0x70000e0,0x0,0x0,0x0,0x0,0x0,0x3ff0,0x1803fd,0xfe01c007,0xffc00700,0x1c,0xffc1f,0xffc00000,
--      0x1c00038,0x7000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x3ff7,0x8018c000,0x0,0x0,0xc,0x60000e00,0x31803fe0,0x7801ef00,0x3de007bc,
--      0xf7801e,0xf003fc0f,0xf01ff81f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83ff8,0x701f01f,0xf803ff00,0x7fe00ffc,0x1ff8000,
--      0x67fe01,0xffc03ff8,0x7ff00ff,0xe001c007,0xeff8,0xffb81ff,0x703fee07,0xfdc0ffb8,0x1ff70ff7,0xf81ff807,0xfe00ffc0,0x1ff803ff,
--      0x3fff87f,0xff0fffe1,0xfffc07fc,0x380e01f,0xf003fe00,0x7fc00ff8,0x1ff0000,0x37fc00,0xfee01fdc,0x3fb807f,0x7001e007,0x7f800780,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0xc,0x30007fc0,0x1e00f8,0x78000000,0x70001c00,
--      0x0,0xe0000,0x3c00,0x700001f0,0x1fff0ff,0xfe07f800,0xe01fe0,0x7e0038,0x3f800,0xfc0003c0,0x700000,0x0,0x700,0x18000e00,0x1c7ff000,
--      0x7e03fe00,0x3fff0700,0x7f038,0x383ffe0,0x1f801c00,0xf1fff8e0,0x38e01e0,0xfc01c00,0x3f80e0,0x787fc00,0xe0007f0,0x7c00f0,0x387800f0,
--      0x1c00ffff,0xe00000,0xe000e000,0x0,0xfc,0x7071f000,0x3f003e38,0x3f00038,0x1f1c1c,0x707fff0,0x1c00700,0xf003f070,0xe1c701c0,
--      0x1f801c7c,0x7c700e,0x1f800,0x3f8078e,0x3c0070,0x707803c0,0x1c007ffc,0x70000e,0x1c000,0x0,0x7c0008,0x1e0000,0xe000e1c0,0x71c30010,
--      0x20000,0x1e1f0,0x3fe00020,0x3ffe00,0x800ffff0,0x2000040,0x0,0x0,0x0,0x0,0x0,0xfc0,0x3001f0,0x78008007,0xffc00700,0x1c,0x3f81f,
--      0xffc00000,0x1c00038,0x407000,0x0,0x0,0x0,0x0,0x0,0xffff800,0x0,0x39c7,0x18c000,0x0,0x0,0x18,0x60001c00,0x61801f80,0x7000ee00,
--      0x1dc003b8,0x77000e,0xe001f80f,0xf007e01f,0xff83fff0,0x7ffe0fff,0xc1fff03f,0xfe07ffc0,0xfff83fc0,0x700f007,0xe000fc00,0x1f8003f0,
--      0x7e0000,0xe1f800,0x7f000fe0,0x1fc003f,0x8001c007,0xe7f0,0x7e380fc,0x701f8e03,0xf1c07e38,0xfc703c1,0xe003f001,0xf8003f00,
--      0x7e000fc,0x3fff87f,0xff0fffe1,0xfffc03f8,0x380e00f,0xc001f800,0x3f0007e0,0xfc0000,0x61f800,0x78e00f1c,0x1e3803c,0x7001c007,
--      0x1f000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x70001c00,0x0,
--      0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
--      0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
--      0x70000e,0x1c000,0x0,0x0,0x1c0000,0xe000c180,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
--      0x0,0x38,0x70e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x2000,0x0,0x1f,0xf8003800,0x7fe00000,0x0,0x0,0x0,0x0,0x4000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,
--      0x0,0x0,0x1c007,0x700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x30001800,
--      0x0,0x1c0000,0x0,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e000,
--      0x0,0x0,0x0,0x0,0x0,0xe00000,0x7000e000,0x0,0x0,0x0,0x0,0x0,0x1c00,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x1c000000,
--      0x70000e,0x1c000,0x0,0x0,0x1c0001,0xe001c380,0x10,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
--      0x0,0x38,0x7fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x3000,0x0,0x1f,0xf8007000,0x7fe00000,0x0,0x0,0x0,0x0,0x6000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x1c007,0x700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x38003800,
--      0x0,0x380000,0x1,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00000,0x0,0x0,0x3c18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf000,
--      0x0,0x0,0x0,0x0,0x0,0xfe0000,0x380fe000,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x38000000,
--      0x78000e,0x3c000,0x0,0x0,0x180001,0xc0018300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,
--      0x38,0x1f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x18c000,0x1800,0x0,0x0,0x6000e000,0x1800000,0x0,0x0,0x0,0x0,0x3000,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x38007,0xe00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x18003000,
--      0x0,0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x1ff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,
--      0x0,0x0,0x0,0xfe0000,0xfe000,0x0,0x0,0x0,0x0,0x0,0x607800,0x0,0x3c00000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x0,0x78000000,
--      0x3f800e,0x3f8000,0x0,0x0,0x300043,0xc0018200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,
--      0x0,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x11800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x23000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78007,
--      0x1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x1c007000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe0000,
--      0xfe000,0x0,0x0,0x0,0x0,0x0,0x7ff000,0x0,0x7f800000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf8000000,0x3f800e,0x3f8000,0x0,
--      0x0,0x10007f,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x38,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x3800,0x0,0x1f800,0x0,0x0,0x6001ff00,0x1800000,0x0,0x0,0x0,0x0,0x3f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f8007,0xfe00,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x7fe000,0x0,
--      0x7f000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xf0000000,0xf800e,0x3e0000,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x1f000,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x3f0007,0xfc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x1fc000,0x0,0x7e000000,0x0,0x0,0x1c00,0x7000,0x0,0x0,0x0,0x3,0xc0000000,0xe,0x0,
--      0x0,0x0,0x3e,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x3800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0007,0xf000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 29x57 font
--    const unsigned int font29x57[29*57*256/32] = {
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x781e00,0x0,0x0,0x7,0x81e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0000,0xf8000,0x7e00000,0x0,0x7,
--      0xc0000000,0x0,0x7c00,0xf80,0x7e000,0x0,0x7c00000,0xf80000,0x7e000000,0x0,0x0,0x1f00,0x3e0,0x1f800,0x0,0x0,0x0,0x3,0xe0000000,
--      0x7c00003f,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x3c3c00,0x0,0x0,0x3,0xc3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,
--      0x1f0000,0x7e00000,0xf838001f,0xf80001f,0xf0000000,0x0,0x3e00,0x1f00,0x7e000,0x3e1f000,0x3e00000,0x1f00000,0x7e00003e,0x1f000000,
--      0x3e0,0xe0000f80,0x7c0,0x1f800,0x3e0e00,0x7c3e000,0x0,0x1,0xf0000000,0xf800003f,0x1f0f,0x800001f0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e7800,0x0,0x0,
--      0x1,0xe7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x1e0000,0xff00001,0xfe38001f,0xf80003f,
--      0xf8000000,0x0,0x1e00,0x1e00,0xff000,0x3e1f000,0x1e00000,0x1e00000,0xff00003e,0x1f000000,0x7f8,0xe0000780,0x780,0x3fc00,0x7f8e00,
--      0x7c3e000,0x0,0x0,0xf0000000,0xf000007f,0x80001f0f,0x800001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xef000,0x0,0x0,0x0,0xef000000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000,0x3c0000,0x1e780003,0xfff8001f,0xf80003c,0x78000000,0x0,0xf00,0x3c00,0x1e7800,
--      0x3e1f000,0xf00000,0x3c00001,0xe780003e,0x1f000000,0xfff,0xe00003c0,0xf00,0x79e00,0xfffe00,0x7c3e000,0x0,0x0,0x78000001,0xe00000f3,
--      0xc0001f0f,0x800003c0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x78000,0x780000,0x3c3c0003,0x8ff0001f,0xf800078,0x3c000000,0x0,0x780,0x7800,0x3c3c00,0x3e1f000,0x780000,0x7800003,0xc3c0003e,
--      0x1f000000,0xe3f,0xc00001e0,0x1e00,0xf0f00,0xe3fc00,0x7c3e000,0x0,0x0,0x3c000003,0xc00001e1,0xe0001f0f,0x80000780,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x1f,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc00,0x7e000,0xfe000,0x0,0x3c000,0xf00000,0x781e0003,
--      0x83e0001f,0xf800070,0x1c000000,0x0,0x3c0,0xf000,0x781e00,0x3e1f000,0x3c0000,0xf000007,0x81e0003e,0x1f000000,0xe0f,0x800000f0,
--      0x3c00,0x1e0780,0xe0f800,0x7c3e000,0x0,0x0,0x1e000007,0x800003c0,0xf0001f0f,0x80000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf8000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ff800,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x78,0xf000000,0x0,0x0,0x780f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ffc00,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x3e000,0x3e00000,0x0,0x78,0x3c000000,0x0,0x1f000,0x3e0,
--      0x3e000,0x0,0x1f000000,0x3e0000,0x3e000000,0x0,0x0,0x7c00,0xf8,0xf800,0x0,0x0,0x0,0xf,0x80000000,0x1f00001f,0x0,0x3e,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x781c0000,0x38,0xe000000,0x0,0x0,0x380e0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x39c00,0x1ce000,0x303e00,
--      0x0,0x0,0x0,0x0,0x0,0x78,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,
--      0x0,0x0,0xf80000,0x7c000,0x3e00000,0xf0380000,0x70,0x1c000000,0x0,0xf800,0x7c0,0x3e000,0x0,0xf800000,0x7c0000,0x3e000000,
--      0x0,0x3c0,0xe0003e00,0x1f0,0xf800,0x3c0e00,0x0,0x0,0x7,0xc0000000,0x3e00001f,0x0,0x7c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0xff,0x0,
--      0xf8,0xf8000,0x1c000,0x0,0x0,0x0,0x0,0x1f,0xc0000000,0x1ff8,0xff00,0x0,0x0,0x3fe000,0x0,0x1fc00001,0xfe000000,0x0,0x0,0x0,
--      0x0,0x7f800,0x0,0x0,0x0,0xff00000,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf8000000,0xfe,0x0,0x7f80,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x780000,0x1,0xe0000000,0x0,0x780000,0x3,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x3fc00,0x0,0x0,0x1fc000,0x0,0x0,0x0,0x1fc0,
--      0x0,0xff000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe1c0000,0x1c,0x1c000000,0x0,0x0,0x1c1c0,0x0,0x0,0x0,0x0,0x1fe0000,
--      0x0,0x0,0x1ff,0x1f0f8,0x0,0xff000,0x0,0x0,0x0,0x3f,0xff00000f,0x80000000,0xfe0,0x3f80,0xf00,0x0,0x0,0x0,0x1,0xf8000003,0xe0000000,
--      0x1c00,0xe000,0xe00,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,
--      0x7f0000,0x0,0x1fc07000,0x0,0x0,0x0,0x0,0x0,0x3f800,0x780000,0x78000,0x7f00001,0xfc38001f,0xf800070,0x1c000000,0x0,0x7800,
--      0x780,0x7f000,0x3e1f000,0x7800000,0x780000,0x7f00003e,0x1f0003f0,0x7f0,0xe0001e00,0x1e0,0x1fc00,0x7f0e00,0x7c3e000,0x0,0x3,
--      0xc0000000,0x3c00003f,0x80001f0f,0x80000078,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x1e078000,0x30000000,0x3ff,0xc00001e0,0xf0,
--      0x78000,0x1c000,0x0,0x0,0x0,0x0,0x1e0007f,0xf000007e,0x1ffff,0x7ffe0,0x1f80,0x3ffff80,0xfff803,0xfffff800,0xfff80007,0xff800000,
--      0x0,0x0,0x0,0x0,0x1ffe00,0x0,0xfe0003,0xfff80000,0x3ffe01ff,0xe00003ff,0xffe01fff,0xff0003ff,0xe01e0007,0x803ffff0,0xfff80,
--      0x3c000fc0,0x7800001f,0x8003f07e,0x1e000f,0xfe0007ff,0xf00003ff,0x8007ffe0,0x1fff8,0x7fffffe,0xf0003c1,0xe000079e,0xf1f,0x1f3e0,
--      0x1f01ff,0xfff8003f,0xf003c000,0x7fe0,0x3f00,0x0,0x3c0000,0x1,0xe0000000,0x0,0x780000,0xf,0xfe000000,0x78000,0x3c00,0xf000,
--      0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xfc0000f0,0x3fe00,0x0,0x0,0xfff00,0x0,0x0,0x3fe000,
--      0x0,0x0,0x0,0x1dc0,0x0,0x3fff00,0x0,0x3ffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff1c07ff,0x3c0f001e,0x3c000000,
--      0x0,0x0,0x1e3c0,0xf80007c,0x0,0x780000,0x0,0xfff8000,0x3e00,0x1f00000,0x7ff,0xc001f0f8,0x0,0x3ffc00,0x0,0x0,0x0,0x3f,0xff00003f,
--      0xe0000000,0x3ff8,0xffe0,0x1e00,0x0,0xfffc00,0x0,0x7,0xf800000f,0xf8000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,
--      0x3f800001,0xfc00003f,0xf80000ff,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,
--      0xfc00,0x3c001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x0,0x7ff8f0f0,0x3c0780,0x1e03c00,0xf01e000,0x783e0001,0xf01e0000,0xffe00,
--      0x3c0000,0xf0000,0x7700001,0xfe38001f,0xf800070,0x1c000000,0x0,0x3c00,0xf00,0x77000,0x3e1f000,0x3c00000,0xf00000,0x7700003e,
--      0x1f0000f8,0xc0007f8,0xe0000f00,0x3c0,0x1dc00,0x7f8e00,0x7c3e000,0x0,0x1,0xe0000000,0x7800003b,0x80001f0f,0x800000f0,0x1e0000,
--      0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x780000,0x3c1e0000,0x1e070000,0x300001f0,0x7ff,0xc00001e0,0x1e0,0x7c000,0x1c000,0x0,0x0,0x0,0x0,0x3c000ff,0xf80007fe,
--      0x3ffff,0x801ffff8,0x1f80,0x3ffff80,0x3fff803,0xfffff801,0xfffc000f,0xffc00000,0x0,0x0,0x0,0x0,0x7fff80,0x0,0xfe0003,0xffff0000,
--      0xffff01ff,0xfc0003ff,0xffe01fff,0xff000fff,0xf01e0007,0x803ffff0,0xfff80,0x3c001f80,0x7800001f,0xc007f07e,0x1e001f,0xff0007ff,
--      0xfc0007ff,0xc007fffc,0x3fffc,0x7fffffe,0xf0003c1,0xf0000f9e,0xf0f,0x8003e1e0,0x1e01ff,0xfff8003f,0xf001e000,0x7fe0,0x3f00,
--      0x0,0x1e0000,0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x1fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x3de0,0x0,0x7fff80,0x0,0xfffff80,
--      0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe7bc07ff,0x3e1f000f,0x78000000,0x0,0x0,0xf780,0x7800078,0x0,0x780000,0x180000,
--      0x1fff8000,0x1e00,0x1e0003c,0xfff,0xc001f0f8,0x0,0x7ffe00,0x0,0x0,0x0,0x3f,0xff00007f,0xf0000000,0x3ffc,0xfff0,0x3c00,0x0,
--      0x7fffc00,0x0,0x7,0xf800003f,0xfe000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xe00001ff,
--      0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000fc00,0x3c003ffe,0x1fff0,
--      0xfff80,0x7ffc00,0x3ffe000,0x0,0xfffce0f0,0x3c0780,0x1e03c00,0xf01e000,0x781e0001,0xe01e0000,0x3fff00,0x1e0000,0x1e0000,0xf780003,
--      0xcf78001f,0xf800078,0x3c000000,0x0,0x1e00,0x1e00,0xf7800,0x3e1f000,0x1e00000,0x1e00000,0xf780003e,0x1f0000fc,0x7c000f3d,
--      0xe0000780,0x780,0x3de00,0xf3de00,0x7c3e000,0x0,0x0,0xf0000000,0xf000007b,0xc0001f0f,0x800001e0,0x1e0000,0x3e1f00,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
--      0x3c1e0000,0x1e0f0000,0x300007fc,0xfff,0xc00001e0,0x1e0,0x3c000,0x1c000,0x0,0x0,0x0,0x0,0x3c001ff,0xfc001ffe,0x3ffff,0xc01ffffc,
--      0x3f80,0x3ffff80,0x7fff803,0xfffff803,0xfffe001f,0xffe00000,0x0,0x0,0x0,0x0,0xffff80,0x7f800,0xfe0003,0xffff8001,0xffff01ff,
--      0xff0003ff,0xffe01fff,0xff001fff,0xf01e0007,0x803ffff0,0xfff80,0x3c003f00,0x7800001f,0xc007f07f,0x1e003f,0xff8007ff,0xff000fff,
--      0xe007ffff,0x7fffc,0x7fffffe,0xf0003c0,0xf0000f1e,0xf07,0x8003c1f0,0x3e01ff,0xfff8003f,0xf001e000,0x7fe0,0x7f80,0x0,0xe0000,
--      0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
--      0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x3fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x78f0,0x0,0xffff80,0x0,0x3fffff80,0x1f,
--      0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc7f80070,0x3e1f0007,0x70000000,0x0,0x0,0x7700,0x7c000f8,0x0,0x780000,0x180000,
--      0x3fff8000,0x1f00,0x3e0003c,0x1f03,0xc001f0f8,0x0,0x703f00,0x0,0x0,0x0,0x3f,0xff0000f0,0xf8000000,0x303e,0xc0f8,0x7800,0x0,
--      0xffffc00,0x0,0x7,0x3800003e,0x3e000000,0x1c00,0xe000,0x3c00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00000f,0xe00001ff,
--      0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000fe00,0x3c007fff,0x3fff8,
--      0x1fffc0,0xfffe00,0x7fff000,0x1,0xffffc0f0,0x3c0780,0x1e03c00,0xf01e000,0x781f0003,0xe01e0000,0x3fff80,0xe0000,0x3c0000,0x1e3c0003,
--      0x8ff0001f,0xf80003c,0x78000000,0x0,0xe00,0x3c00,0x1e3c00,0x3e1f000,0xe00000,0x3c00001,0xe3c0003e,0x1f00007f,0xf8000e3f,0xc0000380,
--      0xf00,0x78f00,0xe3fc00,0x7c3e000,0x0,0x0,0x70000001,0xe00000f1,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0000,
--      0x30000ffe,0xf80,0xc00001e0,0x3c0,0x1e000,0x101c040,0x0,0x0,0x0,0x0,0x78003f0,0x7e001ffe,0x3f807,0xe01f00fe,0x3f80,0x3ffff80,
--      0x7e01803,0xfffff007,0xe03f003f,0x3f00000,0x0,0x0,0x0,0x0,0xfc0fc0,0x3ffe00,0xfe0003,0xffffc003,0xf81f01ff,0xff8003ff,0xffe01fff,
--      0xff003f01,0xf01e0007,0x803ffff0,0xfff80,0x3c007e00,0x7800001f,0xc007f07f,0x1e007e,0xfc007ff,0xff801f83,0xf007ffff,0x800fc07c,
--      0x7fffffe,0xf0003c0,0xf0000f0f,0x1e07,0xc007c0f8,0x7c01ff,0xfff8003c,0xf000,0x1e0,0xffc0,0x0,0xf0000,0x1,0xe0000000,0x0,0x780000,
--      0x3e,0x0,0x78000,0x3c00,0xf000,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0x800000f0,0x1f80,
--      0x0,0x0,0x7e0780,0x0,0x0,0x1f82000,0x0,0x0,0x0,0x7070,0x0,0x1f80f80,0x0,0x7fffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x1,0xc3f80070,0x3f3f0007,0xf0000000,0x0,0x0,0x7f00,0x3e001f0,0x0,0x780000,0x180000,0x7f018000,0xf80,0x7c0003c,0x3e00,
--      0x4001f0f8,0xfe00,0x400f00,0x0,0x0,0x0,0x7f000000,0xe0,0x38000000,0x1e,0x38,0x7800,0x0,0x1ffe1c00,0x0,0x0,0x38000078,0xf000000,
--      0x1c00,0xe000,0x7f800,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xf00001ff,0xffc03f81,0xf007ffff,0xc03ffffe,
--      0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf800fe00,0x3c00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,
--      0x3,0xf07fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x780f8007,0xc01e0000,0x7e0fc0,0xf0000,0x3c0000,0x1c1c0003,0x87f0001f,0xf80003f,
--      0xf8000000,0x0,0xf00,0x3c00,0x1c1c00,0x3e1f000,0xf00000,0x3c00001,0xc1c0003e,0x1f00003f,0xc0000e1f,0xc00003c0,0xf00,0x70700,
--      0xe1fc00,0x7c3e000,0x0,0x0,0x78000001,0xe00000e0,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0001,0xff801e0f,
--      0x1f00,0x1e0,0x3c0,0x1e000,0x3c1c1e0,0x0,0x0,0x0,0x0,0x78007c0,0x1f001f9e,0x3c001,0xf010003e,0x7780,0x3c00000,0xf800000,0xf007,
--      0xc01f007c,0x1f80000,0x0,0x0,0x0,0x0,0xe003e0,0x7fff00,0x1ef0003,0xc007e007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x301e0007,
--      0x80007800,0x780,0x3c00fc00,0x7800001f,0xe00ff07f,0x1e00f8,0x3e00780,0x1fc03e00,0xf807801f,0xc01f001c,0xf000,0xf0003c0,0xf0000f0f,
--      0x1e03,0xc00f8078,0x780000,0xf0003c,0xf000,0x1e0,0x1f3e0,0x0,0x78000,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,
--      0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0xf0,0xf80,0x0,0x0,0xf80180,0x0,0x0,0x1e00000,
--      0x0,0x0,0x0,0xe038,0x0,0x3e00380,0x0,0xfe0f0000,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc0f00070,0x3b370003,0xe0000000,
--      0x0,0x0,0x3e00,0x1e001e0,0x0,0x780000,0x180000,0x7c000000,0x780,0x780003c,0x3c00,0x0,0x7ffc0,0x780,0x0,0x0,0x3,0xffe00000,
--      0x1c0,0x3c000000,0xe,0x38,0xf000,0x0,0x3ffe1c00,0x0,0x0,0x38000078,0xf000000,0x1c00,0xe000,0x7f000,0xf000,0x3de000,0x1ef0000,
--      0xf780000,0x7bc00003,0xde00001e,0xf00003e7,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
--      0xe0001e03,0xfc00fe00,0x3c01f007,0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x7,0xc01f80f0,0x3c0780,0x1e03c00,0xf01e000,0x78078007,
--      0x801e0000,0x7803c0,0x78000,0x780000,0x380e0003,0x81e00000,0x1f,0xf0000000,0x0,0x780,0x7800,0x380e00,0x0,0x780000,0x7800003,
--      0x80e00000,0x1ff,0x80000e07,0x800001e0,0x1e00,0xe0380,0xe07800,0x0,0x0,0x0,0x3c000003,0xc00001c0,0x70000000,0x780,0x1e0000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x780000,0x3c1e0000,0x3c0e0007,0xfff01c07,0x1e00,0x1e0,0x780,0xf000,0x3e1c3e0,0x0,0x0,0x0,0x0,0xf0007c0,0x1f00181e,0x20000,
--      0xf000001f,0xf780,0x3c00000,0x1f000000,0x1f00f,0x800f8078,0xf80000,0x0,0x0,0x0,0x0,0x8003e0,0x1fc0f80,0x1ef0003,0xc001e007,
--      0x800101e0,0x7e003c0,0x1e00,0x7800,0x101e0007,0x80007800,0x780,0x3c00f800,0x7800001e,0xe00ef07f,0x801e00f0,0x1e00780,0x7c03c00,
--      0x78078007,0xc01e0004,0xf000,0xf0003c0,0x78001e0f,0x1e03,0xe00f807c,0xf80000,0x1f0003c,0x7800,0x1e0,0x3e1f0,0x0,0x3c000,0x1,
--      0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,
--      0x1e,0xf0,0x780,0x0,0x0,0x1f00080,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x1e03c,0x0,0x3c00080,0x0,0xf80f0000,0x0,0x1f0000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x3bf70003,0xe0000000,0x0,0x0,0x3e00,0x1f003e0,0x0,0x780000,0x180000,0x78000000,0x7c0,0xf80003c,
--      0x3c00,0x0,0x1f01f0,0x780,0x0,0x0,0xf,0x80f80000,0x1c0,0x1c000000,0xe,0x38,0x1e000,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,0x7800000,
--      0x1c00,0xe000,0x7fc00,0xf000,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x80007800,0x10078000,0x3c0000,
--      0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00ff00,0x3c01e003,0xc00f001e,0x7800f0,0x3c00780,0x1e003c00,
--      0x7,0x800f00f0,0x3c0780,0x1e03c00,0xf01e000,0x7807c00f,0x801e0000,0xf803c0,0x3c000,0xf00000,0x780f0000,0x0,0x7,0xc0000000,
--      0x0,0x3c0,0xf000,0x780f00,0x0,0x3c0000,0xf000007,0x80f00000,0x7ff,0xc0000000,0xf0,0x3c00,0x1e03c0,0x0,0x0,0x0,0x0,0x1e000007,
--      0x800003c0,0x78000000,0xf00,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c1e001f,0xfff03803,0x80001e00,0x1e0,0x780,0xf000,0xf9cf80,
--      0x0,0x0,0x0,0x0,0xf000780,0xf00001e,0x0,0xf800000f,0xe780,0x3c00000,0x1e000000,0x1e00f,0x78078,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,
--      0x3f003c0,0x1ef0003,0xc000f00f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,0x3c01f000,0x7800001e,0xe00ef07f,
--      0x801e01f0,0x1e00780,0x3c07c00,0x78078003,0xc03e0000,0xf000,0xf0003c0,0x78001e0f,0x1e01,0xf01f003c,0xf00000,0x3e0003c,0x7800,
--      0x1e0,0x7c0f8,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,
--      0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x8,0x40,0x0,0x7e0000,0x7c00000,0x1,0xf00f0000,
--      0x0,0x3e0000,0x0,0x3f,0xfc0,0xfc3f0,0xfc3f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,0xf003c0,0x0,0x0,0x180000,0xf8000000,
--      0x3c0,0xf00003c,0x3c00,0x0,0x3c0078,0x7ff80,0x0,0x0,0x1e,0x3c0000,0x1c0,0x1c000000,0xe,0xf0,0x0,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,
--      0x7800000,0x1c00,0xe000,0x3c00,0x0,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x8000f800,0x78000,0x3c0000,
--      0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00ff00,0x3c03e003,0xc01f001e,0xf800f0,0x7c00780,0x3e003c00,
--      0xf,0x800f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803c00f,0x1fffc0,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x307,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x781e003f,0xfff03803,
--      0x80001e00,0x1e0,0xf80,0xf000,0x3dde00,0x0,0x0,0x0,0x0,0xf000f00,0x780001e,0x0,0x7800000f,0x1e780,0x3c00000,0x3e000000,0x3e00f,
--      0x780f0,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,0x7c001e0,0x3ef8003,0xc000f00f,0x1e0,0xf003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,
--      0x3c03e000,0x7800001e,0xf01ef07b,0xc01e01e0,0xf00780,0x3e07800,0x3c078003,0xe03c0000,0xf000,0xf0003c0,0x78001e0f,0x1e00,0xf01e003e,
--      0x1f00000,0x3c0003c,0x7800,0x1e0,0x78078,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,
--      0xe70000,0x7800000,0x1,0xe00f0000,0x0,0x3c0000,0x0,0x3f,0xfc0,0xfc1f0,0x1f83f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,
--      0xf807c0,0x0,0x0,0x180000,0xf0000000,0x3e0,0x1f00003c,0x3e00,0x0,0x70001c,0x3fff80,0x0,0x0,0x38,0xe0000,0x1c0,0x1c000078,
--      0x1c,0x1fe0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x7df000,0x3ef8000,0x1f7c0000,0xfbe00007,
--      0xdf00003c,0x780003c7,0x8000f000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f780,
--      0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0xf80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803e01f,0x1ffff8,0xf001e0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x0,0x0,0x1e0000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x780000,0x3c1e0000,0x781e003e,0x30703803,0x80001e00,0x1e0,0xf00,0x7800,0xff800,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,
--      0x0,0x7800000f,0x3c780,0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x2000000,0x800000,0x1e0,0x78000e0,0x3c78003,
--      0xc000f01e,0x1e0,0xf803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x701cf07b,0xc01e01e0,0xf00780,0x1e07800,
--      0x3c078001,0xe03c0000,0xf000,0xf0003c0,0x7c003e0f,0x1e00,0xf83e001e,0x1e00000,0x7c0003c,0x3c00,0x1e0,0xf807c,0x0,0x0,0x1fe0001,
--      0xe1fc0000,0x7f00003,0xf8780007,0xf000003c,0x7f0,0x783f0,0x0,0x0,0x7800000,0x1e00000,0x3e0f8000,0xfc00007,0xf8000007,0xf00001fc,
--      0xf,0xc0003fc0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,0x1818000,
--      0x7800000,0x1,0xe00f0000,0x0,0x7c0000,0x0,0x1f,0x80001f80,0x7c1f8,0x1f83e0,0x0,0x0,0x0,0x70,0x38c70007,0xf8000000,0x7f03,
--      0xf0000000,0x0,0x780780,0x0,0x0,0xfe0000,0xf0000000,0x1e0,0x1e00003c,0x3f00,0x0,0xe07f0e,0x7fff80,0x0,0x0,0x70,0x70000,0x1c0,
--      0x1c000078,0x3c,0x1fc0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x78f000,0x3c78000,0x1e3c0000,
--      0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
--      0xf80f780,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0x1f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801e01e,0x1ffffc,
--      0xf007e0,0x3fc000,0x1fe0000,0xff00000,0x7f800003,0xfc00001f,0xe0000fc0,0xfc00007f,0xfe0,0x7f00,0x3f800,0x1fc000,0x0,0x0,0x0,
--      0x1,0xf000001f,0x80000ff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x1f80000,0x1fc1e000,0x0,0x0,0x0,0x0,0x1e1fc0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,
--      0x781c007c,0x30003803,0x80001f00,0x1e0,0xf00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,0x0,0x7800000f,0x3c780,
--      0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x1e000000,0xf00000,0x3e0,0xf0000e0,0x3c78003,0xc000f01e,0x1e0,0x7803c0,
--      0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c0f8000,0x7800001e,0x701cf079,0xe01e01e0,0xf00780,0x1e07800,0x3c078001,0xe03c0000,
--      0xf000,0xf0003c0,0x3c003c0f,0x3e00,0x787c001f,0x3e00000,0xf80003c,0x3c00,0x1e0,0x1f003e,0x0,0x0,0x1fffc001,0xe7ff0000,0x3ffe000f,
--      0xfe78003f,0xfc001fff,0xfe001ffc,0xf0078ffc,0x1ffc00,0x7ff000,0x7800f80,0x1e0000f,0x7f1fc01e,0x3ff0001f,0xfe00079f,0xfc0007ff,
--      0x3c003c7f,0xf001fff8,0x1fffff0,0x3c003c0,0xf0000f1e,0xf1f,0x7c1f0,0x1f00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3c00000,0x100000,
--      0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7800000,0x1,0xe00f0000,0x1000000,0xf80000,0x40000002,0xf,0x80001f00,0x7e0f8,0x1f07c0,
--      0x0,0x0,0x0,0x70,0x38c7003f,0xff000000,0xff8f,0xf8000100,0xffffe,0x7c0f80,0x0,0x0,0x3ffc000,0xf0000020,0x1001f0,0x3c00003c,
--      0x1f80,0x0,0x1c3ffc7,0x7c0780,0x0,0x0,0xe3,0xff038000,0xe0,0x38000078,0x78,0x1ff0,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,
--      0x7800000,0x1c00,0xe000,0xe00,0xf000,0x78f000,0x3c78000,0x1e3c0000,0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,
--      0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,
--      0x4000200f,0x3f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801f03e,0x1ffffe,0xf01fe0,0x3fff800,0x1fffc000,0xfffe0007,0xfff0003f,
--      0xff8001ff,0xfc003ff3,0xfe0003ff,0xe0007ff8,0x3ffc0,0x1ffe00,0xfff000,0x3ff80001,0xffc0000f,0xfe00007f,0xf000003f,0xf8003c7f,
--      0xe0003ffc,0x1ffe0,0xfff00,0x7ff800,0x3ffc000,0x1f80000,0xfff1c03c,0x3c01e0,0x1e00f00,0xf007800,0x781f0001,0xf01e7ff0,0x7c0007c,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
--      0x3c1e003f,0xfffff078,0x30003803,0x80000f00,0x1e0,0x1f00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x3c000f00,0x780001e,0x0,0x7800000f,
--      0x78780,0x3c00000,0x3c000000,0x7c00f,0x780f0,0x3c0007,0xe000003f,0x0,0xfe000000,0xfe0000,0x3c0,0x1f000070,0x7c7c003,0xc000f01e,
--      0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c1f0000,0x7800001e,0x783cf079,0xe01e03c0,0xf00780,0x1e0f000,0x3c078001,
--      0xe03c0000,0xf000,0xf0003c0,0x3c003c07,0x81f03c00,0x7c7c000f,0x87c00000,0xf00003c,0x1e00,0x1e0,0x3e001f,0x0,0x0,0x3fffe001,
--      0xefff8000,0x7fff001f,0xff78007f,0xfe001fff,0xfe003ffe,0xf0079ffe,0x1ffc00,0x7ff000,0x7801f00,0x1e0000f,0xffbfe01e,0x7ff8003f,
--      0xff0007bf,0xfe000fff,0xbc003cff,0xf803fffc,0x1fffff0,0x3c003c0,0x78001e1e,0xf0f,0x800f80f0,0x1e00ff,0xffe0001e,0xf0,0x780,
--      0x0,0x0,0x3c00000,0x380000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1008000,0x7800000,0x3,0xe00f0000,0x3800000,0xf00000,0xe0000007,
--      0xf,0x80001f00,0x3e0f8,0x1e07c0,0x0,0x0,0x0,0x70,0x3807007f,0xff800000,0x1ffdf,0xfc000380,0xffffe,0x3e1f00,0x0,0x0,0xfffe000,
--      0xf0000030,0x3800f8,0x7c00003c,0xfc0,0x0,0x18780c3,0xf00780,0x80100,0x0,0xc3,0xffc18000,0xf0,0x78000078,0xf0,0xf0,0x0,0x3c003c0,
--      0xfffe1c00,0x0,0x0,0x380000f0,0x7800801,0x1c00,0xe000,0x1e00,0xf000,0xf8f800,0x7c7c000,0x3e3e0001,0xf1f0000f,0x8f80007c,0x7c000787,
--      0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078001,0xe03c000f,
--      0x1e00078,0xf0003c0,0x78001e00,0xe000701f,0x3fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x7800f87c,0x1e007f,0xf07e00,0x7fffc00,0x3fffe001,
--      0xffff000f,0xfff8007f,0xffc003ff,0xfe007ff7,0xff0007ff,0xf000fffc,0x7ffe0,0x3fff00,0x1fff800,0x3ff80001,0xffc0000f,0xfe00007f,
--      0xf00000ff,0xf8003cff,0xf0007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x1f80001,0xfffb803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,
--      0xe01efff8,0x3c00078,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e003f,0xfffff078,0x30001c07,0xf80,0x1e0,0x1e00,0x3c00,0xff800,0x1e0000,0x0,0x0,0x0,0x3c001e00,
--      0x3c0001e,0x0,0x7800001e,0x70780,0x3c00000,0x78000000,0x78007,0x800f00f0,0x3e0007,0xe000003f,0x3,0xfe000000,0xff8000,0x7c0,
--      0x1e000070,0x783c003,0xc001f01e,0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c3e0000,0x7800001e,0x3838f079,
--      0xe01e03c0,0x780780,0x1e0f000,0x1e078001,0xe03c0000,0xf000,0xf0003c0,0x3c007c07,0x81f03c00,0x3ef80007,0x87800000,0x1f00003c,
--      0x1e00,0x1e0,0x7c000f,0x80000000,0x0,0x3ffff001,0xffffc000,0xffff003f,0xff7800ff,0xff001fff,0xfe007ffe,0xf007bffe,0x1ffc00,
--      0x7ff000,0x7803e00,0x1e0000f,0xffffe01e,0xfff8007f,0xff8007ff,0xff001fff,0xbc003dff,0xf807fffc,0x1fffff0,0x3c003c0,0x78001e0f,
--      0x1e07,0xc01f00f0,0x1e00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7c00000,0x7c0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1018000,0x7800000,
--      0x3,0xc00f0000,0x7c00000,0x1f00001,0xf000000f,0x80000007,0xc0003e00,0x1e07c,0x3e0780,0x0,0x0,0x0,0x70,0x380700ff,0xff800000,
--      0x3ffff,0xfe0007c0,0xffffe,0x1e1e00,0x0,0x780000,0x1fffe000,0xf0000078,0x7c0078,0x7800003c,0xff0,0x0,0x38e0003,0x80f00780,
--      0x180300,0x0,0x1c3,0x81e1c000,0x7f,0xf0000078,0x1e0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800c01,0x80001c00,
--      0xe000,0x603e00,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x7800078,0x3c000f87,0x8001e000,0x78000,0x3c0000,0x1e00000,
--      0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f01,0xf000f81e,
--      0x7bc0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007878,0x1e001f,0xf0f800,0x7fffe00,0x3ffff001,0xffff800f,0xfffc007f,0xffe003ff,
--      0xff007fff,0xff800fff,0xf001fffe,0xffff0,0x7fff80,0x3fffc00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00001ff,0xfc003dff,0xf000ffff,
--      0x7fff8,0x3fffc0,0x1fffe00,0xffff000,0x1f80003,0xffff803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,0xe01ffffc,0x3c00078,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
--      0x3c1e003f,0xfffff078,0x30001e0f,0x300780,0x1e0,0x1e00,0x3c00,0x3dde00,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf800003e,
--      0xf0780,0x3dfc000,0x783f8000,0xf8007,0xc01f00f0,0x3e0007,0xe000003f,0x1f,0xfc000000,0x7ff000,0xf80,0x3e007c70,0x783c003,0xc001e03c,
--      0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,0x80007800,0x780,0x3c7c0000,0x7800001e,0x3878f078,0xf01e03c0,0x780780,0x1e0f000,0x1e078001,
--      0xe03e0000,0xf000,0xf0003c0,0x1e007807,0x83f03c00,0x3ef00007,0xcf800000,0x3e00003c,0xf00,0x1e0,0xf80007,0xc0000000,0x0,0x3e01f801,
--      0xfe07e001,0xf80f007e,0x7f801f8,0x1f801fff,0xfe00fc0f,0xf007f83f,0x1ffc00,0x7ff000,0x7807c00,0x1e0000f,0x87e1e01f,0xe0fc00fc,
--      0xfc007f8,0x1f803f03,0xfc003df0,0x3807e03c,0x1fffff0,0x3c003c0,0x78003e0f,0x1e03,0xe03e00f8,0x3e00ff,0xffe0001e,0xf0,0x780,
--      0x0,0x0,0x7800000,0xfe0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7c00000,0x3,0xc00f0000,0xfe00000,0x3e00003,0xf800001f,
--      0xc0000007,0xc0003e00,0x1e03c,0x3c0f80,0x0,0x0,0x0,0x70,0x380700fc,0x7800000,0x7c1fe,0x3e000fe0,0xffffe,0x1f3e00,0x0,0x780000,
--      0x3f98e000,0xf000003c,0xfcf8007c,0xf800003c,0x3ffc,0x0,0x31c0001,0x80f00f80,0x380700,0x0,0x183,0x80e0c000,0x3f,0xe0000078,
--      0x3c0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x38000078,0xf000e01,0xc003ffe0,0x1fff00,0x7ffc00,0xf000,0xf07800,0x783c000,0x3c1e0001,
--      0xe0f0000f,0x7800078,0x3c000f07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
--      0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf801f01e,0xf3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007cf8,
--      0x1e000f,0x80f0f000,0x7c03f00,0x3e01f801,0xf00fc00f,0x807e007c,0x3f003e0,0x1f80707f,0x8f801f80,0xf003f03f,0x1f81f8,0xfc0fc0,
--      0x7e07e00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00003ff,0xfc003fc1,0xf801f81f,0x800fc0fc,0x7e07e0,0x3f03f00,0x1f81f800,0x1f80007,
--      0xe07f003c,0x3c01e0,0x1e00f00,0xf007800,0x780f8003,0xe01fe07e,0x3e000f8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3f,0xfffff078,0x30000ffe,0x1f007c0,0x0,0x1e00,
--      0x3c00,0xf9cf80,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf00000fc,0x1e0780,0x3fff800,0x78ffe000,0xf0003,0xe03e00f0,
--      0x3e0007,0xe000003f,0x7f,0xe01fffff,0xf00ffc00,0x1f80,0x3c01ff70,0x783c003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,
--      0x80007800,0x780,0x3cfc0000,0x7800001e,0x3c78f078,0xf01e03c0,0x780780,0x3e0f000,0x1e078003,0xc01f0000,0xf000,0xf0003c0,0x1e007807,
--      0x83f83c00,0x1ff00003,0xcf000000,0x3e00003c,0xf00,0x1e0,0x0,0x0,0x0,0x20007801,0xfc03e003,0xe003007c,0x3f803e0,0x7c0003c,
--      0xf807,0xf007e00f,0x3c00,0xf000,0x780f800,0x1e0000f,0x87e1f01f,0x803c00f8,0x7c007f0,0xf803e01,0xfc003f80,0x80f8004,0x3c000,
--      0x3c003c0,0x3c003c0f,0x1e03,0xe03e0078,0x3c0000,0x7c0001e,0xf0,0x780,0x0,0x0,0x3ffff800,0x1ff0000,0x0,0x7800000,0x0,0x18,
--      0xc0,0x0,0x1818000,0x3e00000,0x3,0xc00f0000,0x1ff00000,0x3e00007,0xfc00003f,0xe0000003,0xc0003c00,0xf03c,0x3c0f00,0x0,0x0,
--      0x0,0x70,0x380701f0,0x800000,0x780fc,0x1e001ff0,0x7c,0xf3c00,0x0,0x780000,0x7e182000,0xf000001f,0xfff00ffc,0xffc0003c,0x3cfe,
--      0x0,0x31c0001,0x80f01f80,0x780f00,0x0,0x183,0x80e0c000,0xf,0x80000078,0x780,0x38,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x38000078,
--      0xf000f01,0xe003ffe0,0x1fff00,0x7ff800,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x78000f8,0x3e000f07,0x8003c000,0x78000,
--      0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
--      0x78000f00,0x7c03e01e,0x1e3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78003cf0,0x1e0007,0x80f1e000,0x4000f00,0x20007801,0x3c008,
--      0x1e0040,0xf00200,0x780403f,0x7803e00,0x3007c00f,0x803e007c,0x1f003e0,0xf801f00,0x780000,0x3c00000,0x1e000000,0xf00007f0,
--      0x3e003f00,0x7801f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e003c,0x3c01e0,0x1e00f00,0xf007800,0x78078003,
--      0xc01fc03e,0x1e000f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xf078007c,0x300007fc,0x7e00fe0,0x0,0x1e00,0x3c00,0x3e1c3e0,0x1e0000,0x0,0x0,0x0,0xf0001e00,
--      0x3c0001e,0x1,0xf000fff8,0x1e0780,0x3fffe00,0x79fff000,0x1f0001,0xfffc00f0,0x7e0007,0xe000003f,0x3ff,0x801fffff,0xf003ff80,
--      0x3f00,0x3c03fff0,0xf01e003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3df80000,0x7800001e,
--      0x1c70f078,0x781e03c0,0x780780,0x3c0f000,0x1e078007,0xc01f8000,0xf000,0xf0003c0,0x1e007807,0x83f83c00,0xfe00003,0xff000000,
--      0x7c00003c,0x780,0x1e0,0x0,0x0,0x0,0x7c01,0xf801f007,0xc00100f8,0x1f803c0,0x3c0003c,0x1f003,0xf007c00f,0x80003c00,0xf000,
--      0x783f000,0x1e0000f,0x3c0f01f,0x3e01f0,0x3e007e0,0x7c07c00,0xfc003f00,0xf0000,0x3c000,0x3c003c0,0x3c003c0f,0x1e01,0xf07c007c,
--      0x7c0000,0xfc0001e,0xf0,0x780,0x0,0x0,0x3ffff000,0x3838000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0xff0000,0x3f00000,0x3,0xc00fff00,
--      0x38380000,0x7c0000e,0xe000070,0x70000001,0xe0003c00,0xf01e,0x780e00,0x0,0x0,0x0,0x0,0x1e0,0x0,0x780f8,0xf003838,0xfc,0xffc00,
--      0x0,0x780000,0x7c180000,0xf000000f,0xffe00fff,0xffc0003c,0x783f,0x80000000,0x6380000,0xc0f83f80,0xf81f00,0x0,0x303,0x80e06000,
--      0x0,0x78,0xf00,0x78,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x3800003c,0x3e000f81,0xf003ffe0,0x1fff00,0x1fc000,0xf000,0x1e03c00,
--      0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e000f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,
--      0x3c000001,0xe0001e00,0x3c0f0f0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3e07c01e,0x1e3c0f0,0x3c0780,0x1e03c00,
--      0xf01e000,0x78003ff0,0x1e0007,0x80f1e000,0xf80,0x7c00,0x3e000,0x1f0000,0xf80000,0x7c0001e,0x3c07c00,0x10078007,0x803c003c,
--      0x1e001e0,0xf000f00,0x780000,0x3c00000,0x1e000000,0xf00007c0,0x1e003e00,0x7c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,
--      0xf,0x801f003c,0x3c01e0,0x1e00f00,0xf007800,0x7807c007,0xc01f801f,0x1f001f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xe078003c,0x300001f0,0x3f801ff0,0x0,
--      0x3c00,0x1e00,0x3c1c1e0,0x1e0000,0x0,0x0,0x0,0xf0001e0f,0x3c0001e,0x3,0xe000fff0,0x3c0780,0x3ffff00,0x7bfff800,0x1e0000,0x7ff00078,
--      0x7e0007,0xe000003f,0x1ffc,0x1fffff,0xf0007ff0,0x7e00,0x3c07c3f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,
--      0x1fffff,0x80007800,0x780,0x3ffc0000,0x7800001e,0x1ef0f078,0x781e03c0,0x780780,0x7c0f000,0x1e07801f,0x800ff000,0xf000,0xf0003c0,
--      0xf00f807,0x83b83c00,0xfc00001,0xfe000000,0xf800003c,0x780,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0xc00000f0,0xf80780,0x3c0003c,
--      0x1e001,0xf007c007,0x80003c00,0xf000,0x787e000,0x1e0000f,0x3c0f01f,0x1e01e0,0x1e007c0,0x3c07800,0x7c003f00,0xf0000,0x3c000,
--      0x3c003c0,0x3e007c07,0x80003c00,0xf8f8003c,0x780000,0xf80001e,0xf0,0x780,0x0,0x0,0x7ffff000,0x601c000,0x3,0xffff0000,0x0,
--      0xfff,0xf8007fff,0xc0000000,0x7e003c,0x1fe0000,0xc0003,0xc00fff00,0x601c0000,0xf800018,0x70000c0,0x38000001,0xe0007800,0x701e,
--      0x701e00,0x0,0x0,0x0,0x0,0x1e0,0x6,0x700f8,0xf00601c,0xf8,0x7f800,0x0,0x780000,0xf8180000,0xf000000f,0x87c00fff,0xffc0003c,
--      0xf01f,0xc0000000,0x6380000,0xc07ff780,0x1f03e03,0xfffffe00,0x303,0x81c06000,0x0,0x1ffff,0xfe001e00,0x180f8,0x0,0x3c003c0,
--      0x3ffe1c00,0x3f00000,0x0,0x3800003f,0xfe0007c0,0xf8000000,0x18000000,0xc0000006,0x1f000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,
--      0x3c000f0,0x1e001f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f0f0,
--      0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f0f801e,0x3c3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,
--      0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07c00,0xf0007,0x8078003c,0x3c001e0,0x1e000f00,0x780000,0x3c00000,
--      0x1e000000,0xf0000f80,0x1f003e00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0xf,0x3f003c,0x3c01e0,0x1e00f00,0xf007800,
--      0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe078003f,0xb0000000,0xfc003cf0,0x0,0x3c00,0x1e00,0x101c040,0x1e0000,0x0,0x0,0x1,
--      0xe0001e1f,0x83c0001e,0x7,0xe000fff0,0x3c0780,0x3c03f80,0x7fc0fc00,0x1e0000,0xfff80078,0xfe0007,0xe000003f,0x7fe0,0x1fffff,
--      0xf0000ffc,0xfc00,0x780f81f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3ffc0000,
--      0x7800001e,0x1ef0f078,0x3c1e03c0,0x780780,0x1fc0f000,0x1e07ffff,0x7ff00,0xf000,0xf0003c0,0xf00f007,0xc3b87c00,0x7c00001,0xfe000000,
--      0xf800003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0x800000f0,0xf80780,0x1e0003c,0x1e001,0xf0078007,0x80003c00,0xf000,0x78fc000,
--      0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,0x3c07800,0x7c003e00,0xf0000,0x3c000,0x3c003c0,0x1e007807,0x80003c00,0x7df0003c,0x780000,
--      0x1f00001e,0xf0,0x780,0x0,0x0,0x7800000,0xe7ce000,0x3,0xffff0000,0x0,0xfff,0xf8007fff,0xc0000000,0x1f0,0xffe000,0x1c0003,
--      0xc00fff00,0xe7ce0000,0xf800039,0xf38001cf,0x9c000000,0xe0007800,0x780e,0x701c00,0x0,0x0,0x0,0x0,0x1e0,0x7,0xf0078,0xf00e7ce,
--      0x1f0,0x7f800,0x0,0x780000,0xf0180000,0xf000000e,0x1c0001f,0xe000003c,0xf007,0xe0000000,0x6380000,0xc03fe780,0x3e07c03,0xfffffe00,
--      0x303,0xffc06000,0x0,0x1ffff,0xfe003ffe,0x1fff0,0x0,0x3c003c0,0x1ffe1c00,0x3f00000,0x7,0xffc0001f,0xfc0003e0,0x7c000001,0xfc00000f,
--      0xe000007f,0x1e000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,
--      0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,
--      0x783c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07800,
--      0xf0003,0xc078001e,0x3c000f0,0x1e000780,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,
--      0x7800780,0x3c003c00,0xf,0x7f003c,0x3c01e0,0x1e00f00,0xf007800,0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe070001f,0xf8000007,
--      0xf0007cf8,0x7800000,0x3c00,0x1e00,0x1c000,0x1e0000,0x0,0x0,0x1,0xe0001e1f,0x83c0001e,0xf,0xc000fff8,0x780780,0x2000f80,0x7f803e00,
--      0x3e0003,0xfffe007c,0x1fe0000,0x0,0x3ff00,0x0,0x1ff,0x8001f000,0x780f00f0,0x1f00f003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,
--      0xfe03c00f,0xf81fffff,0x80007800,0x780,0x3ffe0000,0x7800001e,0xee0f078,0x3c1e03c0,0x7807ff,0xff80f000,0x1e07fffe,0x3ffe0,
--      0xf000,0xf0003c0,0xf00f003,0xc7bc7800,0xfc00000,0xfc000001,0xf000003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xe000f80f,0x800001e0,
--      0xf80f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x79f8000,0x1e0000f,0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003e00,
--      0xf0000,0x3c000,0x3c003c0,0x1e007807,0x81e03c00,0x7df0003e,0xf80000,0x3e00003e,0xf0,0x7c0,0xfc000,0x80000000,0x7800000,0x1e7cf000,
--      0x3,0xffff0000,0x0,0x18,0xc0,0x0,0xf80,0x7ffc00,0x380003,0xc00fff01,0xe7cf0000,0x1f000079,0xf3c003cf,0x9e000000,0xe0007000,
--      0x380e,0xe01c00,0x0,0x0,0x0,0x0,0x1e0,0x3,0x800f0078,0xf01e7cf,0x3e0,0x3f000,0x0,0x780000,0xf018001f,0xfff8001e,0x1e0000f,
--      0xc000003c,0xf003,0xe0000000,0x6380000,0xc00fc780,0x7c0f803,0xfffffe00,0x303,0xfe006000,0x0,0x1ffff,0xfe003ffe,0x1ffe0,0x0,
--      0x3c003c0,0xffe1c00,0x3f00000,0x7,0xffc00007,0xf00001f0,0x3e00001f,0xfc0000ff,0xe00007ff,0x3e000,0x3e01e00,0x1f00f000,0xf8078007,
--      0xc03c003e,0x1e001e0,0xf001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,
--      0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000fc0,
--      0x1e0007,0x80f1f000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c0f800,0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,
--      0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1e,0xf7803c,0x3c01e0,0x1e00f00,
--      0xf007800,0x7803e00f,0x801e000f,0x80f803e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe0f0000f,0xff00001f,0x8000f87c,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,
--      0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x1f,0x800000fe,0xf00780,0x7c0,0x7f001e00,0x3c0007,0xe03f003f,0x3fe0000,0x0,0x3fc00,0x0,
--      0x7f,0x8001e000,0x781f00f0,0x1e00f003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3f9f0000,0x7800001e,
--      0xfe0f078,0x3c1e03c0,0x7807ff,0xff00f000,0x1e07fff8,0xfff8,0xf000,0xf0003c0,0xf81f003,0xc7bc7800,0xfe00000,0x78000003,0xe000003c,
--      0x1e0,0x1e0,0x0,0x0,0x0,0x1fffc01,0xe000780f,0x1e0,0x780f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7bf0000,0x1e0000f,
--      0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xf8000,0x3c000,0x3c003c0,0x1f00f807,0x81f03c00,0x3fe0001e,0xf00000,0x7c00007c,
--      0xf0,0x3e0,0x3ff801,0x80000000,0x7800000,0x3cfcf800,0x3,0xffff0000,0x0,0x18,0xc0,0x0,0x7c00,0x1fff00,0x700003,0xc00f0003,
--      0xcfcf8000,0x3e0000f3,0xf3e0079f,0x9f000000,0xf000,0x1000,0x0,0x0,0x0,0x0,0x0,0x1f0,0x1,0xc00f0078,0xf03cfcf,0x800007c0,0x1e000,
--      0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x8000003c,0xf001,0xf0000000,0x6380000,0xc0000000,0xf81f003,0xfffffe00,0x303,
--      0x87006000,0x0,0x1ffff,0xfe003ffe,0x7f00,0x0,0x3c003c0,0x3fe1c00,0x3f00000,0x7,0xffc00000,0xf8,0x1f0001ff,0xf0000fff,0x80007ffc,
--      0xfc000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf001e07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,
--      0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3fc001e,0x1e03c0f0,0x3c0780,
--      0x1e03c00,0xf01e000,0x78000780,0x1e0007,0x80f0fc00,0x3fff80,0x1fffc00,0xfffe000,0x7fff0003,0xfff8001f,0xffc0001e,0x3c0f000,
--      0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,0x3c00000,0x1e000000,0xf0001e00,0xf803c00,0x3c078001,0xe03c000f,0x1e00078,
--      0xf0003c0,0x78001e07,0xfffffe1e,0x1e7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801e00f,0x1e0007,0x807803c0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00007,
--      0xffc0007e,0xf03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x3f,0x3e,0xf00780,0x3c0,0x7e001e00,
--      0x7c000f,0x800f001f,0xffde0000,0x0,0x3e000,0x0,0xf,0x8003e000,0x781e0070,0x1e00f003,0xc001f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,
--      0xf81e0007,0x80007800,0x780,0x3f1f0000,0x7800001e,0x7c0f078,0x1e1e03c0,0x7807ff,0xfc00f000,0x1e07fffe,0xffc,0xf000,0xf0003c0,
--      0x781e003,0xc71c7800,0x1ff00000,0x78000003,0xe000003c,0x1e0,0x1e0,0x0,0x0,0x0,0xffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,
--      0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7f000,0x3c000,
--      0x3c003c0,0xf00f007,0xc1f07c00,0x1fc0001f,0x1f00000,0xfc000ff8,0xf0,0x1ff,0xfffe07,0x80000000,0x7800000,0x7ffcfc00,0x0,0xf000000,
--      0x0,0x18,0xc0,0x0,0x3e000,0x1ff80,0xe00003,0xc00f0007,0xffcfc000,0x3e0001ff,0xf3f00fff,0x9f800000,0x6000,0x0,0x0,0x7c000,
--      0x0,0x0,0x0,0xfe,0x0,0xe00f007f,0xff07ffcf,0xc0000fc0,0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x80000000,0xf800,
--      0xf0000000,0x6380000,0xc0000000,0x1f03c000,0x1e00,0x303,0x83806000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xfe1c00,0x3f00000,0x0,
--      0x0,0x3c,0xf801fff,0xfff8,0x7ffc0,0x1f8000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf003c07,0x8003c000,0x78000,
--      0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
--      0x78000f00,0x1f8001e,0x1e03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e000f,0x80f0ff00,0x1ffff80,0xffffc00,0x7fffe003,
--      0xffff001f,0xfff800ff,0xffc007ff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,
--      0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x3c7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801f01f,
--      0x1e0007,0x807c07c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00000,0xfff003f0,0x1f00f03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x7ff80000,0x3,
--      0xc0001e0f,0x3c0001e,0x7e,0x1f,0x1e00780,0x3e0,0x7e000f00,0x78000f,0x7800f,0xff9e0000,0x0,0x3fc00,0x0,0x7f,0x8003c000,0x781e0070,
--      0x3e00f803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3e0f8000,0x7800001e,0x7c0f078,0x1e1e03c0,
--      0x7807ff,0xf000f000,0x1e07807f,0xfe,0xf000,0xf0003c0,0x781e003,0xc71c7800,0x3ef00000,0x78000007,0xc000003c,0x1e0,0x1e0,0x0,
--      0x0,0x0,0x1ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,
--      0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7ff80,0x3c000,0x3c003c0,0xf00f003,0xc1f07800,0x1fc0000f,0x1e00000,0xf8000ff0,0xf0,
--      0xff,0xffffff,0x80000000,0x3fffc000,0xfff9fe00,0x0,0xf000000,0x0,0x18,0xc0,0x0,0x1f0000,0x1fc0,0x1c00003,0xc00f000f,0xff9fe000,
--      0x7c0003ff,0xe7f81fff,0x3fc00000,0x0,0x0,0x0,0xfe000,0x1ffffc0f,0xfffffc00,0x0,0xff,0xf0000000,0x700f007f,0xff0fff9f,0xe0000f80,
--      0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00fff,0xffc00000,0xf800,0xf0000000,0x6380000,0xc0ffff80,0x3e078000,0x1e00,0x7ff80303,
--      0x83c06000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,0x0,0x7f,0xff00001e,0x7c1fff0,0xfff80,0x7ffc00,0x3f0000,0x7c01f00,
--      0x3e00f801,0xf007c00f,0x803e007c,0x1f003e0,0xf803c07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
--      0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f8001e,0x3c03c0f0,0x3c0780,0x1e03c00,0xf01e000,
--      0x78000780,0x1e001f,0xf07f80,0x3ffff80,0x1ffffc00,0xffffe007,0xffff003f,0xfff801ff,0xffc03fff,0xffc0f000,0x1fffff,0xc0fffffe,
--      0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,
--      0xfffffe1e,0x787803c,0x3c01e0,0x1e00f00,0xf007800,0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x3ff80fc0,0x7fc1e01f,
--      0x7800000,0x3c00,0x1e00,0x0,0x7fffff80,0x0,0x7ff80000,0x7,0x80001e00,0x3c0001e,0xfc,0xf,0x1e00780,0x1e0,0x7c000f00,0x78000f,
--      0x78007,0xff1e0000,0x0,0x3ff00,0x0,0x1ff,0x8003c000,0x781e0070,0x3c007803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,
--      0x80007800,0x780,0x3c07c000,0x7800001e,0x7c0f078,0xf1e03c0,0x780780,0xf000,0x1e07801f,0x3e,0xf000,0xf0003c0,0x781e003,0xcf1c7800,
--      0x3cf80000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,0x0,0x0,0x3ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,
--      0x80003c00,0xf000,0x7ff8000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3fff0,0x3c000,0x3c003c0,0xf81f003,
--      0xc3b87800,0xf80000f,0x1e00001,0xf0000ff0,0xf0,0xff,0xf03fff,0x80000000,0x3fff8001,0xfff1ff00,0x0,0xf000000,0x0,0x18,0xc0,
--      0x0,0x380000,0x7c0,0x3c00003,0xc00f001f,0xff1ff000,0xf80007ff,0xc7fc3ffe,0x3fe00000,0x0,0x0,0x0,0x1ff000,0x7ffffe1f,0xffffff00,
--      0x0,0x7f,0xfe000000,0x780f007f,0xff1fff1f,0xf0001f00,0x1e000,0x0,0x780001,0xe0180000,0xf000001c,0xe00fff,0xffc00000,0x7c00,
--      0xf0000000,0x31c0001,0x80ffff80,0x3e078000,0x1e00,0x7ff80183,0x81c0c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,
--      0x0,0x7f,0xff00001e,0x7c7ff03,0xc03ff8fe,0x1ffc0f0,0x7e0000,0x7800f00,0x3c007801,0xe003c00f,0x1e0078,0xf003c0,0x7803c07,0x8003c000,
--      0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,
--      0xf0001e0,0x78000f00,0x3fc001e,0x7803c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e007f,0xf03fe0,0x7ffff80,0x3ffffc01,
--      0xffffe00f,0xffff007f,0xfff803ff,0xffc07fff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,
--      0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x707803c,0x3c01e0,0x1e00f00,0xf007800,
--      0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x30f81f00,0xffe1e00f,0x87800000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,
--      0x7,0x80001e00,0x3c0001e,0x1f8,0x7,0x83c00780,0x1e0,0x7c000f00,0xf8001e,0x3c001,0xfc1e0000,0x0,0x7fe0,0x0,0xffc,0x3c000,0x781e0070,
--      0x3ffff803,0xc000783c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x380f078,0xf1e03c0,
--      0x780780,0xf000,0x1e07800f,0x8000001e,0xf000,0xf0003c0,0x3c3c003,0xcf1e7800,0x7c780000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,
--      0x0,0x0,0x7f003c01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7f7c000,0x1e0000f,0x3c0f01e,
--      0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfff8,0x3c000,0x3c003c0,0x781e003,0xc3b87800,0x1fc00007,0x83e00003,0xe0000ff8,0xf0,
--      0x1ff,0xc007fe,0x0,0x7fff8001,0xffe3ff00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x3c0,0x7800003,0xc00f001f,0xfe3ff000,0xf80007ff,
--      0x8ffc3ffc,0x7fe00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x1f,0xff000000,0x3c0f007f,0xff1ffe3f,0xf0003e00,0x1e000,0x0,0x780001,
--      0xe0180000,0xf000001e,0x1e00fff,0xffc00000,0x3f00,0xf0000000,0x31c0001,0x80ffff80,0x1f03c000,0x1e00,0x7ff80183,0x81c0c000,
--      0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x7f,0xff00003c,0xf87f007,0xc03f83ff,0x81fc01f0,0x7c0000,0x7ffff00,0x3ffff801,
--      0xffffc00f,0xfffe007f,0xfff003ff,0xff807fff,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
--      0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf003c0f0,0x3c0780,0x1e03c00,0xf01e000,
--      0x78000780,0x1ffffe,0xf00ff0,0xfe00780,0x7f003c03,0xf801e01f,0xc00f00fe,0x7807f0,0x3c0ffff,0xffc0f000,0x1fffff,0xc0fffffe,
--      0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
--      0x1e,0xf07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783e,0x1e0007,0x801e0f80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x307c0801,0xe1f1e00f,0x87000000,
--      0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,0xf,0x1e00,0x3c0001e,0x3f0,0x7,0x83fffffc,0x1e0,0x7c000f00,0xf0001e,0x3c000,0x3e0000,
--      0x0,0x1ffc,0x1fffff,0xf0007ff0,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x3c000,0x781e0007,0x80007800,
--      0x780,0x3c03e000,0x7800001e,0xf078,0x79e03c0,0x780780,0xf000,0x1e078007,0x8000000f,0xf000,0xf0003c0,0x3c3c001,0xee0ef000,
--      0xf87c0000,0x7800001f,0x3c,0x78,0x1e0,0x0,0x0,0x0,0x7c003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
--      0xf000,0x7e3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x1ffc,0x3c000,0x3c003c0,0x781e003,0xe3b8f800,
--      0x1fc00007,0x83c00007,0xc00000fc,0xf0,0x3e0,0x8001f8,0x0,0x7800000,0xffc7fe00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,
--      0xf000003,0xc00f000f,0xfc7fe001,0xf00003ff,0x1ff81ff8,0xffc00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x3,0xff800000,0x1e0f0078,
--      0xffc7f,0xe0007c00,0x1e000,0x0,0x780001,0xe0180000,0xf000000e,0x1c00007,0x80000000,0x1f81,0xe0000000,0x38e0003,0x80000000,
--      0xf81f000,0x1e00,0x7ff801c3,0x80e1c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf8,0x1f070007,0xc03803ff,0xc1c001f0,
--      0xf80000,0xfffff00,0x7ffff803,0xffffc01f,0xfffe00ff,0xfff007ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,
--      0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f00f,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,0xf003c0f0,
--      0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1ffffc,0xf003f8,0xf800780,0x7c003c03,0xe001e01f,0xf00f8,0x7807c0,0x3c0fc1e,0xf000,
--      0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,
--      0xf0003c0,0x78001e00,0x1e,0x1e07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783c,0x1e0007,0x801e0f00,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xffff8000,0x303c0001,
--      0xc071e007,0xcf000000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0xf,0xf00,0x780001e,0x7e0,0x7,0x83fffffc,0x1e0,0x7c000f00,0x1f0001e,
--      0x3c000,0x3c0000,0x0,0x3ff,0x801fffff,0xf003ff80,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,
--      0x80007800,0x780,0x3c01f000,0x7800001e,0xf078,0x79e03c0,0xf00780,0xf000,0x3e078007,0xc000000f,0xf000,0xf0003c0,0x3c3c001,
--      0xee0ef000,0xf03e0000,0x7800003e,0x3c,0x78,0x1e0,0x0,0x0,0x0,0xf8003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,
--      0x80003c00,0xf000,0x7c3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfc,0x3c000,0x3c003c0,0x3c3e001,0xe7b8f000,
--      0x3fe00007,0xc7c0000f,0xc000003e,0xf0,0x7c0,0x0,0x0,0x7c00000,0x7fcffc00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,0x1e000003,
--      0xc00f0007,0xfcffc003,0xe00001ff,0x3ff00ff9,0xff800000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x1f800000,0xf0f0078,0x7fcff,
--      0xc000fc00,0x1e000,0x0,0x780001,0xe0180000,0xf000000f,0x87c00007,0x80000000,0xfe3,0xe0000000,0x18780c3,0x0,0x7c0f800,0x1e00,
--      0xc3,0x80e18000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x1f0,0x3e00000f,0xc0000303,0xe00003f0,0xf00000,0xfffff80,
--      0x7ffffc03,0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,
--      0x3c000001,0xe0001e00,0x780f00f,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1f0f801f,0xe00780f0,0x3c0780,0x1e03c00,
--      0xf01e000,0x78000780,0x1ffff8,0xf000f8,0x1f000780,0xf8003c07,0xc001e03e,0xf01f0,0x780f80,0x3c1f01e,0xf000,0x1e0000,0xf00000,
--      0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
--      0x1e,0x3c07803c,0x3c01e0,0x1e00f00,0xf007800,0x78007c7c,0x1e0007,0x801f1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c00000,0x303c0003,0x8039e003,0xef000000,
--      0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0xfc0,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,
--      0x0,0x7f,0xe01fffff,0xf00ffc00,0x3c000,0x781f00f0,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,0x80007800,
--      0x780,0x3c01f000,0x7800001e,0xf078,0x7de01e0,0xf00780,0x7800,0x3c078003,0xc000000f,0xf000,0xf0003c0,0x3e7c001,0xee0ef001,
--      0xf01e0000,0x7800003e,0x3c,0x3c,0x1e0,0x0,0x0,0x0,0xf0003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
--      0xf000,0x781f000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0x7df00003,
--      0xc780000f,0x8000003e,0xf0,0x780,0x0,0x0,0x3c00000,0x3fcff800,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x1f00fc,0x1e0,0x1e000001,
--      0xe00f0003,0xfcff8003,0xe00000ff,0x3fe007f9,0xff000000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x7c00000,0xf0f0078,0x3fcff,0x8000f800,
--      0x1e000,0x0,0x780001,0xe0180000,0xf000001f,0xffe00007,0x8000003c,0x7ff,0xc0000000,0x1c3ffc7,0x0,0x3e07c00,0x1e00,0xe3,0x80738000,
--      0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x3e0,0x7c00001d,0xc0000001,0xe0000770,0x1f00000,0xfffff80,0x7ffffc03,
--      0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
--      0xe0001e00,0x780f00f,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0x3e07c01f,0xc00780f0,0x3c0780,0x1e03c00,0xf01e000,
--      0x78000780,0x1fffc0,0xf0007c,0x1e000780,0xf0003c07,0x8001e03c,0xf01e0,0x780f00,0x3c1e01e,0xf000,0x1e0000,0xf00000,0x7800000,
--      0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1e,0x7807803c,
--      0x3c01e0,0x1e00f00,0xf007800,0x78003c78,0x1e0007,0x800f1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x83c00000,0x303c0003,0x8039e001,0xee000000,0x1e00,0x3c00,
--      0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0x1f80,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,0x0,0x1f,0xfc1fffff,
--      0xf07ff000,0x0,0x780f00f0,0x78003c03,0xc000781e,0x1e0,0xf803c0,0x1e00,0x1e000,0x781e0007,0x80007800,0x780,0x3c00f800,0x7800001e,
--      0xf078,0x3de01e0,0xf00780,0x7800,0x3c078003,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfe0ff003,0xe01f0000,0x7800007c,0x3c,0x3c,
--      0x1e0,0x0,0x0,0x0,0xf0007c01,0xe000f80f,0x800001e0,0xf80f00,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x780f800,0x1e0000f,
--      0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003c00,0x1e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0xf8f80003,0xe780001f,0x1e,
--      0xf0,0x780,0x0,0x0,0x3c00000,0x1ffff000,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x3bc1de,0x1e0,0xf000001,0xe00f0001,0xffff0007,0xc000007f,
--      0xffc003ff,0xfe000000,0x0,0x0,0x0,0xfe000,0x0,0x0,0x0,0x0,0x3c00000,0x1e0f0078,0x1ffff,0x1f000,0x1e000,0x0,0x780000,0xf0180000,
--      0xf000001f,0xfff00007,0x8000003c,0x1ff,0x80000000,0xe0ff0e,0x0,0x1f03e00,0x1e00,0x70,0x70000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,
--      0xe1c00,0x0,0x0,0x0,0x7c0,0xf8000019,0xc0000000,0xe0000670,0x1e00000,0xf000780,0x78003c03,0xc001e01e,0xf00f0,0x780780,0x3c0f807,
--      0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf80f007,0xbc03c001,0xe01e000f,
--      0xf00078,0x78003c0,0x3c001e00,0x7c03e00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,
--      0xf0007c07,0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0xf800,0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,
--      0xf0001e00,0x7803c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1f8001f,0xf00f803c,0x3c01e0,0x1e00f00,0xf007800,
--      0x78003e78,0x1e000f,0x800f9e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x3c00000,0x303c0003,0x8039f001,0xfe000000,0x1e00,0x3c00,0x0,0x1e0000,0x0,0x0,0x3c,0xf00,
--      0x780001e,0x3f00,0x7,0x80000780,0x3e0,0x3e000f00,0x3c0001e,0x3c000,0x7c0000,0x0,0x3,0xfe000000,0xff8000,0x0,0x3c0f81f0,0xf0001e03,
--      0xc000780f,0x1e0,0xf003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x780,0x3c007c00,0x7800001e,0xf078,0x3de01e0,0xf00780,0x7800,
--      0x3c078001,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfc07f003,0xe00f0000,0x78000078,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
--      0xf000f007,0x800000f0,0xf80780,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
--      0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78001,0xe71df000,0xf8f80001,0xef80003e,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,
--      0xfffe000,0x0,0x3e000000,0x0,0x18,0x7fff,0xc0000000,0x60c306,0x1e0,0x7800001,0xe00f0000,0xfffe0007,0x8000003f,0xff8001ff,
--      0xfc000000,0x0,0x0,0x0,0x7c000,0x0,0x0,0x0,0x0,0x3c00000,0x3c0f0078,0xfffe,0x3e000,0x1e000,0x0,0x780000,0xf0180000,0xf000003c,
--      0xfcf80007,0x8000003c,0x7f,0x0,0x70001c,0x0,0xf81f00,0x0,0x38,0xe0000,0x0,0x0,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf81,
--      0xf0000039,0xc0000000,0xe0000e70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,0x8000f000,0x78000,
--      0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f007,0xbc03c001,0xe01e000f,0xf00078,0x78003c0,
--      0x3c001e00,0xf801f00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,0x8003e03c,
--      0x1f01e0,0xf80f00,0x7c1e01e,0x7800,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,
--      0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xe00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef8,0x1f000f,
--      0x7be00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0xf,0x3c00000,0x307c0003,0x8038f000,0xfc000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e00003c,0x780,0xf00001e,
--      0x7e00,0xf,0x80000780,0x3c0,0x3e001e00,0x3c0001f,0x7c000,0x780007,0xe000003f,0x0,0xfe000000,0xfe0000,0x0,0x3c07c3f0,0xf0001e03,
--      0xc000f80f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x4000f80,0x3c003c00,0x7800001e,0xf078,0x1fe01f0,0x1f00780,
--      0x7c00,0x7c078001,0xf000001f,0xf000,0xf0003c0,0x1e78001,0xfc07f007,0xc00f8000,0x780000f8,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
--      0xf000f007,0xc00000f0,0xf80780,0x3c,0x1f003,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
--      0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78000,0xfe0fe001,0xf07c0001,0xef00007c,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,
--      0x7cfc000,0xfc00000,0x3c00000f,0xc3f00000,0x18,0x7fff,0xc0000000,0x406303,0x3e0,0x3c00001,0xf00f0000,0x7cfc000f,0x8000001f,
--      0x3f0000f9,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x780700f8,0x7cfc,0x7c000,0x1e000,0x0,0x780000,0xf8180000,
--      0xf0000070,0x3c0007,0x8000003c,0x3f,0x80000000,0x3c0078,0x0,0x780f00,0x0,0x1e,0x3c0000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,0xe1c00,
--      0x0,0x0,0x0,0xf01,0xe0000071,0xc0000000,0xe0001c70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
--      0x8000f800,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00f003,0xfc03e003,0xe01f001f,
--      0xf800f8,0x7c007c0,0x3e003e01,0xf000f80f,0xf00f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,
--      0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0x7c00,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,
--      0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xc00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef0,
--      0x1f000f,0x7bc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x780000,0xf,0x3800040,0x30780003,0x8038f800,0x78000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
--      0x780,0x1f00001e,0xfc00,0x20001f,0x780,0x80007c0,0x1f001e00,0x7c0000f,0x78000,0xf80007,0xe000003f,0x0,0x1e000000,0xf00000,
--      0x3c000,0x3c03fff0,0xf0001e03,0xc001f007,0x800101e0,0x7e003c0,0x1e00,0x7800,0x781e0007,0x80007800,0x6000f00,0x3c003e00,0x7800001e,
--      0xf078,0x1fe00f0,0x1e00780,0x3c00,0x78078000,0xf020001e,0xf000,0x7800780,0xff0001,0xfc07f00f,0x8007c000,0x780001f0,0x3c,0xf,
--      0x1e0,0x0,0x0,0x0,0xf800fc01,0xf801f007,0xc00100f8,0x1f807c0,0x40003c,0xf807,0xf0078007,0x80003c00,0xf000,0x7803e00,0x1f0000f,
--      0x3c0f01e,0x1e01f0,0x3e007e0,0x7c07c00,0xfc003c00,0x1e,0x3e000,0x3e007c0,0x1ff8000,0xfe0fe003,0xe03e0001,0xff0000fc,0x1e,
--      0xf0,0x780,0x0,0x0,0x1f00080,0x3cf8000,0xfc00000,0x3c00001f,0x83f00000,0x18,0xc0,0x0,0xc06203,0x40003c0,0x1c00000,0xf80f0000,
--      0x3cf8001f,0xf,0x3e000079,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x700780fc,0x3cf8,0xfc000,0x1e000,0x0,0x780000,
--      0x7c180000,0xf0000020,0x100007,0x8000003c,0xf,0x80000000,0x1f01f0,0x0,0x380700,0x0,0xf,0x80f80000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,
--      0xe1c00,0x0,0x0,0x0,0xe01,0xc0000071,0xc0000001,0xc0001c70,0x1e00040,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
--      0x80007800,0x10078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00f003,0xfc01e003,0xc00f001e,
--      0x7800f0,0x3c00780,0x1e003c00,0xe000700f,0x800f0078,0x7803c0,0x3c01e00,0x1e00f000,0xf0000780,0x1e0000,0xf0003c,0x1f001f80,
--      0xf800fc07,0xc007e03e,0x3f01f0,0x1f80f80,0xfc1e01f,0x7c00,0x100f8000,0x807c0004,0x3e00020,0x1f000100,0x780000,0x3c00000,0x1e000000,
--      0xf0000f80,0x1f003c00,0x3c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,0x1f8000f,0x801f003e,0x7c01f0,0x3e00f80,0x1f007c00,
--      0xf8001ff0,0x1f801f,0x7fc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0xf,0x7800078,0x31f80001,0xc070fc00,0xfc000000,0x1e00,0x7c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
--      0x7c0,0x1f00001e,0x1f000,0x38003f,0x780,0xe000f80,0x1f803e00,0x780000f,0x800f8000,0x1f00007,0xe000003f,0x0,0x2000000,0x800000,
--      0x3c000,0x3e01ff71,0xf0001f03,0xc007f007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x781e0007,0x80007800,0x7801f00,0x3c001f00,0x7800001e,
--      0xf078,0xfe00f8,0x3e00780,0x3e00,0xf8078000,0xf838003e,0xf000,0x7c00f80,0xff0000,0xfc07e00f,0x8003c000,0x780001e0,0x3c,0xf,
--      0x1e0,0x0,0x0,0x0,0xf801fc01,0xfc03e003,0xe003007c,0x3f803e0,0x1c0003c,0xfc0f,0xf0078007,0x80003c00,0xf000,0x7801f00,0xf8000f,
--      0x3c0f01e,0x1e00f8,0x7c007f0,0xf803e01,0xfc003c00,0x8003e,0x1f000,0x1e00fc0,0xff0000,0xfe0fe007,0xc01f0000,0xfe0000f8,0x1e,
--      0xf0,0x780,0x0,0x0,0xf80180,0x1cf0000,0x1f800000,0x3c00001f,0x83e00000,0x18,0xc0,0x0,0xc06203,0x70007c0,0xe00000,0x7e0f0000,
--      0x1cf0001e,0x7,0x3c000039,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x7c00000,0xe00780fc,0x2001cf0,0xf8000,0x1e000,0x0,
--      0x780000,0x7e182000,0xf0000000,0x7,0x8000003c,0x7,0xc0000000,0x7ffc0,0x0,0x180300,0x0,0x3,0xffe00000,0x0,0x0,0x0,0x0,0x0,
--      0x3f00fc0,0xe1c00,0x0,0x0,0x0,0xc01,0x800000e1,0xc0000003,0xc0003870,0x1f001c0,0x3e0003e1,0xf0001f0f,0x8000f87c,0x7c3e0,0x3e1f00,
--      0x1f1e007,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e03,0xfc00f001,0xfc01f007,
--      0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x4000201f,0xc01f007c,0xf803e0,0x7c01f00,0x3e00f801,0xf0000780,0x1e0000,0xf0007c,
--      0x1f003f80,0xf801fc07,0xc00fe03e,0x7f01f0,0x3f80f80,0x1fc1f03f,0x803e00,0x3007c003,0x803e001c,0x1f000e0,0xf800700,0x780000,
--      0x3c00000,0x1e000000,0xf00007c0,0x3e003c00,0x3c01f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e001e,0xfc00f0,
--      0x7e00780,0x3f003c01,0xf8000fe0,0x1fc03e,0x3f800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,0xfff00001,0xe0f07f03,0xfe000000,0xf00,0x7800,0x0,
--      0x1e0000,0xfc0000,0x0,0x7e0000f0,0x3f0,0x7e000fff,0xfc03ffff,0xf83f00fe,0x780,0xfc03f80,0xfc0fc00,0xf800007,0xe03f0018,0x7e00007,
--      0xe000003f,0x0,0x0,0x0,0x3c000,0x1e007c71,0xe0000f03,0xffffe003,0xf01f01ff,0xff8003ff,0xffe01e00,0x3f01,0xf81e0007,0x803ffff0,
--      0x7e03f00,0x3c000f00,0x7ffffe1e,0xf078,0xfe007e,0xfc00780,0x1f83,0xf0078000,0x783f00fe,0xf000,0x3f03f00,0xff0000,0xfc07e01f,
--      0x3e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7e07fc01,0xfe07e001,0xf80f007e,0x7f801f8,0xfc0003c,0x7ffe,0xf0078007,
--      0x807ffffe,0xf000,0x7801f00,0xfff00f,0x3c0f01e,0x1e00fc,0xfc007f8,0x1f803f03,0xfc003c00,0xf80fc,0x1fff0,0x1f83fc0,0xff0000,
--      0xfc07e007,0xc01f0000,0xfe0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfe0780,0xfe0000,0x1f000000,0x3c00001f,0x7c00e03,0x81c00018,
--      0xc0,0x0,0x406203,0x7e01fc0,0x700000,0x7fffff80,0xfe0003f,0xffffc003,0xf800001f,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0,
--      0x1f800001,0xc007c1fe,0x6000fe0,0x1ffffe,0x1e000,0x0,0x780000,0x3f98e03f,0xffff8000,0x7,0x8000003c,0x7,0xc0000000,0xfe00,
--      0x0,0x80100,0x0,0x0,0x7f000000,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3f83fe8,0xe1c00,0x0,0x0,0x0,0x801,0xc1,0xc0000007,0x80003070,
--      0xfc0fc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc03f01,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,
--      0xffff001f,0xfff800ff,0xffc01fff,0xf800f001,0xfc00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,0x1f,0xf07e003f,0x3f001f8,
--      0x1f800fc0,0xfc007e07,0xe0000780,0x1e0000,0xf301f8,0xfc0ff80,0x7e07fc03,0xf03fe01f,0x81ff00fc,0xff807e0,0x7fc0f87f,0x81801f80,
--      0xf003f01f,0x801f80fc,0xfc07e0,0x7e03f00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff807e0,0x7e003c00,0x3c01f81f,0x800fc0fc,0x7e07e0,
--      0x3f03f00,0x1f81f800,0x1f8000f,0xe07e001f,0x83fc00fc,0x1fe007e0,0xff003f07,0xf8000fe0,0x1fe07e,0x3f800,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,
--      0xffe00000,0xffe03fff,0xdf000000,0xf00,0x7800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0x1ff,0xfc000fff,0xfc03ffff,0xf83ffffc,0x780,
--      0xfffff00,0x7fff800,0xf000007,0xffff001f,0xffe00007,0xe000003f,0x0,0x0,0x0,0x3c000,0x1e000001,0xe0000f03,0xffffc001,0xffff01ff,
--      0xff0003ff,0xffe01e00,0x1fff,0xf81e0007,0x803ffff0,0x7fffe00,0x3c000f80,0x7ffffe1e,0xf078,0xfe003f,0xff800780,0xfff,0xf0078000,
--      0x7c3ffffc,0xf000,0x3ffff00,0xff0000,0xf803e01e,0x1e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7fffbc01,0xffffc000,
--      0xffff003f,0xfff800ff,0xffc0003c,0x3ffe,0xf0078007,0x807ffffe,0xf000,0x7800f80,0x7ff00f,0x3c0f01e,0x1e007f,0xff8007ff,0xff001fff,
--      0xbc003c00,0xffffc,0x1fff0,0x1fffbc0,0xff0000,0x7c07c00f,0x800f8000,0x7e0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7fff80,0x7c0000,
--      0x1f000000,0x3c00001e,0x7c00f07,0xc1e00018,0xc0,0x0,0x60e303,0x7ffff80,0x380000,0x3fffff80,0x7c0003f,0xffffc001,0xf000000f,
--      0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff800003,0x8003ffff,0xfe0007c0,0x1ffffe,0x1e000,0x0,0x780000,0x1fffe03f,0xffff8000,
--      0x7,0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3fffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x1c1,
--      0xc000000f,0x7070,0x7fffc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,
--      0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000f001,0xfc007fff,0x3fff8,0x1fffc0,0xfffe00,0x7fff000,0x3b,0xfffc003f,
--      0xfff001ff,0xff800fff,0xfc007fff,0xe0000780,0x1e0000,0xf3fff8,0xffff780,0x7fffbc03,0xfffde01f,0xffef00ff,0xff7807ff,0xfbc0ffff,
--      0xff800fff,0xf001ffff,0x800ffffc,0x7fffe0,0x3ffff00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff803ff,0xfc003c00,0x3c00ffff,0x7fff8,
--      0x3fffc0,0x1fffe00,0xffff000,0x1f,0xfffc001f,0xffbc00ff,0xfde007ff,0xef003fff,0x780007e0,0x1ffffc,0x1f800,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x700003f,
--      0xffc00000,0x7fc01fff,0x9f800000,0xf80,0xf800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0xff,0xf8000fff,0xfc03ffff,0xf83ffff8,0x780,
--      0xffffe00,0x7fff000,0xf000003,0xfffe001f,0xffc00007,0xe000003f,0x0,0x0,0x0,0x3c000,0xf000003,0xe0000f83,0xffff0000,0xffff01ff,
--      0xfc0003ff,0xffe01e00,0xfff,0xf01e0007,0x803ffff0,0x7fffc00,0x3c0007c0,0x7ffffe1e,0xf078,0x7e003f,0xff000780,0x7ff,0xe0078000,
--      0x3c3ffff8,0xf000,0x1fffe00,0x7e0000,0xf803e03e,0x1f000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x3fff3c01,0xefff8000,
--      0x7ffe001f,0xff78007f,0xff80003c,0x1ffc,0xf0078007,0x807ffffe,0xf000,0x78007c0,0x3ff00f,0x3c0f01e,0x1e003f,0xff0007bf,0xfe000fff,
--      0xbc003c00,0xffff8,0xfff0,0xfff3c0,0x7e0000,0x7c07c01f,0x7c000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3fff80,0x380000,
--      0x3e000000,0x7c00003e,0x7801f07,0xc1e00018,0xc0,0x0,0x39c1ce,0x7ffff00,0x1c0000,0xfffff80,0x380003f,0xffffc000,0xe0000007,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff000007,0x1ffcf,0xfe000380,0x1ffffe,0x1e000,0x0,0x780000,0xfffe03f,0xffff8000,0x7,
--      0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x381,
--      0xc000001e,0xe070,0x7fff80,0x7c0001f3,0xe0000f9f,0x7cf8,0x3e7c0,0x1f3e00,0xfbe007,0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,
--      0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000f000,0xfc007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x79,0xfff8001f,
--      0xffe000ff,0xff0007ff,0xf8003fff,0xc0000780,0x1e0000,0xf3fff0,0x7ffe780,0x3fff3c01,0xfff9e00f,0xffcf007f,0xfe7803ff,0xf3c07ff3,
--      0xff8007ff,0xe000ffff,0x7fff8,0x3fffc0,0x1fffe00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff801ff,0xf8003c00,0x3c007ffe,0x3fff0,
--      0x1fff80,0xfffc00,0x7ffe000,0x1d,0xfff8000f,0xff3c007f,0xf9e003ff,0xcf001ffe,0x780007c0,0x1efff8,0x1f000,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0xf000003,
--      0xfe000000,0x1f000fff,0xfc00000,0x780,0xf000,0x0,0x0,0xf80000,0x0,0x7e0001e0,0x7f,0xf0000fff,0xfc03ffff,0xf81ffff0,0x780,
--      0x7fff800,0x1ffe000,0x1f000000,0xfff8001f,0xff000007,0xe000003e,0x0,0x0,0x0,0x3c000,0xf800003,0xc0000783,0xfff80000,0x3ffe01ff,
--      0xe00003ff,0xffe01e00,0x7ff,0xc01e0007,0x803ffff0,0x3fff800,0x3c0003c0,0x7ffffe1e,0xf078,0x7e000f,0xfe000780,0x3ff,0xc0078000,
--      0x3e1fffe0,0xf000,0x7ff800,0x7e0000,0xf803e07c,0xf800,0x780003ff,0xfffc003c,0x3,0xc00001e0,0x0,0x0,0x0,0xffe3c01,0xe7ff0000,
--      0x3ffc000f,0xfe78003f,0xfe00003c,0x7f0,0xf0078007,0x807ffffe,0xf000,0x78003e0,0xff00f,0x3c0f01e,0x1e001f,0xfe00079f,0xfc0007ff,
--      0x3c003c00,0x7ffe0,0x1ff0,0x7fe3c0,0x7e0000,0x7c07c03e,0x3e000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfff00,0x100000,
--      0x3e000000,0x7800003c,0xf800f07,0xc1e00018,0xc0,0x0,0x1f80fc,0x3fffc00,0xc0000,0x3ffff80,0x100003f,0xffffc000,0x40000002,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xfc000006,0xff87,0xfc000100,0x1ffffe,0x1e000,0x0,0x780000,0x3ffc03f,0xffff8000,0x7,
--      0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dff9f8,0xe1c00,0x0,0x0,0x0,0x0,0x3ff,
--      0xf800003c,0xfffe,0x1ffe00,0x780000f3,0xc000079e,0x3cf0,0x1e780,0xf3c00,0x7bc007,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,
--      0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,0xf000,0xfc001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x70,0xfff00007,
--      0xff80003f,0xfc0001ff,0xe0000fff,0x780,0x1e0000,0xf3ffe0,0x1ffc780,0xffe3c00,0x7ff1e003,0xff8f001f,0xfc7800ff,0xe3c03fe1,
--      0xff0003ff,0xc0007ffc,0x3ffe0,0x1fff00,0xfff800,0xfffffc07,0xffffe03f,0xffff01ff,0xfff800ff,0xf0003c00,0x3c003ffc,0x1ffe0,
--      0xfff00,0x7ff800,0x3ffc000,0x38,0xfff00007,0xfe3c003f,0xf1e001ff,0x8f000ffc,0x780007c0,0x1e7ff0,0x1f000,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
--      0x1fc,0x0,0x780,0xf000,0x0,0x0,0x1f80000,0x0,0x1e0,0x1f,0xc0000000,0x0,0x1ff80,0x0,0xffc000,0x7f8000,0x0,0x3fe00007,0xfc000000,
--      0x7e,0x0,0x0,0x0,0x0,0x7c00000,0x0,0x0,0xff00000,0x0,0x0,0xfe,0x0,0x0,0x3fc000,0x0,0x0,0x0,0x3,0xf8000000,0xff,0xc0000000,
--      0x1ff00,0x0,0x1fe000,0x0,0x0,0x0,0x0,0x3c,0x3,0xc00001e0,0x0,0x0,0x0,0x3f80000,0x1fc0000,0x7f00003,0xf8000007,0xf0000000,
--      0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x7,0xf8000787,0xf00001fc,0x3c000000,0x7f80,0x0,0x1f8000,0x0,0x0,0x0,0x7c000000,0x1e,
--      0xf0,0x780,0x0,0x0,0x3fc00,0x0,0x3c000000,0x7800003c,0xf000601,0xc00018,0xc0,0x0,0x0,0x3fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf0000000,0x7e03,0xf0000000,0x0,0x0,0x0,0x0,0xfe0000,0x0,0x0,0x3c,0x2007,0x80000000,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c7e0f0,0xe1c00,0x0,0x3800000,0x0,0x0,0x3ff,0xf8000078,0xfffe,0x7f800,0x0,0x0,0x0,0x0,
--      0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,0x7f0000,0x70,0x3fc00001,0xfe00000f,0xf000007f,
--      0x800003fc,0x0,0x0,0xff00,0x7f0000,0x3f80000,0x1fc00000,0xfe000007,0xf000003f,0x80001f80,0xfc00007f,0xfe0,0x7f00,0x3f800,
--      0x1fc000,0x0,0x0,0x0,0x3f,0xc0000000,0xff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x78,0x3fc00001,0xf800000f,0xc000007e,0x3f0,0x7c0,
--      0x1e1fc0,0x1f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xe0000000,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,0x1e,0xf0,0x780,0x0,0x0,0x0,0x0,0x3c000000,0x78000078,0xf000000,0x18,0xc0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3c0f,0x80000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0x1800000,0x0,0x0,0x3ff,0xf80000f0,0xfffe,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x780,0x1e0000,0x1e000,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
--      0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x1f80000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf8000000,
--      0x1f,0xf0,0xf80,0x0,0x0,0x0,0x0,0x78000000,0xf8000078,0x1e000000,0x8,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3fff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x3c00000,0xe1c00,0x0,0x1c00000,0x0,0x0,0x1,0xc00001e0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x1e0000,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x3c000,0x0,0x0,0x1f00000,
--      0x0,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xfe0100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0xf0007fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,
--      0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x1f,0x800000f0,0x1f80,0x0,0x0,0x0,0x0,
--      0x78000000,0xf0000070,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3ffe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,
--      0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0xf00,0x1e0000,0x3c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x7c000,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x7fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4003,0xe0000000,0x0,0x1f000,0x0,0x0,
--      0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x1,0xf0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0x70000001,0xf00000e0,
--      0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,
--      0x0,0x0,0x3c,0xff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,0x0,0x0,0x1,0xc00003ff,
--      0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00,0x1e0000,
--      0x7c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0xf0,0x78000,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,
--      0x0,0x0,0x0,0x1fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,
--      0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780f,0xc0000000,0x0,0x3e000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
--      0x0,0x0,0x0,0x0,0x3,0xe0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0xf0000103,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x21e00000,0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e00,0x1e0000,0xf8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,
--      0xf8,0xf8000,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x1fe00,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x7fff,0xc0000000,0x0,0x3ffe000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0xe0000000,0x7,0xfc0000f0,
--      0x3fe00,0x0,0x0,0x0,0x0,0x600001ff,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,
--      0x3fe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x7fe00,0x1e0000,0x1ff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff,0x80000000,0x0,0x3ffc000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
--      0x0,0x0,0x0,0x0,0x7f,0xc0000000,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x0,0x0,0x1ff,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3fc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fc00,0x1e0000,0x1ff0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x3ffe,0x0,0x0,0x3ff8000,0x0,0x0,0x0,
--      0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0x80000000,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x80000000,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f800,0x1e0000,0x1fe0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8,0x0,0x0,0x3fe0000,
--      0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7e,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x1e0000,0x1f80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
--      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
--
--    // Definition of a 40x38 'danger' color logo
--    const unsigned char logo40x38[4576] = {
--      177,200,200,200,3,123,123,0,36,200,200,200,1,123,123,0,2,255,255,0,1,189,189,189,1,0,0,0,34,200,200,200,
--      1,123,123,0,4,255,255,0,1,189,189,189,1,0,0,0,1,123,123,123,32,200,200,200,1,123,123,0,5,255,255,0,1,0,0,
--      0,2,123,123,123,30,200,200,200,1,123,123,0,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,29,200,200,200,
--      1,123,123,0,7,255,255,0,1,0,0,0,2,123,123,123,28,200,200,200,1,123,123,0,8,255,255,0,1,189,189,189,1,0,0,0,
--      2,123,123,123,27,200,200,200,1,123,123,0,9,255,255,0,1,0,0,0,2,123,123,123,26,200,200,200,1,123,123,0,10,255,
--      255,0,1,189,189,189,1,0,0,0,2,123,123,123,25,200,200,200,1,123,123,0,3,255,255,0,1,189,189,189,3,0,0,0,1,189,
--      189,189,3,255,255,0,1,0,0,0,2,123,123,123,24,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,3,255,255,0,1,189,
--      189,189,1,0,0,0,2,123,123,123,23,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,4,255,255,0,1,0,0,0,2,123,123,123,
--      22,200,200,200,1,123,123,0,5,255,255,0,5,0,0,0,4,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,21,200,200,200,
--      1,123,123,0,5,255,255,0,5,0,0,0,5,255,255,0,1,0,0,0,2,123,123,123,20,200,200,200,1,123,123,0,6,255,255,0,5,0,0,
--      0,5,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,19,200,200,200,1,123,123,0,6,255,255,0,1,123,123,0,3,0,0,0,1,
--      123,123,0,6,255,255,0,1,0,0,0,2,123,123,123,18,200,200,200,1,123,123,0,7,255,255,0,1,189,189,189,3,0,0,0,1,189,
--      189,189,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,17,200,200,200,1,123,123,0,8,255,255,0,3,0,0,0,8,255,255,
--      0,1,0,0,0,2,123,123,123,16,200,200,200,1,123,123,0,9,255,255,0,1,123,123,0,1,0,0,0,1,123,123,0,8,255,255,0,1,189,
--      189,189,1,0,0,0,2,123,123,123,15,200,200,200,1,123,123,0,9,255,255,0,1,189,189,189,1,0,0,0,1,189,189,189,9,255,255,
--      0,1,0,0,0,2,123,123,123,14,200,200,200,1,123,123,0,11,255,255,0,1,0,0,0,10,255,255,0,1,189,189,189,1,0,0,0,2,123,
--      123,123,13,200,200,200,1,123,123,0,23,255,255,0,1,0,0,0,2,123,123,123,12,200,200,200,1,123,123,0,11,255,255,0,1,189,
--      189,189,2,0,0,0,1,189,189,189,9,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,11,200,200,200,1,123,123,0,11,255,255,
--      0,4,0,0,0,10,255,255,0,1,0,0,0,2,123,123,123,10,200,200,200,1,123,123,0,12,255,255,0,4,0,0,0,10,255,255,0,1,189,189,
--      189,1,0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,12,255,255,0,1,189,189,189,2,0,0,0,1,189,189,189,11,255,255,0,1,
--      0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,27,255,255,0,1,0,0,0,3,123,123,123,8,200,200,200,1,123,123,0,26,255,
--      255,0,1,189,189,189,1,0,0,0,3,123,123,123,9,200,200,200,1,123,123,0,24,255,255,0,1,189,189,189,1,0,0,0,4,123,123,
--      123,10,200,200,200,1,123,123,0,24,0,0,0,5,123,123,123,12,200,200,200,27,123,123,123,14,200,200,200,25,123,123,123,86,
--      200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0};
--
--    // Display a warning message if parameter 'cond' is true.
--    inline void warn(const bool cond, const char *format,...) {
--      if (cimg::exception_mode()>=1 && cond) {
--        std::va_list ap;
--        va_start(ap,format);
--        std::fprintf(stderr,"\n<CImg Warning> ");
--        std::vfprintf(stderr,format,ap);
--        std::fputc('\n',stderr);
--        va_end(ap);
--      }
--    }
--
--    inline int xln(const int x) {
--      return x>0?(int)(1+std::log10((double)x)):1;
--    }
--
--    inline char uncase(const char x) {
--      return (char)((x<'A'||x>'Z')?x:x-'A'+'a');
--    }
--
--    inline float atof(const char *str) {
--      float x=0,y=1;
--      if (!str) return 0; else { std::sscanf(str,"%g/%g",&x,&y); return x/y; }
--    }
--
--    inline int strlen(const char *s) {
--      if (s) { int k; for (k=0; s[k]; k++) ; return k; }
--      return -1;
--    }
--
--    inline int strncmp(const char *s1,const char *s2,const int l) {
--      if (s1 && s2) { int n=0; for (int k=0; k<l; k++) n+=std::abs(s1[k] - s2[k]); return n; }
--      return 0;
--    }
--
--    inline int strncasecmp(const char *s1,const char *s2,const int l) {
--      if (s1 && s2) { int n=0; for (int k=0; k<l; k++) n+=std::abs(uncase(s1[k])-uncase(s2[k])); return n; }
--      return 0;
--    }
--
--    inline int strcmp(const char *s1,const char *s2) {
--      const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
--      return cimg::strncmp(s1,s2,1+(l1<l2?l1:l2));
--    }
--
--    inline int strcasecmp(const char *s1,const char *s2) {
--      const int l1 = cimg::strlen(s1), l2 = cimg::strlen(s2);
--      return cimg::strncasecmp(s1,s2,1+(l1<l2?l1:l2));
--    }
--
--    inline int strfind(const char *s,const char c) {
--      if (s) {
--        int l; for (l=cimg::strlen(s); l>=0 && s[l]!=c; l--) ;
--        return l;
--      }
--      return -1;
--    }
--
--    inline const char* basename(const char *s)  {
--      return (cimg_OS!=2)?(s?s+1+cimg::strfind(s,'/'):0):(s?s+1+cimg::strfind(s,'\\'):0);
--    }
--
--    inline void system(const char *command, const char *module_name=0) {
--#if cimg_OS==2
--      PROCESS_INFORMATION pi;
--      STARTUPINFO si;
--      std::memset(&pi, 0, sizeof(PROCESS_INFORMATION));
--      std::memset(&si, 0, sizeof(STARTUPINFO));
--      GetStartupInfo(&si);
--      si.cb = sizeof(si);
--      si.wShowWindow = SW_HIDE;
--      si.dwFlags |= SW_HIDE;
--      const BOOL res = CreateProcess((LPCTSTR)module_name,(LPTSTR)command,0,0,FALSE,0,0,0,&si,&pi);
--      if (res) {
--        WaitForSingleObject(pi.hProcess, INFINITE);
--        CloseHandle(pi.hThread);
--        CloseHandle(pi.hProcess);
--      } else
--#endif
--      std::system(command);
--      command=module_name=0;
--    }
--
--    //! Return path of the ImageMagick's \c convert tool.
--    /**
--       If you have installed the <a href="http://www.imagemagick.org">ImageMagick package</a>
--       in a standard directory, this function should return the correct path of the \c convert tool
--       used by the %CImg Library to load and save compressed image formats.
--       Conversely, if the \c convert executable is not auto-detected by the function,
--       you can define the macro \c cimg_imagemagick_path with the correct path
--       of the \c convert executable, before including <tt>CImg.h</tt> in your program :
--       \code
--       #define cimg_imagemagick_path "/users/thatsme/local/bin/convert"
--       #include "CImg.h"
--
--       int main() {
--         CImg<> img("my_image.jpg");     // Read a JPEG image file.
--         return 0;
--       }
--       \endcode
--
--       Note that non compressed image formats can be read without installing ImageMagick.
--
--       \sa temporary_path(), get_load_imagemagick(), load_imagemagick(), save_imagemagick().
--    **/
--    inline const char* imagemagick_path() {
--      static char *st_imagemagick_path = 0;
--      if (!st_imagemagick_path) {
--        st_imagemagick_path = new char[1024];
--        bool path_found = false;
--        std::FILE *file = 0;
--#ifdef cimg_imagemagick_path
--        std::strcpy(st_imagemagick_path,cimg_imagemagick_path);
--        if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--#endif
--#if cimg_OS==2
--        if (!path_found) {
--          std::sprintf(st_imagemagick_path,".\\convert.exe");
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\PROGRA~1\\IMAGEM~1.%u-Q\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\PROGRA~1\\IMAGEM~1.%u\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\PROGRA~1\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"C:\\PROGRA~1\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\PROGRA~1\\IMAGEM~1.%u-Q\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\PROGRA~1\\IMAGEM~1.%u\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\PROGRA~1\\IMAGEM~1.%u-Q\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_imagemagick_path,"D:\\PROGRA~1\\IMAGEM~1.%u\\VISUA~1\\BIN\\convert.exe",k);
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        if (!path_found) std::strcpy(st_imagemagick_path,"convert.exe");
--#else
--        if (!path_found) {
--          std::sprintf(st_imagemagick_path,"./convert");
--          if ((file=std::fopen(st_imagemagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) std::strcpy(st_imagemagick_path,"convert");
--#endif
--      }
--      return st_imagemagick_path;
--    }
--
--    //! Return path of the GraphicsMagick's \c gm tool.
--    /**
--       If you have installed the <a href="http://www.graphicsmagick.org">GraphicsMagick package</a>
--       in a standard directory, this function should return the correct path of the \c gm tool
--       used by the %CImg Library to load and save compressed image formats.
--       Conversely, if the \c gm executable is not auto-detected by the function,
--       you can define the macro \c cimg_graphicsmagick_path with the correct path
--       of the \c gm executable, before including <tt>CImg.h</tt> in your program :
--       \code
--       #define cimg_graphicsmagick_path "/users/thatsme/local/bin/gm"
--       #include "CImg.h"
--
--       int main() {
--         CImg<> img("my_image.jpg");     // Read a JPEG image file.
--         return 0;
--       }
--       \endcode
--
--       Note that non compressed image formats can be read without installing ImageMagick.
--
--       \sa temporary_path(), get_load_imagemagick(), load_imagemagick(), save_imagemagick().
--    **/
--    inline const char* graphicsmagick_path() {
--      static char *st_graphicsmagick_path = 0;
--      if (!st_graphicsmagick_path) {
--        st_graphicsmagick_path = new char[1024];
--        bool path_found = false;
--        std::FILE *file = 0;
--#ifdef cimg_graphicsmagick_path
--        std::strcpy(st_graphicsmagick_path,cimg_graphicsmagick_path);
--        if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--#endif
--#if cimg_OS==2
--        if (!path_found) {
--          std::sprintf(st_graphicsmagick_path,".\\gm.exe");
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\PROGRA~1\\GRAPHI~1.%u-Q\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\PROGRA~1\\GRAPHI~1.%u\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\PROGRA~1\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"C:\\PROGRA~1\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\PROGRA~1\\GRAPHI~1.%u-Q\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\PROGRA~1\\GRAPHI~1.%u\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\PROGRA~1\\GRAPHI~1.%u-Q\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        { for (unsigned int k=0; k<=9 && !path_found; k++) {
--          std::sprintf(st_graphicsmagick_path,"D:\\PROGRA~1\\GRAPHI~1.%u\\VISUA~1\\BIN\\gm.exe",k);
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }}
--        if (!path_found) std::strcpy(st_graphicsmagick_path,"gm.exe");
--#else
--        if (!path_found) {
--          std::sprintf(st_graphicsmagick_path,"./gm");
--          if ((file=std::fopen(st_graphicsmagick_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) std::strcpy(st_graphicsmagick_path,"gm");
--#endif
--      }
--      return st_graphicsmagick_path;
--    }
--
--    //! Return path of the \c XMedcon tool.
--    /**
--       If you have installed the <a href="http://xmedcon.sourceforge.net/">XMedcon package</a>
--       in a standard directory, this function should return the correct path of the \c medcon tool
--       used by the %CIg Library to load DICOM image formats.
--       Conversely, if the \c medcon executable is not auto-detected by the function,
--       you can define the macro \c cimg_medcon_path with the correct path
--       of the \c medcon executable, before including <tt>CImg.h</tt> in your program :
--       \code
--       #define cimg_medcon_path "/users/thatsme/local/bin/medcon"
--       #include "CImg.h"
--
--       int main() {
--         CImg<> img("my_image.dcm");    // Read a DICOM image file.
--         return 0;
--       }
--       \endcode
--
--       Note that \c medcon is only needed if you want to read DICOM image formats.
--
--       \sa temporary_path(), get_load_dicom(), load_dicom().
--    **/
--    inline const char* medcon_path() {
--      static char *st_medcon_path = 0;
--      if (!st_medcon_path) {
--        st_medcon_path = new char[1024];
--        bool path_found = false;
--        std::FILE *file = 0;
--#ifdef cimg_medcon_path
--        std::strcpy(st_medcon_path,cimg_medcon_path);
--        if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
--#endif
--#if cimg_OS==2
--        if (!path_found) {
--          std::sprintf(st_medcon_path,".\\medcon.bat");
--          if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) {
--          std::sprintf(st_medcon_path,"C:\\PROGRA~1\\XMedCon\\bin\\medcon.bat");
--          if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) {
--          std::sprintf(st_medcon_path,"D:\\PROGRA~1\\XMedCon\\bin\\medcon.bat");
--          if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) std::strcpy(st_medcon_path,"medcon.bat");
--#else
--        if (!path_found) {
--          std::sprintf(st_medcon_path,"./medcon");
--          if ((file=std::fopen(st_medcon_path,"r"))!=0) { std::fclose(file); path_found = true; }
--        }
--        if (!path_found) std::strcpy(st_medcon_path,"medcon");
--#endif
--      }
--      return st_medcon_path;
--    }
--
--    //! Return path to store temporary files.
--    /**
--       If you are running on a standard Unix or Windows system, this function should return a correct path
--       where temporary files can be stored. If such a path is not auto-detected by this function,
--       you can define the macro \c cimg_temporary_path with a correct path, before including <tt>CImg.h</tt>
--       in your program :
--       \code
--       #define cimg_temporary_path "/users/thatsme/tmp"
--       #include "CImg.h"
--
--       int main() {
--         CImg<> img("my_image.jpg");   // Read a JPEG image file (using the defined temporay path).
--         return 0;
--       }
--       \endcode
--
--       A temporary path is necessary to load and save compressed image formats, using \c convert
--       or \c medcon.
--
--       \sa imagemagick_path(), get_load_imagemagick(), load_imagemagick(), save_imagemagick(), get_load_dicom(), load_dicom().
--    **/
--    inline const char* temporary_path() {
--
--#define cimg_test_temporary_path(p) \
--      if (!path_found) { \
--        std::sprintf(st_temporary_path,p); \
--        std::sprintf(tmp,"%s%s%s",st_temporary_path,cimg_OS==2?"\\":"/",filetmp); \
--        if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; } \
--      }
--
--      static char *st_temporary_path = 0;
--      if (!st_temporary_path) {
--        st_temporary_path = new char[1024];
--        bool path_found = false;
--        char tmp[1024], filetmp[512];
--        std::FILE *file = 0;
--        std::sprintf(filetmp,"CImg%.4d.tmp",std::rand()%10000);
--#ifdef cimg_temporary_path
--        cimg_test_temporary_path(cimg_temporary_path);
--#endif
--#if cimg_OS==2
--        cimg_test_temporary_path("C:\\WINNT\\Temp");
--        cimg_test_temporary_path("C:\\WINDOWS\\Temp");
--        cimg_test_temporary_path("C:\\Temp");
--        cimg_test_temporary_path("C:");
--        cimg_test_temporary_path("D:\\WINNT\\Temp");
--        cimg_test_temporary_path("D:\\WINDOWS\\Temp");
--        cimg_test_temporary_path("D:\\Temp");
--        cimg_test_temporary_path("D:");
--#else
--        cimg_test_temporary_path("/tmp");
--        cimg_test_temporary_path("/var/tmp");
--#endif
--        if (!path_found) {
--          st_temporary_path[0]='\0';
--          std::strcpy(tmp,filetmp);
--          if ((file=std::fopen(tmp,"wb"))!=0) { std::fclose(file); std::remove(tmp); path_found = true; }
--        }
--        if (!path_found)
--          throw CImgIOException("cimg::temporary_path() : Unable to find a temporary path accessible for writing\n"
--                                "you have to set the macro 'cimg_temporary_path' to a valid path where you have writing access :\n"
--                                "#define cimg_temporary_path \"path\" (before including 'CImg.h')");
--      }
--      return st_temporary_path;
--    }
--
--    inline const char *filename_split(const char *const filename, char *const body=0) {
--      if (!filename) { if (body) body[0]='\0'; return 0; }
--      int l = cimg::strfind(filename,'.');
--      if (l>=0) { if (body) { std::strncpy(body,filename,l); body[l]='\0'; }}
--      else { if (body) std::strcpy(body,filename); l=(int)std::strlen(filename)-1; }
--      return filename+l+1;
--    }
--
--    inline char* filename_number(const char *const filename, const int number, const unsigned int n, char *const string) {
--      if (!filename) { if (string) string[0]='\0'; return 0; }
--      char format[1024],body[1024];
--      const char *ext = cimg::filename_split(filename,body);
--      if (n>0) std::sprintf(format,"%s_%%.%ud.%s",body,n,ext);
--      else std::sprintf(format,"%s_%%d.%s",body,ext);
--      std::sprintf(string,format,number);
--      return string;
--    }
--
--    inline std::FILE *fopen(const char *const path,const char *const mode) {
--      if(!path || !mode)
--        throw CImgArgumentException("cimg::fopen() : File '%s' cannot be opened with mode '%s'.",
--                                    path?path:"(null)",mode?mode:"(null)");
--      if (path[0]=='-') return (mode[0]=='r')?stdin:stdout;
--      std::FILE *dest = std::fopen(path,mode);
--      if (!dest)
--        throw CImgIOException("cimg::fopen() : File '%s' cannot be opened%s",
--                              path,mode[0]=='r'?" for reading.":(mode[0]=='w'?" for writing.":"."),path);
--      return dest;
--    }
--
--    inline int fclose(std::FILE *file) {
--      warn(!file,"cimg::fclose() : Can't close (null) file");
--      if (!file || file==stdin || file==stdout) return 0;
--      const int errn=std::fclose(file);
--      warn(errn!=0,"cimg::fclose() : Error %d during file closing",errn);
--      return errn;
--    }
--
--    template<typename T> inline int fread(T *const ptr, const unsigned int nmemb, std::FILE *stream) {
--      if (!ptr || nmemb<=0 || !stream)
--        throw CImgArgumentException("cimg::fread() : Can't read %u x %u bytes of file pointer '%p' in buffer '%p'",
--                                    nmemb,sizeof(T),stream,ptr);
--      const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
--      unsigned int toread=nmemb, alread=0, ltoread=0, lalread=0;
--      do {
--        ltoread = (toread*sizeof(T))<wlimitT?toread:wlimit;
--        lalread = (unsigned int)std::fread((void*)(ptr+alread),sizeof(T),ltoread,stream);
--        alread+=lalread;
--        toread-=lalread;
--      } while (ltoread==lalread && toread>0);
--      cimg::warn(toread>0,"cimg::fread() : File reading problems, only %u/%u elements read",alread,nmemb);
--      return alread;
--    }
--
--    template<typename T> inline int fwrite(const T *ptr, const unsigned int nmemb, std::FILE *stream) {
--      if (!ptr || !stream)
--        throw CImgArgumentException("cimg::fwrite() : Can't write %u x %u bytes of file pointer '%p' from buffer '%p'",
--                                    nmemb,sizeof(T),stream,ptr);
--      if (nmemb<=0) return 0;
--      const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
--      unsigned int towrite=nmemb, alwrite=0, ltowrite=0, lalwrite=0;
--      do {
--        ltowrite = (towrite*sizeof(T))<wlimitT?towrite:wlimit;
--        lalwrite = (unsigned int)std::fwrite((void*)(ptr+alwrite),sizeof(T),ltowrite,stream);
--        alwrite+=lalwrite;
--        towrite-=lalwrite;
--      } while (ltowrite==lalwrite && towrite>0);
--      cimg::warn(towrite>0,"cimg::fwrite() : File writing problems, only %u/%u elements written",alwrite,nmemb);
--      return alwrite;
--    }
--
--    // Exchange the values of variables \p a and \p b
--    template<typename T> inline void swap(T& a,T& b) { T t=a; a=b; b=t; }
--    template<typename T1,typename T2> inline void swap(T1& a1,T1& b1,T2& a2,T2& b2) {
--      cimg::swap(a1,b1); cimg::swap(a2,b2);
--    }
--    template<typename T1,typename T2,typename T3> inline void swap(T1& a1,T1& b1,T2& a2,T2& b2,T3& a3,T3& b3) {
--      cimg::swap(a1,b1,a2,b2); cimg::swap(a3,b3);
--    }
--    template<typename T1,typename T2,typename T3,typename T4>
--    inline void swap(T1& a1,T1& b1,T2& a2,T2& b2,T3& a3,T3& b3,T4& a4,T4& b4) {
--      cimg::swap(a1,b1,a2,b2,a3,b3); cimg::swap(a4,b4);
--    }
--    template<typename T1,typename T2,typename T3,typename T4,typename T5>
--    inline void swap(T1& a1,T1& b1,T2& a2,T2& b2,T3& a3,T3& b3,T4& a4,T4& b4,T5& a5,T5& b5) {
--      cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4); cimg::swap(a5,b5);
--    }
--    template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6>
--    inline void swap(T1& a1,T1& b1,T2& a2,T2& b2,T3& a3,T3& b3,T4& a4,T4& b4,T5& a5,T5& b5,T6& a6,T6& b6) {
--      cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); cimg::swap(a6,b6);
--    }
--
--    template<typename T> inline void endian_swap(T* const buffer, const unsigned int size) {
--      switch (sizeof(T)) {
--      case 1: break;
--      case 2: {
--        for (unsigned short *ptr = (unsigned short*)buffer+size; ptr>(unsigned short*)buffer;) {
--          const unsigned short val = *(--ptr);
--          *ptr = (val>>8)|((val<<8));
--        }
--      } break;
--      case 4: {
--        for (unsigned int *ptr = (unsigned int*)buffer+size; ptr>(unsigned int*)buffer;) {
--          const unsigned int val = *(--ptr);
--          *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24);
--        }
--      } break;
--      default: {
--        for (T* ptr = buffer+size; ptr>buffer; --ptr) {
--          unsigned char *pb=(unsigned char*)(--ptr), *pe=pb+sizeof(T);
--          for (int i=0; i<(int)sizeof(T)/2; i++) cimg::swap(*(pb++),*(--pe));
--        } break;
--      }
--      }
--    }
--    template<typename T> inline T& endian_swap(T& a) { endian_swap(&a,1); return a; }
--
--    inline const char* option(const char *const name, const int argc, char **argv,
--                              const char *defaut, const char *const usage=0) {
--      static bool first=true, visu=false;
--      const char *res = 0;
--      if (first) {
--        first=false;
--        visu = (cimg::option("-h",argc,argv,(char*)0)!=0);
--        visu |= (cimg::option("-help",argc,argv,(char*)0)!=0);
--        visu |= (cimg::option("--help",argc,argv,(char*)0)!=0);
--      }
--      if (!name && visu) {
--        if (usage) {
--          std::fprintf(stderr,"\n %s%s%s",cimg::t_red,cimg::basename(argv[0]),cimg::t_normal);
--          std::fprintf(stderr," : %s",usage);
--          std::fprintf(stderr," (%s, %s)\n\n",__DATE__,__TIME__);
--        }
--        if (defaut) std::fprintf(stderr,"%s\n",defaut);
--      }
--      if (name) {
--        if (argc>0) {
--          int k=0;
--          while (k<argc && cimg::strcmp(argv[k],name)) k++;
--          res=(k++==argc?defaut:(k==argc?argv[--k]:argv[k]));
--        } else res = defaut;
--        if (visu && usage) std::fprintf(stderr,"    %s%-8s%s = %-12s : %s%s%s\n",
--                                        cimg::t_bold,name,cimg::t_normal,res?res:"0",cimg::t_purple,usage,cimg::t_normal);
--      }
--      return res;
--    }
--
--    inline bool option(const char *const name, const int argc, char **argv,
--                       const bool defaut, const char *const usage=0) {
--      const char *s = cimg::option(name,argc,argv,(char*)0);
--      const bool res = s?(cimg::strcasecmp(s,"false") && cimg::strcasecmp(s,"off") && cimg::strcasecmp(s,"0")):defaut;
--      cimg::option(name,0,0,res?"true":"false",usage);
--      return res;
--    }
--
--    inline int option(const char *const name, const int argc, char **argv,
--                      const int defaut, const char *const usage=0) {
--      const char *s = cimg::option(name,argc,argv,(char*)0);
--      const int res = s?std::atoi(s):defaut;
--      char tmp[256];
--      std::sprintf(tmp,"%d",res);
--      cimg::option(name,0,0,tmp,usage);
--      return res;
--    }
--
--    inline char option(const char *const name, const int argc, char **argv,
--                       const char defaut, const char *const usage=0) {
--      const char *s = cimg::option(name,argc,argv,(char*)0);
--      const char res = s?s[0]:defaut;
--      char tmp[8];
--      tmp[0] = res;
--      tmp[1] ='\0';
--      cimg::option(name,0,0,tmp,usage);
--      return res;
--    }
--
--    inline float option(const char *const name, const int argc, char **argv,
--                        const float defaut, const char *const usage=0) {
--      const char *s = cimg::option(name,argc,argv,(char*)0);
--      const float res = s?cimg::atof(s):defaut;
--      char tmp[256];
--      std::sprintf(tmp,"%g",res);
--      cimg::option(name,0,0,tmp,usage);
--      return res;
--    }
--
--    inline double option(const char *const name, const int argc, char **argv,
--                         const double defaut, const char *const usage=0) {
--      const char *s = cimg::option(name,argc,argv,(char*)0);
--      const double res = s?cimg::atof(s):defaut;
--      char tmp[256];
--      std::sprintf(tmp,"%g",res);
--      cimg::option(name,0,0,tmp,usage);
--      return res;
--    }
--
--    //! Return \c false for little endian CPUs (Intel), \c true for big endian CPUs (Motorola).
--    inline bool endian() {
--      const int x=1;
--      return ((unsigned char*)&x)[0]?false:true;
--    }
--
--    //! Print informations about %CImg environement variables.
--    /**
--       Printing is done on the standart error output.
--    **/
--    inline void info() {
--      char tmp[1024] = {0};
--      std::fprintf(stderr,"\n %sCImg Library %g%s, compiled %s ( %s ) with the following flags :\n\n",
--                   cimg::t_red,cimg_version,cimg::t_normal,__DATE__,__TIME__);
--
--      std::fprintf(stderr,"  > CPU endianness :         %s%s Endian%s\n",
--                   cimg::t_bold,
--                   cimg::endian()?"Big":"Little",
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Operating System :       %s%-13s%s %s('cimg_OS'=%d)%s\n",
--                   cimg::t_bold,
--                   cimg_OS==1?"Unix":(cimg_OS==2?"Windows":"Unknow"),
--                   cimg::t_normal,cimg::t_purple,
--                   cimg_OS,
--                   cimg::t_normal);
--
--#ifdef cimg_use_visualcpp6
--      std::fprintf(stderr,"  > Using Visual C++ 6.0 :       %s%-13s%s %s('cimg_use_visual_cpp6' defined)%s\n",
--                   cimg::t_bold,"Yes",cimg::t_normal,cimg::t_purple,cimg::t_normal);
--#endif
--
--      std::fprintf(stderr,"  > Display type :           %s%-13s%s %s('cimg_display_type'=%d)%s\n",
--                   cimg::t_bold,
--                   cimg_display_type==0?"No display":(cimg_display_type==1?"X11":(cimg_display_type==2?"Windows GDI":"Unknow")),
--                   cimg::t_normal,cimg::t_purple,
--                   cimg_display_type,
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Color terminal :         %s%-13s%s %s('cimg_color_terminal' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_color_terminal
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Debug messages :         %s%-13s%s %s('cimg_debug'=%d)%s\n",
--                   cimg::t_bold,
--                   cimg_debug==0?"No":(cimg_debug==1 || cimg_debug==2?"Yes":(cimg_debug==3?"Yes+":"Unknown")),
--                   cimg::t_normal,cimg::t_purple,
--                   cimg_debug,
--                   cimg::t_normal);
--
--#if cimg_display_type==1
--      std::fprintf(stderr,"  > Using XShm for X11 :     %s%-13s%s %s('cimg_use_xshm' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_xshm
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Using XRand for X11 :    %s%-13s%s %s('cimg_use_xrandr' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_xrandr
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--#endif
--
--      std::fprintf(stderr,"  > Using PNG library :      %s%-13s%s %s('cimg_use_png' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_png
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--      std::fprintf(stderr,"  > Using JPEG library :     %s%-13s%s %s('cimg_use_jpeg' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_jpeg
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Using TIFF library :     %s%-13s%s %s('cimg_use_tiff' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_tiff
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Using Magick++ library : %s%-13s%s %s('cimg_use_magick' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_magick
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"  > Using FFTW3 library :    %s%-13s%s %s('cimg_use_fftw3' %s)%s\n",
--                   cimg::t_bold,
--#ifdef cimg_use_fftw3
--                   "Yes",cimg::t_normal,cimg::t_purple,"defined",
--#else
--                   "No",cimg::t_normal,cimg::t_purple,"undefined",
--#endif
--                   cimg::t_normal);
--
--      std::sprintf(tmp,"\"%.1020s\"",cimg::imagemagick_path());
--      std::fprintf(stderr,"  > Path of ImageMagick :    %s%-13s%s %s('cimg_imagemagick_path'%s)%s\n",
--                   cimg::t_bold,
--                   tmp,
--                   cimg::t_normal,
--#ifdef cimg_imagemagick_path
--                   cimg::t_purple,"=\""cimg_imagemagick_path"\"",
--#else
--                   cimg::t_purple," undefined",
--#endif
--                   cimg::t_normal);
--
--      std::sprintf(tmp,"\"%.1020s\"",cimg::graphicsmagick_path());
--      std::fprintf(stderr,"  > Path of GraphicsMagick : %s%-13s%s %s('cimg_graphicsmagick_path'%s)%s\n",
--                   cimg::t_bold,
--                   tmp,
--                   cimg::t_normal,
--#ifdef cimg_graphicsmagick_path
--                   cimg::t_purple,"=\""cimg_graphicsmagick_path"\"",
--#else
--                   cimg::t_purple," undefined",
--#endif
--                   cimg::t_normal);
--
--      std::sprintf(tmp,"\"%.1020s\"",cimg::medcon_path());
--      std::fprintf(stderr,"  > Path of 'medcon' :       %s%-13s%s %s('cimg_medcon_path'%s)%s\n",
--                   cimg::t_bold,
--                   tmp,
--                   cimg::t_normal,
--#ifdef cimg_medcon_path
--                   cimg::t_purple,"=\""cimg_medcon_path"\"",
--#else
--                   cimg::t_purple," undefined",
--#endif
--                   cimg::t_normal);
--
--      std::sprintf(tmp,"\"%.1020s\"",cimg::temporary_path());
--      std::fprintf(stderr,"  > Temporary path :         %s%-13s%s %s('cimg_temporary_path'%s)%s\n",
--                   cimg::t_bold,
--                   tmp,
--                   cimg::t_normal,
--#ifdef cimg_temporary_path
--                   cimg::t_purple,"=\""cimg_temporary_path"\"",
--#else
--                   cimg::t_purple," undefined",
--#endif
--                   cimg::t_normal);
--
--      std::fprintf(stderr,"\n");
--    }
--
--    //! Get the value of a system timer with a millisecond precision.
--    inline unsigned long time() {
--#if cimg_OS==1
--      struct timeval st_time;
--      gettimeofday(&st_time,0);
--      return (unsigned long)(st_time.tv_usec/1000 + st_time.tv_sec*1000);
--#elif cimg_OS==2
--      static SYSTEMTIME st_time;
--      GetSystemTime(&st_time);
--      return (unsigned long)(st_time.wMilliseconds + 1000*(st_time.wSecond + 60*(st_time.wMinute + 60*st_time.wHour)));
--#else
--      return 0;
--#endif
--    }
--
--    //! Sleep for a certain numbers of milliseconds.
--    /**
--       This function frees the CPU ressources during the sleeping time.
--       It may be used to temporize your program properly, without wasting CPU time.
--       \sa wait(), time().
--    **/
--    inline void sleep(const unsigned int milliseconds) {
--#if cimg_OS==1
--      struct timespec tv;
--      tv.tv_sec = milliseconds/1000;
--      tv.tv_nsec = (milliseconds%1000)*1000000;
--      nanosleep(&tv,0);
--#elif cimg_OS==2
--      Sleep(milliseconds);
--#endif
--    }
--
--    inline unsigned int wait(const unsigned int milliseconds, unsigned long& timer) {
--      if (!timer) timer = cimg::time();
--      const unsigned long current_time = cimg::time();
--      if (current_time>=timer+milliseconds) { timer = current_time; return 0; }
--      const unsigned long time_diff = timer + milliseconds - current_time;
--      timer = current_time + time_diff;
--      cimg::sleep(time_diff);
--      return (unsigned int)time_diff;
--    }
--
--    //! Wait for a certain number of milliseconds since the last call.
--    /**
--       This function is equivalent to sleep() but the waiting time is computed with regard to the last call
--       of wait(). It may be used to temporize your program properly.
--       \sa sleep(), time().
--    **/
--    inline unsigned int wait(const unsigned int milliseconds) {
--      static unsigned long timer = 0;
--      if (!timer) timer = cimg::time();
--      return wait(milliseconds,timer);
--    }
--
--    template<typename T> inline const T rol(const T& a, const unsigned int n=1) {
--      return (T)((a<<n)|(a>>((sizeof(T)<<3)-n)));
--    }
--
--    template<typename T> inline const T ror(const T& a, const unsigned int n=1) {
--      return (T)((a>>n)|(a<<((sizeof(T)<<3)-n)));
--    }
--
--    //! Return the absolute value of \p a
--    template<typename T> inline T abs(const T a)      { return a>=0?a:-a; }
--    inline bool abs(const bool a)                     { return a; }
--    inline unsigned char abs(const unsigned char a)   { return a; }
--    inline unsigned short abs(const unsigned short a) { return a; }
--    inline unsigned int abs(const unsigned int a)     { return a; }
--    inline unsigned long abs(const unsigned long a)   { return a; }
--    inline double abs(const double a)                 { return std::fabs(a); }
--    inline float abs(const float a)                   { return (float)std::fabs((double)a); }
--    inline int abs(const int a)                       { return std::abs(a); }
--
--    //! Return the minimum between \p a and \p b.
--    template<typename T> inline const T min(const T a,const T b) { return a<=b?a:b; }
--
--    //! Return the minimum between \p a,\p b and \a c.
--    template<typename T> inline const T min(const T a,const T b,const T c) { return cimg::min(cimg::min(a,b),c); }
--
--    //! Return the minimum between \p a,\p b,\p c and \p d.
--    template<typename T> inline const T min(const T a,const T b,const T c,const T d) { return cimg::min(cimg::min(a,b,c),d); }
--
--    //! Return the maximum between \p a and \p b.
--    template<typename T> inline const T max(const T a,const T b) { return a>=b?a:b; }
--
--    //! Return the maximum between \p a,\p b and \p c.
--    template<typename T> inline const T max(const T a,const T b,const T c) { return cimg::max(cimg::max(a,b),c); }
--
--    //! Return the maximum between \p a,\p b,\p c and \p d.
--    template<typename T> inline const T max(const T a,const T b,const T c,const T d) { return cimg::max(cimg::max(a,b,c),d); }
--
--    //! Return the sign of \p x.
--    template<typename T> inline T sign(const T x) { return (x<0)?(T)(-1):(x==0?(T)0:(T)1); }
--
--    //! Return the nearest power of 2 higher than \p x.
--    template<typename T> inline unsigned long nearest_pow2(const T& x) {
--      unsigned long i=1;
--      while (x>i) i<<=1;
--      return i;
--    }
--
--    //! Return \p x modulo \p m (generic modulo).
--    /**
--       This modulo function accepts negative and floating-points modulo numbers \p m.
--    **/
--    inline double mod(const double x, const double m) { return x-m*std::floor(x/m); }
--    inline float  mod(const float x, const float m)   { return (float)(x-m*std::floor((double)x/m)); }
--    inline int    mod(const int x, const int m)       { return x>=0?x%m:(x%m?m+x%m:0); }
--
--    //! Return minmod(\p a,\p b).
--    /**
--       The operator minmod(\p a,\p b) is defined to be :
--       - minmod(\p a,\p b) = min(\p a,\p b), if (\p a * \p b)>0.
--       - minmod(\p a,\p b) = 0,              if (\p a * \p b)<=0
--    **/
--    template<typename T> inline T minmod(const T& a,const T& b) { return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a)); }
--
--    //! Return a random variable between [0,1], followin a uniform distribution.
--    inline double rand() { return (double)std::rand()/RAND_MAX; }
--
--    //! Return a random variable between [-1,1], following a uniform distribution.
--    inline double crand() { return 1-2*cimg::rand(); }
--
--    //! Return a random variable following a gaussian distribution and a standard deviation of 1.
--    inline double grand() {
--      return std::sqrt(-2*std::log((double)(1e-10 + (1-2e-10)*cimg::rand())))*std::cos((double)(2*PI*cimg::rand()));
--    }
--
--    inline double pythagore(double a, double b) {
--      const double absa = cimg::abs(a), absb = cimg::abs(b);
--      if (absa>absb) { const double tmp = absb/absa; return absa*std::sqrt(1.0+tmp*tmp); }
--      else { const double tmp = absa/absb; return (absb==0?0:absb*std::sqrt(1.0+tmp*tmp)); }
--    }
--
--    // End of the 'cimg' namespace
--  }
--
--  /*
--   #----------------------------------------
--   #
--   #
--   #
--   # Definition of the CImgStats structure
--   #
--   #
--   #
--   #----------------------------------------
--   */
--  //! Class used to compute basic statistics on pixel values of a \ref CImg image.
--  /**
--      Constructing a CImgStats instance from an image CImg<T> or a list CImgList<T>
--      will compute the minimum, maximum and average pixel values of the input object.
--      Optionally, the variance of the pixel values can be computed.
--      Coordinates of the pixels whose values are minimum and maximum are also stored.
--      The example below shows how to use CImgStats objects to retrieve simple statistics of an image :
--      \code
--      const CImg<float> img("my_image.jpg");                 // Read JPEG image file.
--      const CImgStats stats(img);                            // Compute basic statistics on the image.
--      stats.print("My statistics");                          // Display statistics.
--      std::printf("Max-Min = %lf",stats.max-stats.min);      // Compute the difference between extremum values.
--      \endcode
--
--      Note that statistics are computed by considering the set of \a scalar values of the image pixels.
--      No vector-valued statistics are computed.
--  **/
--  struct CImgStats {
--    double min;                 //!< Minimum of the pixel values.
--    double max;                 //!< Maximum of the pixel values.
--    double mean;                //!< Mean of the pixel values.
--    double variance;            //!< Variance of the pixel values.
--    int xmin;                   //!< X-coordinate of the pixel with minimum value.
--    int ymin;                   //!< Y-coordinate of the pixel with minimum value.
--    int zmin;                   //!< Z-coordinate of the pixel with minimum value.
--    int vmin;                   //!< V-coordinate of the pixel with minimum value.
--    int lmin;                   //!< Image number (for a list) containing the minimum pixel.
--    int xmax;                   //!< X-coordinate of the pixel with maximum value.
--    int ymax;                   //!< Y-coordinate of the pixel with maximum value.
--    int zmax;                   //!< Z-coordinate of the pixel with maximum value.
--    int vmax;                   //!< V-coordinate of the pixel with maximum value.
--    int lmax;                   //!< Image number (for a list) containing the maximum pixel.
--
--#ifdef cimgstats_plugin
--#include cimgstats_plugin
--#endif
--
--    //! Default constructor.
--    CImgStats():min(0),max(0),mean(0),variance(0),xmin(-1),ymin(-1),zmin(-1),vmin(-1),lmin(-1),
--                xmax(-1),ymax(-1),zmax(-1),vmax(-1),lmax(-1) {}
--
--    //! In-place version of the default constructor
--    CImgStats& assign() {
--      min = max = mean = variance = 0;
--      xmin = ymin = zmin = vmin = lmin = xmax = ymax = zmax = vmax = lmax = -1;
--      return *this;
--    }
--
--    //! Copy constructor.
--    CImgStats(const CImgStats& stats) {
--      assign(stats);
--    };
--
--    //! In-place version of the copy constructor.
--    CImgStats& assign(const CImgStats& stats) {
--      min = stats.min;
--      max = stats.max;
--      mean = stats.mean;
--      variance = stats.variance;
--      xmin = stats.xmin; ymin = stats.ymin; zmin = stats.zmin; vmin = stats.vmin; lmin = stats.lmin;
--      xmax = stats.xmax; ymax = stats.ymax; zmax = stats.zmax; vmax = stats.vmax; lmax = stats.lmax;
--      return *this;
--    }
--
--    //! Constructor that computes statistics of an input image \p img.
--    /**
--        \param img The input image.
--        \param compute_variance If true, the \c variance field is computed, else it is set to 0.
--    **/
--    template<typename T> CImgStats(const CImg<T>& img, const bool compute_variance=true) {
--      assign(img,compute_variance);
--    }
--
--    //! In-place version of the previous constructor.
--    template<typename T> CImgStats& assign(const CImg<T>& img, const bool compute_variance=true) {
--      if (img.is_empty())
--        throw CImgArgumentException("CImgStats::CImgStats() : Specified input image (%u,%u,%u,%u,%p) is empty.",
--                                    img.width,img.height,img.depth,img.dim,img.data);
--      mean = variance = 0;
--      lmin = lmax = -1;
--      T pmin=img[0], pmax=pmin, *ptrmin=img.data, *ptrmax=ptrmin;
--      cimg_for(img,ptr,T) {
--        const T& a=*ptr;
--        mean+=(double)a;
--        if (a<pmin) { pmin=a; ptrmin = ptr; }
--        if (a>pmax) { pmax=a; ptrmax = ptr; }
--      }
--      mean/=img.size();
--      min=(double)pmin;
--      max=(double)pmax;
--      unsigned long offmin = (unsigned long)(ptrmin-img.data), offmax = (unsigned long)(ptrmax-img.data);
--      const unsigned long whz = img.width*img.height*img.depth, wh = img.width*img.height;
--      vmin = offmin/whz; offmin%=whz; zmin = offmin/wh; offmin%=wh; ymin = offmin/img.width; xmin = offmin%img.width;
--      vmax = offmax/whz; offmax%=whz; zmax = offmax/wh; offmax%=wh; ymax = offmax/img.width; xmax = offmax%img.width;
--      if (compute_variance) {
--        cimg_for(img,ptr,T) { const double tmpf=(*ptr)-mean; variance+=tmpf*tmpf; }
--        const unsigned int siz = img.size();
--        if (siz>1) variance/=(siz-1); else variance=0;
--      }
--      return *this;
--    }
--
--    //! Constructor that computes statistics of an input image list \p list.
--    /**
--       \param list The input list of images.
--       \param compute_variance If true, the \c variance field is computed, else it is set to 0.
--    **/
--    template<typename T> CImgStats(const CImgList<T>& list, const bool compute_variance=true) {
--      assign(list,compute_variance);
--    }
--
--    //! In-place version of the previous constructor.
--    template<typename T> CImgStats& assign(const CImgList<T>& list,const bool compute_variance=true) {
--      if (list.is_empty())
--        throw CImgArgumentException("CImgStats::CImgStats() : Specified input list (%u,%p) is empty.",
--                                    list.size,list.data);
--      mean = variance = lmin = lmax = 0;
--      T pmin = list[0][0], pmax = pmin, *ptrmin = list[0].data, *ptrmax = ptrmin;
--      int psize = 0;
--      cimglist_for(list,l) {
--        cimg_for(list[l],ptr,T) {
--          const T& a=*ptr;
--          mean+=(double)a;
--          if (a<pmin) { pmin=a; ptrmin = ptr; lmin = l; }
--          if (a>pmax) { pmax=a; ptrmax = ptr; lmax = l; }
--        }
--        psize+=list[l].size();
--      }
--      mean/=psize;
--      min=(double)pmin;
--      max=(double)pmax;
--      const CImg<T> &imin = list[lmin], &imax = list[lmax];
--      unsigned long offmin = (ptrmin-imin.data), offmax = (ptrmax-imax.data);
--      const unsigned long whz1 = imin.width*imin.height*imin.depth, wh1 = imin.width*imin.height;
--      vmin = offmin/whz1; offmin%=whz1; zmin = offmin/wh1; offmin%=wh1; ymin = offmin/imin.width; xmin = offmin%imin.width;
--      const unsigned long whz2 = imax.width*imax.height*imax.depth, wh2 = imax.width*imax.height;
--      vmax = offmax/whz2; offmax%=whz2; zmax = offmax/wh2; offmax%=wh2; ymax = offmax/imax.width; xmax = offmax%imax.width;
--      if (compute_variance) {
--        cimglist_for(list,l) cimg_for(list[l],ptr,T) { const double tmpf=(*ptr)-mean; variance+=tmpf*tmpf; }
--        if (psize>1) variance/=(psize-1); else variance=0;
--      }
--      return *this;
--    }
--
--    //! Assignement operator.
--    CImgStats& operator=(const CImgStats& stats) {
--      return assign(stats);
--    }
--
--    //! Return true if the current instance contains valid statistics
--    bool is_empty() const {
--      return (xmin>=0 && ymin>=0 && zmin>=0 && vmin>=0 && xmax>=0 && ymax>=0 && zmax>=0 && vmax>=0);
--    }
--
--    //! Print the current statistics.
--    /**
--       Printing is done on the standart error output.
--    **/
--    const CImgStats& print(const char* title=0) const {
--      if (lmin>=0 && lmax>=0)
--        std::fprintf(stderr,"%-8s(this=%p) : { min=%g, mean=%g [var=%g], max=%g, "
--                     "pmin=[%d](%d,%d,%d,%d), pmax=[%d](%d,%d,%d,%d) }\n",
--                     title?title:"CImgStats",(void*)this,min,mean,variance,max,
--                     lmin,xmin,ymin,zmin,vmin,lmax,xmax,ymax,zmax,vmax);
--      else
--        std::fprintf(stderr,"%-8s(this=%p) : { min=%g, mean=%g [var=%g], max=%g, "
--                     "pmin=(%d,%d,%d,%d), pmax=(%d,%d,%d,%d) }\n",
--                     title?title:"CImgStats",(void*)this,min,mean,variance,max,
--                     xmin,ymin,zmin,vmin,xmax,ymax,zmax,vmax);
--      return *this;
--    }
--
--  };
--
--  /*
--   #-------------------------------------------
--   #
--   #
--   #
--   # Definition of the CImgDisplay structure
--   #
--   #
--   #
--   #-------------------------------------------
--   */
--
--  //! This class represents a window which can display \ref CImg images and handles mouse and keyboard events.
--  /**
--     Creating a \c CImgDisplay instance opens a window that can be used to display a \c CImg<T> image
--     of a \c CImgList<T> image list inside. When a display is created, associated window events
--     (such as mouse motion, keyboard and window size changes) are handled and can be easily
--     detected by testing specific \c CImgDisplay data fields.
--     See \ref cimg_displays for a complete tutorial on using the \c CImgDisplay class.
--  **/
--
--  struct CImgDisplay {
--
--    //! Width of the display
--    unsigned int width;
--
--    //! Height of the display
--    unsigned int height;
--
--    //! Normalization type used for the display
--    unsigned int normalization;
--
--    //! Range of events detected by the display
--    unsigned int events;
--
--    //! Fullscreen state of the display
--    bool is_fullscreen;
--
--    //! Display title
--    char* title;
--
--    //! X-pos of the display on the screen
--    volatile int window_x;
--
--    //! Y-pos of the display on the screen
--    volatile int window_y;
--
--    //! Width of the underlying window
--    volatile unsigned int window_width;
--
--    //! Height of the underlying window
--    volatile unsigned int window_height;
--
--    //! X-coordinate of the mouse pointer on the display
--    volatile int mouse_x;
--
--    //! Y-coordinate of the mouse pointer on the display
--    volatile int mouse_y;
--
--    //! Button state of the mouse
--    volatile unsigned int buttons[256];
--    volatile unsigned int& button;
--
--    //! Wheel state of the mouse
--    volatile int wheel;
--
--    //! Key value if pressed
--    volatile unsigned int& key;
--    volatile unsigned int keys[256];
--
--    //! Key value if released
--    volatile unsigned int& released_key;
--    volatile unsigned int released_keys[256];
--
--    //! Closed state of the window
--    volatile bool is_closed;
--
--    //! Resized state of the window
--    volatile bool is_resized;
--
--    //! Moved state of the window
--    volatile bool is_moved;
--
--    //! Event state of the window
--    volatile bool is_event;
--
--    float fps_fps, min, max;
--    unsigned long timer, fps_frames, fps_timer;
--
--#ifdef cimgdisplay_plugin
--#include cimgdisplay_plugin
--#endif
--
--    //! Create a display window with a specified size \p pwidth x \p height.
--    /** \param dimw       : Width of the display window.
--        \param dimh       : Height of the display window.
--        \param title      : Title of the display window.
--        \param normalization_type  : Normalization type of the display window (see CImgDisplay::normalize).
--        \param events_type : Type of events handled by the display window.
--        \param fullscreen_flag : Fullscreen mode.
--        \param closed_flag : Initially visible mode.
--        A black image will be initially displayed in the display window.
--    **/
--    CImgDisplay(const unsigned int dimw, const unsigned int dimh, const char *title=0,
--                const unsigned int normalization_type=3, const unsigned int events_type=3,
--                const bool fullscreen_flag=false, const bool closed_flag=false):
--      width(0),height(0),normalization(0),events(0),is_fullscreen(false),title(0),
--      window_x(0),window_y(0),window_width(0),window_height(0),
--      mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
--      is_closed(true),is_resized(false),is_moved(false),is_event(false),
--      min(0),max(0) {
--      assign(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--    }
--
--    //! Create a display window from an image.
--    /** \param img : Image that will be used to create the display window.
--        \param title : Title of the display window
--        \param normalization_type : Normalization type of the display window.
--        \param events_type : Type of events handled by the display window.
--        \param fullscreen_flag : Fullscreen mode.
--        \param closed_flag : Initially visible mode.
--    **/
--    template<typename T>
--    CImgDisplay(const CImg<T>& img, const char *title=0,
--                const unsigned int normalization_type=3, const unsigned int events_type=3,
--                const bool fullscreen_flag=false, const bool closed_flag=false):
--      width(0),height(0),normalization(0),events(0),is_fullscreen(false),title(0),
--      window_x(0),window_y(0),window_width(0),window_height(0),
--      mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
--      is_closed(true),is_resized(false),is_moved(false),is_event(false),min(0),max(0) {
--      assign(img,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--    }
--
--    //! Create a display window from an image list.
--    /** \param list : The list of images to display.
--        \param title : Title of the display window
--        \param normalization_type : Normalization type of the display window.
--        \param events_type : Type of events handled by the display window.
--        \param fullscreen_flag : Fullscreen mode.
--        \param closed_flag : Initially visible mode.
--    **/
--    template<typename T>
--    CImgDisplay(const CImgList<T>& list,const char *title=0,
--                const unsigned int normalization_type=3,const unsigned int events_type=3,
--                const bool fullscreen_flag=false,const bool closed_flag=false):
--      width(0),height(0),normalization(0),events(0),is_fullscreen(false),title(0),
--      window_x(0),window_y(0),window_width(0),window_height(0),
--      mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
--      is_closed(true),is_resized(false),is_moved(false),is_event(false),min(0),max(0) {
--      assign(list,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--    }
--
--    //! Create a display window by copying another one.
--    /** \param win   : Display window to copy.
--        \param title : Title of the new display window.
--    **/
--    CImgDisplay(const CImgDisplay& disp):
--      width(0),height(0),normalization(0),events(0),is_fullscreen(false),title(0),
--      window_x(0),window_y(0),window_width(0),window_height(0),
--      mouse_x(0),mouse_y(0),button(*buttons),wheel(0),key(*keys),released_key(*released_keys),
--      is_closed(true),is_resized(false),is_moved(false),is_event(false),min(0),max(0) {
--      assign(disp);
--    }
--
--    //! Destructor
--    ~CImgDisplay() {
--      _assign();
--    }
--
--    //! Assignement operator
--    CImgDisplay& operator=(const CImgDisplay& disp) {
--      return assign(disp);
--    }
--
--    //! Return display width
--    int dimx() const {
--      return (int)width;
--    }
--
--    //! Return display height
--    int dimy() const {
--      return (int)height;
--    }
--
--    //! Return display window width
--    int window_dimx() const {
--      return (int)window_width;
--    }
--
--    //! Return display window height
--    int window_dimy() const {
--      return (int)window_height;
--    }
--
--    //! Return X-coordinate of the window
--    int window_posx() const {
--      return window_x;
--    }
--
--    //! Return Y-coordinate of the window
--    int window_posy() const {
--      return window_y;
--    }
--
--    //! Synchronized waiting function. Same as cimg::wait().
--    /** \see cimg::wait()
--     **/
--    CImgDisplay& wait(const unsigned int milliseconds) {
--      cimg::wait(milliseconds, timer);
--      return *this;
--    }
--
--    //! Wait for an event occuring on the current display
--    CImgDisplay& wait() {
--      wait(*this);
--      return *this;
--    }
--
--    //! Wait for any event occuring on the display \c disp1
--    static void wait(CImgDisplay& disp1) {
--      disp1.is_event = 0;
--      while (!disp1.is_event) wait_all();
--    }
--
--    //! Wait for any event occuring either on the display \c disp1 or \c disp2
--    static void wait(CImgDisplay& disp1, CImgDisplay& disp2) {
--      disp1.is_event = disp2.is_event = 0;
--      while (!disp1.is_event && !disp2.is_event) wait_all();
--    }
--
--    //! Wait for any event occuring either on the display \c disp1, \c disp2 or \c disp3
--    static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3) {
--      disp1.is_event = disp2.is_event = disp3.is_event = 0;
--      while (!disp1.is_event && !disp2.is_event && !disp3.is_event) wait_all();
--    }
--
--    //! Wait for any event occuring either on the display \c disp1, \c disp2, \c disp3 or \c disp4
--    static void wait(CImgDisplay& disp1, CImgDisplay& disp2, CImgDisplay& disp3, CImgDisplay& disp4) {
--      disp1.is_event = disp2.is_event = disp3.is_event = disp4.is_event = 0;
--      while (!disp1.is_event && !disp2.is_event && !disp3.is_event && !disp4.is_event) wait_all();
--    }
--
--    //! Return the frame per second rate
--    float frames_per_second() {
--      if (!fps_timer) fps_timer = cimg::time();
--      const float delta = (cimg::time()-fps_timer)/1000.0f;
--      fps_frames++;
--      if (delta>=1.0f) {
--        fps_fps = fps_frames/delta;
--        fps_frames = 0;
--        fps_timer = cimg::time();
--      }
--      return fps_fps;
--    }
--
--    //! Display an image list CImgList<T> into a display window.
--    /** First, all images of the list are appended into a single image used for visualization,
--        then this image is displayed in the current display window.
--        \param list     : The list of images to display.
--        \param axe      : The axe used to append the image for visualization. Can be 'x' (default),'y','z' or 'v'.
--        \param align : Defines the relative alignment of images when displaying images of different sizes.
--        Can be '\p c' (centered, which is the default), '\p p' (top alignment) and '\p n' (bottom aligment).
--
--        \see CImg::get_append()
--    **/
--    template<typename T> CImgDisplay& display(const CImgList<T>& list,const char axe='x',const char align='c') {
--      return display(list.get_append(axe,align));
--    }
--
--    //! Display an image CImg<T> into a display window.
--    template<typename T> CImgDisplay& operator<<(const CImg<T>& img) {
--      return display(img);
--    }
--
--    //! Display an image CImg<T> into a display window.
--    template<typename T> CImgDisplay& operator<<(const CImgList<T>& list) {
--      return display(list);
--    }
--
--    //! Resize a display window with the size of an image.
--    /** \param img    : Input image. \p image.width and \p image.height give the new dimensions of the display window.
--        \param redraw : If \p true (default), the current displayed image in the display window will
--        be bloc-interpolated to fit the new dimensions. If \p false, a black image will be drawn in the resized window.
--        \see CImgDisplay::is_resized, CImgDisplay::resizedimx(), CImgDisplay::resizedimy()
--    **/
--    template<typename T> CImgDisplay& resize(const CImg<T>& img, const bool redraw=true) {
--      return resize(img.width,img.height,redraw);
--    }
--
--    //! Resize a display window using the size of the given display \p disp
--    CImgDisplay& resize(const CImgDisplay& disp, const bool redraw=true) {
--      return resize(disp.width,disp.height,redraw);
--    }
--
--    //! Resize a display window in its current size.
--    CImgDisplay& resize(const bool redraw=true) {
--      resize(window_width,window_height,redraw);
--      return *this;
--    }
--
--    //! Display a 3d object
--    template<typename tp, typename tf, typename T, typename to>
--    CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
--                                  const CImgList<T>& colors, const to& opacities,
--                                  const bool centering=true,
--                                  const int render_static=4, const int render_motion=1,
--                                  const bool double_sided=false,
--                                  const float focale=500.0f, const float ambiant_light=0.05f,
--                                  const bool display_axes = true, float *const pose_matrix=0) {
--      CImg<T>(width,height,1,3,0).display_object3d(points,primitives,colors,opacities,*this,
--                                                   centering,render_static,render_motion,
--                                                   double_sided,focale,ambiant_light,display_axes,pose_matrix);
--      return *this;
--    }
--
--    //! Display a 3D object.
--    template<typename tp, typename tf, typename T>
--    CImgDisplay& display_object3d(const tp& points, const CImgList<tf>& primitives,
--                                  const CImgList<T>& colors,
--                                  const bool centering=true,
--                                  const int render_static=4, const int render_motion=1,
--                                  const bool double_sided=false,
--                                  const float focale=500.0f, const float ambiant_light=0.05f,
--                                  const float opacity=1.0f, const bool display_axes = true, float *const pose_matrix=0) {
--      typedef typename cimg::largest<tp,float>::type to;
--      CImg<T>(width,height,1,3,0).display_object3d(points,primitives,colors,
--                                                   CImg<to>(primitives.size)=(to)opacity,*this,
--                                                   centering,render_static,render_motion,
--                                                   double_sided,focale,ambiant_light,display_axes,pose_matrix);
--      return *this;
--    }
--
--    //! Toggle fullscreen mode
--    CImgDisplay& toggle_fullscreen() {
--      return assign(width,height,title,normalization,events,!is_fullscreen,is_closed);
--    }
--
--    // Inner routine used for fast resizing of buffer to display size.
--    template<typename t, typename T> static void _render_resize(const T *ptrs, const unsigned int ws, const unsigned int hs,
--                                                                t *ptrd, const unsigned int wd, const unsigned int hd) {
--      unsigned int *const offx = new unsigned int[wd], *const offy = new unsigned int[hd+1], *poffx, *poffy;
--      float s, curr, old;
--      s = (float)ws/wd;
--      poffx = offx; curr=0; for (unsigned int x=0; x<wd; x++) { old=curr; curr+=s; *(poffx++) = (unsigned int)curr-(unsigned int)old; }
--      s = (float)hs/hd;
--      poffy = offy; curr=0; for (unsigned int y=0; y<hd; y++) { old=curr; curr+=s; *(poffy++) = ws*((unsigned int)curr-(unsigned int)old); }
--      *poffy=0;
--      poffy = offy;
--      {for (unsigned int y=0; y<hd; ) {
--        const T *ptr = ptrs;
--        poffx = offx;
--        for (unsigned int x=0; x<wd; x++) { *(ptrd++)=*ptr; ptr+=*(poffx++); }
--        y++;
--        unsigned int dy=*(poffy++);
--        for (;!dy && y<hd; std::memcpy(ptrd, ptrd-wd, sizeof(t)*wd), y++, ptrd+=wd, dy=*(poffy++));
--        ptrs+=dy;
--      }}
--      delete[] offx; delete[] offy;
--    }
--
--    //! Test if a specific key is pressed
--    bool is_pressed(const unsigned int key1) const {
--      bool pressed = false;
--      for (unsigned int i=0; i<256; ++i) {
--        if (released_keys[i]==key1) { pressed = false; break; }
--        if (keys[i]==key1) { pressed = true; break; }
--      }
--      return pressed;
--    }
--
--    //! Test if a key sequence has been typed
--    bool is_typed(const unsigned int *const keyseq, const unsigned int N, const bool remove=true) {
--      if (keyseq && N) {
--        const unsigned int *const ps_end = keyseq+N-1, k = *ps_end, *const pk_end = (unsigned int*)keys+257-N;
--        for (unsigned int *pk = (unsigned int*)keys; pk<pk_end; ) {
--          if (*(pk++)==k) {
--            bool res = true;
--            const unsigned int *ps = ps_end, *pk2 = pk;
--            for (unsigned int i=1; i<N; ++i) res = (*(--ps)==*(pk2++));
--            if (res) {
--              if (remove) std::memset((void*)(pk-1),0,sizeof(unsigned int)*N);
--              return true;
--            }
--          }
--        }
--      }
--      return false;
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const bool remove=true) {
--      return is_typed(&key1,1,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const bool remove=true) {
--      const unsigned int seq[2] = { key1, key2 };
--      return is_typed(seq,2,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3, const bool remove=true) {
--      const unsigned int seq[3] = { key1, key2, key3 };
--      return is_typed(seq,3,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const bool remove=true) {
--      const unsigned int seq[4] = { key1, key2, key3, key4 };
--      return is_typed(seq,4,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const unsigned int key5, const bool remove=true) {
--      const unsigned int seq[5] = { key1, key2, key3, key4,key5 };
--      return is_typed(seq,5,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const unsigned int key5, const unsigned int key6, const bool remove=true) {
--      const unsigned int seq[6] = { key1, key2, key3, key4,key5,key6 };
--      return is_typed(seq,6,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const unsigned int key5, const unsigned int key6,
--                  const unsigned int key7, const bool remove=true) {
--      const unsigned int seq[7] = { key1, key2, key3, key4,key5,key6,key7 };
--      return is_typed(seq,7,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const unsigned int key5, const unsigned int key6,
--                  const unsigned int key7, const unsigned int key8, const bool remove=true) {
--      const unsigned int seq[8] = { key1, key2, key3, key4,key5,key6,key7,key8 };
--      return is_typed(seq,8,remove);
--    }
--
--    //! Test if a key combination has been typed
--    bool is_typed(const unsigned int key1, const unsigned int key2, const unsigned int key3,
--                  const unsigned int key4, const unsigned int key5, const unsigned int key6,
--                  const unsigned int key7, const unsigned int key8, const unsigned int key9, const bool remove=true) {
--      const unsigned int seq[9] = { key1, key2, key3, key4,key5,key6,key7,key8,key9 };
--      return is_typed(seq,9,remove);
--    }
--
--    // When no display available
--    //---------------------------
--#if cimg_display_type==0
--
--    //! Return the width of the screen resolution.
--    static int screen_dimx() {
--      return 0;
--    }
--
--    //! Return the height of the screen resolution.
--    static int screen_dimy() {
--      return 0;
--    }
--
--    //! In-place version of the previous constructor
--    CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
--                        const unsigned int normalization_type=3, const unsigned int events_type=3,
--                        const bool fullscreen_flag=false, const bool closed_flag=false) {
--      throw CImgDisplayException("CImgDisplay() : Display has been required but is not available (cimg_display_type=0)");
--      fps_timer = 0*(unsigned long)(dimw + dimh + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
--      return *this;
--    }
--
--    //! In-place version of the previous constructor
--    template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      fps_timer = 0*(unsigned long)(img.width + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
--      return assign(0,0);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      fps_timer = 0*(unsigned long)(list.size + title + normalization_type + events_type + (int)fullscreen_flag + (int)closed_flag);
--      return assign(0,0);
--    }
--
--    //! In-place version of the previous constructor
--    CImgDisplay& assign(const CImgDisplay &disp) {
--      return assign(disp.width,disp.height);
--    }
--
--    // In-place version of the destructor (should not be used by the user).
--    CImgDisplay& _assign() {
--      return *this;
--    }
--
--    //! Display an image in a window.
--    template<typename T> CImgDisplay& display(const CImg<T>& img) {
--      fps_timer = 0*img.width;
--      return *this;
--    }
--
--    //! Resize window
--    CImgDisplay& resize(const int width, const int height, const bool redraw=true) {
--      fps_timer = 0*width*height*(int)redraw;
--      return *this;
--    }
--
--    //! Move window
--    CImgDisplay& move(const int posx, const int posy) {
--      fps_timer = 0*posx*posy;
--      return *this;
--    }
--
--    //! Move mouse pointer to a specific location
--    CImgDisplay& set_mouse(const int posx, const int posy) {
--      fps_timer = 0*posx*posy;
--      return *this;
--    }
--
--    //! Hide mouse pointer
--    CImgDisplay& hide_mouse() {
--      return *this;
--    }
--
--    //! Show mouse pointer
--    CImgDisplay& show_mouse() {
--      return *this;
--    }
--
--    //! Wait for a window event in any CImg window
--    static void wait_all() {}
--
--    //! Show a closed display
--    CImgDisplay& show() {
--      return *this;
--    }
--
--    //! Close a visible display
--    CImgDisplay& close() {
--      return *this;
--    }
--
--    //! Set the window title
--    CImgDisplay& set_title(const char *format,...) {
--      fps_timer = 0*(unsigned long)format;
--      return *this;
--    }
--
--    //! Re-paint image content in window
--    CImgDisplay& paint() {
--      return *this;
--    }
--
--    //! Render image buffer into GDI native image format
--    template<typename T> CImgDisplay& render(const CImg<T>& img) {
--      fps_timer = 0*img.width;
--      return *this;
--    }
--
--    // X11-based display
--    //-------------------
--#elif cimg_display_type==1
--    void *data;
--    Window window;
--    Window background_window;
--    XImage *image;
--    Colormap colormap;
--    Atom wm_delete_window, wm_delete_protocol;
--#ifdef cimg_use_xshm
--    XShmSegmentInfo *shminfo;
--#endif
--
--    static int screen_dimx() {
--      int res = 0;
--      if (!cimg::X11attr().display) {
--        Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
--        if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimx() : Can't open X11 display");
--        res = DisplayWidth(disp,DefaultScreen(disp));
--        XCloseDisplay(disp);
--      } else {
--#ifdef cimg_use_xrandr
--        if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
--          res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width;
--        else
--#endif
--          res = DisplayWidth(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
--      }
--      return res;
--    }
--
--    static int screen_dimy() {
--      int res = 0;
--      if (!cimg::X11attr().display) {
--        Display *disp = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
--        if (!disp) throw CImgDisplayException("CImgDisplay::screen_dimy() : Can't open X11 display");
--        res = DisplayHeight(disp,DefaultScreen(disp));
--        XCloseDisplay(disp);
--      } else {
--#ifdef cimg_use_xrandr
--        if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution)
--          res = cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height; else
--#endif
--            res = DisplayHeight(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
--      }
--      return res;
--    }
--
--    CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
--                        const unsigned int normalization_type=3, const unsigned int events_type=3,
--                        const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (!dimw || !dimh)
--        throw CImgArgumentException("CImgDisplay::assign() : Specified window size (%u,%u) is not valid.",dimw,dimh);
--      assign_lowlevel(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      min = max = 0;
--      std::memset(data,0,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
--                          (cimg::X11attr().nb_bits==16?sizeof(unsigned short):sizeof(unsigned int)))*width*height);
--      return paint();
--    }
--
--    template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (img.is_empty())
--        throw CImgArgumentException("CImgDisplay::CImgDisplay() : Specified input image (%u,%u,%u,%u,%p) is empty.",
--                                    img.width,img.height,img.depth,img.dim,img.data);
--      CImg<T> tmp;
--      const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--      assign_lowlevel(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      if (normalization==2) { const CImgStats st(nimg,false); min = (float)st.min; max = (float)st.max; }
--      return render(nimg).paint();
--    }
--
--    template<typename T> CImgDisplay& assign(const CImgList<T>& list, const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (list.is_empty())
--        throw CImgArgumentException("CImgDisplay::CImgDisplay() : Specified input list (%u,%p) is empty.",
--                                    list.size,list.data);
--      CImg<T> tmp;
--      const CImg<T> img = list.get_append('x'),
--        &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--      assign_lowlevel(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      if (normalization==2) { const CImgStats st(nimg,false); min = (float)st.min; max = (float)st.max; }
--      return render(nimg).paint();
--    }
--
--    CImgDisplay& assign(const CImgDisplay& win) {
--      assign_lowlevel(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
--      std::memcpy(data,win.data,(cimg::X11attr().nb_bits==8?sizeof(unsigned char):
--                                 cimg::X11attr().nb_bits==16?sizeof(unsigned short):
--                                 sizeof(unsigned int))*width*height);
--      return paint();
--    }
--
--    CImgDisplay& _assign() {
--      if (width && height) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--
--        // Remove display window from event thread list
--        unsigned int i;
--        for (i=0; i<cimg::X11attr().nb_wins && cimg::X11attr().wins[i]!=this; i++);
--        for (; i<cimg::X11attr().nb_wins-1; i++) cimg::X11attr().wins[i]=cimg::X11attr().wins[i+1];
--        cimg::X11attr().nb_wins--;
--
--        // Destroy window, image, colormap and title
--        if (is_fullscreen) _desinit_fullscreen();
--        XDestroyWindow(cimg::X11attr().display,window);
--        window = 0;
--#ifdef cimg_use_xshm
--        if (shminfo) {
--          XShmDetach(cimg::X11attr().display, shminfo);
--          XDestroyImage(image);
--          shmdt(shminfo->shmaddr);
--          shmctl(shminfo->shmid,IPC_RMID,0);
--          delete shminfo;
--          shminfo = 0;
--        } else
--#endif
--          XDestroyImage(image);
--        data = 0;
--        image = 0;
--        if (cimg::X11attr().nb_bits==8) XFreeColormap(cimg::X11attr().display,colormap);
--        colormap = 0;
--        XSync(cimg::X11attr().display, False);
--
--        // Reset display variables
--        if (title) delete[] title;
--        width = height = normalization = events = 0;
--        is_fullscreen = is_resized = is_moved = is_event = false;
--        is_closed = true;
--        title = 0;
--        window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
--        std::memset((void*)buttons,0,256*sizeof(unsigned int));
--        std::memset((void*)keys,0,256*sizeof(unsigned int));
--        std::memset((void*)released_keys,0,256*sizeof(unsigned int));
--        min = max = 0;
--
--        // End event thread and close display if necessary
--        if (!cimg::X11attr().nb_wins) {
--
--          // Kill event thread
--          pthread_cancel(*cimg::X11attr().event_thread);
--          pthread_mutex_unlock(cimg::X11attr().mutex);
--          pthread_join(*cimg::X11attr().event_thread,0);
--          delete cimg::X11attr().event_thread;
--          cimg::X11attr().event_thread = 0;
--          pthread_mutex_destroy(cimg::X11attr().mutex);
--          delete cimg::X11attr().mutex;
--          cimg::X11attr().mutex = 0;
--          XSync(cimg::X11attr().display, False);
--          XCloseDisplay(cimg::X11attr().display);
--          cimg::X11attr().display=0;
--          delete cimg::X11attr().gc;
--          cimg::X11attr().gc = 0;
--        } else pthread_mutex_unlock(cimg::X11attr().mutex);
--      }
--      return *this;
--    }
--
--    template<typename T> CImgDisplay& display(const CImg<T>& img) {
--      return render(img).paint(false);
--    }
--
--    CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
--      if (!(nwidth && nheight))
--        throw CImgArgumentException("CImgDisplay::resize() : Specified window size (%d,%d) is not valid.",
--                                    nwidth,nheight);
--      const unsigned int
--        tmpdimx=(nwidth>0)?nwidth:(-nwidth*width/100),
--        tmpdimy=(nheight>0)?nheight:(-nheight*height/100),
--        dimx = tmpdimx?tmpdimx:1,
--        dimy = tmpdimy?tmpdimy:1;
--      const bool
--        is_disp_different = (width!=dimx || height!=dimy),
--        is_win_different = (window_width!=dimx || window_height!=dimy);
--      if (is_disp_different || is_win_different) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        XResizeWindow(cimg::X11attr().display,window,dimx,dimy);
--        window_width = dimx;
--        window_height = dimy;
--        is_resized = false;
--        if (is_disp_different) {
--          switch (cimg::X11attr().nb_bits) {
--          case 8:  { unsigned char foo=0; _resize(foo,dimx,dimy,redraw);  } break;
--          case 16: { unsigned short foo=0; _resize(foo,dimx,dimy,redraw); } break;
--          default: { unsigned int foo=0; _resize(foo,dimx,dimy,redraw);   } break;
--          }
--          width = dimx;
--          height = dimy;
--        }
--        pthread_mutex_unlock(cimg::X11attr().mutex);
--        if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
--        if (redraw) return paint();
--      }
--      return *this;
--    }
--
--    CImgDisplay& move(const int posx, const int posy) {
--      show();
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      XMoveWindow(cimg::X11attr().display,window,posx,posy);
--      is_moved = false;
--      window_x = posx;
--      window_y = posy;
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return paint();
--    }
--
--    CImgDisplay& set_mouse(const int posx, const int posy) {
--      if (!is_closed && posx>=0 && posy>=0) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        XWarpPointer(cimg::X11attr().display,None,window,0,0,0,0,posx,posy);
--        is_moved = false;
--        mouse_x = posx;
--        mouse_y = posy;
--        XSync(cimg::X11attr().display, False);
--        pthread_mutex_unlock(cimg::X11attr().mutex);
--      }
--      return *this;
--    }
--
--    CImgDisplay& hide_mouse() {
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      const char pix_data[8] = { 0 };
--      XColor col;
--      col.red = col.green = col.blue = 0;
--      Pixmap pix = XCreateBitmapFromData(cimg::X11attr().display,window,pix_data,8,8);
--      Cursor cur = XCreatePixmapCursor(cimg::X11attr().display,pix,pix,&col,&col,0,0);
--      XFreePixmap(cimg::X11attr().display,pix);
--      XDefineCursor(cimg::X11attr().display,window,cur);
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return *this;
--    }
--
--    CImgDisplay& show_mouse() {
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      XDefineCursor(cimg::X11attr().display,window,None);
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return *this;
--    }
--
--    static void wait_all() {
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      bool flag = true;
--      XEvent event;
--      while (flag) {
--        for (unsigned int i=0; i<cimg::X11attr().nb_wins; i++) {
--          cimg::X11attr().wins[i]->is_event = false;
--          const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
--          const unsigned int emask =
--            ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
--            ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
--            ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
--          XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
--        }
--        XNextEvent(cimg::X11attr().display, &event);
--        for (unsigned int i=0; i<cimg::X11attr().nb_wins; i++)
--          if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window) {
--            cimg::X11attr().wins[i]->_handle_events(&event);
--            if (cimg::X11attr().wins[i]->is_event) flag = false;
--          }
--      }
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--    }
--
--    CImgDisplay& show() {
--      if (is_closed) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        if (is_fullscreen) _init_fullscreen();
--        _map_window();
--        is_closed = false;
--        pthread_mutex_unlock(cimg::X11attr().mutex);
--      }
--      return paint();
--    }
--
--    CImgDisplay& close() {
--      if (!is_closed) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        if (is_fullscreen) _desinit_fullscreen();
--        XUnmapWindow(cimg::X11attr().display,window);
--        window_x = window_y = -1;
--        is_closed = true;
--        pthread_mutex_unlock(cimg::X11attr().mutex);
--      }
--      return *this;
--    }
--
--    CImgDisplay& set_title(const char *format,...) {
--      char tmp[1024]={0};
--      va_list ap;
--      va_start(ap, format);
--      std::vsprintf(tmp,format,ap);
--      va_end(ap);
--      if (title) delete[] title;
--      const int s = cimg::strlen(tmp)+1;
--      title = new char[s];
--      std::memcpy(title,tmp,s*sizeof(char));
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      XStoreName(cimg::X11attr().display,window,tmp);
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return *this;
--    }
--
--    CImgDisplay& paint(const bool wait_expose=true) {
--      pthread_mutex_lock(cimg::X11attr().mutex);
--      _paint(wait_expose);
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return *this;
--    }
--
--    template<typename T> CImgDisplay& render(const CImg<T>& img, const bool flag8=false) {
--      if (img.is_empty())
--        throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
--                                    img.width,img.height,img.depth,img.dim,img.data);
--      if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--      if (cimg::X11attr().nb_bits==8 && (img.width!=width || img.height!=height)) return render(img.get_resize(width,height,1,-100,1));
--      if (cimg::X11attr().nb_bits==8 && !flag8 && img.dim==3) return render(img.get_RGBtoLUT(true),true);
--
--      const unsigned int xymax = img.width*img.height;
--      const T
--        *data1 = img.ptr(),
--        *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
--        *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
--      if (cimg::X11attr().blue_first) cimg::swap(data1,data3);
--      pthread_mutex_lock(cimg::X11attr().mutex);
--
--      if (!normalization || (normalization==3 && cimg::type<T>::id()==cimg::type<unsigned char>::id())) {
--      min = max = 0;
--        switch (cimg::X11attr().nb_bits) {
--        case 8: {
--          _set_colormap(colormap,img.dim);
--          unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          switch (img.dim) {
--          case 1: for (unsigned int xy=0; xy<xymax; xy++) (*ptrd++) = (unsigned char)*(data1++);
--            break;
--          case 2: for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++);
--            (*ptrd++) = (R&0xf0)|(G>>4);
--          } break;
--          default: for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char R = (unsigned char)*(data1++), G = (unsigned char)*(data2++), B = (unsigned char)*(data3++);
--            (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
--          } break;
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
--        } break;
--        case 16: {
--          unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          const unsigned int M = 248;
--          if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char G = (unsigned char)*(data2++)>>2;
--            *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3);
--            *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
--          } else for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char G = (unsigned char)*(data2++)>>2;
--            *(ptrd++) = (G<<5) | ((unsigned char)*(data3++)>>3);
--            *(ptrd++) = (unsigned char)*(data1++)&M | (G>>3);
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
--        } break;
--        default: {
--          unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; xy++) {
--            *(ptrd++) = 0;
--            *(ptrd++) = (unsigned char)*(data1++);
--            *(ptrd++) = (unsigned char)*(data2++);
--            *(ptrd++) = (unsigned char)*(data3++);
--          } else for (unsigned int xy=0; xy<xymax; xy++) {
--            *(ptrd++) = (unsigned char)*(data3++);
--            *(ptrd++) = (unsigned char)*(data2++);
--            *(ptrd++) = (unsigned char)*(data1++);
--            *(ptrd++) = 0;
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
--        } break;
--        };
--      } else {
--        if (normalization==3) {
--          if (cimg::type<T>::is_float()) { const CImgStats st(img,false); min = (float)st.min; max = (float)st.max; }
--          else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
--        } else if ((min>max) || normalization==1) { const CImgStats st(img,false); min = (float)st.min; max = (float)st.max; }
--        const float delta = max-min, mm = delta?delta:1.0f;
--        switch (cimg::X11attr().nb_bits) {
--        case 8: {
--          _set_colormap(colormap,img.dim);
--          unsigned char *const ndata = (img.width==width && img.height==height)?(unsigned char*)data:new unsigned char[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          switch (img.dim) {
--          case 1: for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char R = (unsigned char)(255*(*(data1++)-min)/mm);
--            *(ptrd++) = R;
--          } break;
--          case 2: for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char
--              R = (unsigned char)(255*(*(data1++)-min)/mm),
--              G = (unsigned char)(255*(*(data2++)-min)/mm);
--            (*ptrd++) = (R&0xf0) | (G>>4);
--          } break;
--          default:
--            for (unsigned int xy=0; xy<xymax; xy++) {
--              const unsigned char
--                R = (unsigned char)(255*(*(data1++)-min)/mm),
--                G = (unsigned char)(255*(*(data2++)-min)/mm),
--                B = (unsigned char)(255*(*(data3++)-min)/mm);
--              *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
--            } break;
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned char*)data,width,height); delete[] ndata; }
--        } break;
--        case 16: {
--          unsigned short *const ndata = (img.width==width && img.height==height)?(unsigned short*)data:new unsigned short[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          const unsigned int M = 248;
--          if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
--            *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3);
--            *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
--          } else for (unsigned int xy=0; xy<xymax; xy++) {
--            const unsigned char G = (unsigned char)(255*(*(data2++)-min)/mm)>>2;
--            *(ptrd++) = (G<<5) | ((unsigned char)(255*(*(data3++)-min)/mm)>>3);
--            *(ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm)&M | (G>>3);
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned short*)data,width,height); delete[] ndata; }
--        } break;
--        default: {
--          unsigned int *const ndata = (img.width==width && img.height==height)?(unsigned int*)data:new unsigned int[img.width*img.height];
--          unsigned char *ptrd = (unsigned char*)ndata;
--          if (cimg::X11attr().byte_order) for (unsigned int xy=0; xy<xymax; xy++) {
--            (*ptrd++) = 0;
--            (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
--            (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
--            (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
--          } else for (unsigned int xy=0; xy<xymax; xy++) {
--            (*ptrd++) = (unsigned char)(255*(*(data3++)-min)/mm);
--            (*ptrd++) = (unsigned char)(255*(*(data2++)-min)/mm);
--            (*ptrd++) = (unsigned char)(255*(*(data1++)-min)/mm);
--            (*ptrd++) = 0;
--          }
--          if (ndata!=data) { _render_resize(ndata,img.width,img.height,(unsigned int*)data,width,height); delete[] ndata; }
--        } break;
--        }
--      }
--
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--      return *this;
--    }
--
--    static int _assign_lowlevel_xshm(Display *dpy, XErrorEvent *error) {
--      dpy = 0; error = 0;
--      cimg::X11attr().shm_enabled = false;
--      return 0;
--    }
--
--    void assign_lowlevel(const unsigned int dimw, const unsigned int dimh, const char *ptitle=0,
--                         const unsigned int normalization_type=3, const unsigned int events_type=3,
--                         const bool fullscreen_flag=false, const bool closed_flag=false) {
--
--      // Allocate space for window title
--      const int s = cimg::strlen(ptitle)+1;
--      char *tmp_title = s?new char[s]:0;
--      if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
--
--      // Destroy previous display window if existing
--      if (width && height) _assign();
--
--      // Open X11 display if necessary.
--      if (!cimg::X11attr().display) {
--        cimg::X11attr().nb_wins = 0;
--        cimg::X11attr().mutex = new pthread_mutex_t;
--        pthread_mutex_init(cimg::X11attr().mutex,0);
--
--        cimg::X11attr().display = XOpenDisplay((std::getenv("DISPLAY") ? std::getenv("DISPLAY") : ":0.0"));
--        if (!cimg::X11attr().display)
--          throw CImgDisplayException("CImgDisplay::_create_window() : Can't open X11 display");
--        cimg::X11attr().nb_bits = DefaultDepth(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display));
--        if (cimg::X11attr().nb_bits!=8 && cimg::X11attr().nb_bits!=16 && cimg::X11attr().nb_bits!=24 && cimg::X11attr().nb_bits!=32)
--          throw CImgDisplayException("CImgDisplay::_create_window() : %u bits mode is not supported "
--                                     "(only 8, 16, 24 and 32 bits modes are supported)",cimg::X11attr().nb_bits);
--        cimg::X11attr().gc = new GC;
--        *cimg::X11attr().gc = DefaultGC(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
--        Visual *visual = DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display));
--        XVisualInfo vtemplate;
--        vtemplate.visualid = XVisualIDFromVisual(visual);
--        int nb_visuals;
--        XVisualInfo *vinfo = XGetVisualInfo(cimg::X11attr().display,VisualIDMask,&vtemplate,&nb_visuals);
--        if (vinfo && vinfo->red_mask<vinfo->blue_mask) cimg::X11attr().blue_first = true;
--        cimg::X11attr().byte_order = ImageByteOrder(cimg::X11attr().display);
--
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        cimg::X11attr().event_thread = new pthread_t;
--        pthread_create(cimg::X11attr().event_thread,0,_events_thread,0);
--      } else pthread_mutex_lock(cimg::X11attr().mutex);
--
--      // Set display variables
--      width = dimw;
--      height = dimh;
--      normalization = normalization_type%4;
--      events = events_type%4;
--      is_fullscreen = fullscreen_flag;
--      title = tmp_title;
--      window_x = window_y = wheel = 0;
--      mouse_x = mouse_y = -1;
--      std::memset((void*)buttons,0,256*sizeof(unsigned int));
--      std::memset((void*)keys,0,256*sizeof(unsigned int));
--      std::memset((void*)released_keys,0,256*sizeof(unsigned int));
--      is_resized = is_moved = is_event = false;
--      is_closed = closed_flag;
--      fps_timer = fps_frames = timer = 0;
--      fps_fps = 0;
--
--      // Create X11 window and palette (if 8bits display)
--      if (is_fullscreen) {
--        _init_fullscreen();
--        const unsigned int sx = screen_dimx(), sy = screen_dimy();
--        XSetWindowAttributes winattr;
--        winattr.override_redirect = True;
--        window = XCreateWindow(cimg::X11attr().display,
--                               RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                               (sx-width)/2,(sy-height)/2,
--                               width,height,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
--      } else
--        window = XCreateSimpleWindow(cimg::X11attr().display,
--                                     RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                                     0,0,width,height,2,0,0x0L);
--      XStoreName(cimg::X11attr().display,window,title?title:" ");
--      if (cimg::X11attr().nb_bits==8) {
--        colormap = XCreateColormap(cimg::X11attr().display,window,DefaultVisual(cimg::X11attr().display,
--                                                                                DefaultScreen(cimg::X11attr().display)),AllocAll);
--        _set_colormap(colormap,3);
--        XSetWindowColormap(cimg::X11attr().display,window,colormap);
--      }
--      window_width = width;
--      window_height = height;
--
--      // Create XImage
--      const unsigned int bufsize = width*height*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
--#ifdef cimg_use_xshm
--      shminfo = 0;
--      if (XShmQueryExtension(cimg::X11attr().display)) {
--        shminfo = new XShmSegmentInfo;
--        image = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                                cimg::X11attr().nb_bits,ZPixmap,0,shminfo,width,height);
--        if (!image) { delete shminfo; shminfo = 0; }
--        else {
--          shminfo->shmid = shmget(IPC_PRIVATE, bufsize, IPC_CREAT | 0777);
--          if (shminfo->shmid==-1) { XDestroyImage(image); delete shminfo; shminfo = 0; }
--          else {
--            shminfo->shmaddr = image->data = (char*)(data = shmat(shminfo->shmid,0,0));
--            if (shminfo->shmaddr==(char*)-1) { XDestroyImage(image); shmctl(shminfo->shmid,IPC_RMID,0); delete shminfo; shminfo = 0; }
--            shminfo->readOnly = False;
--            cimg::X11attr().shm_enabled = true;
--            XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_lowlevel_xshm);
--            XShmAttach(cimg::X11attr().display, shminfo);
--            XSync(cimg::X11attr().display, False);
--            XSetErrorHandler(oldXErrorHandler);
--            if (!cimg::X11attr().shm_enabled) {
--              XDestroyImage(image);
--              shmdt(shminfo->shmaddr);
--              shmctl(shminfo->shmid,IPC_RMID,0);
--              delete shminfo; shminfo = 0;
--            }
--          }
--        }
--      }
--      if (!shminfo)
--#endif
--        {
--          data = std::malloc(bufsize);
--          image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                               cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,width,height,8,0);
--        }
--
--      if (!is_closed) _map_window(); else { window_x = window_y = cimg::type<int>::min(); }
--
--      if (events) {
--        wm_delete_window = XInternAtom(cimg::X11attr().display, "WM_DELETE_WINDOW", False);
--        wm_delete_protocol = XInternAtom(cimg::X11attr().display, "WM_PROTOCOLS", False);
--        XSetWMProtocols(cimg::X11attr().display, window, &wm_delete_window, 1);
--        if (is_fullscreen) XGrabKeyboard(cimg::X11attr().display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
--      }
--      cimg::X11attr().wins[cimg::X11attr().nb_wins++]=this;
--      pthread_mutex_unlock(cimg::X11attr().mutex);
--    }
--
--    void _map_window() {
--      XWindowAttributes attr;
--      XEvent event;
--      XSelectInput(cimg::X11attr().display,window,ExposureMask | StructureNotifyMask);
--      bool exposed = false, mapped = false;
--      XMapRaised(cimg::X11attr().display,window);
--      XSync(cimg::X11attr().display,False);
--      do {
--        XWindowEvent(cimg::X11attr().display,window,StructureNotifyMask | ExposureMask,&event);
--        switch (event.type) {
--        case MapNotify: mapped = true; break;
--        case Expose: exposed = true; break;
--        default:  XSync(cimg::X11attr().display, False); cimg::sleep(10);
--        }
--      } while (!(exposed && mapped));
--      do {
--        XGetWindowAttributes(cimg::X11attr().display, window, &attr);
--        if (attr.map_state!=IsViewable) { XSync(cimg::X11attr().display,False); cimg::sleep(10); }
--      } while (attr.map_state != IsViewable);
--      window_x = attr.x;
--      window_y = attr.y;
--    }
--
--    void _set_colormap(Colormap& colormap, const unsigned int dim) {
--      XColor palette[256];
--      switch (dim) {
--      case 1:  // palette for greyscale images
--        for (unsigned int index=0; index<256; index++) {
--          palette[index].pixel = index;
--          palette[index].red = palette[index].green = palette[index].blue = index<<8;
--          palette[index].flags = DoRed | DoGreen | DoBlue;
--        }
--        break;
--      case 2: // palette for RG images
--        for (unsigned int index=0, r=8; r<256; r+=16)
--          for (unsigned int g=8; g<256; g+=16) {
--            palette[index].pixel = index;
--            palette[index].red   = palette[index].blue = r<<8;
--            palette[index].green = g<<8;
--            palette[index++].flags = DoRed | DoGreen | DoBlue;
--          }
--        break;
--      default: // palette for RGB images
--        for (unsigned int index=0, r=16; r<256; r+=32)
--          for (unsigned int g=16; g<256; g+=32)
--            for (unsigned int b=32; b<256; b+=64) {
--              palette[index].pixel = index;
--              palette[index].red   = r<<8;
--              palette[index].green = g<<8;
--              palette[index].blue  = b<<8;
--              palette[index++].flags = DoRed | DoGreen | DoBlue;
--            }
--        break;
--      }
--      XStoreColors(cimg::X11attr().display,colormap,palette,256);
--    }
--
--    void _paint(const bool wait_expose=true) {
--      if (!is_closed) {
--        if (wait_expose) {
--          static XEvent event;
--          event.xexpose.type = Expose;
--          event.xexpose.serial = 0;
--          event.xexpose.send_event = True;
--          event.xexpose.display = cimg::X11attr().display;
--          event.xexpose.window = window;
--          event.xexpose.x = 0;
--          event.xexpose.y = 0;
--          event.xexpose.width = (int)width;
--          event.xexpose.height = (int)height;
--          event.xexpose.count = 0;
--          XSendEvent(cimg::X11attr().display, window, False, 0, &event);
--        } else {
--#if cimg_use_xshm
--          if (shminfo) XShmPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height,False);
--          else
--#endif
--            XPutImage(cimg::X11attr().display,window,*cimg::X11attr().gc,image,0,0,0,0,width,height);
--          XSync(cimg::X11attr().display, False);
--        }
--      }
--    }
--
--    template<typename T> void _resize(T foo, const unsigned int ndimx, const unsigned int ndimy, const bool redraw) {
--      foo = 0;
--#ifdef cimg_use_xshm
--      if (shminfo) {
--        XShmSegmentInfo *nshminfo = new XShmSegmentInfo;
--        XImage *nimage = XShmCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                                         cimg::X11attr().nb_bits,ZPixmap,0,nshminfo,ndimx,ndimy);
--        nshminfo->shmid = shmget(IPC_PRIVATE, ndimx*ndimy*sizeof(T), IPC_CREAT | 0777);
--        nshminfo->shmaddr = nimage->data = (char*)shmat(nshminfo->shmid,0,0);
--        nshminfo->readOnly = False;
--        XShmAttach(cimg::X11attr().display, nshminfo);
--        XSync(cimg::X11attr().display, False);
--        T *const ndata = (T*)nimage->data;
--        if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
--        else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
--        XShmDetach(cimg::X11attr().display, shminfo);
--        XDestroyImage(image);
--        shmdt(shminfo->shmaddr);
--        shmctl(shminfo->shmid,IPC_RMID,0);
--        delete shminfo;
--        shminfo = nshminfo;
--        image = nimage;
--        data = (void*)ndata;
--      } else
--#endif
--        {
--          T *ndata = (T*)std::malloc(ndimx*ndimy*sizeof(T));
--          if (redraw) _render_resize((T*)data,width,height,ndata,ndimx,ndimy);
--          else std::memset(ndata,0,sizeof(T)*ndimx*ndimy);
--          data = (void*)ndata;
--          XDestroyImage(image);
--          image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                               cimg::X11attr().nb_bits,ZPixmap,0,(char*)data,ndimx,ndimy,8,0);
--        }
--    }
--
--    void _init_fullscreen() {
--      background_window = 0;
--      if (is_fullscreen && !is_closed) {
--#ifdef cimg_use_xrandr
--        int foo;
--        if (XRRQueryExtension(cimg::X11attr().display,&foo,&foo)) {
--          XRRRotations(cimg::X11attr().display, DefaultScreen(cimg::X11attr().display), &cimg::X11attr().curr_rotation);
--          if (!cimg::X11attr().resolutions) {
--            cimg::X11attr().resolutions = XRRSizes(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display),&foo);
--            cimg::X11attr().nb_resolutions = (unsigned int)foo;
--          }
--          if (cimg::X11attr().resolutions) {
--            cimg::X11attr().curr_resolution = 0;
--            for (unsigned int i=0; i<cimg::X11attr().nb_resolutions; i++) {
--              const unsigned int
--                nw = (unsigned int)(cimg::X11attr().resolutions[i].width),
--                nh = (unsigned int)(cimg::X11attr().resolutions[i].height);
--              if (nw>=width && nh>=height &&
--                  nw<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].width) &&
--                  nh<=(unsigned int)(cimg::X11attr().resolutions[cimg::X11attr().curr_resolution].height))
--                cimg::X11attr().curr_resolution = i;
--            }
--            if (cimg::X11attr().curr_resolution>0) {
--              XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
--              XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
--                                 cimg::X11attr().curr_resolution, cimg::X11attr().curr_rotation, CurrentTime);
--              XRRFreeScreenConfigInfo(config);
--              XSync(cimg::X11attr().display, False);
--            }
--          }
--        }
--        cimg::warn(!cimg::X11attr().resolutions,"CImgDisplay::_create_window() : Xrandr extension is not supported by the X server.");
--#endif
--        const unsigned int sx = screen_dimx(), sy = screen_dimy();
--        XSetWindowAttributes winattr;
--        winattr.override_redirect = True;
--        if (sx!=width || sy!=height) {
--          background_window = XCreateWindow(cimg::X11attr().display,
--                                            RootWindow(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),0,0,
--                                            sx,sy,0,0,InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
--          const unsigned int bufsize = sx*sy*(cimg::X11attr().nb_bits==8?1:(cimg::X11attr().nb_bits==16?2:4));
--          void *background_data = std::malloc(bufsize);
--          std::memset(background_data,0,bufsize);
--          XImage *background_image = XCreateImage(cimg::X11attr().display,DefaultVisual(cimg::X11attr().display,DefaultScreen(cimg::X11attr().display)),
--                                                  cimg::X11attr().nb_bits,ZPixmap,0,(char*)background_data,sx,sy,8,0);
--          XEvent event;
--          XSelectInput(cimg::X11attr().display,background_window,StructureNotifyMask);
--          XMapRaised(cimg::X11attr().display,background_window);
--          do XWindowEvent(cimg::X11attr().display,background_window,StructureNotifyMask,&event);
--          while (event.type!=MapNotify);
--          XPutImage(cimg::X11attr().display,background_window,*cimg::X11attr().gc,background_image,0,0,0,0,sx,sy);
--          XWindowAttributes attr;
--          XGetWindowAttributes(cimg::X11attr().display, background_window, &attr);
--          while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
--          XDestroyImage(background_image);
--        }
--      }
--    }
--
--    void _desinit_fullscreen() {
--      if (is_fullscreen) {
--        XUngrabKeyboard(cimg::X11attr().display,CurrentTime);
--#if cimg_use_xrandr
--        if (cimg::X11attr().resolutions && cimg::X11attr().curr_resolution) {
--          XRRScreenConfiguration *config = XRRGetScreenInfo(cimg::X11attr().display, DefaultRootWindow(cimg::X11attr().display));
--          XRRSetScreenConfig(cimg::X11attr().display, config, DefaultRootWindow(cimg::X11attr().display),
--                             0, cimg::X11attr().curr_rotation, CurrentTime);
--          XRRFreeScreenConfigInfo(config);
--          XSync(cimg::X11attr().display, False);
--          cimg::X11attr().curr_resolution = 0;
--        }
--#endif
--        if (background_window) XDestroyWindow(cimg::X11attr().display,background_window);
--        background_window = 0;
--        is_fullscreen = false;
--      }
--    }
--
--    void _handle_events(const XEvent *const pevent) {
--      XEvent event=*pevent;
--      switch (event.type) {
--      case ClientMessage:
--        if ((int)event.xclient.message_type==(int)wm_delete_protocol &&
--            (int)event.xclient.data.l[0]==(int)wm_delete_window) {
--          XUnmapWindow(cimg::X11attr().display,window);
--          mouse_x = mouse_y = -1;
--          std::memmove((void*)(buttons+1),(void*)buttons,255);
--          std::memmove((void*)(keys+1),(void*)keys,255);
--          if (key) { std::memmove((void*)(released_keys+1),(void*)released_keys,255); released_key = key; }
--          key = button = 0;
--          is_closed = is_event = true;
--        }
--        break;
--     case ConfigureNotify: {
--        while (XCheckWindowEvent(cimg::X11attr().display,window,StructureNotifyMask,&event));
--        const unsigned int
--          nw = event.xconfigure.width,
--          nh = event.xconfigure.height;
--        const int
--          nx = event.xconfigure.x,
--          ny = event.xconfigure.y;
--        if (nw && nh && (nw!=window_width || nh!=window_height)) {
--          window_width = nw;
--          window_height = nh;
--          mouse_x = mouse_y = -1;
--          XResizeWindow(cimg::X11attr().display,window,window_width,window_height);
--          is_resized = is_event = true;
--        }
--        if (nx!=window_x || ny!=window_y) {
--          window_x = nx;
--          window_y = ny;
--          is_moved = is_event = true;
--        }
--     } break;
--      case Expose: {
--        while (XCheckWindowEvent(cimg::X11attr().display,window,ExposureMask,&event));
--        _paint(false);
--        if (is_fullscreen) {
--          XWindowAttributes attr;
--          XGetWindowAttributes(cimg::X11attr().display, window, &attr);
--          while (attr.map_state != IsViewable) XSync(cimg::X11attr().display, False);
--          XSetInputFocus(cimg::X11attr().display, window, RevertToParent, CurrentTime);
--        }
--      } break;
--      case ButtonPress: {
--        do {
--          switch (event.xbutton.button) {
--          case 1: std::memmove((void*)(buttons+1),(void*)buttons,255); button|=1; is_event = true; break;
--          case 2: std::memmove((void*)(buttons+1),(void*)buttons,255); button|=4; is_event = true; break;
--          case 3: std::memmove((void*)(buttons+1),(void*)buttons,255); button|=2; is_event = true; break;
--          default: break;
--          }
--        } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonPressMask,&event));
--      } break;
--      case ButtonRelease: {
--        do {
--          switch (event.xbutton.button) {
--          case 1: std::memmove((void*)(buttons+1),(void*)buttons,255); button&=~1U; is_event = true; break;
--          case 2: std::memmove((void*)(buttons+1),(void*)buttons,255); button&=~4U; is_event = true; break;
--          case 3: std::memmove((void*)(buttons+1),(void*)buttons,255); button&=~2U; is_event = true; break;
--          case 4: wheel++; is_event = true; break;
--          case 5: wheel--; is_event = true; break;
--          default: break;
--          }
--        } while (XCheckWindowEvent(cimg::X11attr().display,window,ButtonReleaseMask,&event));
--      } break;
--      case KeyPress: {
--        char tmp;
--        KeySym ksym;
--        XLookupString(&event.xkey,&tmp,1,&ksym,0);
--        std::memmove((void*)(keys+1),(void*)keys,255); key = (unsigned int)ksym;
--        std::memmove((void*)(released_keys+1),(void*)released_keys,255); released_key = 0;
--        is_event = true;
--      } break;
--      case KeyRelease: {
--        char tmp;
--        KeySym ksym;
--        XLookupString(&event.xkey,&tmp,1,&ksym,0);
--        std::memmove((void*)(keys+1),(void*)keys,255); key = 0;
--        std::memmove((void*)(released_keys+1),(void*)released_keys,255); released_key = (unsigned int)ksym;
--        is_event = true;
--        } break;
--      case LeaveNotify:
--        while (XCheckWindowEvent(cimg::X11attr().display,window,LeaveWindowMask,&event));
--        mouse_x = mouse_y =-1;
--        is_event = true;
--        break;
--      case MotionNotify:
--        while (XCheckWindowEvent(cimg::X11attr().display,window,PointerMotionMask,&event));
--        mouse_x = event.xmotion.x;
--        mouse_y = event.xmotion.y;
--        if (mouse_x<0 || mouse_y<0 || mouse_x>=dimx() || mouse_y>=dimy()) mouse_x = mouse_y = -1;
--        is_event = true;
--        break;
--      }
--    }
--
--    static void* _events_thread(void *arg) {
--      arg = 0;
--      XEvent event;
--      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0);
--      pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
--      for (;;) {
--        pthread_mutex_lock(cimg::X11attr().mutex);
--        for (unsigned int i=0; i<cimg::X11attr().nb_wins; i++) {
--          const unsigned int xevent_type = (cimg::X11attr().wins[i]->events)&3;
--          const unsigned int emask =
--            ((xevent_type>=1)?ExposureMask|StructureNotifyMask:0)|
--            ((xevent_type>=2)?ButtonPressMask|KeyPressMask|PointerMotionMask|LeaveWindowMask:0)|
--            ((xevent_type>=3)?ButtonReleaseMask|KeyReleaseMask:0);
--          XSelectInput(cimg::X11attr().display,cimg::X11attr().wins[i]->window,emask);
--        }
--        bool event_flag = XCheckTypedEvent(cimg::X11attr().display, ClientMessage, &event);
--        if (!event_flag) event_flag = XCheckMaskEvent(cimg::X11attr().display,
--                                                      ExposureMask|StructureNotifyMask|ButtonPressMask|
--                                                      KeyPressMask|PointerMotionMask|LeaveWindowMask|ButtonReleaseMask|
--                                                      KeyReleaseMask,&event);
--        if (event_flag) {
--          for (unsigned int i=0; i<cimg::X11attr().nb_wins; i++)
--            if (!cimg::X11attr().wins[i]->is_closed && event.xany.window==cimg::X11attr().wins[i]->window)
--              cimg::X11attr().wins[i]->_handle_events(&event);
--        }
--        pthread_mutex_unlock(cimg::X11attr().mutex);
--        pthread_testcancel();
--        cimg::sleep(7);
--      }
--      return 0;
--    }
--
--    // Windows-based display
--    //-----------------------
--#elif cimg_display_type==2
--    CLIENTCREATESTRUCT ccs;
--    BITMAPINFO bmi;
--    unsigned int *data;
--    DEVMODE curr_mode;
--    HWND window;
--    HWND background_window;
--    HDC hdc;
--    HANDLE thread;
--    HANDLE created;
--    HANDLE mutex;
--    bool visible_cursor;
--
--    static int screen_dimx() {
--      DEVMODE mode;
--      mode.dmSize = sizeof(DEVMODE);
--      mode.dmDriverExtra = 0;
--      EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
--      return mode.dmPelsWidth;
--    }
--
--    static int screen_dimy() {
--      DEVMODE mode;
--      mode.dmSize = sizeof(DEVMODE);
--      mode.dmDriverExtra = 0;
--      EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
--      return mode.dmPelsHeight;
--    }
--
--    CImgDisplay& assign(const unsigned int dimw, const unsigned int dimh, const char *title=0,
--                        const unsigned int normalization_type=3, const unsigned int events_type=3,
--                        const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (!dimw || !dimh)
--        throw CImgArgumentException("CImgDisplay::assign() : Specified window size (%u,%u) is not valid.",dimw,dimh);
--      assign_lowlevel(dimw,dimh,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      min = max = 0;
--      std::memset(data,0,sizeof(unsigned int)*width*height);
--      return paint();
--    }
--
--    template<typename T> CImgDisplay& assign(const CImg<T>& img, const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (img.is_empty())
--        throw CImgArgumentException("CImgDisplay::CImgDisplay() : Specified input image (%u,%u,%u,%u,%p) is empty.",
--                                    img.width,img.height,img.depth,img.dim,img.data);
--      CImg<T> tmp;
--      const CImg<T>& nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--      assign_lowlevel(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      if (normalization==2) { const CImgStats st(nimg,false); min = (float)st.min; max = (float)st.max; }
--      return display(nimg);
--    }
--
--    template<typename T> CImgDisplay& assign(const CImgList<T>& list,const char *title=0,
--                                             const unsigned int normalization_type=3, const unsigned int events_type=3,
--                                             const bool fullscreen_flag=false, const bool closed_flag=false) {
--      if (list.is_empty())
--        throw CImgArgumentException("CImgDisplay::CImgDisplay() : Specified input list (%u,%p) is empty.",
--                                    list.size,list.data);
--      CImg<T> tmp;
--      const CImg<T> img = list.get_append('x'),
--        &nimg = (img.depth==1)?img:(tmp=img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--      assign_lowlevel(nimg.width,nimg.height,title,normalization_type,events_type,fullscreen_flag,closed_flag);
--      if (normalization==2) { const CImgStats st(nimg,false); min = (float)st.min; max = (float)st.max; }
--      return display(nimg);
--    }
--
--    CImgDisplay& assign(const CImgDisplay& win) {
--      assign_lowlevel(win.width,win.height,win.title,win.normalization,win.events,win.is_fullscreen,win.is_closed);
--      std::memcpy(data,win.data,sizeof(unsigned int)*width*height);
--      return paint();
--    }
--
--    CImgDisplay& _assign() {
--      DestroyWindow(window);
--      if (events) TerminateThread(thread,0);
--      if (data) delete[] data;
--      if (title) delete[] title;
--      if (is_fullscreen) _desinit_fullscreen();
--      width = height = normalization = events = 0;
--      is_fullscreen = is_resized = is_moved = is_event = false;
--      is_closed = true;
--      title = 0;
--      window_x = window_y = window_width = window_height = mouse_x = mouse_y = wheel = 0;
--      std::memset((void*)buttons,0,256*sizeof(unsigned int));
--      std::memset((void*)keys,0,256*sizeof(unsigned int));
--      std::memset((void*)released_keys,0,256*sizeof(unsigned int));
--      min = max = 0;
--      return *this;
--    }
--
--   template<typename T> CImgDisplay& display(const CImg<T>& img) {
--      return render(img).paint();
--    }
--
--    CImgDisplay& resize(const int nwidth, const int nheight, const bool redraw=true) {
--      if (!(nwidth && nheight))
--        throw CImgArgumentException("CImgDisplay::resize() : Specified window size (%d,%d) is not valid.",
--                                    nwidth,nheight);
--      const unsigned int
--        tmpdimx=(nwidth>0)?nwidth:(-nwidth*width/100),
--        tmpdimy=(nheight>0)?nheight:(-nheight*height/100),
--        dimx = tmpdimx?tmpdimx:1,
--        dimy = tmpdimy?tmpdimy:1;
--      const bool
--        is_disp_different = (width!=dimx || height!=dimy),
--        is_win_different = (window_width!=dimx || window_height!=dimy);
--
--      if (is_disp_different || is_win_different) {
--        RECT rect; rect.left=rect.top=0; rect.right = dimx-1; rect.bottom = dimy-1;
--        AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
--        const int cwidth = rect.right-rect.left+1, cheight = rect.bottom-rect.top+1;
--        SetWindowPos(window,0,0,0,cwidth,cheight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS);
--        window_width  = dimx;
--        window_height = dimy;
--        is_resized = false;
--        if (is_disp_different) {
--          unsigned int *ndata = new unsigned int[dimx*dimy];
--          if (redraw) _render_resize(data,width,height,ndata,dimx,dimy);
--          else std::memset(ndata,0x80,sizeof(unsigned int)*dimx*dimy);
--          delete[] data;
--          data = ndata;
--          bmi.bmiHeader.biWidth = dimx;
--          bmi.bmiHeader.biHeight = -(int)dimy;
--          width = dimx;
--          height = dimy;
--        }
--        if (is_fullscreen) move((screen_dimx()-width)/2,(screen_dimy()-height)/2);
--        if (redraw) return paint();
--      }
--      return *this;
--    }
--
--    CImgDisplay& move(const int posx,const int posy) {
--      if (!is_fullscreen) {
--        RECT rect; rect.left=rect.top=0; rect.right=window_width-1; rect.bottom=window_height-1;
--        AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
--        const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
--        SetWindowPos(window,0,posx-border1,posy-border2,0,0,SWP_NOSIZE | SWP_NOZORDER);
--      } else SetWindowPos(window,0,posx,posy,0,0,SWP_NOSIZE | SWP_NOZORDER);
--      window_x = posx;
--      window_y = posy;
--      is_moved = false;
--      return show();
--    }
--
--    // Internal routine to retrieve the position of the current window.
--    CImgDisplay& _update_window_pos() {
--      if (!is_closed) {
--        RECT rect;
--        rect.left = rect.top = 0; rect.right = width-1; rect.bottom = height-1;
--        AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
--        const int border1 = (rect.right-rect.left+1-width)/2, border2 = rect.bottom-rect.top+1-height-border1;
--        GetWindowRect(window,&rect);
--        window_x = rect.left + border1;
--        window_y = rect.top + border2;
--      } else window_x = window_y = -1;
--      return *this;
--    }
--
--    CImgDisplay& set_mouse(const int posx, const int posy) {
--      if (!is_closed && posx>=0 && posy>=0) {
--        _update_window_pos();
--        SetCursorPos(window_x+posx,window_y+posy);
--        mouse_x = posx;
--        mouse_y = posy;
--      }
--      return *this;
--    }
--
--    CImgDisplay& hide_mouse() {
--      visible_cursor = false;
--        ShowCursor(FALSE);
--        SendMessage(window,WM_SETCURSOR,0,0);
--      return *this;
--    }
--
--    CImgDisplay& show_mouse() {
--      visible_cursor = true;
--        ShowCursor(TRUE);
--        SendMessage(window,WM_SETCURSOR,0,0);
--      return *this;
--    }
--
--    static void wait_all() {
--      WaitForSingleObject(cimg::Win32attr().wait_event,INFINITE);
--    }
--
--    CImgDisplay& show() {
--      if (is_closed) {
--        is_closed = false;
--        if (is_fullscreen) _init_fullscreen();
--        ShowWindow(window,SW_SHOW);
--        _update_window_pos();
--      }
--      return paint();
--    }
--
--    CImgDisplay& close() {
--      if (!is_closed && !is_fullscreen) {
--        if (is_fullscreen) _desinit_fullscreen();
--        ShowWindow(window,SW_HIDE);
--        is_closed = true;
--        window_x = window_y = 0;
--      }
--      return *this;
--    }
--
--    CImgDisplay& set_title(const char *format,...) {
--      char tmp[1024]={0};
--      va_list ap;
--      va_start(ap, format);
--      std::vsprintf(tmp,format,ap);
--      va_end(ap);
--      if (title) delete[] title;
--      const int s = cimg::strlen(tmp)+1;
--      title = new char[s];
--      std::memcpy(title,tmp,s*sizeof(char));
--      SetWindowTextA(window, tmp);
--      return *this;
--    }
--
--    CImgDisplay& paint() {
--      if (!is_closed) {
--        WaitForSingleObject(mutex,INFINITE);
--        SetDIBitsToDevice(hdc,0,0,width,height,0,0,0,height,data,&bmi,DIB_RGB_COLORS);
--        ReleaseMutex(mutex);
--      }
--      return *this;
--    }
--
--    template<typename T> CImgDisplay& render(const CImg<T>& img) {
--      if (img.is_empty())
--        throw CImgArgumentException("CImgDisplay::_render_image() : Specified input image (%u,%u,%u,%u,%p) is empty.",
--                                    img.width,img.height,img.depth,img.dim,img.data);
--      if (img.depth!=1) return render(img.get_projections2d(img.width/2,img.height/2,img.depth/2));
--
--      const T
--        *data1 = img.ptr(),
--        *data2 = (img.dim>=2)?img.ptr(0,0,0,1):data1,
--        *data3 = (img.dim>=3)?img.ptr(0,0,0,2):data1;
--
--      WaitForSingleObject(mutex,INFINITE);
--      unsigned int
--        *const ndata = (img.width==width && img.height==height)?data:new unsigned int[img.width*img.height],
--        *ptrd = ndata;
--
--      if (!normalization || (normalization==3 && cimg::type<T>::id()==cimg::type<unsigned char>::id())) {
--      min = max = 0;
--        for (unsigned int xy = img.width*img.height; xy>0; xy--)
--          *(ptrd++) = ((unsigned char)*(data1++)<<16) | ((unsigned char)*(data2++)<<8) | (unsigned char)*(data3++);
--      } else {
--        if (normalization==3) {
--          if (cimg::type<T>::is_float()) { const CImgStats st(img,false); min = (float)st.min; max = (float)st.max; }
--          else { min = (float)cimg::type<T>::min(); max = (float)cimg::type<T>::max(); }
--        } else if ((min>max) || normalization==1) { const CImgStats st(img,false); min = (float)st.min; max = (float)st.max; }
--        const float delta = max-min, mm = delta?delta:1.0f;
--        for (unsigned int xy = img.width*img.height; xy>0; xy--) {
--          const unsigned char
--            R = (unsigned char)(255*(*(data1++)-min)/mm),
--            G = (unsigned char)(255*(*(data2++)-min)/mm),
--            B = (unsigned char)(255*(*(data3++)-min)/mm);
--          *(ptrd++) = (R<<16) | (G<<8) | (B);
--        }
--      }
--      if (ndata!=data) { _render_resize(ndata,img.width,img.height,data,width,height); delete[] ndata; }
--      ReleaseMutex(mutex);
--      return *this;
--    }
--
--    CImgDisplay& assign_lowlevel(const unsigned int dimw,const unsigned int dimh,const char *ptitle=0,
--                                 const unsigned int normalization_type=3,const unsigned int events_type=3,
--                                 const bool fullscreen_flag=false,const bool closed_flag=false) {
--
--
--      // Allocate space for window title
--      const int s = cimg::strlen(ptitle)+1;
--      char *tmp_title = s?new char[s]:0;
--      if (s) std::memcpy(tmp_title,ptitle,s*sizeof(char));
--
--      // Destroy previous window if existing
--      if (width && height) _assign();
--
--      // Set display variables
--      width = dimw;
--      height = dimh;
--      normalization = normalization_type%4;
--      events = events_type%4;
--      is_fullscreen = fullscreen_flag;
--      title = tmp_title;
--      window_x = window_y = wheel = 0;
--      mouse_x = mouse_y = -1;
--      std::memset((void*)buttons,0,256*sizeof(unsigned int));
--      std::memset((void*)keys,0,256*sizeof(unsigned int));
--      std::memset((void*)released_keys,0,256*sizeof(unsigned int));
--      is_resized = is_moved = is_event = false;
--      is_closed = closed_flag;
--      fps_timer = fps_frames = timer = 0;
--      fps_fps = 0;
--      visible_cursor = true;
--
--      if (is_fullscreen) _init_fullscreen();
--
--      // Create event thread
--      void *arg = (void*)(new void*[2]);
--      ((void**)arg)[0]=(void*)this;
--      ((void**)arg)[1]=(void*)title;
--      if (events) {
--        unsigned long ThreadID = 0;
--        mutex     = CreateMutex(0,FALSE,0);
--        created   = CreateEvent(0,FALSE,FALSE,0);
--        thread    = CreateThread(0,0,_events_thread,arg,0,&ThreadID);
--        WaitForSingleObject(created,INFINITE);
--      } else _events_thread(arg);
--
--      return *this;
--    }
--
--    static LRESULT APIENTRY _handle_events(HWND window,UINT msg,WPARAM wParam,LPARAM lParam) {
--#ifdef _WIN64
--      CImgDisplay* disp = (CImgDisplay*)GetWindowLongPtr(window,GWLP_USERDATA);
--#else
--      CImgDisplay* disp = (CImgDisplay*)GetWindowLong(window,GWL_USERDATA);
--#endif
--      MSG st_msg;
--
--      switch(msg) {
--      case WM_CLOSE:
--        disp->mouse_x = disp->mouse_y = -1;
--        disp->window_x = disp->window_y = 0;
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        std::memmove((void*)(disp->keys+1),(void*)disp->keys,255);
--        if (disp->key) {
--          std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,255);
--          disp->released_key = disp->key;
--        }
--        disp->key = disp->button = 0;
--        disp->is_closed=true;
--        ReleaseMutex(disp->mutex);
--        ShowWindow(disp->window,SW_HIDE);
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        return 0;
--      case WM_SIZE: {
--        while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
--        WaitForSingleObject(disp->mutex,INFINITE);
--        const unsigned int nw = LOWORD(lParam),nh = HIWORD(lParam);
--        if (nw && nh && (nw!=disp->width || nh!=disp->height)) {
--          disp->window_width  = nw;
--          disp->window_height = nh;
--          disp->mouse_x = disp->mouse_y = -1;
--          disp->is_resized = disp->is_event = true;
--          SetEvent(cimg::Win32attr().wait_event);
--        }
--        ReleaseMutex(disp->mutex);
--      } break;
--      case WM_MOVE: {
--        while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE));
--        WaitForSingleObject(disp->mutex,INFINITE);
--        const int nx = (int)(short)(LOWORD(lParam)), ny = (int)(short)(HIWORD(lParam));
--        if (nx!=disp->window_x || ny!=disp->window_y) {
--          disp->window_x = nx;
--          disp->window_y = ny;
--          disp->is_moved = disp->is_event = true;
--          SetEvent(cimg::Win32attr().wait_event);
--        }
--        ReleaseMutex(disp->mutex);
--      } break;
--      case WM_PAINT:
--        disp->paint();
--        break;
--      }
--      if (disp->events>=2) switch(msg) {
--      case WM_KEYDOWN:
--        std::memmove((void*)(disp->keys+1),(void*)disp->keys,255); disp->key = (int)wParam;
--        std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,255); disp->released_key = 0;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_MOUSEMOVE: {
--        while (PeekMessage(&st_msg,window,WM_MOUSEMOVE,WM_MOUSEMOVE,PM_REMOVE));
--        disp->mouse_x = LOWORD(lParam);
--        disp->mouse_y = HIWORD(lParam);
--        if (disp->mouse_x<0 || disp->mouse_y<0 || disp->mouse_x>=disp->dimx() || disp->mouse_y>=disp->dimy())
--          disp->mouse_x=disp->mouse_y=-1;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--      } break;
--      case WM_LBUTTONDOWN:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button|=1U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_RBUTTONDOWN:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button|=2U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_MBUTTONDOWN:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button|=4U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case 0x020A: // WM_MOUSEWHEEL:
--        disp->wheel+=(int)((short)HIWORD(wParam))/120;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--      }
--      if (disp->events>=3) switch(msg) {
--      case WM_KEYUP:
--        std::memmove((void*)(disp->keys+1),(void*)disp->keys,255); disp->key = 0;
--        std::memmove((void*)(disp->released_keys+1),(void*)disp->released_keys,255); disp->released_key = (int)wParam;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_LBUTTONUP:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button&=~1U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_RBUTTONUP:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button&=~2U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_MBUTTONUP:
--        std::memmove((void*)(disp->buttons+1),(void*)disp->buttons,255);
--        disp->button&=~4U;
--        disp->is_event = true;
--        SetEvent(cimg::Win32attr().wait_event);
--        break;
--      case WM_SETCURSOR:
--        if (disp->visible_cursor) ShowCursor(TRUE);
--        else ShowCursor(FALSE);
--        break;
--      }
--      return DefWindowProc(window,msg,wParam,lParam);
--    }
--
--    static DWORD WINAPI _events_thread(void* arg) {
--      CImgDisplay *disp  = (CImgDisplay*)(((void**)arg)[0]);
--      const char *title = (const char*)(((void**)arg)[1]);
--      MSG msg;
--      delete[] (void**)arg;
--      disp->bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
--      disp->bmi.bmiHeader.biWidth=disp->width;
--      disp->bmi.bmiHeader.biHeight=-(int)disp->height;
--      disp->bmi.bmiHeader.biPlanes=1;
--      disp->bmi.bmiHeader.biBitCount=32;
--      disp->bmi.bmiHeader.biCompression=BI_RGB;
--      disp->bmi.bmiHeader.biSizeImage=0;
--      disp->bmi.bmiHeader.biXPelsPerMeter=1;
--      disp->bmi.bmiHeader.biYPelsPerMeter=1;
--      disp->bmi.bmiHeader.biClrUsed=0;
--      disp->bmi.bmiHeader.biClrImportant=0;
--      disp->data = new unsigned int[disp->width*disp->height];
--      if (!disp->is_fullscreen) { // Normal window
--        RECT rect;
--        rect.left=rect.top=0; rect.right=disp->width-1; rect.bottom=disp->height-1;
--        AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,false);
--        const int border1 = (rect.right-rect.left+1-disp->width)/2, border2 = rect.bottom-rect.top+1-disp->height-border1;
--        disp->window = CreateWindowA("MDICLIENT",title?title:" ",
--                                     WS_OVERLAPPEDWINDOW | (disp->is_closed?0:WS_VISIBLE), CW_USEDEFAULT,CW_USEDEFAULT,
--                                     disp->width + 2*border1, disp->height + border1 + border2,
--                                     0,0,0,&(disp->ccs));
--        if (!disp->is_closed) {
--          GetWindowRect(disp->window,&rect);
--          disp->window_x = rect.left + border1;
--          disp->window_y = rect.top + border2;
--        } else disp->window_x = disp->window_y = 0;
--      } else { // Fullscreen window
--        const unsigned int sx = screen_dimx(), sy = screen_dimy();
--        disp->window = CreateWindowA("MDICLIENT",title?title:" ",
--                                     WS_POPUP | (disp->is_closed?0:WS_VISIBLE), (sx-disp->width)/2, (sy-disp->height)/2,
--                                     disp->width,disp->height,0,0,0,&(disp->ccs));
--        disp->window_x = disp->window_y = 0;
--      }
--      SetForegroundWindow(disp->window);
--      disp->hdc = GetDC(disp->window);
--      disp->window_width = disp->width;
--      disp->window_height = disp->height;
--      disp->mouse_x = disp->mouse_y = -1;
--      disp->wheel = 0;
--      std::memset((void*)disp->buttons,0,256*sizeof(unsigned int));
--      std::memset((void*)disp->keys,0,256*sizeof(unsigned int));
--      std::memset((void*)disp->released_keys,0,256*sizeof(unsigned int));
--      disp->is_resized = disp->is_moved = disp->is_event = false;
--      if (disp->events) {
--#ifdef _WIN64
--        SetWindowLongPtr(disp->window,GWLP_USERDATA,(LONG_PTR)disp);
--        SetWindowLongPtr(disp->window,GWLP_WNDPROC,(LONG_PTR)_handle_events);
--#else
--        SetWindowLong(disp->window,GWL_USERDATA,(LONG)disp);
--        SetWindowLong(disp->window,GWL_WNDPROC,(LONG)_handle_events);
--#endif
--        SetEvent(disp->created);
--        while( GetMessage(&msg,0,0,0) ) DispatchMessage( &msg );
--      }
--      return 0;
--    }
--
--    void _init_fullscreen() {
--      background_window = 0;
--      if (is_fullscreen && !is_closed) {
--        DEVMODE mode;
--        unsigned int imode=0, ibest=0, bestbpp=0, bw=~0U, bh=~0U;
--        for (mode.dmSize = sizeof(DEVMODE), mode.dmDriverExtra = 0; EnumDisplaySettings(0,imode,&mode); imode++) {
--          const unsigned int nw = mode.dmPelsWidth, nh = mode.dmPelsHeight;
--          if (nw>=width && nh>=height && mode.dmBitsPerPel>=bestbpp && nw<=bw && nh<=bh) {
--            bestbpp = mode.dmBitsPerPel;
--            ibest = imode;
--            bw = nw; bh = nh;
--          }
--        }
--        if (bestbpp) {
--          curr_mode.dmSize = sizeof(DEVMODE); curr_mode.dmDriverExtra = 0;
--          EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&curr_mode);
--          EnumDisplaySettings(0,ibest,&mode);
--          ChangeDisplaySettings(&mode,0);
--        } else curr_mode.dmSize = 0;
--
--        const unsigned int sx = screen_dimx(), sy = screen_dimy();
--        if (sx!=width || sy!=height) {
--          CLIENTCREATESTRUCT background_ccs;
--          background_window = CreateWindowA("MDICLIENT"," ",WS_POPUP | WS_VISIBLE, 0,0,sx,sy,0,0,0,&background_ccs);
--          SetForegroundWindow(background_window);
--        }
--      } else curr_mode.dmSize = 0;
--    }
--
--    void _desinit_fullscreen() {
--      if (is_fullscreen) {
--        if (background_window) DestroyWindow(background_window);
--        background_window = 0;
--        if (curr_mode.dmSize) ChangeDisplaySettings(&curr_mode,0);
--        is_fullscreen = false;
--      }
--    }
--
--#endif
--
--  };
--
--  /*
--   #--------------------------------------
--   #
--   #
--   #
--   # Definition of the CImg<T> structure
--   #
--   #
--   #
--   #--------------------------------------
--   */
--
--  //! Class representing an image (up to 4 dimensions wide), each pixel being of type \c T.
--  /**
--     This is the main class of the %CImg Library. It declares and constructs
--     an image, allows access to its pixel values, and is able to perform various image operations.
--
--     \par Image representation
--
--     A %CImg image is defined as an instance of the container \ref CImg<T>, which contains a regular grid of pixels,
--     each pixel value being of type \c T. The image grid can have up to 4 dimensions : width, height, depth
--     and number of channels.
--     Usually, the three first dimensions are used to describe spatial coordinates <tt>(x,y,z)</tt>, while the number of channels
--     is rather used as a vector-valued dimension (it may describe the R,G,B color channels for instance).
--     If you need a fifth dimension, you can use image lists \ref CImgList<T> rather than simple images \ref CImg<T>.
--
--     Thus, the \ref CImg<T> class is able to represent volumetric images of vector-valued pixels,
--     as well as images with less dimensions (1D scalar signal, 2D color images, ...).
--     Most member functions of the class CImg<T> are designed to handle this maximum case of (3+1) dimensions.
--
--     Concerning the pixel value type \c T :
--     fully supported template types are the basic C++ types : <tt>unsigned char, char, short, unsigned int, int,
--     unsigned long, long, float, double, ... </tt>.
--     Typically, fast image display can be done using <tt>CImg<unsigned char></tt> images,
--     while complex image processing algorithms may be rather coded using <tt>CImg<float></tt> or <tt>CImg<double></tt>
--     images that have floating-point pixel values. The default value for the template T is \c float.
--     Using your own template types may be possible. However, you will certainly have to define the complete set
--     of arithmetic and logical operators for your class.
--
--     \par Image structure
--
--     The \ref CImg<\c T> structure contains \a five fields :
--     - \ref width defines the number of \a columns of the image (size along the X-axis).
--     - \ref height defines the number of \a rows of the image (size along the Y-axis).
--     - \ref depth defines the number of \a slices of the image (size along the Z-axis).
--     - \ref dim defines the number of \a channels of the image (size along the V-axis).
--     - \ref data defines a \a pointer to the \a pixel \a data (of type \c T).
--
--     You can access these fields publicly although it is recommended to use the dedicated functions
--     dimx(), dimy(), dimz(), dimv() and ptr() to do so.
--     Image dimensions are not limited to a specific range (as long as you got enough available memory).
--     A value of \e 1 usually means that the corresponding dimension is \a flat.
--     If one of the dimensions is \e 0, or if the data pointer is null, the image is considered as \e empty.
--     Empty images should not contain any pixel data and thus, will not be processed by CImg member functions
--     (a CImgInstanceException will be thrown instead).
--     Pixel data are stored in memory, in a non interlaced mode (See \ref cimg_storage).
--
--     \par Image declaration and construction
--
--     Declaring an image can be done by using one of the several available constructors.
--     Here is a list of the most used :
--
--     - Construct images from arbitrary dimensions :
--         - <tt>CImg<char> img;</tt> declares an empty image.
--         - <tt>CImg<unsigned char> img(128,128);</tt> declares a 128x128 greyscale image with
--         \c unsigned \c char pixel values.
--         - <tt>CImg<double> img(3,3);</tt> declares a 3x3 matrix with \c double coefficients.
--         - <tt>CImg<unsigned char> img(256,256,1,3);</tt> declares a 256x256x1x3 (color) image
--         (colors are stored as an image with three channels).
--         - <tt>CImg<double> img(128,128,128);</tt> declares a 128x128x128 volumetric and greyscale image
--         (with \c double pixel values).
--         - <tt>CImg<> img(128,128,128,3);</tt> declares a 128x128x128 volumetric color image
--         (with \c float pixels, which is the default value of the template parameter \c T).
--         - \b Note : images pixels are <b>not automatically initialized to 0</b>. You may use the function \ref fill() to
--         do it, or use the specific constructor taking 5 parameters like this :
--         <tt>CImg<> img(128,128,128,3,0);</tt> declares a 128x128x128 volumetric color image with all pixel values to 0.
--
--     - Construct images from filenames :
--         - <tt>CImg<unsigned char> img("image.jpg");</tt> reads a JPEG color image from the file "image.jpg".
--         - <tt>CImg<float> img("analyze.hdr");</tt> reads a volumetric image (ANALYZE7.5 format) from the file "analyze.hdr".
--         - \b Note : You need to install <a href="http://www.imagemagick.org">ImageMagick</a>
--         to be able to read common compressed image formats (JPG,PNG,...) (See \ref cimg_files_io).
--
--     - Construct images from C-style arrays :
--         - <tt>CImg<int> img(data_buffer,256,256);</tt> constructs a 256x256 greyscale image from a \c int* buffer
--         \c data_buffer (of size 256x256=65536).
--         - <tt>CImg<unsigned char> img(data_buffer,256,256,1,3,false);</tt> constructs a 256x256 color image
--         from a \c unsigned \c char* buffer \c data_buffer (where R,G,B channels follow each others).
--         - <tt>CImg<unsigned char> img(data_buffer,256,256,1,3,true);</tt> constructs a 256x256 color image
--         from a \c unsigned \c char* buffer \c data_buffer (where R,G,B channels are multiplexed).
--
--         The complete list of constructors can be found <a href="#constructors">here</a>.
--
--     \par Most useful functions
--
--     The \ref CImg<T> class contains a lot of functions that operates on images.
--     Some of the most useful are :
--
--     - operator()(), operator[]() : allows to access or write pixel values.
--     - display() : displays the image in a new window.
--
--     \sa CImgList, CImgStats, CImgDisplay, CImgException.
--
--  **/
--  template<typename T> struct CImg {
--
--    //! Variable representing the width of the instance image (i.e. dimensions along the X-axis).
--    /**
--       \remark
--       - Prefer using the function CImg<T>::dimx() to get information about the width of an image.
--       - Use function CImg<T>::resize() to set a new width for an image. Setting directly the variable \c width would probably
--       result in a library crash.
--       - Empty images have \c width defined to \c 0.
--    **/
--    unsigned int width;
--
--    //! Variable representing the height of the instance image (i.e. dimensions along the Y-axis).
--    /**
--       \remark
--       - Prefer using the function CImg<T>::dimy() to get information about the height of an image.
--       - Use function CImg<T>::resize() to set a new height for an image. Setting directly the variable \c height would probably
--       result in a library crash.
--       - 1D signals have \c height defined to \c 1.
--       - Empty images have \c height defined to \c 0.
--    **/
--    unsigned int height;
--
--    //! Variable representing the depth of the instance image (i.e. dimensions along the Z-axis).
--    /**
--       \remark
--       - Prefer using the function CImg<T>::dimz() to get information about the depth of an image.
--       - Use function CImg<T>::resize() to set a new depth for an image. Setting directly the variable \c depth would probably
--       result in a library crash.
--       - Classical 2D images have \c depth defined to \c 1.
--       - Empty images have \c depth defined to \c 0.
--    **/
--    unsigned int depth;
--
--    //! Variable representing the number of channels of the instance image (i.e. dimensions along the V-axis).
--    /**
--       \remark
--       - Prefer using the function CImg<T>::dimv() to get information about the depth of an image.
--       - Use function CImg<T>::resize() to set a new vector dimension for an image. Setting directly the variable \c dim would probably
--       result in a library crash.
--       - Scalar-valued images (one value per pixel) have \c dim defined to \c 1.
--       - Empty images have \c depth defined to \c 0.
--    **/
--    unsigned int dim;
--
--    //! Variable telling if pixel buffer of the instance image is shared with another one.
--    bool is_shared;
--
--    //! Pointer to the first pixel of the pixel buffer.
--    T *data;
--
--    //! Iterator type for CImg<T>.
--    /**
--       \remark
--       - An \p iterator is a <tt>T*</tt> pointer (address of a pixel value in the pixel buffer).
--       - Iterators are not directly used in %CImg functions, they have been introduced for compatibility with the STL.
--    **/
--    typedef T* iterator;
--
--    //! Const iterator type for CImg<T>.
--    /**
--       \remark
--       - A \p const_iterator is a <tt>const T*</tt> pointer (address of a pixel value in the pixel buffer).
--       - Iterators are not directly used in %CImg functions, they have been introduced for compatibility with the STL.
--    **/
--    typedef const T* const_iterator;
--
--    //! Get value type
--    typedef T value_type;
--
--    //@}
--    //---------------------------
--    //
--    //! \name Plugins
--    //@{
--    //---------------------------
--#ifdef cimg_plugin
--#include cimg_plugin
--#endif
--    //@}
--
--    //--------------------------------------
--    //
--    //! \name Constructors-Destructor-Copy
--    //@{
--    //--------------------------------------
--
--    //! Default constructor.
--    /**
--       The default constructor creates an empty instance image.
--       \remark
--       - An empty image does not contain any data and has all of its dimensions \ref width, \ref height, \ref depth, \ref dim
--       set to 0 as well as its pointer to the pixel buffer \ref data.
--       - An empty image is non-shared.
--       \see ~CImg(), assign(), is_empty().
--    **/
--    CImg():
--      width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {}
--
--    //! Destructor.
--    /**
--       The destructor destroys the instance image.
--       \remark
--       - Destructing an empty or shared image does nothing.
--       - Otherwise, all memory used to store the pixel data of the instance image is freed.
--       - When destroying a non-shared image, be sure that every shared instances of the same image are
--       also destroyed to avoid further access to desallocated memory buffers.
--       \see CImg(), assign(), is_empty().
--    **/
--    ~CImg() {
--      if (data && !is_shared) delete[] data;
--    }
--
--    //! In-place version of the default constructor.
--    /**
--       This function replaces the instance image by an empty image.
--       \remark
--       - Memory used by the previous content of the instance image is freed if necessary.
--       - If the instance image was initially shared, it is replaced by a (non-shared) empty image.
--       - This function is useful to free memory used by an image that is not of use, but which
--       has been created in the current code scope (i.e. not destroyed yet).
--       \see ~CImg(), assign(), is_empty().
--    **/
--    CImg& assign() {
--      if (data && !is_shared) delete[] data;
--      width = height = depth = dim = 0; is_shared = false; data = 0;
--      return *this;
--    }
--
--    //! In-place version of the default constructor.
--    /**
--       This function is strictly equivalent to \ref assign() and has been
--       introduced for having a STL-compliant function name.
--       \see assign().
--    **/
--    CImg& clear() {
--      return assign();
--    }
--
--    //! Default copy constructor.
--    /**
--       The default copy constructor creates a new instance image having same dimensions
--       (\ref width, \ref height, \ref depth, \ref dim) and same pixel values as the input image \p img.
--       \param img The input image to copy.
--       \remark
--       - If the input image \p img is non-shared or have a different template type \p t != \p T,
--       the default copy constructor allocates a new pixel buffer and copy the pixel data
--       of \p img into it. In this case, the pointers \ref data to the pixel buffers of the two images are different
--       and the resulting instance image is non-shared.
--       - If the input image \p img is shared and has the same template type \p t == \p T,
--       the default copy constructor does not allocate a new pixel buffer and the resulting instance image
--       shares its pixel buffer with the input image \p img, which means that modifying pixels of \p img also modifies
--       the created instance image.
--       - Copying an image having a different template type \p t != \p T performs a crude static cast conversion of each pixel value from
--       type \p t to type \p T.
--       - Copying an image having the same template type \p t == \p T is significantly faster.
--       \see assign(const CImg< t >&), CImg(const CImg< t >&,const bool).
--    **/
--    template<typename t> CImg(const CImg<t>& img):is_shared(false) {
--      const unsigned int siz = img.size();
--      if (img.data && siz) {
--        width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
--        const t *ptrs = img.data+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
--      } else { width = height = depth = dim = 0; data = 0; }
--    }
--
--    CImg(const CImg& img) {
--      const unsigned int siz = img.size();
--      if (img.data && siz) {
--        width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = img.is_shared;
--        if (is_shared) data = const_cast<T*>(img.data);
--        else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
--      } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--    }
--
--    //! In-place version of the default copy constructor.
--    /**
--       This function assigns a copy of the input image \p img to the current instance image.
--       \param img The input image to copy.
--       \remark
--       - If the instance image is not shared, the content of the input image \p img is copied into a new buffer
--       becoming the new pixel buffer of the instance image, while the old pixel buffer is freed if necessary.
--       - If the instance image is shared, the content of the input image \p img is copied into the current (shared) pixel buffer
--       of the instance image, modifying then the image referenced by the shared instance image. The instance image still remains shared.
--       \see CImg(const CImg< t >&), operator=(const CImg< t >&).
--    **/
--    template<typename t> CImg& assign(const CImg<t>& img) {
--      return assign(img.data,img.width,img.height,img.depth,img.dim);
--    }
--
--    //! Advanced copy constructor.
--    /**
--       The advanced copy constructor - as the default constructor CImg(const CImg< t >&) - creates a new instance image having same dimensions
--       \ref width, \ref height, \ref depth, \ref dim and same pixel values as the input image \p img.
--       But it also decides if the created instance image shares its memory with the input image \p img (if the input parameter
--       \p shared is set to \p true) or not (if the input parameter \p shared is set to \p false).
--       \param img The input image to copy.
--       \param shared Boolean flag that decides if the copy is shared on non-shared.
--       \remark
--       - It is not possible to create a shared copy if the input image \p img is empty or has a different pixel type \p t != \p T.
--       - If a non-shared copy of the input image \p img is created, a new memory buffer is allocated for pixel data.
--       - If a shared copy of the input image \p img is created, no extra memory is allocated and the pixel buffer of the instance
--       image is the same as the one used by the input image \p img.
--       \see CImg(const CImg< t >&), assign(const CImg< t >&,const bool).
--    **/
--    template<typename t> CImg(const CImg<t>& img, const bool shared):is_shared(false) {
--      if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a CImg<%s> image "
--                                              "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
--      const unsigned int siz = img.size();
--      if (img.data && siz) {
--        width = img.width; height = img.height; depth = img.depth; dim = img.dim; data = new T[siz];
--        const t *ptrs = img.data+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
--      } else { width = height = depth = dim = 0; data = 0; }
--    }
--
--    CImg(const CImg& img, const bool shared) {
--      const unsigned int siz = img.size();
--      if (img.data && siz) {
--        width = img.width; height = img.height; depth = img.depth; dim = img.dim; is_shared = shared;
--        if (is_shared) data = const_cast<T*>(img.data);
--        else { data = new T[siz]; std::memcpy(data,img.data,siz*sizeof(T)); }
--      } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--    }
--
--    //! In-place version of the advanced constructor.
--    /**
--       This function - as the simpler function assign(const CImg< t >&) - assigns a copy of the input image \p img to the
--       current instance image. But it also decides if the copy is shared (if the input parameter \p shared is set to \true) or non-shared
--       (if the input parameter \p shared is set to false).
--       \param img The input image to copy.
--       \param shared Boolean flag that decides if the copy is shared or non-shared.
--       \remark
--       - It is not possible to assign a shared copy if the input image \p img is empty or has a different pixel type \p t != \p T.
--       - If a non-shared copy of the input image \p img is assigned, a new memory buffer is allocated for pixel data.
--       - If a shared copy of the input image \p img is assigned, no extra memory is allocated and the pixel buffer of the instance
--       image is the same as the one used by the input image \p img.
--       \see CImg(const CImg< t >&,const bool), assign(const CImg< t >&).
--    **/
--    template<typename t> CImg& assign(const CImg<t>& img, const bool shared) {
--      return assign(img.data,img.width,img.height,img.depth,img.dim,shared);
--    }
--
--    //! Constructs a new image with given size (\p dx,\p dy,\p dz,\p dv).
--    /**
--       This constructors create an instance image of size (\p dx,\p dy,\p dz,\p dv) with pixels of type \p T.
--       \param dx Desired size along the X-axis, i.e. the \ref width of the image.
--       \param dy Desired size along the Y-axis, i.e. the \ref height of the image.
--       \param dz Desired size along the Z-axis, i.e. the \ref depth of the image.
--       \param dv Desired size along the V-axis, i.e. the number of image channels \ref dim.
--       \remark
--       - If one of the input dimension \p dx,\p dy,\p dz or \p dv is set to 0, the created image is empty
--       and all has its dimensions set to 0. No memory for pixel data is then allocated.
--       - This constructor creates only non-shared images.
--       - Image pixels allocated by this constructor are \b not \b initialized.
--       Use the constructor CImg(const unsigned int,const unsigned int,const unsigned int,const unsigned int,const T&)
--       to get an image of desired size with pixels set to a particular value.
--       \see assign(const unsigned int,const unsigned int,const unsigned int,const unsigned int),
--       CImg(const unsigned int,const unsigned int,const unsigned int,const unsigned int,const T&).
--    **/
--    explicit CImg(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1):
--      is_shared(false) {
--      const unsigned int siz = dx*dy*dz*dv;
--      if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; }
--      else { width = height = depth = dim = 0; data = 0; }
--    }
--
--    //! In-place version of the previous constructor.
--    /**
--       This function replaces the instance image by a new image of size (\p dx,\p dy,\p dz,\p dv) with pixels of type \p T.
--       \param dx Desired size along the X-axis, i.e. the \ref width of the image.
--       \param dy Desired size along the Y-axis, i.e. the \ref height of the image.
--       \param dz Desired size along the Z-axis, i.e. the \ref depth of the image.
--       \param dv Desired size along the V-axis, i.e. the number of image channels \p dim.
--       - If one of the input dimension \p dx,\p dy,\p dz or \p dv is set to 0, the instance image becomes empty
--       and all has its dimensions set to 0. No memory for pixel data is then allocated.
--       - Memory buffer used to store previous pixel values is freed if necessary.
--       - If the instance image is shared, this constructor actually does nothing more than verifying
--       that new and old image dimensions fit.
--       - Image pixels allocated by this function are \b not \b initialized.
--       Use the function assign(const unsigned int,const unsigned int,const unsigned int,const unsigned int,const T&)
--       to assign an image of desired size with pixels set to a particular value.
--       \see CImg(), assign(const unsigned int,const unsigned int,const unsigned int,const unsigned int).
--    **/
--    CImg& assign(const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1, const unsigned int dv=1) {
--      const unsigned long siz = dx*dy*dz*dv, curr_siz = size();
--      if (is_shared) {
--        if (siz!=curr_siz)
--          throw CImgArgumentException("CImg<%s>::assign() : Cannot assign image (%u,%u,%u,%u) to shared instance image (%u,%u,%u,%u,%p).",
--                                      pixel_type(),dx,dy,dz,dv,width,height,depth,dim,data);
--      } else {
--        if (siz) {
--          if (siz!=curr_siz) { if (data) delete[] data; data = new T[siz]; }
--          width = dx; height = dy; depth = dz; dim = dv;
--        } else {
--          if (data) delete[] data;
--          width = height = depth = dim = 0; data = 0;
--        }
--      }
--      return *this;
--    }
--
--    //! Construct an image with given size (\p dx,\p dy,\p dz,\p dv) and with pixel having a default value \p val.
--    /**
--       This constructor creates an instance image of size (\p dx,\p dy,\p dz,\p dv) with pixels of type \p T and sets all pixel
--       values of the created instance image to \p val.
--       \param dx Desired size along the X-axis, i.e. the \ref width of the image.
--       \param dy Desired size along the Y-axis, i.e. the \ref height of the image.
--       \param dz Desired size along the Z-axis, i.e. the \ref depth of the image.
--       \param dv Desired size along the V-axis, i.e. the number of image channels \p dim.
--       \param val Default value for image pixels.
--       \remark
--       - This constructor has the same properties as CImg(const unsigned int,const unsigned int,const unsigned int,const unsigned int).
--       \see CImg(const unsigned int,const unsigned int,const unsigned int,const unsigned int).
--    **/
--    CImg(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T& val):
--      is_shared(false) {
--      const unsigned int siz = dx*dy*dz*dv;
--      if (siz) { width = dx; height = dy; depth = dz; dim = dv; data = new T[siz]; fill(val); }
--      else { width = height = depth = dim = 0; data = 0; }
--    }
--
--    //! In-place version of the previous constructor.
--    /**
--       This function replaces the instance image by a new image of size (\p dx,\p dy,\p dz,\p dv) with pixels of type \p T
--       and sets all pixel values of the instance image to \p val.
--       \param dx Desired size along the X-axis, i.e. the \ref width of the image.
--       \param dy Desired size along the Y-axis, i.e. the \ref height of the image.
--       \param dz Desired size along the Z-axis, i.e. the \ref depth of the image.
--       \param dv Desired size along the V-axis, i.e. the number of image channels \p dim.
--       \param val Default value for image pixels.
--       \remark
--       - This function has the same properties as assign(const unsigned int,const unsigned int,const unsigned int,const unsigned int).
--       \see assign(const unsigned int,const unsigned int,const unsigned int,const unsigned int).
--    **/
--    CImg& assign(const unsigned int dx, const unsigned int dy, const unsigned int dz, const unsigned int dv, const T& val) {
--      return assign(dx,dy,dz,dv).fill(val);
--    }
--
--    //! Construct an image from an image file.
--    /**
--       This constructor creates an instance image by reading it from a file.
--       \param filename Filename of the image file.
--       \remark
--       - The image format is deduced from the filename only by looking for the filename extension i.e. without
--       analyzing the file itself.
--       - Recognized image formats depend on the tools installed on your system or the external libraries you use to link your code with.
--       More informations on this topic can be found in cimg_files_io.
--       - If the filename is not found, a CImgIOException is thrown by this constructor.
--       \see assign(const char *const), load(const char *const)
--    **/
--    CImg(const char *const filename):width(0),height(0),depth(0),dim(0),is_shared(false),data(0) {
--      assign(filename);
--    }
--
--    //! In-place version of the previous constructor.
--    /**
--       This function replaces the instance image by the one that have been read from the given file.
--       \param filename Filename of the image file.
--       - The image format is deduced from the filename only by looking for the filename extension i.e. without
--       analyzing the file itself.
--       - Recognized image formats depend on the tools installed on your system or the external libraries you use to link your code with.
--       More informations on this topic can be found in cimg_files_io.
--       - If the filename is not found, a CImgIOException is thrown by this constructor.
--    **/
--    CImg& assign(const char *const filename) {
--      return load(filename);
--    }
--
--    //! Construct an image from raw memory buffer.
--    /**
--       This constructor creates an instance image of size (\p dx,\p dy,\p dz,\p dv) and fill its pixel buffer by
--       copying data values from the input raw pixel buffer \p data_buffer.
--    **/
--    template<typename t> CImg(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
--                              const unsigned int dz=1, const unsigned int dv=1, const bool shared=false):is_shared(false) {
--      if (shared) throw CImgArgumentException("CImg<%s>::CImg() : Cannot construct a shared copy from a (%s*) buffer "
--                                              "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
--      const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) {
--        width = dx; height = dy; depth = dz; dim = dv; data = new T[siz];
--        const t *ptrs = data_buffer+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
--      } else { width = height = depth = dim = 0; data = 0; }
--    }
--
--#ifdef cimg_use_visualcpp6
--    CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
--         const unsigned int dz, const unsigned int dv, const bool shared) {
--#else
--    CImg(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
--         const unsigned int dz=1, const unsigned int dv=1, const bool shared=false) {
--#endif
--        const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) {
--        width = dx; height = dy; depth = dz; dim = dv; is_shared = shared;
--        if (is_shared) data = const_cast<T*>(data_buffer);
--        else { data = new T[siz]; std::memcpy(data,data_buffer,siz*sizeof(T)); }
--      } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--    }
--
--        template<typename t> CImg(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1, const unsigned int dz=1) {
--
--        }
--
--    //! In-place version of the previous constructor.
--#ifdef cimg_use_visualcpp6
--    template<typename t> CImg& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
--                                      const unsigned int dz, const unsigned int dv) {
--#else
--    template<typename t> CImg& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy=1,
--                                      const unsigned int dz=1, const unsigned int dv=1) {
--#endif
--      assign(dx,dy,dz,dv);
--      const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) { const t *ptrs = data_buffer+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs); }
--      else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--      return *this;
--    }
--
--    CImg& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy=1,
--                 const unsigned int dz=1, const unsigned int dv=1) {
--      assign(dx,dy,dz,dv);
--      const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) std::memcpy(data,data_buffer,siz*sizeof(T));
--      else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--      return *this;
--    }
--
--    //! In-place version of the previous constructor, allowing to force the shared state of the instance image.
--    template<typename t> CImg& assign(const t *const data_buffer, const unsigned int dx, const unsigned int dy,
--                                      const unsigned int dz, const unsigned int dv, const bool shared) {
--      if (shared) throw CImgArgumentException("CImg<%s>::assign() : Cannot define a shared copy from a CImg<%s> image "
--                                              "(different pixel types).",pixel_type(),CImg<t>::pixel_type());
--      if (data && !is_shared) delete[] data;
--      is_shared = false;
--      const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) {
--        width = dx; height = dy; depth = dz; dim = dv; data = new T[siz];
--        const t *ptrs = data_buffer+siz; cimg_for(*this,ptrd,T) *ptrd = (T)*(--ptrs);
--      } else { width = height = depth = dim = 0; data = 0; }
--      return *this;
--    }
--
--    CImg& assign(const T *const data_buffer, const unsigned int dx, const unsigned int dy,
--                 const unsigned int dz, const unsigned int dv, const bool shared) {
--      if (data && !is_shared) delete[] data;
--      const unsigned int siz = dx*dy*dz*dv;
--      if (data_buffer && siz) {
--        width = dx; height = dy; depth = dz; dim = dv; is_shared = shared;
--        if (is_shared) data = const_cast<T*>(data_buffer);
--        else { data = new T[siz]; std::memcpy(data,data_buffer,siz*sizeof(T)); }
--      } else { width = height = depth = dim = 0; is_shared = false; data = 0; }
--      return *this;
--    }
--
--    // INNER ROUTINE : Swap fields of an image (use it carefully!)
--    // If one of the image is shared, its content is replaced by the non-shared image (which remains unchanged).
--    CImg& swap(CImg& img) {
--      if (img.is_shared==is_shared) {
--        cimg::swap(width,img.width);
--        cimg::swap(height,img.height);
--        cimg::swap(depth,img.depth);
--        cimg::swap(dim,img.dim);
--        cimg::swap(data,img.data);
--      } else {
--        if (img.is_shared) img.assign(*this);
--        else assign(img);
--      }
--      return img;
--    }
--
--    //@}
--    //-------------------------------------
--    //
--    //! \name Image Informations
--    //@{
--    //-------------------------------------
--
--    //! Return the type of the pixel values.
--    /**
--       \return a string describing the type of the image pixels (template parameter \p T).
--       - The string returned may contains spaces (<tt>"unsigned char"</tt>).
--       - If the template parameter T does not correspond to a registered type, the string <tt>"unknown"</tt> is returned.
--    **/
--    static const char* pixel_type() {
--      return cimg::type<T>::id();
--    }
--
--    //! Return the total number of pixel values in an image.
--    /**
--       - Equivalent to : dimx() * dimy() * dimz() * dimv().
--
--       \par example:
--       \code
--       CImg<> img(100,100,1,3);
--       if (img.size()==100*100*3) std::fprintf(stderr,"This statement is true");
--       \endcode
--       \sa dimx(), dimy(), dimz(), dimv()
--    **/
--    unsigned long size() const {
--      return width*height*depth*dim;
--    }
--
--    //! Return the number of columns of the instance image (size along the X-axis, i.e image width).
--    /**
--       \sa width, dimy(), dimz(), dimv(), size().
--    **/
--    int dimx() const {
--      return (int)width;
--    }
--
--    //! Return the number of rows of the instance image (size along the Y-axis, i.e image height).
--    /**
--       \sa height, dimx(), dimz(), dimv(), size().
--    **/
--    int dimy() const {
--      return (int)height;
--    }
--
--    //! Return the number of slices of the instance image (size along the Z-axis).
--    /**
--       \sa depth, dimx(), dimy(), dimv(), size().
--    **/
--    int dimz() const {
--      return (int)depth;
--    }
--
--    //! Return the number of vector channels of the instance image (size along the V-axis).
--    /**
--       \sa dim, dimx(), dimy(), dimz(), size().
--    **/
--    int dimv() const {
--      return (int)dim;
--    }
--
--    //! Return \c true if images \c (*this) and \c img have same width.
--    template<typename t> bool is_sameX(const CImg<t>& img) const {
--      return (width==img.width);
--    }
--
--    //! Return \c true if images \c (*this) and the display \c disp have same width.
--    bool is_sameX(const CImgDisplay& disp) const {
--      return (width==disp.width);
--    }
--
--    //! Return \c true if images \c (*this) and \c img have same height.
--    template<typename t> bool is_sameY(const CImg<t>& img) const {
--      return (height==img.height);
--    }
--
--    //! Return \c true if images \c (*this) and the display \c disp have same height.
--    bool is_sameY(const CImgDisplay& disp) const {
--      return (height==disp.height);
--    }
--
--    //! Return \c true if images \c (*this) and \c img have same depth.
--    template<typename t> bool is_sameZ(const CImg<t>& img) const {
--      return (depth==img.depth);
--    }
--
--    //! Return \c true if images \c (*this) and \c img have same dim.
--    template<typename t> bool is_sameV(const CImg<t>& img) const {
--      return (dim==img.dim);
--    }
--
--    //! Return \c true if images have same width and same height.
--    template<typename t> bool is_sameXY(const CImg<t>& img) const {
--      return (is_sameX(img) && is_sameY(img));
--    }
--
--    //! Return \c true if image \c (*this) and the display \c disp have same width and same height.
--    bool is_sameXY(const CImgDisplay& disp) const {
--      return (is_sameX(disp) && is_sameY(disp));
--    }
--
--    //! Return \c true if images have same width, same height and same depth.
--    template<typename t> bool is_sameXYZ(const CImg<t>& img) const {
--      return (is_sameXY(img) && is_sameZ(img));
--    }
--
--    //! Return \c true if images \c (*this) and \c img have same width, same height, same depth and same number of channels.
--    template<typename t> bool is_sameXYZV(const CImg<t>& img) const {
--      return (is_sameXYZ(img) && is_sameV(img));
--    }
--
--    //! Return \c true if pixel (x,y,z,v) is inside the image boundaries.
--    bool contains(const int x, const int y=0, const int z=0, const int v=0) const {
--      return data && x>=0 && x<(int)width && y>=0 && y<(int)height && z>=0 && z<(int)depth && v>=0 && v<(int)dim;
--    }
--
--    //! Return \c true if current image is empty.
--    bool is_empty() const {
--      return !(data && width && height && depth && dim);
--    }
--
--    //! Return the offset of the pixel coordinates (\p x,\p y,\p z,\p v) with respect to the data pointer \c data.
--    /**
--       \param x X-coordinate of the pixel.
--       \param y Y-coordinate of the pixel.
--       \param z Z-coordinate of the pixel.
--       \param v V-coordinate of the pixel.
--
--       - No checking is done on the validity of the given coordinates.
--
--       \par example:
--       \code
--       CImg<float> img(100,100,1,3,0);         // Define a 100x100 color image with float-valued black pixels.
--       long off = img.offset(10,10,0,2);       // Get the offset of the blue value of the pixel located at (10,10).
--       float val = img[off];                   // Get the blue value of the pixel.
--       \endcode
--       \sa ptr(), operator()(), operator[](), cimg_storage.
--    **/
--    long offset(const int x=0, const int y=0, const int z=0, const int v=0) const {
--      return x + y*width + z*width*height + v*width*height*depth;
--    }
--
--    //! Return a pointer to the pixel value located at (\p x,\p y,\p z,\p v).
--    /**
--       \param x X-coordinate of the pixel.
--       \param y Y-coordinate of the pixel.
--       \param z Z-coordinate of the pixel.
--       \param v V-coordinate of the pixel.
--
--       - When called without parameters, ptr() returns a pointer to the begining of the pixel buffer.
--       - If the macro \c cimg_debug == 3, boundary checking is performed and warning messages may appear if
--       given coordinates are outside the image range (but function performances decrease).
--
--       \par example:
--       \code
--       CImg<float> img(100,100,1,1,0);   // Define a 100x100 greyscale image with float-valued pixels.
--       float *ptr = ptr(10,10);          // Get a pointer to the pixel located at (10,10).
--       float val = *ptr;                 // Get the pixel value.
--       \endcode
--       \sa data, offset(), operator()(), operator[](), cimg_storage, cimg_environment.
--    **/
--    T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
--      const long off = offset(x,y,z,v);
--#if cimg_debug>=3
--      if (off<0 || off>=(long)size()) {
--        cimg::warn(true,"CImg<%s>::ptr() : Asked for a pointer at coordinates (%u,%u,%u,%u) (offset=%u), "
--                   "outside image range (%u,%u,%u,%u) (size=%u)",
--                   pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--        return data;
--      }
--#endif
--      return data+off;
--    }
--
--    const T* ptr(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
--      const long off = offset(x,y,z,v);
--#if cimg_debug>=3
--      if (off<0 || off>=(long)size()) {
--        cimg::warn(true,"CImg<%s>::ptr() : Trying to get a pointer at (%u,%u,%u,%u) (offset=%d) which is"
--                   "outside the data of the image (%u,%u,%u,%u) (size=%u)",
--                   pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--        return data;
--      }
--#endif
--      return data+off;
--    }
--
--    //! Return an iterator to the first image pixel
--    iterator begin() {
--      return data;
--    }
--
--    const_iterator begin() const {
--      return data;
--    }
--
--    //! Return an iterator to the last image pixel
--    iterator end() {
--      return data + size();
--    }
--
--    const_iterator end() const {
--      return data + size();
--    }
--
--    //! Fast access to pixel value for reading or writing.
--    /**
--       \param x X-coordinate of the pixel.
--       \param y Y-coordinate of the pixel.
--       \param z Z-coordinate of the pixel.
--       \param v V-coordinate of the pixel.
--
--       - If one image dimension is equal to 1, it can be omitted in the coordinate list (see example below).
--       - If the macro \c cimg_debug == 3, boundary checking is performed and warning messages may appear
--       (but function performances decrease).
--
--       \par example:
--       \code
--       CImg<float> img(100,100,1,3,0);                       // Define a 100x100 color image with float-valued black pixels.
--       const float valR = img(10,10,0,0);                    // Read the red component at coordinates (10,10).
--       const float valG = img(10,10,0,1);                    // Read the green component at coordinates (10,10)
--       const float valB = img(10,10,2);                      // Read the blue component at coordinates (10,10) (Z-coordinate omitted here).
--       const float avg = (valR + valG + valB)/3;             // Compute average pixel value.
--       img(10,10,0) = img(10,10,1) = img(10,10,2) = avg;     // Replace the pixel (10,10) by the average grey value.
--       \endcode
--
--       \sa operator[](), ptr(), offset(), cimg_storage, cimg_environment.
--    **/
--    T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
--      const long off = offset(x,y,z,v);
--#if cimg_debug>=3
--      if (!data || off>=(long)size()) {
--        cimg::warn(true,"CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%d) "
--                   "outside the image range (%u,%u,%u,%u) (size=%u)",
--                   pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--        return *data;
--      }
--#endif
--      return data[off];
--    }
--
--    const T& operator()(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
--      const long off = offset(x,y,z,v);
--#if cimg_debug>=3
--      if (!data || off>=(long)size()) {
--        cimg::warn(true,"CImg<%s>::operator() : Pixel access requested at (%u,%u,%u,%u) (offset=%d) "
--                   "outside the image range (%u,%u,%u,%u) (size=%u)",
--                   pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--        return *data;
--      }
--#endif
--      return data[off];
--    }
--
--    //! Return pixel value at a given position. Equivalent to operator().
--    T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) {
--      const long off = offset(x,y,z,v);
--      if (!data || off>=(long)size())
--        throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%d) "
--                                    "outside the image range (%u,%u,%u,%u) (size=%u)",
--                                    pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--      return data[off];
--    }
--
--    const T& at(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int v=0) const {
--      const long off = offset(x,y,z,v);
--      if (!data || off>=(long)size())
--        throw CImgArgumentException("CImg<%s>::at() : Pixel access requested at (%u,%u,%u,%u) (offset=%d) "
--                                    "outside the image range (%u,%u,%u,%u) (size=%u)",
--                                    pixel_type(),x,y,z,v,off,width,height,depth,dim,size());
--      return data[off];
--    }
--
--    //! Fast access to pixel value for reading or writing, using an offset to the image pixel.
--    /**
--       \param off Offset of the pixel according to the begining of the pixel buffer, given by ptr().
--
--       - If the macro \c cimg_debug==3, boundary checking is performed and warning messages may appear
--       (but function performances decrease).
--       - As pixel values are aligned in memory, this operator can sometime useful to access values easier than
--       with operator()() (see example below).
--
--       \par example:
--       \code
--       CImg<float> vec(1,10);        // Define a vector of float values (10 lines, 1 row).
--       const float val1 = vec(0,4);  // Get the fifth element using operator()().
--       const float val2 = vec[4];    // Get the fifth element using operator[]. Here, val2==val1.
--       \endcode
--
--       \sa operator()(), ptr(), offset(), cimg_storage, cimg_environment.
--    **/
--    T& operator[](const unsigned long off) {
--      return operator()(off);
--    }
--
--    const T& operator[](const unsigned long off) const {
--      return operator()(off);
--    }
--
--    //! Return a reference to the last image value
--    T& back() {
--      return operator()(size()-1);
--    }
--
--    const T& back() const {
--      return operator()(size()-1);
--    }
--
--    //! Return a reference to the first image value
--    T& front() {
--      return *data;
--    }
--
--    const T& front() const {
--      return *data;
--    }
--
--    //! Read a pixel value with Dirichlet or Neumann boundary conditions.
--    /**
--       \param x X-coordinate of the pixel.
--       \param y Y-coordinate of the pixel.
--       \param z Z-coordinate of the pixel.
--       \param v V-coordinate of the pixel.
--       \param out_val Desired value if pixel coordinates are outside the image range (optional parameter).
--
--       - This function allows to read pixel values with boundary checking on all coordinates.
--       - If given coordinates are outside the image range and the parameter out_val is specified, the value \c out_val is returned.
--       - If given coordinates are outside the image range and the parameter out_val is not specified, the closest pixel value
--       is returned.
--
--       \par example:
--       \code
--       CImg<float> img(100,100,1,1,128);                     // Define a 100x100 images with all pixel values equal to 128.
--       const float val1 = img.pix4d(10,10,0,0,0);  // Equivalent to val1=img(10,10) (but slower).
--       const float val2 = img.pix4d(-4,5,0,0,0);   // Return 0, since coordinates are outside the image range.
--       const float val3 = img.pix4d(10,10,5,0,64); // Return 64, since coordinates are outside the image range.
--       \endcode
--
--       \sa operator()(), linear_pix4d(), cubic_pix2d().
--    **/
--    T pix4d(const int x, const int y, const int z, const int v, const T& out_val) const {
--      return (x<0 || y<0 || z<0 || v<0 || x>=dimx() || y>=dimy() || z>=dimz() || v>=dimv())?out_val:(*this)(x,y,z,v);
--    }
--
--    T pix4d(const int x, const int y, const int z, const int v) const {
--      return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
--                     z<0?0:(z>=dimz()?dimz()-1:z), v<0?0:(v>=dimv()?dimv()-1:v));
--    }
--
--    //! Read a pixel value with Dirichlet or Neumann boundary conditions for the three first coordinates (\c x,\c y,\c z).
--    T pix3d(const int x, const int y, const int z, const int v, const T& out_val) const {
--      return (x<0 || y<0 || z<0 || x>=dimx() || y>=dimy() || z>=dimz())?out_val:(*this)(x,y,z,v);
--    }
--
--    const T& pix3d(const int x, const int y, const int z, const int v=0) const {
--      return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),
--                     z<0?0:(z>=dimz()?dimz()-1:z),v);
--    }
--
--    //! Read a pixel value with Dirichlet or Neumann boundary conditions for the two first coordinates (\c x,\c y).
--    T pix2d(const int x, const int y, const int z, const int v, const T& out_val) const {
--      return (x<0 || y<0 || x>=dimx() || y>=dimy())?out_val:(*this)(x,y,z,v);
--    }
--
--    const T& pix2d(const int x,const int y,const int z=0,const int v=0) const {
--      return (*this)(x<0?0:(x>=dimx()?dimx()-1:x), y<0?0:(y>=dimy()?dimy()-1:y),z,v);
--    }
--
--    //! Read a pixel value with Dirichlet or Neumann boundary conditions for the first coordinate \c x.
--    T pix1d(const int x, const int y, const int z, const int v, const T& out_val) const {
--      return (x<0 || x>=dimx())?out_val:(*this)(x,y,z,v);
--    }
--
--    const T& pix1d(const int x, const int y=0, const int z=0, const int v=0) const {
--      return (*this)(x<0?0:(x>=dimx()?dimx()-1:x),y,z,v);
--    }
--
--    //! Read a pixel value using linear interpolation.
--    /**
--       \param ffx X-coordinate of the pixel (float-valued).
--       \param ffy Y-coordinate of the pixel (float-valued).
--       \param ffz Z-coordinate of the pixel (float-valued).
--       \param ffv V-coordinate of the pixel (float-valued).
--       \param out_val Out-of-border pixel value
--
--       - This function allows to read pixel values with boundary checking on all coordinates.
--       - If given coordinates are outside the image range, the value of the nearest pixel inside the image is returned
--       (Neumann boundary conditions).
--       - If given coordinates are float-valued, a linear interpolation is performed in order to compute the returned value.
--
--       \par example:
--       \code
--       CImg<float> img(2,2);     // Define a greyscale 2x2 image.
--       img(0,0) = 0;             // Fill image with specified pixel values.
--       img(1,0) = 1;
--       img(0,1) = 2;
--       img(1,1) = 3;
--       const double val = img.linear_pix4d(0.5,0.5);  // Return val=1.5, which is the average intensity of the four pixels values.
--       \endcode
--
--       \sa operator()(), linear_pix3d(), linear_pix2d(), linear_pix1d(), cubic_pix2d().
--    **/
--    typename cimg::largest<T,float>::type linear_pix4d(const float fx,const float fy,const float fz,const float fv,
--                                                       const T& out_val) const {
--      const int x = (int)fx-(fx>=0?0:1), y = (int)fy-(fy>=0?0:1), z = (int)fz-(fz>=0?0:1), v = (int)fv-(fv>=0?0:1),
--        nx = x+1, ny = y+1, nz = z+1, nv = v+1;
--      const float dx = fx-x, dy = fy-y, dz = fz-z, dv = fv-v;
--      const T
--        Icccc = pix4d(x,y,z,v,out_val),    Inccc = pix4d(nx,y,z,v,out_val),
--        Icncc = pix4d(x,ny,z,v,out_val),   Inncc = pix4d(nx,ny,z,v,out_val),
--        Iccnc = pix4d(x,y,nz,v,out_val),   Incnc = pix4d(nx,y,nz,v,out_val),
--        Icnnc = pix4d(x,ny,nz,v,out_val),  Innnc = pix4d(nx,ny,nz,v,out_val),
--        Icccn = pix4d(x,y,z,nv,out_val),   Inccn = pix4d(nx,y,z,nv,out_val),
--        Icncn = pix4d(x,ny,z,nv,out_val),  Inncn = pix4d(nx,ny,z,nv,out_val),
--        Iccnn = pix4d(x,y,nz,nv,out_val),  Incnn = pix4d(nx,y,nz,nv,out_val),
--        Icnnn = pix4d(x,ny,nz,nv,out_val), Innnn = pix4d(nx,ny,nz,nv,out_val);
--      return Icccc +
--        dx*(Inccc-Icccc +
--            dy*(Icccc+Inncc-Icncc-Inccc +
--                dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
--                    dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
--                dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
--            dz*(Icccc+Incnc-Iccnc-Inccc +
--                dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
--            dv*(Icccc+Inccn-Inccc-Icccn)) +
--        dy*(Icncc-Icccc +
--            dz*(Icccc+Icnnc-Iccnc-Icncc +
--                dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
--            dv*(Icccc+Icncn-Icncc-Icccn)) +
--        dz*(Iccnc-Icccc +
--            dv*(Icccc+Iccnn-Iccnc-Icccn)) +
--        dv*(Icccn-Icccc);
--    }
--
--    typename cimg::largest<T,float>::type linear_pix4d(const float ffx,const float ffy=0,const float ffz=0,const float ffv=0) const {
--      const float
--        fx = ffx<0?0:(ffx>width-1?width-1:ffx), fy = ffy<0?0:(ffy>height-1?height-1:ffy),
--        fz = ffz<0?0:(ffz>depth-1?depth-1:ffz), fv = ffv<0?0:(ffv>dim-1?dim-1:ffv);
--      const unsigned int x = (unsigned int)fx, y = (unsigned int)fy,  z = (unsigned int)fz, v = (unsigned int)fv;
--      const float dx = fx-x, dy = fy-y, dz = fz-z, dv = fv-v;
--      const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y,  nz = dz>0?z+1:z, nv = dv>0?v+1:v;
--      const T
--        &Icccc = (*this)(x,y,z,v),   &Inccc = (*this)(nx,y,z,v),   &Icncc = (*this)(x,ny,z,v),   &Inncc = (*this)(nx,ny,z,v),
--        &Iccnc = (*this)(x,y,nz,v),  &Incnc = (*this)(nx,y,nz,v),  &Icnnc = (*this)(x,ny,nz,v),  &Innnc = (*this)(nx,ny,nz,v),
--        &Icccn = (*this)(x,y,z,nv),  &Inccn = (*this)(nx,y,z,nv),  &Icncn = (*this)(x,ny,z,nv),  &Inncn = (*this)(nx,ny,z,nv),
--        &Iccnn = (*this)(x,y,nz,nv), &Incnn = (*this)(nx,y,nz,nv), &Icnnn = (*this)(x,ny,nz,nv), &Innnn = (*this)(nx,ny,nz,nv);
--      return Icccc +
--        dx*(Inccc-Icccc +
--            dy*(Icccc+Inncc-Icncc-Inccc +
--                dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
--                    dv*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
--                dv*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
--            dz*(Icccc+Incnc-Iccnc-Inccc +
--                dv*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
--            dv*(Icccc+Inccn-Inccc-Icccn)) +
--        dy*(Icncc-Icccc +
--            dz*(Icccc+Icnnc-Iccnc-Icncc +
--                dv*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
--            dv*(Icccc+Icncn-Icncc-Icccn)) +
--        dz*(Iccnc-Icccc +
--            dv*(Icccc+Iccnn-Iccnc-Icccn)) +
--        dv*(Icccn-Icccc);
--    }
--
--    //! Read a pixel value using linear interpolation for the three first coordinates (\c cx,\c cy,\c cz).
--    /**
--       - Same as linear_pix4d(), except that linear interpolation and boundary checking is performed only on the three first coordinates.
--
--       \sa operator()(), linear_pix4d(), linear_pix2d(), linear_pix1d(), linear_pix3d(), cubic_pix2d().
--    **/
--    typename cimg::largest<T,float>::type linear_pix3d(const float fx,const float fy,const float fz,const int v,
--                                                       const T& out_val) const {
--      const int x = (int)fx-(fx>=0?0:1), y = (int)fy-(fy>=0?0:1), z = (int)fz-(fz>=0?0:1), nx = x+1, ny = y+1, nz = z+1;
--      const float dx = fx-x, dy = fy-y, dz = fz-z;
--      const T
--        Iccc = pix3d(x,y,z,v,out_val),  Incc = pix3d(nx,y,z,v,out_val),  Icnc = pix3d(x,ny,z,v,out_val),  Innc = pix3d(nx,ny,z,v,out_val),
--        Iccn = pix3d(x,y,nz,v,out_val), Incn = pix3d(nx,y,nz,v,out_val), Icnn = pix3d(x,ny,nz,v,out_val), Innn = pix3d(nx,ny,nz,v,out_val);
--      return Iccc +
--        dx*(Incc-Iccc +
--            dy*(Iccc+Innc-Icnc-Incc +
--                dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
--            dz*(Iccc+Incn-Iccn-Incc)) +
--        dy*(Icnc-Iccc +
--            dz*(Iccc+Icnn-Iccn-Icnc)) +
--        dz*(Iccn-Iccc);
--    }
--
--    typename cimg::largest<T,float>::type linear_pix3d(const float ffx,const float ffy=0,const float ffz=0,const int v=0) const {
--      const float fx = ffx<0?0:(ffx>width-1?width-1:ffx), fy = ffy<0?0:(ffy>height-1?height-1:ffy), fz = ffz<0?0:(ffz>depth-1?depth-1:ffz);
--      const unsigned int x = (unsigned int)fx, y = (unsigned int)fy, z = (unsigned int)fz;
--      const float dx = fx-x, dy = fy-y, dz = fz-z;
--      const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y, nz = dz>0?z+1:z;
--      const T
--        &Iccc = (*this)(x,y,z,v),  &Incc = (*this)(nx,y,z,v),  &Icnc = (*this)(x,ny,z,v),  &Innc = (*this)(nx,ny,z,v),
--        &Iccn = (*this)(x,y,nz,v), &Incn = (*this)(nx,y,nz,v), &Icnn = (*this)(x,ny,nz,v), &Innn = (*this)(nx,ny,nz,v);
--      return Iccc +
--        dx*(Incc-Iccc +
--            dy*(Iccc+Innc-Icnc-Incc +
--                dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
--            dz*(Iccc+Incn-Iccn-Incc)) +
--        dy*(Icnc-Iccc +
--            dz*(Iccc+Icnn-Iccn-Icnc)) +
--        dz*(Iccn-Iccc);
--    }
--
--    //! Read a pixel value using linear interpolation for the two first coordinates (\c cx,\c cy).
--    /**
--       - Same as linear_pix4d(), except that linear interpolation and boundary checking is performed only on the two first coordinates.
--
--       \sa operator()(), linear_pix4d(), linear_pix3d(), linear_pix1d(), linear_pix2d(), cubic_pix2d().
--    **/
--    typename cimg::largest<T,float>::type linear_pix2d(const float fx, const float fy, const int z, const int v,
--                                                       const T& out_val) const {
--      const int x = (int)fx-(fx>0?0:1), y = (int)fy-(fy>0?0:1), nx = x+1, ny = y+1;
--      const float dx = fx-x, dy = fy-y;
--      const T
--        Icc = pix2d(x,y,z,v,out_val),  Inc = pix2d(nx,y,z,v,out_val),
--        Icn = pix2d(x,ny,z,v,out_val), Inn = pix2d(nx,ny,z,v,out_val);
--      return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
--    }
--
--    typename cimg::largest<T,float>::type linear_pix2d(const float ffx, const float ffy=0, const int z=0, const int v=0) const {
--      const float fx = ffx<0?0:(ffx>width-1?width-1:ffx), fy = ffy<0?0:(ffy>height-1?height-1:ffy);
--      const unsigned int x = (unsigned int)fx, y = (unsigned int)fy;
--      const float dx = fx-x, dy = fy-y;
--      const unsigned int nx = dx>0?x+1:x, ny = dy>0?y+1:y;
--      const T &Icc = (*this)(x,y,z,v), &Inc = (*this)(nx,y,z,v), &Icn = (*this)(x,ny,z,v), &Inn = (*this)(nx,ny,z,v);
--      return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
--    }
--
--    //! Read a pixel value using linear interpolation for the first coordinate \c cx.
--    /**
--       - Same as linear_pix4d(), except that linear interpolation and boundary checking is performed only on the first coordinate.
--
--       \sa operator()(), linear_pix4d(), linear_pix3d(), linear_pix2d(), linear_pix1d(), cubic_pix1d().
--    **/
--    typename cimg::largest<T,float>::type linear_pix1d(const float fx,const int y,const int z,const int v,
--                                                       const T& out_val) const {
--      const int x = (int)fx-(fx>0?0:1), nx = x+1;
--      const float dx = fx-x;
--      const T Ic = pix1d(x,y,z,v,out_val), In = pix2d(nx,y,z,v,out_val);
--      return Ic + dx*(In-Ic);
--    }
--
--    typename cimg::largest<T,float>::type linear_pix1d(const float ffx,const int y=0,const int z=0,const int v=0) const {
--      const float fx = ffx<0?0:(ffx>width-1?width-1:ffx);
--      const unsigned int x = (unsigned int)fx;
--      const float dx = fx-x;
--      const unsigned int nx = dx>0?x+1:x;
--      const T &Ic = (*this)(x,y,z,v), &In = (*this)(nx,y,z,v);
--      return Ic + dx*(In-Ic);
--    }
--
--    // This function is used as a subroutine for cubic interpolation
--    static float _cubic_R(const float x) {
--      const float xp2 = x+2, xp1 = x+1, xm1 = x-1,
--        nxp2 = xp2>0?xp2:0, nxp1 = xp1>0?xp1:0, nx = x>0?x:0, nxm1 = xm1>0?xm1:0;
--      return (nxp2*nxp2*nxp2 - 4*nxp1*nxp1*nxp1 + 6*nx*nx*nx - 4*nxm1*nxm1*nxm1)/6.0f;
--    }
--
--    //! Read a pixel value using cubic interpolation for the first coordinate \c cx.
--    /**
--       - Same as cubic_pix2d(), except that cubic interpolation and boundary checking is performed only on the first coordinate.
--
--       \sa operator()(), cubic_pix2d(), linear_pix1d().
--    **/
--    typename cimg::largest<T,float>::type cubic_pix1d(const float fx, const int y, const int z, const int v,
--                                                      const T& out_val) const {
--      const int x = (int)fx-(fx>=0?0:1), px = x-1, nx = x+1, ax = nx+1;
--      const float dx = fx-x;
--      const T a = pix2d(px,y,z,v,out_val), b = pix2d(x,y,z,v,out_val), c = pix2d(nx,y,z,v,out_val), d = pix2d(ax,y,z,v,out_val);
--      const float Rxp = _cubic_R(-1-dx), Rxc = _cubic_R(dx), Rxn = _cubic_R(1-dx), Rxa = _cubic_R(2-dx);
--      return Rxp*a + Rxc*b + Rxn*c + Rxa*d;
--    }
--
--    typename cimg::largest<T,float>::type cubic_pix1d(const float pfx, const int y=0, const int z=0, const int v=0) const {
--      const float fx = pfx<0?0:(pfx>width-1?width-1:pfx);
--      const unsigned int x = (unsigned int)fx, px = (int)x-1>=0?x-1:0, nx = x+1<width?x+1:width-1, ax = nx+1<width?nx+1:width-1;
--      const float dx = fx-x;
--      const T& a = (*this)(px,y,z,v), b = (*this)(x,y,z,v), c = (*this)(nx,y,z,v), d = (*this)(ax,y,z,v);
--      const float Rxp = _cubic_R(-1-dx), Rxc = _cubic_R(dx), Rxn = _cubic_R(1-dx), Rxa = _cubic_R(2-dx);
--      return Rxp*a + Rxc*b + Rxn*c + Rxa*d;
--    }
--
--    //! Read a pixel value using bicubic interpolation.
--    /**
--       \param pfx X-coordinate of the pixel (float-valued).
--       \param pfy Y-coordinate of the pixel (float-valued).
--       \param z   Z-coordinate of the pixel.
--       \param v   V-coordinate of the pixel.
--
--       - This function allows to read pixel values with boundary checking on the two first coordinates.
--       - If given coordinates are outside the image range, the value of the nearest pixel inside the image is returned
--       (Neumann boundary conditions).
--       - If given coordinates are float-valued, a cubic interpolation is performed in order to compute the returned value.
--
--       \sa operator()(), cubic_pix1d(), linear_pix2d().
--    **/
--    typename cimg::largest<T,float>::type cubic_pix2d(const float fx, const float fy, const int z, const int v,
--                                                      const T& out_val) const {
--      const int
--        x = (int)fx-(fx>=0?0:1), y = (int)fy-(fy>=0?0:1),
--        px = x-1, nx = x+1, ax = nx+1, py = y-1, ny = y+1, ay = ny+1;
--      const float dx = fx-x, dy = fy-y;
--      const T
--        a = pix2d(px,py,z,v,out_val), b = pix2d(x,py,z,v,out_val), c = pix2d(nx,py,z,v,out_val), d = pix2d(ax,py,z,v,out_val),
--        e = pix2d(px, y,z,v,out_val), f = pix2d(x, y,z,v,out_val), g = pix2d(nx, y,z,v,out_val), h = pix2d(ax, y,z,v,out_val),
--        i = pix2d(px,ny,z,v,out_val), j = pix2d(x,ny,z,v,out_val), k = pix2d(nx,ny,z,v,out_val), l = pix2d(ax,ny,z,v,out_val),
--        m = pix2d(px,ay,z,v,out_val), n = pix2d(x,ay,z,v,out_val), o = pix2d(nx,ay,z,v,out_val), p = pix2d(ax,ay,z,v,out_val);
--      const float
--        Rxp = _cubic_R(-1-dx), Rxc = _cubic_R(dx), Rxn = _cubic_R(1-dx), Rxa = _cubic_R(2-dx),
--        Ryp = _cubic_R(dy+1),  Ryc = _cubic_R(dy), Ryn = _cubic_R(dy-1), Rya = _cubic_R(dy-2);
--      return
--        Rxp*Ryp*a + Rxc*Ryp*b + Rxn*Ryp*c + Rxa*Ryp*d +
--        Rxp*Ryc*e + Rxc*Ryc*f + Rxn*Ryc*g + Rxa*Ryc*h +
--        Rxp*Ryn*i + Rxc*Ryn*j + Rxn*Ryn*k + Rxa*Ryn*l +
--        Rxp*Rya*m + Rxc*Rya*n + Rxn*Rya*o + Rxa*Rya*p;
--    }
--
--    typename cimg::largest<T,float>::type cubic_pix2d(const float pfx, const float pfy=0, const int z=0, const int v=0) const {
--      const float fx = pfx<0?0:(pfx>width-1?width-1:pfx), fy = pfy<0?0:(pfy>height-1?height-1:pfy);
--      const unsigned int
--        x = (unsigned int)fx,  px = (int)x-1>=0?x-1:0, nx = x+1<width?x+1:width-1, ax = nx+1<width?nx+1:width-1,
--        y = (unsigned int)fy,  py = (int)y-1>=0?y-1:0, ny = y+1<height?y+1:height-1, ay = ny+1<height?ny+1:height-1;
--      const float dx = fx-x, dy = fy-y;
--      const T&
--        a = (*this)(px,py,z,v), b = (*this)(x,py,z,v), c = (*this)(nx,py,z,v), d = (*this)(ax,py,z,v),
--        e = (*this)(px, y,z,v), f = (*this)(x, y,z,v), g = (*this)(nx, y,z,v), h = (*this)(ax, y,z,v),
--        i = (*this)(px,ny,z,v), j = (*this)(x,ny,z,v), k = (*this)(nx,ny,z,v), l = (*this)(ax,ny,z,v),
--        m = (*this)(px,ay,z,v), n = (*this)(x,ay,z,v), o = (*this)(nx,ay,z,v), p = (*this)(ax,ay,z,v);
--      const float
--        Rxp = _cubic_R(-1-dx), Rxc = _cubic_R(dx), Rxn = _cubic_R(1-dx), Rxa = _cubic_R(2-dx),
--        Ryp = _cubic_R(dy+1),  Ryc = _cubic_R(dy), Ryn = _cubic_R(dy-1), Rya = _cubic_R(dy-2);
--      return
--        Rxp*Ryp*a + Rxc*Ryp*b + Rxn*Ryp*c + Rxa*Ryp*d +
--        Rxp*Ryc*e + Rxc*Ryc*f + Rxn*Ryc*g + Rxa*Ryc*h +
--        Rxp*Ryn*i + Rxc*Ryn*j + Rxn*Ryn*k + Rxa*Ryn*l +
--        Rxp*Rya*m + Rxc*Rya*n + Rxn*Rya*o + Rxa*Rya*p;
--    }
--
--    //! Display informations about the image on the standard error output.
--    /**
--       \param title Name for the considered image (optional).
--       \param print_flag Level of informations to be printed.
--
--       - The possible values for \c print_flag are :
--           - 0 : print only informations about image size and pixel buffer.
--           - 1 : print also statistics on the image pixels.
--           - 2 : print also the content of the pixel buffer, in a matlab-style.
--
--       \par example:
--       \code
--       CImg<float> img("foo.jpg");      // Load image from a JPEG file.
--       img.print("Image : foo.jpg",1);  // Print image informations and statistics.
--       \endcode
--
--       \sa CImgStats
--    **/
--    const CImg& print(const char *title=0, const unsigned int print_flag=1) const {
--      std::fprintf(stderr,"%-8s(this=%p): { size=(%u,%u,%u,%u), data=(%s*)%p (%s)",
--                   title?title:"CImg",(void*)this,
--                   width,height,depth,dim,pixel_type(),(void*)data,
--                   is_shared?"shared":"not shared");
--      if (is_empty()) { std::fprintf(stderr,", [Undefined pixel data] }\n"); return *this; }
--      if (print_flag>=1) {
--        const CImgStats st(*this);
--        std::fprintf(stderr,", min=%g, mean=%g [var=%g], max=%g, pmin=(%d,%d,%d,%d), pmax=(%d,%d,%d,%d)",
--                     st.min,st.mean,st.variance,st.max,st.xmin,st.ymin,st.zmin,st.vmin,st.xmax,st.ymax,st.zmax,st.vmax);
--      }
--      if (print_flag>=2 || size()<=16) {
--        std::fprintf(stderr," }\n%s = [ ",title?title:"data");
--        cimg_forXYZV(*this,x,y,z,k)
--          std::fprintf(stderr,"%g%s",(double)(*this)(x,y,z,k),
--                       ((x+1)*(y+1)*(z+1)*(k+1)==(int)size()?" ]\n":(((x+1)%width==0)?" ; ":" ")));
--      } else std::fprintf(stderr," }\n");
--      return *this;
--    }
--
--    //! Display informations about the image on the standart output.
--    const CImg& print(const unsigned int print_flag) const {
--      return print(0,print_flag);
--    }
--
--    //@}
--    //------------------------------------------
--    //
--    //! \name Arithmetic and Boolean Operators
--    //@{
--    //------------------------------------------
--
--    //! Assignement operator.
--    /**
--       This operator assigns a copy of the input image \p img to the current instance image.
--       \param img The input image to copy.
--       \remark
--       - This operator is strictly equivalent to the function assign(const CImg< t >&) and has exactly the same properties.
--       \see assign(const CImg< t >&).
--    **/
--    template<typename t> CImg<T>& operator=(const CImg<t>& img) {
--      return assign(img);
--    }
--
--    CImg& operator=(const CImg& img) {
--      return assign(img);
--    }
--
--    //! Assign values of a C-array to the instance image.
--    /**
--       \param buf Pointer to a C-style array having a size of (at least) <tt>this->size()</tt>.
--
--       - Replace pixel values by the content of the array \c buf.
--       - Warning : the value types in the array and in the image must be the same.
--
--       \par example:
--       \code
--       float tab[4*4] = { 1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16 };  // Define a 4x4 matrix in C-style.
--       CImg<float> matrice(4,4);                                        // Define a 4x4 greyscale image.
--       matrice = tab;                                                   // Fill the image by the values in tab.
--       \endcode
--    **/
--    CImg& operator=(const T *buf) {
--      if (buf) std::memcpy(data,buf,size()*sizeof(T));
--      else assign();
--      return *this;
--    }
--
--    //! Assign a value to each image pixel of the instance image.
--    CImg& operator=(const T& val) {
--      return fill(val);
--    }
--
--    //! Operator+
--    /**
--       \remark
--       - This operator can be used to get a non-shared copy of an image.
--    **/
--    CImg operator+() const {
--      return CImg<T>(*this,false);
--    }
--
--    //! Operator+=;
--#ifdef cimg_use_visualcpp6
--    CImg& operator+=(const T& val) {
--#else
--        template<typename t> CImg& operator+=(const t& val) {
--#endif
--      cimg_for(*this,ptr,T) (*ptr)=(T)((*ptr)+val);
--      return *this;
--    }
--
--    //! Operator+=
--    template<typename t> CImg& operator+=(const CImg<t>& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      t *ptrs = img.data+smin;
--      for (T *ptrd = data+smin; ptrd>data; --ptrd, (*ptrd)=(T)((*ptrd)+(*(--ptrs))));
--      return *this;
--    }
--
--    //! Operator++;
--    CImg& operator++() {
--      cimg_for(*this,ptr,T) (*ptr)++;
--      return *this;
--    }
--
--    //! Operator-.
--    CImg operator-() const {
--      return CImg<T>(width,height,depth,dim,0)-=*this;
--    }
--
--    //! Operator-=.
--#ifdef cimg_use_visualcpp6
--        CImg& operator-=(const T& val) {
--#else
--        template<typename t> CImg& operator-=(const t& val) {
--#endif
--                cimg_for(*this,ptr,T) (*ptr)=(T)((*ptr)-val);
--      return *this;
--    }
--
--    //! Operator-=.
--    template<typename t> CImg& operator-=(const CImg<t>& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      t *ptrs = img.data+smin;
--      for (T *ptrd = data+smin; ptrd>data; --ptrd, (*ptrd)=(T)((*ptrd)-(*(--ptrs))));
--      return *this;
--    }
--
--    //! Operator--.
--    CImg& operator--() {
--      cimg_for(*this,ptr,T) (*ptr)--;
--      return *this;
--    }
--
--    //! Operator*=.
--#ifdef cimg_use_visualcpp6
--    CImg& operator*=(const double val) {
--#else
--        template<typename t> CImg& operator*=(const t& val) {
--#endif
--                cimg_for(*this,ptr,T) (*ptr)=(T)((*ptr)*val);
--      return *this;
--    }
--
--    //! Operator*=.
--    template<typename t> CImg& operator*=(const CImg<t>& img) {
--      return ((*this)*img).swap(*this);
--    }
--
--    //! Operator/=.
--#ifdef cimg_use_visualcpp6
--    CImg& operator/=(const double val) {
--#else
--    template<typename t> CImg& operator/=(const t& val) {
--#endif
--                cimg_for(*this,ptr,T) (*ptr)=(T)((*ptr)/val);
--      return *this;
--    }
--
--    //! Operator/=.
--    template<typename t> CImg& operator/=(const CImg<t>& img) {
--      return assign(*this*img.get_inverse());
--    }
--
--    //! Modulo.
--    CImg operator%(const CImg& img) const {
--      return (+*this)%=img;
--    }
--
--    //! Modulo.
--    CImg operator%(const T& val) const {
--      return (+*this)%=val;
--    }
--
--    //! In-place modulo.
--    CImg& operator%=(const T& val) {
--      cimg_for(*this,ptr,T) (*ptr)%=val;
--      return *this;
--    }
--
--    //! In-place modulo.
--    CImg& operator%=(const CImg& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      for (T *ptrs=img.data+smin, *ptrd=data+smin; ptrd>data; *(--ptrd)%=*(--ptrs));
--      return *this;
--    }
--
--    //! Bitwise AND.
--    CImg operator&(const CImg& img) const {
--      return (+*this)&=img;
--    }
--
--    //! Bitwise AND.
--    CImg operator&(const T& val) const {
--      return (+*this)&=val;
--    }
--
--    //! In-place bitwise AND.
--    CImg& operator&=(const CImg& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      for (T *ptrs=img.data+smin, *ptrd=data+smin; ptrd>data; *(--ptrd)&=*(--ptrs));
--      return *this;
--    }
--
--    //! In-place bitwise AND.
--    CImg& operator&=(const T& val) {
--      cimg_for(*this,ptr,T) (*ptr)&=val;
--      return *this;
--    }
--
--    //! Bitwise OR.
--    CImg operator|(const CImg& img) const {
--      return (+*this)|=img;
--    }
--
--    //! Bitwise OR.
--    CImg operator|(const T& val) const {
--      return (+*this)|=val;
--    }
--
--    //! In-place bitwise OR.
--    CImg& operator|=(const CImg& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      for (T *ptrs=img.data+smin, *ptrd=data+smin; ptrd>data; *(--ptrd)|=*(--ptrs));
--      return *this;
--    }
--
--    //! In-place bitwise OR.
--    CImg& operator|=(const T& val) {
--      cimg_for(*this,ptr,T) (*ptr)|=val;
--      return *this;
--    }
--
--    //! Bitwise XOR.
--    CImg operator^(const CImg& img) const {
--      return (+*this)^=img;
--    }
--
--    //! Bitwise XOR.
--    CImg operator^(const T& val) const {
--      return (+*this)^=val;
--    }
--
--    //! In-place bitwise XOR.
--    CImg& operator^=(const CImg& img) {
--      const unsigned int smin = cimg::min(size(),img.size());
--      for (T *ptrs=img.data+smin, *ptrd=data+smin; ptrd>data; *(--ptrd)^=*(--ptrs));
--      return *this;
--    }
--
--    //! In-place bitwise XOR.
--    CImg& operator^=(const T& val) {
--      cimg_for(*this,ptr,T) (*ptr)^=val;
--      return *this;
--    }
--
--    //! Boolean NOT.
--    CImg operator!() const {
--      CImg<T> res(width,height,depth,dim);
--      const T *ptrs = end();
--      cimg_for(res,ptrd,T) *ptrd=!(*(--ptrs));
--      return res;
--    }
--
--    //! Bitwise NOT.
--    CImg operator~() const {
--      CImg<T> res(width,height,depth,dim);
--      const T *ptrs = end();
--      cimg_for(res,ptrd,T) *ptrd=~(*(--ptrs));
--      return res;
--    }
--
--    //! Bitwise shift
--    CImg& operator<<=(const unsigned int n) {
--      cimg_for(*this,ptr,T) (*ptr)<<=n;
--      return *this;
--    }
--
--    //! Bitwise shift
--    CImg operator<<(const unsigned int n) const {
--      return (+*this)<<=n;
--    }
--
--    //! Bitwise shift
--    CImg& operator>>=(const unsigned int n) {
--      cimg_for(*this,ptr,T) (*ptr)>>=n;
--      return *this;
--    }
--
--    //! Bitwise shift
--    CImg operator>>(const unsigned int n) const {
--      return (+*this)>>=n;
--    }
--
--    //! Boolean equality.
--    template<typename t> bool operator==(const CImg<t>& img) const {
--      const unsigned int siz = size();
--      bool vequal = true;
--      if (siz!=img.size()) return false;
--      t *ptrs=img.data+siz;
--      for (T *ptrd=data+siz; vequal && ptrd>data; vequal=vequal&&((*(--ptrd))==(*(--ptrs))));
--      return vequal;
--    }
--
--    //! Boolean difference.
--    template<typename t> bool operator!=(const CImg<t>& img) const {
--      return !((*this)==img);
--    }
--
--    //! Get a new list
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> operator<<(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this,img);
--    }
--
--    //@}
--    //---------------------------------------
--    //
--    //! \name Usual Mathematics
--    //@{
--    //---------------------------------------
--
--    //! Apply a R->R function on all image value.
--    template<typename ts, typename td> CImg& apply(td (*func)(ts)) {
--      cimg_for(*this,ptr,T) *ptr = (T)func(*ptr);
--      return *this;
--    }
--
--    //! Return an image where each pixel value is equal to func(x).
--    template<typename ts, typename td> CImg<typename cimg::largest<T,td>::type> get_apply(td (*func)(ts)) {
--      typedef typename cimg::largest<T,td>::type restype;
--      return CImg<restype>(*this,false).apply(func);
--    }
--
--    //! In-place pointwise multiplication between \c *this and \c img.
--    /**
--       This is the in-place version of get_mul().
--       \sa get_mul().
--    **/
--    template<typename t> CImg& mul(const CImg<t>& img) {
--      t *ptrs = img.data;
--      T *ptrf = data + cimg::min(size(),img.size());
--      for (T* ptrd = data; ptrd<ptrf; ptrd++) (*ptrd)=(T)(*ptrd*(*(ptrs++)));
--      return *this;
--    }
--
--    //! Pointwise multiplication between \c *this and \c img.
--    /**
--       \param img Argument of the multiplication.
--       - if \c *this and \c img have different size, the multiplication is applied on the maximum possible range.
--       \sa get_div(),mul(),div()
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type> get_mul(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImg<restype>(*this,false).mul(img);
--    }
--
--    //! Replace the image by the pointwise division between \p *this and \p img.
--    /**
--       This is the in-place version of get_div().
--       \see get_div().
--    **/
--    template<typename t> CImg& div(const CImg<t>& img) {
--      t *ptrs = img.data;
--      T *ptrf = data + cimg::min(size(),img.size());
--      for (T* ptrd = data; ptrd<ptrf; ptrd++) (*ptrd)=(T)(*ptrd/(*(ptrs++)));
--      return *this;
--    }
--
--    //! Return an image from a pointwise division between \p *this and \p img.
--    /**
--       \param img = argument of the division.
--       \note if \c *this and \c img have different size, the division is applied
--       only on possible values.
--       \see get_mul(),mul(),div()
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type> get_div(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImg<restype>(*this,false).div(img);
--    }
--
--    //! Replace the image by the pointwise max operator between \p *this and \p img
--    /**
--       This is the in-place version of get_max().
--       \see get_max().
--    **/
--    template<typename t> CImg& max(const CImg<t>& img) {
--      t *ptrs = img.data;
--      T *ptrf = data + cimg::min(size(),img.size());
--      for (T* ptrd = data; ptrd<ptrf; ptrd++) (*ptrd)=cimg::max((T)*(ptrs++),*ptrd);
--      return *this;
--    }
--
--    //! Return the image corresponding to the max value for each pixel.
--    /**
--       \param img = second argument of the max operator (the first one is *this).
--       \see max(), min(), get_min()
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type> get_max(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImg<restype>(*this,false).max(img);
--    }
--
--    //! Replace the image by the pointwise max operator between \p *this and \p val
--    /**
--       This is the in-place version of get_max().
--       \see get_max().
--    **/
--#ifdef cimg_use_visualcpp6
--    CImg& max(const T val) {
--#else
--        CImg& max(const T& val) {
--#endif
--      cimg_for(*this,ptr,T) (*ptr)=cimg::max(*ptr,val);
--      return *this;
--    }
--
--    //! Return the image corresponding to the max value for each pixel.
--    /**
--       \param val = second argument of the max operator (the first one is *this).
--       \see max(), min(), get_min()
--    **/
--#ifdef cimg_use_visualcpp6
--    CImg get_max(const T val) const {
--#else
--        CImg get_max(const T& val) const {
--#endif
--      return (+*this).max(val);
--    }
--
--    //! Replace the image by the pointwise min operator between \p *this and \p img
--    /**
--       This is the in-place version of get_min().
--       \see get_min().
--    **/
--    template<typename t> CImg& min(const CImg<t>& img) {
--      t *ptrs = img.data;
--      T *ptrf = data + cimg::min(size(),img.size());
--      for (T* ptrd = data; ptrd<ptrf; ptrd++) (*ptrd)=cimg::min((T)*(ptrs++),*ptrd);
--      return *this;
--    }
--    //! Return the image corresponding to the min value for each pixel.
--    /**
--       \param img = second argument of the min operator (the first one is *this).
--       \see min(), max(), get_max()
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type> get_min(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImg<restype>(*this,false).min(img);
--    }
--
--    //! Replace the image by the pointwise min operator between \p *this and \p val
--    /**
--       This is the in-place version of get_min().
--       \see get_min().
--    **/
--#ifdef cimg_use_visualcpp6
--    CImg& min(const T val) {
--#else
--        CImg& min(const T& val) {
--#endif
--      cimg_for(*this,ptr,T) (*ptr)=cimg::min(*ptr,val);
--      return *this;
--    }
--
--    //! Return the image corresponding to the min value for each pixel.
--    /**
--       \param val = second argument of the min operator (the first one is *this).
--       \see min(), max(), get_max()
--    **/
--#ifdef cimg_use_visualcpp6
--    CImg get_min(const T val) const {
--#else
--        CImg get_min(const T& val) const {
--#endif
--      return (+*this).min(val);
--    }
--
--    //! Replace each image pixel by its square root.
--    /**
--       \see get_sqrt()
--    **/
--    CImg& sqrt() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::sqrt((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the square root of the pixel values.
--    /**
--       \see sqrt()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_sqrt() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).sqrt();
--    }
--
--    //! Replace each image pixel by its exponential.
--    CImg& exp() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::exp((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the exponential of the pixel values.
--    CImg<typename cimg::largest<T,float>::type> get_exp() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).exp();
--    }
--
--    //! Replace each image pixel by its log.
--    /**
--       \see get_log(), log10(), get_log10()
--    **/
--    CImg& log() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::log((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the log of the pixel values.
--    /**
--       \see log(), log10(), get_log10()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_log() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).log();
--    }
--
--    //! Replace each image pixel by its log10.
--    /**
--       \see get_log10(), log(), get_log()
--    **/
--    CImg& log10() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::log10((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the log10 of the pixel values.
--    /**
--       \see log10(), log(), get_log()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_log10() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).log10();
--    }
--
--    //! Replace each image pixel by its power by \p p.
--    /**
--       \param p = power
--       \see get_pow(), sqrt(), get_sqrt()
--    **/
--    CImg& pow(const double p) {
--      if (p==0) return fill(1);
--      if (p==1) return *this;
--      if (p==2) { cimg_for(*this,ptr,T) { const T& val = *ptr; *ptr=val*val; } return *this; }
--      if (p==3) { cimg_for(*this,ptr,T) { const T& val = *ptr; *ptr=val*val*val; } return *this; }
--      if (p==4) { cimg_for(*this,ptr,T) { const T& val = *ptr; *ptr=val*val*val*val; } return *this; }
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::pow((double)(*ptr),p);
--      return *this;
--    }
--
--    //! Return the image of the square root of the pixel values.
--    /**
--       \param p = power
--       \see pow(), sqrt(), get_sqrt()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_pow(const double p) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).pow(p);
--    }
--
--    //! Return each image pixel (*this)(x,y,z,k) by its power by \p img(x,y,z,k)
--    /**
--       In-place version
--    **/
--    template<typename t> CImg& pow(const CImg<t>& img) {
--      t *ptrs = img.data;
--      T *ptrf = data + cimg::min(size(),img.size());
--      for (T* ptrd = data; ptrd<ptrf; ptrd++) (*ptrd)=(T)std::pow((double)*ptrd,(double)(*(ptrs++)));
--      return *this;
--    }
--
--    //! Return each image pixel (*this)(x,y,z,k) by its power by \p img(x,y,z,k)
--    template<typename t> CImg<typename cimg::largest<T,float>::type> get_pow(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).pow(img);
--    }
--
--    //! Replace each pixel value by its absolute value.
--    /**
--       \see get_abs()
--    **/
--    CImg& abs() {
--      cimg_for(*this,ptr,T) (*ptr)=cimg::abs(*ptr);
--      return *this;
--    }
--
--    //! Return the image of the absolute value of the pixel values.
--    /**
--       \see abs()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_abs() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).abs();
--    }
--
--    //! Replace each image pixel by its cosinus.
--    /**
--       \see get_cos(), sin(), get_sin(), tan(), get_tan()
--    **/
--    CImg& cos() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::cos((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the cosinus of the pixel values.
--    /**
--       \see cos(), sin(), get_sin(), tan(), get_tan()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_cos() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).cos();
--    }
--
--    //! Replace each image pixel by its sinus.
--    /**
--       \see get_sin(), cos(), get_cos(), tan(), get_tan()
--    **/
--    CImg& sin() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::sin((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the sinus of the pixel values.
--    /**
--       \see sin(), cos(), get_cos(), tan(), get_tan()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_sin() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).sin();
--    }
--
--    //! Replace each image pixel by its tangent.
--    /**
--       \see get_tan(), cos(), get_cos(), sin(), get_sin()
--    **/
--    CImg& tan() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::tan((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the tangent of the pixel values.
--    /**
--       \see tan(), cos(), get_cos(), sin(), get_sin()
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_tan() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).tan();
--    }
--
--    //! Replace each image pixel by its arc-cosinus.
--    CImg& acos() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::acos((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the arc-cosinus of the pixel values.
--    CImg<typename cimg::largest<T,float>::type> get_acos() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).acos();
--    }
--
--    //! Replace each image pixel by its arc-sinus.
--    CImg& asin() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::asin((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the arc-sinus of the pixel values.
--    CImg<typename cimg::largest<T,float>::type> get_asin() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).asin();
--    }
--
--    //! Replace each image pixel by its arc-tangent.
--    CImg& atan() {
--      cimg_for(*this,ptr,T) (*ptr)=(T)std::atan((double)(*ptr));
--      return *this;
--    }
--
--    //! Return the image of the arc-tangent of the pixel values.
--    CImg<typename cimg::largest<T,float>::type> get_atan() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).atan();
--    }
--
--    //! Return the MSE (Mean-Squared Error) between two images.
--    template<typename t> double MSE(const CImg<t>& img) const {
--      if (img.size()!=size())
--        throw CImgArgumentException("CImg<%s>::MSE() : Instance image (%u,%u,%u,%u) and given image (%u,%u,%u,%u) have different dimensions.",
--                                    pixel_type(),width,height,depth,dim,img.width,img.height,img.depth,img.dim);
--
--      double vMSE = 0;
--      const t* ptr2 = img.end();
--      cimg_for(*this,ptr1,T) {
--        const double diff = (double)*ptr1 - (double)*(--ptr2);
--        vMSE += diff*diff;
--      }
--      vMSE/=img.size();
--      return vMSE;
--    }
--
--    //! Return the PSNR between two images.
--    template<typename t> double PSNR(const CImg<t>& img, const double valmax=255.0) const {
--      const double vMSE = std::sqrt(MSE(img));
--      return (vMSE!=0)?(20*std::log10(valmax/vMSE)):(cimg::type<double>::max());
--    }
--
--    //@}
--    //-----------------------------------
--    //
--    //! \name Usual Image Transformations
--    //@{
--    //-----------------------------------
--
--    //! Fill an image by a value \p val.
--    /**
--       \param val = fill value
--       \note All pixel values of the instance image will be initialized by \p val.
--       \see operator=().
--    **/
--    CImg& fill(const T& val) {
--      if (!is_empty()) {
--        if (val!=0 && sizeof(T)!=1) cimg_for(*this,ptr,T) *ptr=val;
--        else std::memset(data,(int)val,size()*sizeof(T));
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val) const {
--      return (+*this).fill(val);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 respectively.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--    **/
--    CImg& fill(const T& val0,const T& val1) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-1;
--        for (ptr=data; ptr<ptr_end; ) { *(ptr++)=val0; *(ptr++)=val1; }
--        if (ptr!=ptr_end+1) *(ptr++)=val0;
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1) const {
--      return (+*this).fill(val0,val1);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-2;
--        for (ptr=data; ptr<ptr_end; ) { *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; }
--        ptr_end+=2;
--        switch (ptr_end-ptr) {
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2) const {
--      return (+*this).fill(val0,val1,val2);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-3;
--        for (ptr=data; ptr<ptr_end; ) { *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; }
--        ptr_end+=3;
--        switch (ptr_end-ptr) {
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3) const {
--      return (+*this).fill(val0,val1,val2,val3);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a val4.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,const T& val4) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-4;
--        for (ptr=data; ptr<ptr_end; ) { *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; }
--        ptr_end+=4;
--        switch (ptr_end-ptr) {
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4) const {
--      return (+*this).fill(val0,val1,val2,val3,val4);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a val4 and \a val5
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,const T& val4,const T& val5) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-5;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5;
--        }
--        ptr_end+=5;
--        switch (ptr_end-ptr) {
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a val4 and \a val5
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,
--               const T& val4,const T& val5,const T& val6) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-6;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5; *(ptr++)=val6;
--        }
--        ptr_end+=6;
--        switch (ptr_end-ptr) {
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val7.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,
--               const T& val4,const T& val5,const T& val6,const T& val7) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-7;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3;
--          *(ptr++)=val4; *(ptr++)=val5; *(ptr++)=val6; *(ptr++)=val7;
--        }
--        ptr_end+=7;
--        switch (ptr_end-ptr) {
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val8.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,
--               const T& val3,const T& val4,const T& val5,
--               const T& val6,const T& val7,const T& val8) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-8;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2;
--          *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5;
--          *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8;
--        }
--        ptr_end+=8;
--        switch (ptr_end-ptr) {
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7, const T& val8) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val9.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--       \param val9 = fill value 10
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,const T& val4,
--               const T& val5,const T& val6,const T& val7,const T& val8,const T& val9) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-9;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4;
--          *(ptr++)=val5; *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8; *(ptr++)=val9;
--        }
--        ptr_end+=9;
--        switch (ptr_end-ptr) {
--        case 9: *(--ptr_end)=val8;
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7, const T& val8, const T& val9) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val11.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--       \param val9 = fill value 10
--       \param val10 = fill value 11
--       \param val11 = fill value 12
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,
--               const T& val4,const T& val5,const T& val6,const T& val7,
--               const T& val8,const T& val9,const T& val10,const T& val11) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-11;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5;
--          *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8; *(ptr++)=val9; *(ptr++)=val10; *(ptr++)=val11;
--        }
--        ptr_end+=11;
--        switch (ptr_end-ptr) {
--        case 11: *(--ptr_end)=val10;
--        case 10: *(--ptr_end)=val9;
--        case 9: *(--ptr_end)=val8;
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val11.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--       \param val9 = fill value 10
--       \param val10 = fill value 11
--       \param val11 = fill value 12
--       \param val12 = fill value 13
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,
--               const T& val4,const T& val5,const T& val6,const T& val7,
--               const T& val8,const T& val9,const T& val10,const T& val11,
--               const T& val12) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-12;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5;
--          *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8; *(ptr++)=val9; *(ptr++)=val10; *(ptr++)=val11;
--          *(ptr++)=val12;
--        }
--        ptr_end+=12;
--        switch (ptr_end-ptr) {
--        case 12: *(--ptr_end)=val11;
--        case 11: *(--ptr_end)=val10;
--        case 10: *(--ptr_end)=val9;
--        case 9: *(--ptr_end)=val8;
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11,
--                  const T& val12, const T& val13) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13);
--    }
--
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val15.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--       \param val9 = fill value 10
--       \param val10 = fill value 11
--       \param val11 = fill value 12
--       \param val12 = fill value 13
--       \param val13 = fill value 14
--       \param val14 = fill value 15
--       \param val15 = fill value 16
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,
--               const T& val4,const T& val5,const T& val6,const T& val7,
--               const T& val8,const T& val9,const T& val10,const T& val11,
--               const T& val12,const T& val13,const T& val14,const T& val15) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-15;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4; *(ptr++)=val5;
--          *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8; *(ptr++)=val9; *(ptr++)=val10; *(ptr++)=val11;
--          *(ptr++)=val12; *(ptr++)=val13; *(ptr++)=val14; *(ptr++)=val15;
--        }
--        ptr_end+=15;
--        switch (ptr_end-ptr) {
--        case 15: *(--ptr_end)=val14;
--        case 14: *(--ptr_end)=val13;
--        case 13: *(--ptr_end)=val12;
--        case 12: *(--ptr_end)=val11;
--        case 11: *(--ptr_end)=val10;
--        case 10: *(--ptr_end)=val9;
--        case 9: *(--ptr_end)=val8;
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0, const T& val1, const T& val2, const T& val3, const T& val4, const T& val5,
--                  const T& val6, const T& val7, const T& val8, const T& val9, const T& val10, const T& val11,
--                  const T& val12, const T& val13, const T& val14, const T& val15) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,val13,val14,val15);
--    }
--
--    //! Fill sequentially all pixel values with values \a val0 and \a val1 and \a val2 and \a val3 and \a ... and \a val24.
--    /**
--       \param val0 = fill value 1
--       \param val1 = fill value 2
--       \param val2 = fill value 3
--       \param val3 = fill value 4
--       \param val4 = fill value 5
--       \param val5 = fill value 6
--       \param val6 = fill value 7
--       \param val7 = fill value 8
--       \param val8 = fill value 9
--       \param val9 = fill value 10
--       \param val10 = fill value 11
--       \param val11 = fill value 12
--       \param val12 = fill value 13
--       \param val13 = fill value 14
--       \param val14 = fill value 15
--       \param val15 = fill value 16
--       \param val16 = fill value 17
--       \param val17 = fill value 18
--       \param val18 = fill value 19
--       \param val19 = fill value 20
--       \param val20 = fill value 21
--       \param val21 = fill value 22
--       \param val22 = fill value 23
--       \param val23 = fill value 24
--       \param val24 = fill value 25
--    **/
--    CImg& fill(const T& val0,const T& val1,const T& val2,const T& val3,const T& val4,
--               const T& val5,const T& val6,const T& val7,const T& val8,const T& val9,
--               const T& val10,const T& val11,const T& val12,const T& val13,const T& val14,
--               const T& val15,const T& val16,const T& val17,const T& val18,const T& val19,
--               const T& val20,const T& val21,const T& val22,const T& val23,const T& val24) {
--      if (!is_empty()) {
--        T *ptr, *ptr_end = end()-24;
--        for (ptr=data; ptr<ptr_end; ) {
--          *(ptr++)=val0; *(ptr++)=val1; *(ptr++)=val2; *(ptr++)=val3; *(ptr++)=val4;
--          *(ptr++)=val5; *(ptr++)=val6; *(ptr++)=val7; *(ptr++)=val8; *(ptr++)=val9;
--          *(ptr++)=val10; *(ptr++)=val11; *(ptr++)=val12; *(ptr++)=val13; *(ptr++)=val14;
--          *(ptr++)=val15; *(ptr++)=val16; *(ptr++)=val17; *(ptr++)=val18; *(ptr++)=val19;
--          *(ptr++)=val20; *(ptr++)=val21; *(ptr++)=val22; *(ptr++)=val23; *(ptr++)=val24;
--        }
--        ptr_end+=24;
--        switch (ptr_end-ptr) {
--        case 24: *(--ptr_end)=val23;
--        case 23: *(--ptr_end)=val22;
--        case 22: *(--ptr_end)=val21;
--        case 21: *(--ptr_end)=val20;
--        case 20: *(--ptr_end)=val19;
--        case 19: *(--ptr_end)=val18;
--        case 18: *(--ptr_end)=val17;
--        case 17: *(--ptr_end)=val16;
--        case 16: *(--ptr_end)=val15;
--        case 15: *(--ptr_end)=val14;
--        case 14: *(--ptr_end)=val13;
--        case 13: *(--ptr_end)=val12;
--        case 12: *(--ptr_end)=val11;
--        case 11: *(--ptr_end)=val10;
--        case 10: *(--ptr_end)=val9;
--        case 9: *(--ptr_end)=val8;
--        case 8: *(--ptr_end)=val7;
--        case 7: *(--ptr_end)=val6;
--        case 6: *(--ptr_end)=val5;
--        case 5: *(--ptr_end)=val4;
--        case 4: *(--ptr_end)=val3;
--        case 3: *(--ptr_end)=val2;
--        case 2: *(--ptr_end)=val1;
--        case 1: *(--ptr_end)=val0;
--        }
--      }
--      return *this;
--    }
--
--    CImg get_fill(const T& val0,const T& val1,const T& val2,const T& val3,const T& val4,
--                  const T& val5,const T& val6,const T& val7,const T& val8,const T& val9,
--                  const T& val10,const T& val11,const T& val12,const T& val13,const T& val14,
--                  const T& val15,const T& val16,const T& val17,const T& val18,const T& val19,
--                  const T& val20,const T& val21,const T& val22,const T& val23,const T& val24) const {
--      return (+*this).fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,
--                                 val10,val11,val12,val13,val14,val15,val16,val17,val18,val19,
--                                 val20,val21,val22,val23,val24);
--    }
--
--    //! Linear normalization of the pixel values between \a a and \a b.
--    /**
--       \param a = minimum pixel value after normalization.
--       \param b = maximum pixel value after normalization.
--       \see get_normalize(), cut(), get_cut().
--    **/
--    CImg& normalize(const T& a, const T& b) {
--      if (!is_empty()) {
--        const CImgStats st(*this,false);
--        if (st.min==st.max) return fill(0);
--        if (st.min!=a || st.max!=b) cimg_for(*this,ptr,T) *ptr=(T)((*ptr-st.min)/(st.max-st.min)*(b-a)+a);
--      }
--      return *this;
--    }
--
--    //! Return the image of normalized values.
--    /**
--       \param a = minimum pixel value after normalization.
--       \param b = maximum pixel value after normalization.
--       \see normalize(), cut(), get_cut().
--    **/
--    CImg get_normalize(const T& a, const T& b) const {
--      return (+*this).normalize(a,b);
--    }
--
--    //! Cut pixel values between \a a and \a b.
--    /**
--       \param a = minimum pixel value after cut.
--       \param b = maximum pixel value after cut.
--       \see get_cut(), normalize(), get_normalize().
--    **/
--    CImg& cut(const T& a, const T& b) {
--      if (!is_empty())
--        cimg_for(*this,ptr,T) *ptr = (*ptr<a)?a:((*ptr>b)?b:*ptr);
--      return *this;
--    }
--
--    //! Return the image of cutted values.
--    /**
--       \param a = minimum pixel value after cut.
--       \param b = maximum pixel value after cut.
--       \see cut(), normalize(), get_normalize().
--    **/
--    CImg get_cut(const T& a, const T& b) const {
--      return (+*this).cut(a,b);
--    }
--
--    //! Quantize pixel values into \n levels.
--    /**
--       \param n = number of quantification levels
--       \see get_quantize().
--    **/
--    CImg& quantize(const unsigned int n=256) {
--      if (!is_empty()) {
--        if (!n) throw CImgArgumentException("CImg<%s>::quantize() : Cannot quantize image to 0 values.",
--                                            pixel_type());
--        const CImgStats st(*this,false);
--        const double range = st.max-st.min;
--        if (range>0) cimg_for(*this,ptr,T) {
--          const unsigned int val = (unsigned int)((*ptr-st.min)*n/range);
--          *ptr = (T)(st.min + cimg::min(val,n-1)*range);
--        }
--      }
--      return *this;
--    }
--
--    //! Return a quantified image, with \n levels.
--    /**
--       \param n = number of quantification levels
--       \see quantize().
--    **/
--    CImg get_quantize(const unsigned int n=256) const {
--      return (+*this).quantize(n);
--    }
--
--    //! Threshold the image.
--    /**
--       \param thres = threshold
--       \see get_threshold().
--    **/
--    CImg& threshold(const T& thres) {
--      if (!is_empty()) cimg_for(*this,ptr,T) *ptr = *ptr<=thres?(T)0:(T)1;
--      return *this;
--    }
--
--    //! Return a thresholded image.
--    /**
--       \param thres = threshold.
--       \see threshold().
--    **/
--    CImg get_threshold(const T& thres) const {
--      return (+*this).threshold(thres);
--    }
--
--    //! Return a rotated image.
--    /**
--       \param angle = rotation angle (in degrees).
--       \param cond = rotation type. can be :
--       - 0 = zero-value at borders
--       - 1 = repeat image at borders
--       - 2 = zero-value at borders and linear interpolation
--       \note Returned image will probably have a different size than the instance image *this.
--       \see rotate()
--    **/
--    CImg get_rotate(const float angle, const unsigned int cond=3) const {
--      if (is_empty()) return CImg<T>();
--      CImg dest;
--      const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
--        ca=(float)std::cos(rad), sa=(float)std::sin(rad);
--      if (cond!=1 && cimg::mod(nangle,90.0f)==0) { // optimized version for orthogonal angles
--        const int wm1 = dimx()-1, hm1 = dimy()-1;
--        const int iangle = (int)nangle/90;
--        switch (iangle) {
--        case 1: {
--          dest.assign(height,width,depth,dim);
--          cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(y,hm1-x,z,v);
--        } break;
--        case 2: {
--          dest.assign(width,height,depth,dim);
--          cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-x,hm1-y,z,v);
--        } break;
--        case 3: {
--          dest.assign(height,width,depth,dim);
--          cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(wm1-y,x,z,v);
--        } break;
--        default:
--          return *this;
--        }
--      } else { // generic version
--        const float
--          ux  = (float)(cimg::abs(width*ca)),  uy  = (float)(cimg::abs(width*sa)),
--          vx  = (float)(cimg::abs(height*sa)), vy  = (float)(cimg::abs(height*ca)),
--          w2  = 0.5f*width,           h2  = 0.5f*height,
--          dw2 = 0.5f*(ux+vx),         dh2 = 0.5f*(uy+vy);
--        dest.assign((int)(ux+vx), (int)(uy+vy),depth,dim);
--        switch (cond) {
--        case 0: {
--          cimg_forXY(dest,x,y)
--            cimg_forZV(*this,z,v)
--            dest(x,y,z,v) = pix2d((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,v,0);
--        } break;
--        case 1: {
--          cimg_forXY(dest,x,y)
--            cimg_forZV(*this,z,v)
--            dest(x,y,z,v) = (*this)(cimg::mod((int)(w2 + (x-dw2)*ca + (y-dh2)*sa),width),
--                                    cimg::mod((int)(h2 - (x-dw2)*sa + (y-dh2)*ca),height),z,v);
--        } break;
--        case 2: {
--          cimg_forXY(dest,x,y) {
--            const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
--            cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
--          }
--        } break;
--        default: {
--          cimg_forXY(dest,x,y) {
--            const float X = w2 + (x-dw2)*ca + (y-dh2)*sa, Y = h2 - (x-dw2)*sa + (y-dh2)*ca;
--            cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
--          }
--        } break;
--        }
--      }
--      return dest;
--    }
--
--    //! Rotate the image
--    /**
--       \param angle = rotation angle (in degrees).
--       \param cond = rotation type. can be :
--       - 0 = zero-value at borders
--       - 1 = repeat image at borders
--       - 2 = zero-value at borders and linear interpolation
--       \see get_rotate()
--    **/
--    CImg& rotate(const float angle,const unsigned int cond=3) { return get_rotate(angle,cond).swap(*this); }
--
--    //! Return a rotated image around the point (\c cx,\c cy).
--    /**
--       \param angle = rotation angle (in degrees).
--       \param cx = X-coordinate of the rotation center.
--       \param cy = Y-coordinate of the rotation center.
--       \param zoom = zoom.
--       \param cond = rotation type. can be :
--       - 0 = zero-value at borders
--       - 1 = repeat image at borders
--       - 2 = zero-value at borders and linear interpolation
--       \see rotate()
--    **/
--    CImg get_rotate(const float angle,const float cx,const float cy,const float zoom=1,const unsigned int cond=3) const {
--      if (is_empty()) return CImg<T>();
--      CImg dest(width,height,depth,dim);
--      const float nangle = cimg::mod(angle,360.0f), rad = (float)((nangle*cimg::PI)/180.0),
--        ca=(float)std::cos(rad)/zoom, sa=(float)std::sin(rad)/zoom;
--      if (cond!=1 && zoom==1 && cimg::mod(nangle,90.0f)==0) { // optimized version for orthogonal angles
--        const int iangle = (int)nangle/90;
--        switch (iangle) {
--        case 1: {
--          dest.fill(0);
--          const unsigned int
--            xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
--            ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
--            xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
--            yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
--          cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; y++) for (unsigned int x=xmin; x<xmax; x++)
--            dest(x,y,z,v) = (*this)(y-yoff,height-1-x+xoff,z,v);
--        } break;
--        case 2: {
--          cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = (*this)(width-1-x,height-1-y,z,v);
--        } break;
--        case 3: {
--          dest.fill(0);
--          const unsigned int
--            xmin = cimg::max(0,(dimx()-dimy())/2), xmax = cimg::min(width,xmin+height),
--            ymin = cimg::max(0,(dimy()-dimx())/2), ymax = cimg::min(height,ymin+width),
--            xoff = xmin + cimg::min(0,(dimx()-dimy())/2),
--            yoff = ymin + cimg::min(0,(dimy()-dimx())/2);
--          cimg_forZV(dest,z,v) for (unsigned int y=ymin; y<ymax; y++) for (unsigned int x=xmin; x<xmax; x++)
--            dest(x,y,z,v) = (*this)(width-1-y+yoff,x-xoff,z,v);
--        } break;
--        default:
--          return *this;
--        }
--      } else
--        switch (cond) { // generic version
--        case 0: {
--          cimg_forXY(dest,x,y)
--            cimg_forZV(*this,z,v)
--            dest(x,y,z,v) = pix2d((int)(cx + (x-cx)*ca + (y-cy)*sa),(int)(cy - (x-cx)*sa + (y-cy)*ca),z,v,0);
--        } break;
--        case 1: {
--          cimg_forXY(dest,x,y)
--            cimg_forZV(*this,z,v)
--            dest(x,y,z,v) = (*this)(cimg::mod((int)(cx + (x-cx)*ca + (y-cy)*sa),width),
--                                    cimg::mod((int)(cy - (x-cx)*sa + (y-cy)*ca),height),z,v);
--        } break;
--        case 2: {
--          cimg_forXY(dest,x,y) {
--            const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
--            cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)linear_pix2d(X,Y,z,v,0);
--          }
--        } break;
--        default: {
--          cimg_forXY(dest,x,y) {
--            const float X = cx + (x-cx)*ca + (y-cy)*sa, Y = cy - (x-cx)*sa + (y-cy)*ca;
--            cimg_forZV(*this,z,v) dest(x,y,z,v) = (T)cubic_pix2d(X,Y,z,v,0);
--          }
--        } break;
--        }
--      return dest;
--    }
--
--    //! Rotate the image around the point (\c cx,\c cy).
--    /**
--       \param angle = rotation angle (in degrees).
--       \param cx = X-coordinate of the rotation center.
--       \param cy = Y-coordinate of the rotation center.
--       \param zoom = zoom.
--       \param cond = rotation type. can be :
--       - 0 = zero-value at borders
--       - 1 = repeat image at borders
--       - 2 = zero-value at borders and linear interpolation
--       \note Rotation does not change the image size. If you want to get an image with a new size, use get_rotate() instead.
--       \see get_rotate()
--    **/
--    CImg& rotate(const float angle,const float cx,const float cy,const float zoom=1,const unsigned int cond=3) {
--      return get_rotate(angle,cx,cy,zoom,cond).swap(*this);
--    }
--
--    //! Return a resized image.
--    /**
--       \param pdx = Number of columns (new size along the X-axis).
--       \param pdy = Number of rows (new size along the Y-axis).
--       \param pdz = Number of slices (new size along the Z-axis).
--       \param pdv = Number of vector-channels (new size along the V-axis).
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    CImg get_resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
--                    const unsigned int interp=1, const int border_condition=-1) const {
--      if (!pdx || !pdy || !pdz || !pdv) return CImg<T>();
--      const unsigned int
--        tdx = pdx<0?-pdx*width/100:pdx,
--        tdy = pdy<0?-pdy*height/100:pdy,
--        tdz = pdz<0?-pdz*depth/100:pdz,
--        tdv = pdv<0?-pdv*dim/100:pdv,
--        dx = tdx?tdx:1,
--        dy = tdy?tdy:1,
--        dz = tdz?tdz:1,
--        dv = tdv?tdv:1;
--      if (is_empty()) return CImg<T>(dx,dy,dz,dv,0);
--      if (width==dx && height==dy && depth==dz && dim==dv) return *this;
--      CImg res;
--
--      switch (interp) {
--      case 0:  // Zero filling
--        res.assign(dx,dy,dz,dv,0).draw_image(*this,0,0,0,0);
--        break;
--
--      case 1: { // Nearest-neighbor interpolation
--        res.assign(dx,dy,dz,dv);
--        unsigned int
--          *const offx = new unsigned int[dx],
--          *const offy = new unsigned int[dy+1],
--          *const offz = new unsigned int[dz+1],
--          *const offv = new unsigned int[dv+1],
--          *poffx, *poffy, *poffz, *poffv,
--          curr, old;
--        const unsigned int wh = width*height, whd = width*height*depth, rwh = dx*dy, rwhd = dx*dy*dz;
--        poffx = offx; curr=0; { cimg_forX(res,x) { old=curr; curr=(x+1)*width/dx;  *(poffx++) = (unsigned int)curr-(unsigned int)old; }}
--        poffy = offy; curr=0; { cimg_forY(res,y) { old=curr; curr=(y+1)*height/dy; *(poffy++) = width*((unsigned int)curr-(unsigned int)old); }} *poffy=0;
--        poffz = offz; curr=0; { cimg_forZ(res,z) { old=curr; curr=(z+1)*depth/dz;  *(poffz++) = wh*((unsigned int)curr-(unsigned int)old); }} *poffz=0;
--        poffv = offv; curr=0; { cimg_forV(res,k) { old=curr; curr=(k+1)*dim/dv;    *(poffv++) = whd*((unsigned int)curr-(unsigned int)old); }} *poffv=0;
--        T *ptrd = res.ptr();
--        const T* ptrv = ptr();
--        poffv = offv;
--        for (unsigned int k=0; k<dv; ) {
--          const T *ptrz = ptrv;
--          poffz = offz;
--          for (unsigned int z=0; z<dz; ) {
--            const T *ptry = ptrz;
--            poffy = offy;
--            for (unsigned int y=0; y<dy; ) {
--              const T *ptrx = ptry;
--              poffx = offx;
--              cimg_forX(res,x) { *(ptrd++)=*ptrx; ptrx+=*(poffx++); }
--              y++;
--              unsigned int dy=*(poffy++);
--              for (;!dy && y<dy; std::memcpy(ptrd, ptrd-dx, sizeof(T)*dx), y++, ptrd+=dx, dy=*(poffy++));
--              ptry+=dy;
--            }
--            z++;
--            unsigned int dz=*(poffz++);
--            for (;!dz && z<dz; std::memcpy(ptrd, ptrd-rwh, sizeof(T)*rwh), z++, ptrd+=rwh, dz=*(poffz++));
--            ptrz+=dz;
--          }
--          k++;
--          unsigned int dv=*(poffv++);
--          for (;!dv && k<dv; std::memcpy(ptrd, ptrd-rwhd, sizeof(T)*rwhd), k++, ptrd+=rwhd, dv=*(poffv++));
--          ptrv+=dv;
--        }
--        delete[] offx; delete[] offy; delete[] offz; delete[] offv;
--      } break;
--
--      case 2: { // Mosaic filling
--        res.assign(dx,dy,dz,dv);
--        for (unsigned int k=0; k<dv; k+=dim)
--          for (unsigned int z=0; z<dz; z+=depth)
--            for (unsigned int y=0; y<dy; y+=height)
--              for (unsigned int x=0; x<dx; x+=width) res.draw_image(*this,x,y,z,k);
--      } break;
--
--      case 3: { // Linear interpolation
--        const unsigned int dimmax = cimg::max(dx,dy,dz,dv);
--        const bool bborder = (interp>1 && border_condition<0);
--        const float
--          sx = bborder?(dx>0?(width-1.0f)/(dx-1) :0):(float)width/dx,
--          sy = bborder?(dy>0?(height-1.0f)/(dy-1):0):(float)height/dy,
--          sz = bborder?(dz>0?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
--          sv = bborder?(dv>0?(dim-1.0f)/(dv-1)   :0):(float)dim/dv;
--        unsigned int *const off = new unsigned int[dimmax], *poff;
--        float *const foff = new float[dimmax], *pfoff, old, curr;
--        CImg resx, resy, resz, resv;
--        T *ptrd;
--
--        if (dx!=width) {
--          if (width==1) resx = get_resize(dx,height,depth,dim,1,0);
--          else {
--            resx.assign(dx,height,depth,dim);
--            curr = old = 0; poff = off; pfoff = foff;
--            cimg_forX(resx,x) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sx; *(poff++) = (unsigned int)curr-(unsigned int)old; }
--            ptrd = resx.ptr();
--            const T *ptrs0 = ptr();
--            cimg_forYZV(resx,y,z,k) {
--              poff = off; pfoff = foff;
--              const T *ptrs = ptrs0, *const ptrsmax = ptrs0 + (width-1);
--              cimg_forX(resx,x) {
--                const float alpha = *(pfoff++);
--                const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+1):(border_condition?val1:0);
--                *(ptrd++) = (T)((1-alpha)*val1 + alpha*val2);
--                ptrs+=*(poff++);
--              }
--              ptrs0+=width;
--            }
--          }
--        } else resx.assign(*this,true);
--
--        if (dy!=height) {
--          if (height==1) resy = resx.get_resize(dx,dy,depth,dim,1,0);
--          else {
--            resy.assign(dx,dy,depth,dim);
--            curr = old = 0; poff = off; pfoff = foff;
--            cimg_forY(resy,y) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sy; *(poff++) = dx*((unsigned int)curr-(unsigned int)old); }
--            cimg_forXZV(resy,x,z,k) {
--              ptrd = resy.ptr(x,0,z,k);
--              const T *ptrs = resx.ptr(x,0,z,k), *const ptrsmax = ptrs + (height-1)*dx;
--              poff = off; pfoff = foff;
--              cimg_forY(resy,y) {
--                const float alpha = *(pfoff++);
--                const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+dx):(border_condition?val1:0);
--                *ptrd = (T)((1-alpha)*val1 + alpha*val2);
--                ptrd+=dx;
--                ptrs+=*(poff++);
--              }
--            }
--          }
--          resx.assign();
--        } else resy.assign(resx,true);
--
--        if (dz!=depth) {
--          if (depth==1) resz = resy.get_resize(dx,dy,dz,dim,1,0);
--          else {
--            const unsigned int wh = dx*dy;
--            resz.assign(dx,dy,dz,dim);
--            curr = old = 0; poff = off; pfoff = foff;
--            cimg_forZ(resz,z) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sz; *(poff++) = wh*((unsigned int)curr-(unsigned int)old); }
--            cimg_forXYV(resz,x,y,k) {
--              ptrd = resz.ptr(x,y,0,k);
--              const T *ptrs = resy.ptr(x,y,0,k), *const ptrsmax = ptrs + (depth-1)*wh;
--              poff = off; pfoff = foff;
--              cimg_forZ(resz,z) {
--                const float alpha = *(pfoff++);
--                const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+wh):(border_condition?val1:0);
--                *ptrd = (T)((1-alpha)*val1 + alpha*val2);
--                ptrd+=wh;
--                ptrs+=*(poff++);
--              }
--            }
--          }
--          resy.assign();
--        } else resz.assign(resy,true);
--
--        if (dv!=dim) {
--          if (dim==1) resv = resz.get_resize(dx,dy,dz,dv,1,0);
--          else {
--            const unsigned int whd = dx*dy*dz;
--            resv.assign(dx,dy,dz,dv);
--            curr = old = 0; poff = off; pfoff = foff;
--            cimg_forV(resv,k) { *(pfoff++) = curr-(unsigned int)curr; old = curr; curr+=sv; *(poff++) = whd*((unsigned int)curr-(unsigned int)old); }
--            cimg_forXYZ(resv,x,y,z) {
--              ptrd = resv.ptr(x,y,z,0);
--              const T *ptrs = resz.ptr(x,y,z,0), *const ptrsmax = ptrs + (dim-1)*whd;
--              poff = off; pfoff = foff;
--              cimg_forV(resv,k) {
--                const float alpha = *(pfoff++);
--                const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+whd):(border_condition?val1:0);
--                *ptrd = (T)((1-alpha)*val1 + alpha*val2);
--                ptrd+=whd;
--                ptrs+=*(poff++);
--              }
--            }
--          }
--          resz.assign();
--        } else resv.assign(resz,true);
--
--        delete[] off; delete[] foff;
--        return resv.is_shared?(resz.is_shared?(resy.is_shared?(resx.is_shared?(+(*this)):resx):resy):resz):resv;
--      } break;
--
--      case 4: { // Grid filling
--        res.assign(dx,dy,dz,dv,0);
--        cimg_forXYZV(*this,x,y,z,k) res(x*dx/width,y*dy/height,z*dz/depth,k*dv/dim) = (*this)(x,y,z,k);
--      } break;
--
--      case 5: { // Cubic interpolation
--        const bool bborder = (interp>1 && border_condition<0);
--        const float
--          sx = bborder?(dx>0?(width-1.0f)/(dx-1) :0):(float)width/dx,
--          sy = bborder?(dy>0?(height-1.0f)/(dy-1):0):(float)height/dy,
--          sz = bborder?(dz>0?(depth-1.0f)/(dz-1) :0):(float)depth/dz,
--          sv = bborder?(dv>0?(dim-1.0f)/(dv-1)   :0):(float)dim/dv;
--        res.assign(dx,dy,dz,dv);
--        float cx, cy, cz, ck = 0;
--        cimg_forV(res,k) { cz = 0;
--        cimg_forZ(res,z) { cy = 0;
--        cimg_forY(res,y) { cx = 0;
--        cimg_forX(res,x) { res(x,y,z,k) = (T)(border_condition?cubic_pix2d(cx,cy,(int)cz,(int)ck):cubic_pix2d(cx,cy,(int)cz,(int)ck,0));
--        cx+=sx;
--        } cy+=sy;
--        } cz+=sz;
--        } ck+=sv;
--        }
--      } break;
--
--      }
--
--      return res;
--    }
--
--    //! Return a resized image.
--    /**
--       \param src = Image giving the geometry of the resize.
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    template<typename t> CImg get_resize(const CImg<t>& src, const unsigned int interp=1, const int border_condition=-1) const {
--      return get_resize(src.width,src.height,src.depth,src.dim,interp,border_condition);
--    }
--
--    //! Return a resized image.
--    /**
--       \param disp = Display giving the geometry of the resize.
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    CImg get_resize(const CImgDisplay& disp,const unsigned int interp=1, const int border_condition=-1) const {
--      return get_resize(disp.width,disp.height,depth,dim,interp,border_condition);
--    }
--
--    //! Resize the image.
--    /**
--       \param pdx = Number of columns (new size along the X-axis).
--       \param pdy = Number of rows (new size along the Y-axis).
--       \param pdz = Number of slices (new size along the Z-axis).
--       \param pdv = Number of vector-channels (new size along the V-axis).
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    CImg& resize(const int pdx=-100, const int pdy=-100, const int pdz=-100, const int pdv=-100,
--                 const unsigned int interp=1, const int border_condition=-1) {
--      if (!pdx || !pdy || !pdz || !pdv) return assign();
--      const unsigned int
--        dx = pdx<0?-pdx*width/100:pdx,
--        dy = pdy<0?-pdy*height/100:pdy,
--        dz = pdz<0?-pdz*depth/100:pdz,
--        dv = pdv<0?-pdv*dim/100:pdv;
--      if (width==dx && height==dy && depth==dz && dim==dv) return *this;
--      return get_resize(dx,dy,dz,dv,interp,border_condition).swap(*this);
--    }
--
--    //! Resize the image.
--    /**
--       \param src = Image giving the geometry of the resize.
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    template<typename t> CImg& resize(const CImg<t>& src, const unsigned int interp=1, const int border_condition=-1) {
--      return resize(src.width,src.height,src.depth,src.dim,interp,border_condition);
--    }
--
--    //! Resize the image
--    /**
--       \param disp = Display giving the geometry of the resize.
--       \param interp = Resizing type :
--       - 0 = no interpolation : additionnal space is filled with 0.
--       - 1 = bloc interpolation (nearest point).
--       - 2 = mosaic : image is repeated if necessary.
--       - 3 = linear interpolation.
--       - 4 = grid interpolation.
--       - 5 = bi-cubic interpolation.
--       \note If pd[x,y,z,v]<0, it corresponds to a percentage of the original size (the default value is -100).
--    **/
--    CImg& resize(const CImgDisplay& disp, const unsigned int interp=1, const int border_condition=-1) {
--      return resize(disp.width,disp.height,depth,dim,interp,border_condition);
--    }
--
--    //! Return an half-resized image, using a special filter.
--    /**
--       \see resize_halfXY(), resize(), get_resize().
--    **/
--    CImg get_resize_halfXY() const {
--      typedef typename cimg::largest<T,float>::type ftype;
--      if (is_empty()) return CImg<T>();
--      CImg<ftype> mask = CImg<ftype>::matrix(0.07842776544f, 0.1231940459f, 0.07842776544f,
--                                             0.1231940459f,  0.1935127547f, 0.1231940459f,
--                                             0.07842776544f, 0.1231940459f, 0.07842776544f);
--      CImg_3x3(I,ftype);
--      CImg dest(width/2,height/2,depth,dim);
--      cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I)
--        if (x%2 && y%2) dest(x/2,y/2,z,k) = (T)cimg_conv3x3(I,mask);
--      return dest;
--    }
--
--    //! Half-resize the image, using a special filter
--    /**
--       \see get_resize_halfXY(), resize(), get_resize().
--    **/
--    CImg& resize_halfXY() {
--      return get_resize_halfXY().swap(*this);
--    }
--
--    //! Return a square region of the image, as a new image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param z0 = Z-coordinate of the upper-left crop rectangle corner.
--       \param v0 = V-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param z1 = Z-coordinate of the lower-right crop rectangle corner.
--       \param v1 = V-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = Dirichlet (false) or Neumann border conditions.
--       \see crop()
--    **/
--    CImg get_crop(const unsigned int x0,const unsigned int y0,const unsigned int z0,const unsigned int v0,
--                  const unsigned int x1,const unsigned int y1,const unsigned int z1,const unsigned int v1,
--                  const bool border_condition = false) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::get_crop() : Instance image (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      const unsigned int dx=x1-x0+1, dy=y1-y0+1, dz=z1-z0+1, dv=v1-v0+1;
--      CImg dest(dx,dy,dz,dv);
--      if (x0>=width || x1>=width || y0>=height || y1>=height || z0>=depth || z1>=depth ||
--          v0>=dim || v1>=dim || x1<x0 || y1<y0 || z1<z0 || v1<v0)
--        switch (border_condition) {
--        case false: { cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = pix4d(x0+x,y0+y,z0+z,v0+v,0); } break;
--        default: { cimg_forXYZV(dest,x,y,z,v) dest(x,y,z,v) = pix4d(x0+x,y0+y,z0+z,v0+v); } break;
--        } else {
--          const T *psrc = ptr(x0,y0,z0,v0);
--          T *pdest = dest.ptr(0,0,0,0);
--          if (dx!=width)
--            for (unsigned int k=0; k<dv; k++) {
--              for (unsigned int z=0; z<dz; z++) {
--                for (unsigned int y=0; y<dy; y++) {
--                  std::memcpy(pdest,psrc,dx*sizeof(T));
--                  pdest+=dx;
--                  psrc+=width;
--                }
--                psrc+=width*(height-dy);
--              }
--              psrc+=width*height*(depth-dz);
--            }
--          else {
--            if (dy!=height)
--              for (unsigned int k=0; k<dv; k++) {
--                for (unsigned int z=0; z<dz; z++) {
--                  std::memcpy(pdest,psrc,dx*dy*sizeof(T));
--                  pdest+=dx*dy;
--                  psrc+=width*height;
--                }
--                psrc+=width*height*(depth-dz);
--              }
--            else {
--              if (dz!=depth)
--                for (unsigned int k=0; k<dv; k++) {
--                  std::memcpy(pdest,psrc,dx*dy*dz*sizeof(T));
--                  pdest+=dx*dy*dz;
--                  psrc+=width*height*depth;
--                }
--              else std::memcpy(pdest,psrc,dx*dy*dz*dv*sizeof(T));
--            }
--          }
--        }
--      return dest;
--    }
--
--    //! Return a square region of the image, as a new image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param z0 = Z-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param z1 = Z-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see crop()
--    **/
--    CImg get_crop(const unsigned int x0,const unsigned int y0,const unsigned int z0,
--                  const unsigned int x1,const unsigned int y1,const unsigned int z1,
--                  const bool border_condition=false) const {
--      return get_crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
--    }
--
--    //! Return a square region of the image, as a new image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see crop()
--    **/
--    CImg get_crop(const unsigned int x0,const unsigned int y0,
--                  const unsigned int x1,const unsigned int y1,
--                  const bool border_condition=false) const {
--      return get_crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
--    }
--
--    //! Return a square region of the image, as a new image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see crop()
--    **/
--    CImg get_crop(const unsigned int x0,const unsigned int x1,const bool border_condition=false) const {
--      return get_crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
--    }
--
--    //! Replace the image by a square region of the image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param z0 = Z-coordinate of the upper-left crop rectangle corner.
--       \param v0 = V-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param z1 = Z-coordinate of the lower-right crop rectangle corner.
--       \param v1 = V-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see get_crop()
--    **/
--    CImg& crop(const unsigned int x0,const unsigned int y0,const unsigned int z0,const unsigned int v0,
--               const unsigned int x1,const unsigned int y1,const unsigned int z1,const unsigned int v1,
--               const bool border_condition=false) {
--      return get_crop(x0,y0,z0,v0,x1,y1,z1,v1,border_condition).swap(*this);
--    }
--
--    //! Replace the image by a square region of the image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param z0 = Z-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param z1 = Z-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see get_crop()
--    **/
--    CImg& crop(const unsigned int x0,const unsigned int y0,const unsigned int z0,
--               const unsigned int x1,const unsigned int y1,const unsigned int z1,
--               const bool border_condition=false) {
--      return crop(x0,y0,z0,0,x1,y1,z1,dim-1,border_condition);
--    }
--
--    //! Replace the image by a square region of the image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param y0 = Y-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param y1 = Y-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see get_crop()
--    **/
--    CImg& crop(const unsigned int x0,const unsigned int y0,
--               const unsigned int x1,const unsigned int y1,
--               const bool border_condition=false) {
--      return crop(x0,y0,0,0,x1,y1,depth-1,dim-1,border_condition);
--    }
--
--    //! Replace the image by a square region of the image
--    /**
--       \param x0 = X-coordinate of the upper-left crop rectangle corner.
--       \param x1 = X-coordinate of the lower-right crop rectangle corner.
--       \param border_condition = determine the type of border condition if
--       some of the desired region is outside the image.
--       \see get_crop()
--    **/
--    CImg& crop(const unsigned int x0,const unsigned int x1,const bool border_condition=false) {
--      return crop(x0,0,0,0,x1,height-1,depth-1,dim-1,border_condition);
--    }
--
--    //! Return a set of columns
--    CImg get_columns(const unsigned int x0, const unsigned int x1) const {
--      return get_crop(x0,0,0,0,x1,height-1,depth-1,dim-1);
--    }
--
--    //! Replace the instance image by a set of its columns
--    CImg& columns(const unsigned int x0, const unsigned int x1) {
--      return get_columns(x0,x1).swap(*this);
--    }
--
--    //! Return one column
--    CImg get_column(const unsigned int x0) const {
--      return get_columns(x0,x0);
--    }
--
--    //! Replace the instance image by one of its column
--    CImg& column(const unsigned int x0) {
--      return columns(x0,x0);
--    }
--
--    //! Get a copy of a set of lines of the instance image.
--    CImg get_lines(const unsigned int y0, const unsigned int y1) const {
--      return get_crop(0,y0,0,0,width-1,y1,depth-1,dim-1);
--    }
--
--    //! Replace the instance image by a set of lines of the instance image.
--    CImg& lines(const unsigned int y0, const unsigned int y1) {
--      return get_lines(y0,y1).swap(*this);
--    }
--
--    //! Get a copy of a line of the instance image.
--    CImg get_line(const unsigned int y0) const {
--      return get_lines(y0,y0);
--    }
--
--    //! Replace the instance image by one of its line.
--    CImg& line(const unsigned int y0) {
--      return lines(y0,y0);
--    }
--
--    //! Get a set of slices
--    CImg get_slices(const unsigned int z0, const unsigned int z1) const {
--      return get_crop(0,0,z0,0,width-1,height-1,z1,dim-1);
--    }
--
--    // Replace the image by a set of its z-slices
--    CImg& slices(const unsigned int z0, const unsigned int z1) {
--      return get_slices(z0,z1).swap(*this);
--    }
--
--    //! Get the z-slice \a z of *this, as a new image.
--    CImg get_slice(const unsigned int z0) const {
--      return get_slices(z0,z0);
--    }
--
--    //! Replace the image by one of its slice.
--    CImg& slice(const unsigned int z0) {
--      return slices(z0,z0);
--    }
--
--    //! Return a copy of a set of channels of the instance image.
--    CImg get_channels(const unsigned int v0, const unsigned int v1) const {
--      return get_crop(0,0,0,v0,width-1,height-1,depth-1,v1);
--    }
--
--    //! Replace the instance image by a set of channels of the instance image.
--    CImg& channels(const unsigned int v0, const unsigned int v1) {
--      return get_channels(v0,v1).swap(*this);
--    }
--
--    //! Return a copy of a channel of the instance image.
--    CImg get_channel(const unsigned int v0) const {
--      return get_channels(v0,v0);
--    }
--
--    //! Replace the instance image by one of its channel.
--    CImg& channel(const unsigned int v0) {
--      return channels(v0,v0);
--    }
--
--    //! Get a shared-memory image referencing a set of points of the instance image.
--    CImg get_shared_points(const unsigned int x0, const unsigned int x1,
--                           const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) {
--      const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
--    }
--
--    //! Get a shared-memory image referencing a set of points of the instance image (const version).
--    const CImg get_shared_points(const unsigned int x0, const unsigned int x1,
--                                 const unsigned int y0=0, const unsigned int z0=0, const unsigned int v0=0) const {
--      const unsigned long beg = offset(x0,y0,z0,v0), end = offset(x1,y0,z0,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_points() : Cannot return a shared-memory subset (%u->%u,%u,%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),x0,x1,y0,z0,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,x1-x0+1,1,1,1,true);
--    }
--
--    //! Return a shared-memory image referencing a set of lines of the instance image.
--    CImg get_shared_lines(const unsigned int y0, const unsigned int y1,
--                          const unsigned int z0=0, const unsigned int v0=0) {
--      const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
--    }
--
--    //! Return a shared-memory image referencing a set of lines of the instance image (const version).
--    const CImg get_shared_lines(const unsigned int y0, const unsigned int y1,
--                                const unsigned int z0=0, const unsigned int v0=0) const {
--      const unsigned long beg = offset(0,y0,z0,v0), end = offset(0,y1,z0,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_lines() : Cannot return a shared-memory subset (0->%u,%u->%u,%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,y0,y1,z0,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,width,y1-y0+1,1,1,true);
--    }
--
--    //! Return a shared-memory image referencing one particular line (y0,z0,v0) of the instance image.
--    CImg get_shared_line(const unsigned int y0, const unsigned int z0=0, const unsigned int v0=0) {
--      return get_shared_lines(y0,y0,z0,v0);
--    }
--
--    //! Return a shared-memory image referencing one particular line (y0,z0,v0) of the instance image (const version).
--    const CImg get_shared_line(const unsigned int y0,const unsigned int z0=0,const unsigned int v0=0) const {
--      return get_shared_lines(y0,y0,z0,v0);
--    }
--
--    //! Return a shared memory image referencing a set of planes (z0->z1,v0) of the instance image.
--    CImg get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) {
--      const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
--    }
--
--    //! Return a shared-memory image referencing a set of planes (z0->z1,v0) of the instance image (const version).
--    const CImg get_shared_planes(const unsigned int z0, const unsigned int z1, const unsigned int v0=0) const {
--      const unsigned long beg = offset(0,0,z0,v0), end = offset(0,0,z1,v0);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_planes() : Cannot return a shared-memory subset (0->%u,0->%u,%u->%u,%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,z0,z1,v0,width,height,depth,dim);
--      return CImg<T>(data+beg,width,height,z1-z0+1,1,true);
--    }
--
--    //! Return a shared-memory image referencing one plane (z0,v0) of the instance image.
--    CImg get_shared_plane(const unsigned int z0, const unsigned int v0=0) {
--      return get_shared_planes(z0,z0,v0);
--    }
--
--    //! Return a shared-memory image referencing one plane (z0,v0) of the instance image (const version).
--    const CImg get_shared_plane(const unsigned int z0, const unsigned int v0=0) const {
--      return get_shared_planes(z0,z0,v0);
--    }
--
--    //! Return a shared-memory image referencing a set of channels (v0->v1) of the instance image.
--    CImg get_shared_channels(const unsigned int v0, const unsigned int v1) {
--      const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
--      return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
--    }
--
--    //! Return a shared-memory image referencing a set of channels (v0->v1) of the instance image (const version).
--    const CImg get_shared_channels(const unsigned int v0, const unsigned int v1) const {
--      const unsigned long beg = offset(0,0,0,v0), end = offset(0,0,0,v1);
--      if (beg>end || beg>=size() || end>=size())
--        throw CImgArgumentException("CImg<%s>::get_shared_channels() : Cannot return a shared-memory subset (0->%u,0->%u,0->%u,%u->%u) from "
--                                    "a (%u,%u,%u,%u) image.",pixel_type(),width-1,height-1,depth-1,v0,v1,width,height,depth,dim);
--      return CImg<T>(data+beg,width,height,depth,v1-v0+1,true);
--    }
--
--    //! Return a shared-memory image referencing one channel v0 of the instance image.
--    CImg get_shared_channel(const unsigned int v0) {
--      return get_shared_channels(v0,v0);
--    }
--
--    //! Return a shared-memory image referencing one channel v0 of the instance image (const version).
--    const CImg get_shared_channel(const unsigned int v0) const {
--      return get_shared_channels(v0,v0);
--    }
--
--    //! Return a shared version of the instance image.
--    CImg get_shared() {
--      return CImg<T>(data,width,height,depth,dim,true);
--    }
--
--    //! Return a shared version of the instance image (const version).
--    const CImg get_shared() const {
--      return CImg<T>(data,width,height,depth,dim,true);
--    }
--
--    //! Mirror an image along the specified axis.
--    /**
--       This is the in-place version of get_mirror().
--       \sa get_mirror().
--    **/
--    CImg& mirror(const char axe='x') {
--      if (!is_empty()) {
--        T *pf,*pb,*buf=0;
--        switch (cimg::uncase(axe)) {
--        case 'x': {
--          pf = ptr(); pb = ptr(width-1);
--          for (unsigned int yzv=0; yzv<height*depth*dim; yzv++) {
--            for (unsigned int x=0; x<width/2; x++) { const T val = *pf; *(pf++)=*pb; *(pb--)=val; }
--            pf+=width-width/2;
--            pb+=width+width/2;
--          }
--        } break;
--        case 'y': {
--          buf = new T[width];
--          pf = ptr(); pb = ptr(0,height-1);
--          for (unsigned int zv=0; zv<depth*dim; zv++) {
--            for (unsigned int y=0; y<height/2; y++) {
--              std::memcpy(buf,pf,width*sizeof(T));
--              std::memcpy(pf,pb,width*sizeof(T));
--              std::memcpy(pb,buf,width*sizeof(T));
--              pf+=width;
--              pb-=width;
--            }
--            pf+=width*(height-height/2);
--            pb+=width*(height+height/2);
--          }
--        } break;
--        case 'z': {
--          buf = new T[width*height];
--          pf = ptr(); pb = ptr(0,0,depth-1);
--          cimg_forV(*this,v) {
--            for (unsigned int z=0; z<depth/2; z++) {
--              std::memcpy(buf,pf,width*height*sizeof(T));
--              std::memcpy(pf,pb,width*height*sizeof(T));
--              std::memcpy(pb,buf,width*height*sizeof(T));
--              pf+=width*height;
--              pb-=width*height;
--            }
--            pf+=width*height*(depth-depth/2);
--            pb+=width*height*(depth+depth/2);
--          }
--        } break;
--        case 'v': {
--          buf = new T[width*height*depth];
--          pf = ptr(); pb = ptr(0,0,0,dim-1);
--          for (unsigned int v=0; v<dim/2; v++) {
--            std::memcpy(buf,pf,width*height*depth*sizeof(T));
--            std::memcpy(pf,pb,width*height*depth*sizeof(T));
--            std::memcpy(pb,buf,width*height*depth*sizeof(T));
--            pf+=width*height*depth;
--            pb-=width*height*depth;
--          }
--        } break;
--        default:
--          throw CImgArgumentException("CImg<%s>::mirror() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
--        }
--        if (buf) delete[] buf;
--      }
--      return *this;
--    }
--
--    //! Get a mirrored version of the image, along the specified axis.
--    /**
--       \param axe Axe used to mirror the image. Can be \c 'x', \c 'y', \c 'z' or \c 'v'.
--       \sa mirror().
--    **/
--    CImg get_mirror(const char axe='x') {
--      return (+*this).mirror(axe);
--    }
--
--    //! Translate the image
--    /**
--       This is the in-place version of get_translate().
--       \sa get_translate().
--    **/
--    CImg& translate(const int deltax,const int deltay=0,const int deltaz=0,const int deltav=0,const int border_condition=0) {
--      if (!is_empty()) {
--
--        if (deltax) // Translate along X-axis
--          switch (border_condition) {
--          case 0:
--            if (cimg::abs(deltax)>=(int)width) return fill(0);
--            if (deltax>0) cimg_forYZV(*this,y,z,k) {
--              std::memmove(ptr(0,y,z,k),ptr(deltax,y,z,k),(width-deltax)*sizeof(T));
--              std::memset(ptr(width-deltax,y,z,k),0,deltax*sizeof(T));
--            } else cimg_forYZV(*this,y,z,k) {
--              std::memmove(ptr(-deltax,y,z,k),ptr(0,y,z,k),(width+deltax)*sizeof(T));
--              std::memset(ptr(0,y,z,k),0,-deltax*sizeof(T));
--            }
--            break;
--          case 1:
--            if (deltax>0) {
--              const int ndeltax = (deltax>=(int)width)?width-1:deltax;
--              if (!ndeltax) return *this;
--              cimg_forYZV(*this,y,z,k) {
--                std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
--                T *ptrd = ptr(width-1,y,z,k);
--                const T &val = *ptrd;
--                for (int l=0; l<ndeltax-1; l++) *(--ptrd) = val;
--              }
--            } else {
--              const int ndeltax = (-deltax>=(int)width)?width-1:-deltax;
--              if (!ndeltax) return *this;
--              cimg_forYZV(*this,y,z,k) {
--                std::memmove(ptr(ndeltax,y,z,k),ptr(0,y,z,k),(width-ndeltax)*sizeof(T));
--                T *ptrd = ptr(0,y,z,k);
--                const T &val = *ptrd;
--                for (int l=0; l<ndeltax-1; l++) *(++ptrd) = val;
--              }
--            }
--            break;
--          case 2: {
--            const int ml = cimg::mod(deltax,width), ndeltax = (ml<=(int)width/2)?ml:(ml-(int)width);
--            if (!ndeltax) return *this;
--            T* buf = new T[cimg::abs(ndeltax)];
--            if (ndeltax>0) cimg_forYZV(*this,y,z,k) {
--              std::memcpy(buf,ptr(0,y,z,k),ndeltax*sizeof(T));
--              std::memmove(ptr(0,y,z,k),ptr(ndeltax,y,z,k),(width-ndeltax)*sizeof(T));
--              std::memcpy(ptr(width-ndeltax,y,z,k),buf,ndeltax*sizeof(T));
--            } else cimg_forYZV(*this,y,z,k) {
--              std::memcpy(buf,ptr(width+ndeltax,y,z,k),-ndeltax*sizeof(T));
--              std::memmove(ptr(-ndeltax,y,z,k),ptr(0,y,z,k),(width+ndeltax)*sizeof(T));
--              std::memcpy(ptr(0,y,z,k),buf,-ndeltax*sizeof(T));
--            }
--            delete[] buf;
--          } break;
--          }
--
--        if (deltay) // Translate along Y-axis
--          switch (border_condition) {
--          case 0:
--            if (cimg::abs(deltay)>=(int)height) return fill(0);
--            if (deltay>0) cimg_forZV(*this,z,k) {
--              std::memmove(ptr(0,0,z,k),ptr(0,deltay,z,k),width*(height-deltay)*sizeof(T));
--              std::memset(ptr(0,height-deltay,z,k),0,width*deltay*sizeof(T));
--            } else cimg_forZV(*this,z,k) {
--              std::memmove(ptr(0,-deltay,z,k),ptr(0,0,z,k),width*(height+deltay)*sizeof(T));
--              std::memset(ptr(0,0,z,k),0,-deltay*width*sizeof(T));
--            }
--            break;
--          case 1:
--            if (deltay>0) {
--              const int ndeltay = (deltay>=(int)height)?height-1:deltay;
--              if (!ndeltay) return *this;
--              cimg_forZV(*this,z,k) {
--                std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
--                T *ptrd = ptr(0,height-ndeltay,z,k), *ptrs = ptr(0,height-1,z,k);
--                for (int l=0; l<ndeltay-1; l++) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
--              }
--            } else {
--              const int ndeltay = (-deltay>=(int)height)?height-1:-deltay;
--              if (!ndeltay) return *this;
--              cimg_forZV(*this,z,k) {
--                std::memmove(ptr(0,ndeltay,z,k),ptr(0,0,z,k),width*(height-ndeltay)*sizeof(T));
--                T *ptrd = ptr(0,1,z,k), *ptrs = ptr(0,0,z,k);
--                for (int l=0; l<ndeltay-1; l++) { std::memcpy(ptrd,ptrs,width*sizeof(T)); ptrd+=width; }
--              }
--            }
--            break;
--          case 2: {
--            const int ml = cimg::mod(deltay,height), ndeltay = (ml<=(int)height/2)?ml:(ml-(int)height);
--            if (!ndeltay) return *this;
--            T* buf = new T[width*cimg::abs(ndeltay)];
--            if (ndeltay>0) cimg_forZV(*this,z,k) {
--              std::memcpy(buf,ptr(0,0,z,k),width*ndeltay*sizeof(T));
--              std::memmove(ptr(0,0,z,k),ptr(0,ndeltay,z,k),width*(height-ndeltay)*sizeof(T));
--              std::memcpy(ptr(0,height-ndeltay,z,k),buf,width*ndeltay*sizeof(T));
--            } else cimg_forZV(*this,z,k) {
--              std::memcpy(buf,ptr(0,height+ndeltay,z,k),-ndeltay*width*sizeof(T));
--              std::memmove(ptr(0,-ndeltay,z,k),ptr(0,0,z,k),width*(height+ndeltay)*sizeof(T));
--              std::memcpy(ptr(0,0,z,k),buf,-ndeltay*width*sizeof(T));
--            }
--            delete[] buf;
--          } break;
--          }
--
--        if (deltaz) // Translate along Z-axis
--          switch (border_condition) {
--          case 0:
--            if (cimg::abs(deltaz)>=(int)depth) return fill(0);
--            if (deltaz>0) cimg_forV(*this,k) {
--              std::memmove(ptr(0,0,0,k),ptr(0,0,deltaz,k),width*height*(depth-deltaz)*sizeof(T));
--              std::memset(ptr(0,0,depth-deltaz,k),0,width*height*deltaz*sizeof(T));
--            } else cimg_forV(*this,k) {
--              std::memmove(ptr(0,0,-deltaz,k),ptr(0,0,0,k),width*height*(depth+deltaz)*sizeof(T));
--              std::memset(ptr(0,0,0,k),0,-deltaz*width*height*sizeof(T));
--            }
--            break;
--          case 1:
--            if (deltaz>0) {
--              const int ndeltaz = (deltaz>=(int)depth)?depth-1:deltaz;
--              if (!ndeltaz) return *this;
--              cimg_forV(*this,k) {
--                std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
--                T *ptrd = ptr(0,0,depth-ndeltaz,k), *ptrs = ptr(0,0,depth-1,k);
--                for (int l=0; l<ndeltaz-1; l++) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
--              }
--            } else {
--              const int ndeltaz = (-deltaz>=(int)depth)?depth-1:-deltaz;
--              if (!ndeltaz) return *this;
--              cimg_forV(*this,k) {
--                std::memmove(ptr(0,0,ndeltaz,k),ptr(0,0,0,k),width*height*(depth-ndeltaz)*sizeof(T));
--                T *ptrd = ptr(0,0,1,k), *ptrs = ptr(0,0,0,k);
--                for (int l=0; l<ndeltaz-1; l++) { std::memcpy(ptrd,ptrs,width*height*sizeof(T)); ptrd+=width*height; }
--              }
--            }
--            break;
--          case 2: {
--            const int ml = cimg::mod(deltaz,depth), ndeltaz = (ml<=(int)depth/2)?ml:(ml-(int)depth);
--            if (!ndeltaz) return *this;
--            T* buf = new T[width*height*cimg::abs(ndeltaz)];
--            if (ndeltaz>0) cimg_forV(*this,k) {
--              std::memcpy(buf,ptr(0,0,0,k),width*height*ndeltaz*sizeof(T));
--              std::memmove(ptr(0,0,0,k),ptr(0,0,ndeltaz,k),width*height*(depth-ndeltaz)*sizeof(T));
--              std::memcpy(ptr(0,0,depth-ndeltaz,k),buf,width*height*ndeltaz*sizeof(T));
--            } else cimg_forV(*this,k) {
--              std::memcpy(buf,ptr(0,0,depth+ndeltaz,k),-ndeltaz*width*height*sizeof(T));
--              std::memmove(ptr(0,0,-ndeltaz,k),ptr(0,0,0,k),width*height*(depth+ndeltaz)*sizeof(T));
--              std::memcpy(ptr(0,0,0,k),buf,-ndeltaz*width*height*sizeof(T));
--            }
--            delete[] buf;
--          } break;
--          }
--
--        if (deltav) // Translate along V-axis
--          switch (border_condition) {
--          case 0:
--            if (cimg::abs(deltav)>=(int)dim) return fill(0);
--            if (deltav>0) {
--              std::memmove(data,ptr(0,0,0,deltav),width*height*depth*(dim-deltav)*sizeof(T));
--              std::memset(ptr(0,0,0,dim-deltav),0,width*height*depth*deltav*sizeof(T));
--            } else cimg_forV(*this,k) {
--              std::memmove(ptr(0,0,0,-deltav),data,width*height*depth*(dim+deltav)*sizeof(T));
--              std::memset(data,0,-deltav*width*height*depth*sizeof(T));
--            }
--            break;
--          case 1:
--            if (deltav>0) {
--              const int ndeltav = (deltav>=(int)dim)?dim-1:deltav;
--              if (!ndeltav) return *this;
--              std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
--              T *ptrd = ptr(0,0,0,dim-ndeltav), *ptrs = ptr(0,0,0,dim-1);
--              for (int l=0; l<ndeltav-1; l++) { std::memcpy(ptrd,ptrs,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
--            } else {
--              const int ndeltav = (-deltav>=(int)dim)?dim-1:-deltav;
--              if (!ndeltav) return *this;
--              std::memmove(ptr(0,0,0,ndeltav),data,width*height*depth*(dim-ndeltav)*sizeof(T));
--              T *ptrd = ptr(0,0,0,1);
--              for (int l=0; l<ndeltav-1; l++) { std::memcpy(ptrd,data,width*height*depth*sizeof(T)); ptrd+=width*height*depth; }
--            }
--            break;
--          case 2: {
--            const int ml = cimg::mod(deltav,dim), ndeltav = (ml<=(int)dim/2)?ml:(ml-(int)dim);
--            if (!ndeltav) return *this;
--            T* buf = new T[width*height*depth*cimg::abs(ndeltav)];
--            if (ndeltav>0) {
--              std::memcpy(buf,data,width*height*depth*ndeltav*sizeof(T));
--              std::memmove(data,ptr(0,0,0,ndeltav),width*height*depth*(dim-ndeltav)*sizeof(T));
--              std::memcpy(ptr(0,0,0,dim-ndeltav),buf,width*height*depth*ndeltav*sizeof(T));
--            } else {
--              std::memcpy(buf,ptr(0,0,0,dim+ndeltav),-ndeltav*width*height*depth*sizeof(T));
--              std::memmove(ptr(0,0,0,-ndeltav),data,width*height*depth*(dim+ndeltav)*sizeof(T));
--              std::memcpy(data,buf,-ndeltav*width*height*depth*sizeof(T));
--            }
--            delete[] buf;
--          } break;
--          }
--      }
--      return *this;
--    }
--
--    //! Return a translated image.
--    /**
--       \param deltax Amount of displacement along the X-axis.
--       \param deltay Amount of displacement along the Y-axis.
--       \param deltaz Amount of displacement along the Z-axis.
--       \param deltav Amount of displacement along the V-axis.
--       \param border_condition Border condition.
--
--       - \c border_condition can be :
--          - 0 : Zero border condition (Dirichlet).
--          - 1 : Nearest neighbors (Neumann).
--          - 2 : Repeat Pattern (Fourier style).
--    **/
--    CImg get_translate(const int deltax,const int deltay=0,const int deltaz=0,const int deltav=0,
--                    const int border_condition=0) const {
--      return (+*this).translate(deltax,deltay,deltaz,deltav,border_condition);
--    }
--
--    //! Return a 2D representation of a 3D image, with three slices.
--    CImg get_projections2d(const unsigned int px0,const unsigned int py0,const unsigned int pz0) const {
--      if (is_empty()) return CImg<T>();
--      const unsigned int
--        x0=(px0>=width)?width-1:px0,
--        y0=(py0>=height)?height-1:py0,
--        z0=(pz0>=depth)?depth-1:pz0;
--      CImg res(width+depth,height+depth,1,dim);
--      res.fill((*this)[0]);
--      { cimg_forXYV(*this,x,y,k) res(x,y,0,k)        = (*this)(x,y,z0,k); }
--      { cimg_forYZV(*this,y,z,k) res(width+z,y,0,k)  = (*this)(x0,y,z,k); }
--      { cimg_forXZV(*this,x,z,k) res(x,height+z,0,k) = (*this)(x,y0,z,k); }
--      return res;
--    }
--
--    //! Return the image histogram.
--    /**
--       The histogram H of an image I is a 1D-function where H(x) is the number of
--       occurences of the value x in I.
--       \param nblevels = Number of different levels of the computed histogram.
--       For classical images, this value is 256 (default value). You should specify more levels
--       if you are working with CImg<float> or images with high range of pixel values.
--       \param val_min = Minimum value considered for the histogram computation. All pixel values lower than val_min
--       won't be counted.
--       \param val_max = Maximum value considered for the histogram computation. All pixel values higher than val_max
--       won't be counted.
--       \note If val_min==val_max==0 (default values), the function first estimates the minimum and maximum
--       pixel values of the current image, then uses these values for the histogram computation.
--       \result The histogram is returned as a 1D CImg<float> image H, having a size of (nblevels,1,1,1) such that
--       H(0) and H(nblevels-1) are respectively equal to the number of occurences of the values val_min and val_max in I.
--       \note Histogram computation always returns a 1D function. Histogram of multi-valued (such as color) images
--       are not multi-dimensional.
--       \see get_equalize_histogram(), equalize_histogram()
--    **/
--    CImg<float> get_histogram(const unsigned int nblevels=256,const T val_min=(T)0,const T val_max=(T)0) const {
--      if (is_empty()) return CImg<float>();
--      if (nblevels<1)
--        throw CImgArgumentException("CImg<%s>::get_histogram() : Can't compute an histogram with %u levels",
--                                    pixel_type(),nblevels);
--      T vmin=val_min, vmax=val_max;
--      CImg<float> res(nblevels,1,1,1,0);
--      if (vmin==vmax && vmin==0) { const CImgStats st(*this,false); vmin = (T)st.min; vmax = (T)st.max; }
--      cimg_for(*this,ptr,T) {
--        const int pos = (int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
--        if (pos>=0 && pos<(int)nblevels) res[pos]++;
--      }
--      return res;
--    }
--
--    //! Equalize the image histogram
--    /** This is the in-place version of \ref get_equalize_histogram() **/
--    CImg& equalize_histogram(const unsigned int nblevels=256,const T val_min=(T)0,const T val_max=(T)0) {
--      if (!is_empty()) {
--        T vmin=val_min, vmax=val_max;
--        if (vmin==vmax && vmin==0) { const CImgStats st(*this,false); vmin = (T)st.min; vmax = (T)st.max; }
--        CImg<float> hist = get_histogram(nblevels,vmin,vmax);
--        float cumul=0;
--        cimg_forX(hist,pos) { cumul+=hist[pos]; hist[pos]=cumul; }
--        cimg_for(*this,ptr,T) {
--          const int pos = (unsigned int)((*ptr-vmin)*(nblevels-1)/(vmax-vmin));
--          if (pos>=0 && pos<(int)nblevels) *ptr = (T)(vmin + (vmax-vmin)*hist[pos]/size());
--        }
--      }
--      return *this;
--    }
--
--    //! Return the histogram-equalized version of the current image.
--    /**
--       The histogram equalization is a classical image processing algorithm that enhances the image contrast
--       by expanding its histogram.
--       \param nblevels = Number of different levels of the computed histogram.
--       For classical images, this value is 256 (default value). You should specify more levels
--       if you are working with CImg<float> or images with high range of pixel values.
--       \param val_min = Minimum value considered for the histogram computation. All pixel values lower than val_min
--       won't be changed.
--       \param val_max = Maximum value considered for the histogram computation. All pixel values higher than val_max
--       won't be changed.
--       \note If val_min==val_max==0 (default values), the function acts on all pixel values of the image.
--       \return A new image with same size is returned, where pixels have been equalized.
--       \see get_histogram(), equalize_histogram()
--    **/
--    CImg get_equalize_histogram(const unsigned int nblevels=256,const T val_min=(T)0,const T val_max=(T)0) const {
--      return (+*this).equalize_histogram(nblevels,val_min,val_max);
--    }
--
--    //! Return the scalar image of vector norms.
--    /**
--       When dealing with vector-valued images (i.e images with dimv()>1), this function computes the L1,L2 or Linf norm of each
--       vector-valued pixel.
--       \param norm_type = Type of the norm being computed (1 = L1, 2 = L2, -1 = Linf).
--       \return A scalar-valued image CImg<float> with size (dimx(),dimy(),dimz(),1), where each pixel is the norm
--       of the corresponding pixels in the original vector-valued image.
--       \see get_orientation_pointwise, orientation_pointwise, norm_pointwise.
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_norm_pointwise(int norm_type=2) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImg<restype>();
--      CImg<restype> res(width,height,depth);
--      switch(norm_type) {
--      case -1: {             // Linf norm
--        cimg_forXYZ(*this,x,y,z) {
--          restype n=0; cimg_forV(*this,v) {
--            const restype tmp = (restype)cimg::abs((*this)(x,y,z,v));
--            if (tmp>n) n=tmp; res(x,y,z) = n;
--          }
--        }
--      } break;
--      case 1: {              // L1 norm
--        cimg_forXYZ(*this,x,y,z) {
--          restype n=0; cimg_forV(*this,v) n+=cimg::abs((*this)(x,y,z,v)); res(x,y,z) = n;
--        }
--      } break;
--      default: {             // L2 norm
--        cimg_forXYZ(*this,x,y,z) {
--          restype n=0; cimg_forV(*this,v) n+=(*this)(x,y,z,v)*(*this)(x,y,z,v); res(x,y,z) = (restype)std::sqrt((double)n);
--        }
--      } break;
--      }
--      return res;
--    }
--
--    //! Replace each pixel value with its vector norm.
--    /**
--       This is the in-place version of \ref get_norm_pointwise().
--       \note Be careful when using this function on CImg<T> with T=char, unsigned char,unsigned int or int. The vector norm
--       is usually a floating point value, and a rough cast will be done here.
--    **/
--    CImg& norm_pointwise() {
--      return CImg<T>(get_norm_pointwise()).swap(*this);
--    }
--
--    //! Return the image of normalized vectors
--    /**
--       When dealing with vector-valued images (i.e images with dimv()>1), this function return the image of normalized vectors
--       (unit vectors). Null vectors are unchanged. The L2-norm is computed for the normalization.
--       \return A new vector-valued image with same size, where each vector-valued pixels have been normalized.
--       \see get_norm_pointwise, norm_pointwise, orientation_pointwise.
--    **/
--    CImg<typename cimg::largest<T,float>::type> get_orientation_pointwise() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImg<restype>();
--      return CImg<restype>(*this,false).orientation_pointwise();
--    }
--
--    //! Replace each pixel value by its normalized vector
--    /** This is the in-place version of \ref get_orientation_pointwise() **/
--    CImg& orientation_pointwise() {
--      cimg_forXYZ(*this,x,y,z) {
--        float n = 0.0f;
--        cimg_forV(*this,v) n+=(float)((*this)(x,y,z,v)*(*this)(x,y,z,v));
--        n = (float)std::sqrt(n);
--        if (n>0) cimg_forV(*this,v) (*this)(x,y,z,v)=(T)((*this)(x,y,z,v)/n);
--        else cimg_forV(*this,v) (*this)(x,y,z,v)=0;
--      }
--      return *this;
--    }
--
--    //! Split image into a list CImgList<>.
--    CImgList<T> get_split(const char axe='x', const unsigned int nb=0) const {
--      if (is_empty()) return CImgList<T>();
--      CImgList<T> res;
--      switch (cimg::uncase(axe)) {
--      case 'x': {
--        if (nb>width)
--          throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'x' into %u images.",
--                                      pixel_type(),width,height,depth,dim,data,nb);
--        res.assign(nb?nb:width);
--        const unsigned int delta = width/res.size + ((width%res.size)?1:0);
--        unsigned int l,x;
--        for (l=0, x=0; l<res.size-1; l++, x+=delta) res[l] = get_crop(x,0,0,0,x+delta-1,height-1,depth-1,dim-1);
--        res[res.size-1] = get_crop(x,0,0,0,width-1,height-1,depth-1,dim-1);
--      } break;
--      case 'y': {
--        if (nb>height)
--          throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'y' into %u images.",
--                                      pixel_type(),width,height,depth,dim,data,nb);
--        res.assign(nb?nb:height);
--        const unsigned int delta = height/res.size + ((height%res.size)?1:0);
--        unsigned int l,x;
--        for (l=0, x=0; l<res.size-1; l++, x+=delta) res[l] = get_crop(0,x,0,0,width-1,x+delta-1,depth-1,dim-1);
--        res[res.size-1] = get_crop(0,x,0,0,width-1,height-1,depth-1,dim-1);
--      } break;
--      case 'z': {
--        if (nb>depth)
--          throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'z' into %u images.",
--                                      pixel_type(),width,height,depth,dim,data,nb);
--        res.assign(nb?nb:depth);
--        const unsigned int delta = depth/res.size + ((depth%res.size)?1:0);
--        unsigned int l,x;
--        for (l=0, x=0; l<res.size-1; l++, x+=delta) res[l] = get_crop(0,0,x,0,width-1,height-1,x+delta-1,dim-1);
--        res[res.size-1] = get_crop(0,0,x,0,width-1,height-1,depth-1,dim-1);
--      } break;
--      case 'v': {
--        if (nb>dim)
--          throw CImgArgumentException("CImg<%s>::get_split() : Cannot split instance image (%u,%u,%u,%u,%p) along 'v' into %u images.",
--                                      pixel_type(),width,height,depth,dim,data,nb);
--        res.assign(nb?nb:dim);
--        const unsigned int delta = dim/res.size + ((dim%res.size)?1:0);
--        unsigned int l,x;
--        for (l=0, x=0; l<res.size-1; l++, x+=delta) res[l] = get_crop(0,0,0,x,width-1,height-1,depth-1,x+delta-1);
--        res[res.size-1] = get_crop(0,0,0,x,width-1,height-1,depth-1,dim-1);
--      } break;
--      default:
--        throw CImgArgumentException("CImg<%s>::get_split() : Unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
--        break;
--      }
--      return res;
--    }
--
--    //! Append an image to another one
--    CImg get_append(const CImg<T>& img, const char axis='x', const char align='c') const {
--      if (img.is_empty()) return *this;
--      if (is_empty()) return img;
--      CImgList<T> temp(2);
--      temp[0].width = width; temp[0].height = height; temp[0].depth = depth;
--      temp[0].dim = dim; temp[0].data = data;
--      temp[1].width = img.width; temp[1].height = img.height; temp[1].depth = img.depth;
--      temp[1].dim = img.dim; temp[1].data = img.data;
--      const CImg<T> res = temp.get_append(axis,align);
--      temp[0].width = temp[0].height = temp[0].depth = temp[0].dim = 0; temp[0].data = 0;
--      temp[1].width = temp[1].height = temp[1].depth = temp[1].dim = 0; temp[1].data = 0;
--      return res;
--    }
--
--    //! Append an image to another one (in-place version)
--    CImg& append(const CImg<T>& img, const char axis='x', const char align='c') {
--      if (img.is_empty()) return *this;
--      if (is_empty()) return (*this=img);
--      return get_append(img,axis,align).swap(*this);
--    }
--
--    //! Return a list of images, corresponding to the XY-gradients of an image.
--    /**
--       \param scheme = Numerical scheme used for the gradient computation :
--       - -1 = Backward finite differences
--       - 0 = Centered finite differences
--       - 1 = Forward finite differences
--       - 2 = Using Sobel masks
--       - 3 = Using rotation invariant masks
--       - 4 = Using Deriche recusrsive filter.
--    **/
--    CImgList<typename cimg::largest<T,float>::type> get_gradientXY(const int scheme=0) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImgList<restype>(2);
--      CImgList<restype> res(2,width,height,depth,dim);
--      switch(scheme) {
--      case -1: { // backward finite differences
--        CImg_3x3(I,restype);
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) { res[0](x,y,z,k) = Icc-Ipc; res[1](x,y,z,k) = Icc-Icp; }
--      } break;
--      case 1: { // forward finite differences
--        CImg_2x2(I,restype);
--        cimg_forZV(*this,z,k) cimg_for2x2(*this,x,y,z,k,I) { res[0](x,y,0,k) = Inc-Icc; res[1](x,y,z,k) = Icn-Icc; }
--      } break;
--      case 2: { // using Sobel mask
--        CImg_3x3(I,restype);
--        const float a = 1, b = 2;
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
--          res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
--        }
--      } break;
--      case 3: { // using rotation invariant mask
--        CImg_3x3(I,restype);
--        const float a = (float)(0.25*(2-std::sqrt(2.0))), b = (float)(0.5f*(std::sqrt(2.0)-1));
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = -a*Ipp-b*Ipc-a*Ipn+a*Inp+b*Inc+a*Inn;
--          res[1](x,y,z,k) = -a*Ipp-b*Icp-a*Inp+a*Ipn+b*Icn+a*Inn;
--        }
--      } break;
--      case 4: { // using Deriche filter with low standard variation
--        res[0] = get_deriche(0,1,'x');
--        res[1] = get_deriche(0,1,'y');
--      } break;
--      default: { // central finite differences
--        CImg_3x3(I,restype);
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = 0.5f*(Inc-Ipc);
--          res[1](x,y,z,k) = 0.5f*(Icn-Icp);
--        }
--      } break;
--      }
--      return res;
--    }
--
--    //! Return a list of images, corresponding to the XYZ-gradients of an image.
--    /**
--       \see get_gradientXY().
--    **/
--    CImgList<typename cimg::largest<T,float>::type> get_gradientXYZ(const int scheme=0) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImgList<restype>(3);
--      CImgList<restype> res(3,width,height,depth,dim);
--      CImg_3x3x3(I,restype);
--      switch(scheme) {
--      case -1: { // backward finite differences
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = Iccc-Ipcc;
--          res[1](x,y,z,k) = Iccc-Icpc;
--          res[2](x,y,z,k) = Iccc-Iccp;
--        }
--      } break;
--      case 1: { // forward finite differences
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = Incc-Iccc;
--          res[1](x,y,z,k) = Icnc-Iccc;
--          res[2](x,y,z,k) = Iccn-Iccc;
--        }
--      } break;
--      case 4: { // using Deriche filter with low standard variation
--        res[0] = get_deriche(0,1,'x');
--        res[1] = get_deriche(0,1,'y');
--        res[2] = get_deriche(0,1,'z');
--      } break;
--      default: { // central finite differences
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          res[0](x,y,z,k) = 0.5f*(Incc-Ipcc);
--          res[1](x,y,z,k) = 0.5f*(Icnc-Icpc);
--          res[2](x,y,z,k) = 0.5f*(Iccn-Iccp);
--        }
--      } break;
--      }
--      return res;
--    }
--
--    //! Return the 2D structure tensor field of an image
--    CImg<typename cimg::largest<T,float>::type> get_structure_tensorXY(const int scheme=1) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImg<restype>();
--      CImg<restype> res(width,height,depth,3,0);
--      CImg_3x3(I,restype);
--      switch (scheme) {
--      case 0: { // classical central finite differences
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
--          const restype
--            ix = 0.5f*(Inc-Ipc),
--            iy = 0.5f*(Icn-Icp);
--          res(x,y,z,0)+=ix*ix;
--          res(x,y,z,1)+=ix*iy;
--          res(x,y,z,2)+=iy*iy;
--        }
--      } break;
--      default: { // Precise forward/backward finite differences
--        cimg_forZV(*this,z,k) cimg_for3x3(*this,x,y,0,k,I) {
--          const restype
--            ixf = Inc-Icc, ixb = Icc-Ipc,
--            iyf = Icn-Icc, iyb = Icc-Icp;
--          res(x,y,z,0) += 0.5f*(ixf*ixf+ixb*ixb);
--          res(x,y,z,1) += 0.25f*(ixf*iyf+ixf*iyb+ixb*iyf+ixb*iyb);
--          res(x,y,z,2) += 0.5f*(iyf*iyf+iyb*iyb);
--        }
--      } break;
--      }
--      return res;
--    }
--
--    //! In-place version of the previous function
--    CImg& structure_tensorXY(const int scheme=1) {
--      return get_structure_tensorXY(scheme).swap(*this);
--    }
--
--    //! Return the 3D structure tensor field of an image
--    CImg<typename cimg::largest<T,float>::type> get_structure_tensorXYZ(const int scheme=1) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      if (is_empty()) return CImg<restype>();
--      CImg<restype> res(width,height,depth,6,0);
--      CImg_3x3x3(I,restype);
--      switch (scheme) {
--      case 0: { // classical central finite differences
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          const restype
--            ix = 0.5f*(Incc-Ipcc),
--            iy = 0.5f*(Icnc-Icpc),
--            iz = 0.5f*(Iccn-Iccp);
--          res(x,y,z,0)+=ix*ix;
--          res(x,y,z,1)+=ix*iy;
--          res(x,y,z,2)+=ix*iz;
--          res(x,y,z,3)+=iy*iy;
--          res(x,y,z,4)+=iy*iz;
--          res(x,y,z,5)+=iz*iz;
--        }
--      } break;
--      default: { // Precise forward/backward finite differences
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          const restype
--            ixf = Incc-Iccc, ixb = Iccc-Ipcc,
--            iyf = Icnc-Iccc, iyb = Iccc-Icpc,
--            izf = Iccn-Iccc, izb = Iccc-Iccp;
--          res(x,y,z,0) += 0.5f*(ixf*ixf + ixb*ixb);
--          res(x,y,z,1) += 0.25f*(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb);
--          res(x,y,z,2) += 0.25f*(ixf*izf + ixf*izb + ixb*izf + ixb*izb);
--          res(x,y,z,3) += 0.5f*(iyf*iyf + iyb*iyb);
--          res(x,y,z,4) += 0.25f*(iyf*izf + iyf*izb + iyb*izf + iyb*izb);
--          res(x,y,z,5) += 0.5f*(izf*izf + izb*izb);
--        }
--      } break;
--      }
--      return res;
--    }
--
--    //! In-place version of the previous function
--    CImg& structure_tensorXYZ(const int scheme=1) {
--      return get_structure_tensorXYZ(scheme).swap(*this);
--    }
--
--    //@}
--    //-------------------------------------
--    //
--    //! \name Meshes and Triangulations
--    //@{
--    //-------------------------------------
--
--    struct _marching_squares_func {
--      const CImg<T>& ref;
--      _marching_squares_func(const CImg<T>& pref):ref(pref) {}
--      float operator()(const float x, const float y) const {
--        return (float)ref((int)x,(int)y);
--      }
--    };
--
--    struct _marching_cubes_func {
--      const CImg<T>& ref;
--      _marching_cubes_func(const CImg<T>& pref):ref(pref) {}
--      float operator()(const float x, const float y, const float z) const {
--        return (float)ref((int)x,(int)y,(int)z);
--      }
--    };
--
--    struct _marching_squares_func_float {
--      const CImg<T>& ref;
--      _marching_squares_func_float(const CImg<T>& pref):ref(pref) {}
--      float operator()(const float x, const float y) const {
--        return (float)ref.linear_pix2d(x,y);
--      }
--    };
--
--    struct _marching_cubes_func_float {
--      const CImg<T>& ref;
--      _marching_cubes_func_float(const CImg<T>& pref):ref(pref) {}
--      float operator()(const float x, const float y, const float z) const {
--        return (float)ref.linear_pix3d(x,y,z);
--      }
--    };
--
--    //! Get a vectorization of an implicit function defined by the instance image.
--    template<typename tp, typename tf>
--    const CImg& marching_squares(const float isovalue,CImgList<tp>& points, CImgList<tf>& primitives) const {
--      if (height<=1 || depth>1 || dim>1)
--        throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
--                                    pixel_type(),width,height,depth,dim,data);
--      const _marching_squares_func func(*this);
--      cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,1.0f,1.0f,points,primitives);
--      return *this;
--    }
--
--    //! Get a vectorization of an implicit function defined by the instance image.
--    /**
--       This version allows to specify the marching squares resolution along x,y, and z.
--    **/
--    template<typename tp, typename tf>
--    const CImg& marching_squares(const float isovalue,
--                                 const float resx, const float resy,
--                                 CImgList<tp>& points, CImgList<tf>& primitives) const {
--      if (height<=1 || depth>1 || dim>1)
--        throw CImgInstanceException("CImg<%s>::marching_squares() : Instance image (%u,%u,%u,%u,%p) is not a 2D scalar image.",
--                                    pixel_type(),width,height,depth,dim,data);
--      const _marching_squares_func_float func(*this);
--      cimg::marching_squares(func,isovalue,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,resx,resy,points,primitives);
--      return *this;
--    }
--
--    //! Get a triangulation of an implicit function defined by the instance image
--    template<typename tp, typename tf>
--    const CImg& marching_cubes(const float isovalue,CImgList<tp>& points, CImgList<tf>& primitives,
--                               const bool invert_faces = false) const {
--      if (depth<=1 || dim>1)
--        throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
--                                    pixel_type(),width,height,depth,dim,data);
--      const _marching_cubes_func func(*this);
--      cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
--                           1.0f,1.0f,1.0f,points,primitives,invert_faces);
--      return *this;
--    }
--
--    //! Get a triangulation of an implicit function defined by the instance image
--    /**
--       This version allows to specify the marching cube resolution along x,y and z.
--    **/
--    template<typename tp, typename tf>
--    const CImg& marching_cubes(const float isovalue,
--                               const float resx, const float resy, const float resz,
--                               CImgList<tp>& points, CImgList<tf>& primitives,
--                               const bool invert_faces = false) const {
--      if (depth<=1 || dim>1)
--        throw CImgInstanceException("CImg<%s>::marching_cubes() : Instance image (%u,%u,%u,%u,%p) is not a 3D scalar image.",
--                                    pixel_type(),width,height,depth,dim,data);
--      const _marching_cubes_func_float func(*this);
--      cimg::marching_cubes(func,isovalue,0.0f,0.0f,0.0f,dimx()-1.0f,dimy()-1.0f,dimz()-1.0f,
--                           resx,resy,resz,points,primitives,invert_faces);
--      return *this;
--    }
--
--    //@}
--    //----------------------------
--    //
--    //! \name Color conversions
--    //@{
--    //----------------------------
--
--    //! Return the default 256 colors palette.
--    /**
--       The default color palette is used by %CImg when displaying images on 256 colors displays.
--       It consists in the quantification of the (R,G,B) color space using 3:3:2 bits for color coding
--       (i.e 8 levels for the Red and Green and 4 levels for the Blue).
--       \return A 256x1x1x3 color image defining the palette entries.
--    **/
--    static CImg<T> get_default_LUT8() {
--      static CImg<T> palette;
--      if (!palette.data) {
--        palette.assign(256,1,1,3);
--        for (unsigned int index=0, r=16; r<256; r+=32)
--          for (unsigned int g=16; g<256; g+=32)
--            for (unsigned int b=32; b<256; b+=64) {
--              palette(index,0) = r;
--              palette(index,1) = g;
--              palette(index++,2) = b;
--            }
--      }
--      return palette;
--    }
--
--    //! Convert color pixels from (R,G,B) to match a specified palette.
--    /**
--       This function return a (R,G,B) image where colored pixels are constrained to match entries
--       of the specified color \c palette.
--       \param palette User-defined palette that will constraint the color conversion.
--       \param dithering Enable/Disable Floyd-Steinberg dithering.
--       \param indexing If \c true, each resulting image pixel is an index to the given color palette.
--       Otherwise, (R,G,B) values of the palette are copied instead.
--    **/
--    template<typename t> CImg<t> get_RGBtoLUT(const CImg<t>& palette, const bool dithering=true,const bool indexing=false) const {
--      if (is_empty()) return CImg<t>();
--      if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoLUT() : Input image dimension is dim=%u, "
--                                              "should be a (R,G,B) image.",pixel_type(),dim);
--      if (palette.data && palette.dim!=3)
--        throw CImgArgumentException("CImg<%s>::RGBtoLUT() : Given palette dimension is dim=%u, "
--                                    "should be a (R,G,B) palette",pixel_type(),palette.dim);
--      CImg<t> res(width,height,depth,indexing?1:3), pal = palette.data?palette:CImg<t>::get_default_LUT8();
--      float *line1 = new float[3*width], *line2 = new float[3*width], *pline1 = line1, *pline2 = line2;
--      cimg_forZ(*this,z) {
--        float *ptr=pline2; cimg_forX(*this,x) { *(ptr++)=(*this)(x,0,z,0); *(ptr++)=(*this)(x,0,z,1); *(ptr++)=(*this)(x,0,z,2); }
--        cimg_forY(*this,y) {
--          cimg::swap(pline1,pline2);
--          if (y<dimy()-1) {
--            const int ny = y+1;
--            float *ptr=pline2; cimg_forX(*this,x) { *(ptr++)=(*this)(x,ny,z,0); *(ptr++)=(*this)(x,ny,z,1); *(ptr++)=(*this)(x,ny,z,2); }
--          }
--          float *ptr1=pline1, *ptr2=pline2;
--          cimg_forX(*this,x) {
--            float R = *(ptr1++), G = *(ptr1++), B = *(ptr1++);
--            R = R<0?0:(R>255?255:R); G = G<0?0:(G>255?255:G); B = B<0?0:(B>255?255:B);
--            int best_index = 0;
--            t Rbest=0,Gbest=0,Bbest=0;
--            if (palette.data) { // find best match in given color palette
--              float min = cimg::type<float>::max();
--              cimg_forX(palette,off) {
--                const t Rp = palette(off,0), Gp = palette(off,1), Bp = palette(off,2);
--                const float error = (float)((Rp-R)*(Rp-R) + (Gp-G)*(Gp-G) + (Bp-B)*(Bp-B));
--                if (error<min) { min=error; best_index=off; Rbest=Rp; Gbest=Gp; Bbest=Bp; }
--              }
--            } else {
--              Rbest = (t)((unsigned char)R&0xe0); Gbest = (t)((unsigned char)G&0xe0); Bbest = (t)((unsigned char)B&0xc0);
--              best_index = (unsigned char)Rbest | ((unsigned char)Gbest>>3) | ((unsigned char)Bbest>>6);
--            }
--            if (indexing) res(x,y,z) = best_index;
--            else { res(x,y,z,0) = Rbest; res(x,y,z,1) = Gbest; res(x,y,z,2) = Bbest; }
--            if (dithering) { // apply dithering to neighborhood pixels if needed
--              const float dR = (float)(R-Rbest), dG = (float)(G-Gbest), dB = (float)(B-Bbest);
--              if (x<dimx()-1) { *(ptr1++)+= dR*7/16; *(ptr1++)+= dG*7/16; *(ptr1++)+= dB*7/16; ptr1-=3; }
--              if (y<dimy()-1) {
--                *(ptr2++)+= dR*5/16; *(ptr2++)+= dG*5/16; *ptr2+= dB*5/16; ptr2-=2;
--                if (x>0) { *(--ptr2)+= dB*3/16; *(--ptr2)+= dG*3/16; *(--ptr2)+= dR*3/16; ptr2+=3; }
--                if (x<dimx()-1) { ptr2+=3; *(ptr2++)+= dR/16; *(ptr2++)+= dG/16; *ptr2+= dB/16; ptr2-=5; }
--              }
--            }
--            ptr2+=3;
--          }
--        }
--      }
--      delete[] line1; delete[] line2;
--      return res;
--    }
--
--    //! Convert color pixels from (R,G,B) to match the default 256 colors palette.
--    /**
--       Same as get_RGBtoLUT() with the default color palette given by get_default_LUT8().
--    **/
--    CImg<T> get_RGBtoLUT(const bool dithering=true, const bool indexing=false) const {
--      CImg<T> foo;
--      return get_RGBtoLUT(foo,dithering,indexing);
--    }
--
--    //! Convert color pixels from (R,G,B) to match the specified color palette.
--    /** This is the in-place version of get_RGBtoLUT(). **/
--    CImg& RGBtoLUT(const CImg<T>& palette,const bool dithering=true,const bool indexing=false) {
--      return get_RGBtoLUT(palette,dithering,indexing).swap(*this);
--    }
--
--    //! Convert color pixels from (R,G,B) to match the specified color palette.
--    /** This is the in-place version of get_RGBtoLUT(). **/
--    CImg& RGBtoLUT(const bool dithering=true,const bool indexing=false) {
--      CImg<T> foo;
--      return get_RGBtoLUT(foo,dithering,indexing).swap(*this);
--    }
--
--    //! Convert an indexed image to a (R,G,B) image using the specified color palette.
--    template<typename t> CImg<t> get_LUTtoRGB(const CImg<t>& palette) const {
--      if (is_empty()) return CImg<t>();
--      if (dim!=1) throw CImgInstanceException("CImg<%s>::LUTtoRGB() : Input image dimension is dim=%u, "
--                                              "should be a LUT image",pixel_type(),dim);
--      if (palette.data && palette.dim!=3)
--        throw CImgArgumentException("CImg<%s>::LUTtoRGB() : Given palette dimension is dim=%u, "
--                                    "should be a (R,G,B) palette",pixel_type(),palette.dim);
--      CImg<t> res(width,height,depth,3);
--      CImg<t> pal = palette.data?palette:get_default_LUT8();
--      cimg_forXYZ(*this,x,y,z) {
--        const unsigned int index = (unsigned int)(*this)(x,y,z);
--        res(x,y,z,0) = pal(index,0);
--        res(x,y,z,1) = pal(index,1);
--        res(x,y,z,2) = pal(index,2);
--      }
--      return res;
--    }
--
--    //! Convert an indexed image (with the default palette) to a (R,G,B) image.
--    CImg<T> get_LUTtoRGB() const {
--      CImg<T> foo;
--      return get_LUTtoRGB(foo);
--    }
--
--    //! In-place version of get_LUTtoRGB().
--    CImg& LUTtoRGB(const CImg<T>& palette) {
--      return get_LUTtoRGB(palette).swap(*this);
--    }
--
--    //! In-place version of get_LUTroRGB().
--    CImg& LUTtoRGB() {
--      CImg<T> foo;
--      return get_LUTtoRGB(foo).swap(*this);
--    }
--
--    //! Convert color pixels from (R,G,B) to (H,S,V).
--    CImg& RGBtoHSV() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoHSV() : Input image dimension is dim=%u, "
--                                                "should be a (R,G,B) image.",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const float
--            R = (float)((*this)(x,y,z,0)/255.0f),
--            G = (float)((*this)(x,y,z,1)/255.0f),
--            B = (float)((*this)(x,y,z,2)/255.0f);
--          const float m = cimg::min(R,G,B), v = cimg::max(R,G,B);
--          float h,s;
--          if (v==m) { h=-1; s=0; } else {
--            const float
--              f = (R==m)?(G-B):((G==m)?(B-R):(R-G)),
--              i = (R==m)?3.0f:((G==m)?5.0f:1.0f);
--            h = (i-f/(v-m));
--            s = (v-m)/v;
--            if (h>=6.0f) h-=6.0f;
--            h*=(float)cimg::PI/3.0f;
--          }
--          (*this)(x,y,z,0) = (T)h;
--          (*this)(x,y,z,1) = (T)s;
--          (*this)(x,y,z,2) = (T)v;
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (H,S,V) to (R,G,B).
--    CImg& HSVtoRGB() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::HSVtoRGB() : Input image dimension is dim=%u, "
--                                                "should be a (H,S,V) image",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          float
--            H = (float)((*this)(x,y,z,0)),
--            S = (float)((*this)(x,y,z,1)),
--            V = (float)((*this)(x,y,z,2));
--          float R=0,G=0,B=0;
--          if (H<0) R=G=B=V;
--          else {
--            H/=(float)cimg::PI/3.0f;
--            const int i = (int)std::floor(H);
--            const float
--              f = (i&1)?(H-i):(1.0f-H+i),
--              m = V*(1.0f-S),
--              n = V*(1.0f-S*f);
--            switch(i) {
--            case 6:
--            case 0: R=V; G=n; B=m; break;
--            case 1: R=n; G=V; B=m; break;
--            case 2: R=m; G=V; B=n; break;
--            case 3: R=m; G=n; B=V; break;
--            case 4: R=n; G=m; B=V; break;
--            case 5: R=V; G=m; B=n; break;
--            }
--          }
--          (*this)(x,y,z,0) = (T)(R*255.0f);
--          (*this)(x,y,z,1) = (T)(G*255.0f);
--          (*this)(x,y,z,2) = (T)(B*255.0f);
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (R,G,B) to (Y,Cb,Cr)_8 (Thanks to Chen Wang).
--    CImg& RGBtoYCbCr() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYCbCr() : Input image dimension is dim=%u, "
--                                                "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const int
--            R = (int)((*this)(x,y,z,0)),
--            G = (int)((*this)(x,y,z,1)),
--            B = (int)((*this)(x,y,z,2));
--          const int
--            Y  = ((66*R+129*G+25*B+128)>>8) + 16,
--            Cb = ((-38*R-74*G+112*B+128)>>8) + 128,
--            Cr = ((112*R-94*G-18*B+128)>>8) + 128;
--          (*this)(x,y,z,0) = (T)(Y<0?0:(Y>255?255:Y));
--          (*this)(x,y,z,1) = (T)(Cb<0?0:(Cb>255?255:Cb));
--          (*this)(x,y,z,2) = (T)(Cr<0?0:(Cr>255?255:Cr));
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (Y,Cb,Cr)_8 to (R,G,B).
--    CImg& YCbCrtoRGB() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::YCbCrtoRGB() : Input image dimension is dim=%u, "
--                                                "should be a (Y,Cb,Cr)_8 image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const int
--            Y  = (int)((*this)(x, y, z, 0)-16),
--            Cb = (int)((*this)(x, y, z, 1)-128),
--            Cr = (int)((*this)(x, y, z, 2)-128);
--          const int
--            R = ((298*Y + 409*Cr + 128) >> 8 ),
--            G = ((298*Y - 100*Cb - 208*Cr + 128) >> 8 ),
--            B = ((298*Y + 516*Cb + 128) >> 8 );
--          (*this)(x,y,z,0) = (T)(R<0?0:(R>255?255:R));
--          (*this)(x,y,z,1) = (T)(G<0?0:(G>255?255:G));
--          (*this)(x,y,z,2) = (T)(B<0?0:(B>255?255:B));
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (R,G,B) to (Y,U,V).
--    CImg& RGBtoYUV() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoYUV() : Input image dimension is dim=%u, "
--                                                "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const float
--            R = (*this)(x,y,z,0)/255.0f,
--            G = (*this)(x,y,z,1)/255.0f,
--            B = (*this)(x,y,z,2)/255.0f,
--            Y = (T)(0.299*R + 0.587*G + 0.114*B);
--          (*this)(x,y,z,0) = Y;
--          (*this)(x,y,z,1) = (T)(0.492*(B-Y));
--          (*this)(x,y,z,2) = (T)(0.877*(R-Y));
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (Y,U,V) to (R,G,B).
--    CImg& YUVtoRGB() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::YUVtoRGB() : Input image dimension is dim=%u, "
--                                                "should be a (Y,U,V) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const T Y = (*this)(x,y,z,0), U = (*this)(x,y,z,1), V = (*this)(x,y,z,2);
--          (*this)(x,y,z,0) = (T)((Y + 1.140*V)*255.0f);
--          (*this)(x,y,z,1) = (T)((Y - 0.395*U - 0.581*V)*255.0f);
--          (*this)(x,y,z,2) = (T)((Y + 2.032*U)*255.0f);
--        }
--      }
--      return *this;
--    }
--
--    //! Convert color pixels from (R,G,B) to (X,Y,Z)_709.
--    CImg& RGBtoXYZ() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::RGBtoXYZ() : Input image dimension is dim=%u, "
--                                                "should be a (R,G,B) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const float
--            R = (float)((*this)(x,y,z,0)/255.0f),
--            G = (float)((*this)(x,y,z,1)/255.0f),
--            B = (float)((*this)(x,y,z,2)/255.0f);
--          (*this)(x,y,z,0) = (T)(0.412453*R + 0.357580*G + 0.180423*B);
--          (*this)(x,y,z,1) = (T)(0.212671*R + 0.715160*G + 0.072169*B);
--          (*this)(x,y,z,2) = (T)(0.019334*R + 0.119193*G + 0.950227*B);
--        }
--      }
--      return *this;
--    }
--
--    //! Convert (X,Y,Z)_709 pixels of a color image into the (R,G,B) color space.
--    CImg& XYZtoRGB() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoRGB() : Input image dimension is dim=%u, "
--                                                "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const float
--            X = (float)(255.0f*(*this)(x,y,z,0)),
--            Y = (float)(255.0f*(*this)(x,y,z,1)),
--            Z = (float)(255.0f*(*this)(x,y,z,2));
--          (*this)(x,y,z,0) = (T)(3.240479*X  - 1.537150*Y - 0.498535*Z);
--          (*this)(x,y,z,1) = (T)(-0.969256*X + 1.875992*Y + 0.041556*Z);
--          (*this)(x,y,z,2) = (T)(0.055648*X  - 0.204043*Y + 1.057311*Z);
--        }
--      }
--      return *this;
--    }
--
--    //! Convert (X,Y,Z)_709 pixels of a color image into the (L*,a*,b*) color space.
--#define cimg_Labf(x)  ((x)>=0.008856?(std::pow(x,1/3.0)):(7.787*(x)+16.0/116.0))
--#define cimg_Labfi(x) ((x)>=0.206893?((x)*(x)*(x)):(((x)-16.0/116.0)/7.787))
--
--    CImg& XYZtoLab() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoLab() : Input image dimension is dim=%u, "
--                                                "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
--        const double
--          Xn = 0.412453 + 0.357580 + 0.180423,
--          Yn = 0.212671 + 0.715160 + 0.072169,
--          Zn = 0.019334 + 0.119193 + 0.950227;
--        cimg_forXYZ(*this,x,y,z) {
--          const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2);
--          const double
--            XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn,
--            fX = cimg_Labf(XXn), fY = cimg_Labf(YYn), fZ = cimg_Labf(ZZn);
--          (*this)(x,y,z,0) = (T)(116*fY-16);
--          (*this)(x,y,z,1) = (T)(500*(fX-fY));
--          (*this)(x,y,z,2) = (T)(200*(fY-fZ));
--        }
--      }
--      return *this;
--    }
--
--    //! Convert (L,a,b) pixels of a color image into the (X,Y,Z) color space.
--    CImg& LabtoXYZ() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::LabtoXYZ() : Input image dimension is dim=%u, "
--                                                "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
--        const double
--          Xn = 0.412453 + 0.357580 + 0.180423,
--          Yn = 0.212671 + 0.715160 + 0.072169,
--          Zn = 0.019334 + 0.119193 + 0.950227;
--        cimg_forXYZ(*this,x,y,z) {
--          const T L = (*this)(x,y,z,0), a = (*this)(x,y,z,1), b = (*this)(x,y,z,2);
--          const double
--            cY = (L+16)/116.0,
--            Y = Yn*cimg_Labfi(cY),
--            pY = std::pow(Y/Yn,1.0/3),
--            cX = a/500+pY,
--            X = Xn*cX*cX*cX,
--            cZ = pY-b/200,
--            Z = Zn*cZ*cZ*cZ;
--          (*this)(x,y,z,0) = (T)(X);
--          (*this)(x,y,z,1) = (T)(Y);
--          (*this)(x,y,z,2) = (T)(Z);
--        }
--      }
--      return *this;
--    }
--
--    //! Convert (X,Y,Z)_709 pixels of a color image into the (x,y,Y) color space.
--    CImg& XYZtoxyY() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::XYZtoxyY() : Input image dimension is dim=%u, "
--                                                "should be a (X,Y,Z) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const T X = (*this)(x,y,z,0), Y = (*this)(x,y,z,1), Z = (*this)(x,y,z,2), sum = (X+Y+Z), nsum = sum>0?sum:1;
--          (*this)(x,y,z,0) = X/nsum;
--          (*this)(x,y,z,1) = Y/nsum;
--          (*this)(x,y,z,2) = Y;
--        }
--      }
--      return *this;
--    }
--
--    //! Convert (x,y,Y) pixels of a color image into the (X,Y,Z)_709 color space.
--    CImg& xyYtoXYZ() {
--      if (!is_empty()) {
--        if (dim!=3) throw CImgInstanceException("CImg<%s>::xyYtoXYZ() : Input image dimension is dim=%u, "
--                                                "should be a (x,y,Y) image (dim=3)",pixel_type(),dim);
--        cimg_forXYZ(*this,x,y,z) {
--          const T px = (*this)(x,y,z,0), py = (*this)(x,y,z,1), Y = (*this)(x,y,z,2), ny = py>0?py:1;
--          (*this)(x,y,z,0) = (T)(px*Y/ny);
--          (*this)(x,y,z,1) = Y;
--          (*this)(x,y,z,2) = (T)((1-px-py)*Y/ny);
--        }
--      }
--      return *this;
--    }
--
--    //! In-place version of get_RGBtoLab().
--    CImg& RGBtoLab() {
--      return RGBtoXYZ().XYZtoLab();
--    }
--
--    //! In-place version of get_LabtoRGb().
--    CImg& LabtoRGB() {
--      return LabtoXYZ().XYZtoRGB();
--    }
--
--    //! In-place version of get_RGBtoxyY().
--    CImg& RGBtoxyY() {
--      return RGBtoXYZ().XYZtoxyY();
--    }
--
--    //! In-place version of get_xyYtoRGB().
--    CImg& xyYtoRGB() {
--      return xyYtoXYZ().XYZtoRGB();
--    }
--
--    //! Convert a (R,G,B) image to a (H,S,V) one.
--    CImg get_RGBtoHSV() const {
--      return (+*this).RGBtoHSV();
--    }
--
--    //! Convert a (H,S,V) image to a (R,G,B) one.
--    CImg get_HSVtoRGB() const {
--      return (+*this).HSVtoRGB();
--    }
--
--    //! Convert a (R,G,B) image to a (Y,Cb,Cr) one.
--    CImg get_RGBtoYCbCr() const {
--      return (+*this).RGBtoYCbCr();
--    }
--
--    //! Convert a (Y,Cb,Cr) image to a (R,G,B) one.
--    CImg get_YCbCrtoRGB() const {
--      return (+*this).YCbCrtoRGB();
--    }
--
--    //! Convert a (R,G,B) image into a (Y,U,V) one.
--    CImg<typename cimg::largest<T,float>::type> get_RGBtoYUV() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).RGBtoYUV();
--    }
--
--    //! Convert a (Y,U,V) image into a (R,G,B) one.
--    CImg get_YUVtoRGB() const {
--      return (+*this).YUVtoRGB();
--    }
--
--    //! Convert a (R,G,B) image to a (X,Y,Z) one.
--    CImg<typename cimg::largest<T,float>::type> get_RGBtoXYZ() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).RGBtoXYZ();
--    }
--
--    //! Convert a (X,Y,Z) image to a (R,G,B) one.
--    CImg get_XYZtoRGB() const {
--      return (+*this).XYZtoRGB();
--    }
--
--    //! Convert a (X,Y,Z) image to a (L,a,b) one.
--    CImg get_XYZtoLab() const {
--      return (+*this).XYZtoLab();
--    }
--
--    //! Convert a (L,a,b) image to a (X,Y,Z) one.
--    CImg get_LabtoXYZ() const {
--      return (+*this).LabtoXYZ();
--    }
--
--    //! Convert a (X,Y,Z) image to a (x,y,Y) one.
--    CImg get_XYZtoxyY() const {
--      return (+*this).XYZtoxyY();
--    }
--
--    //! Convert a (x,y,Y) image to a (X,Y,Z) one.
--    CImg get_xyYtoXYZ() const {
--      return (+*this).xyYtoXYZ();
--    }
--
--    //! Convert a (R,G,B) image to a (L,a,b) one.
--    CImg get_RGBtoLab() const {
--      return (+*this).RGBtoLab();
--    }
--
--    //! Convert a (L,a,b) image to a (R,G,B) one.
--    CImg get_LabtoRGB() const {
--      return (+*this).LabtoRGB();
--    }
--
--    //! Convert a (R,G,B) image to a (x,y,Y) one.
--    CImg get_RGBtoxyY() const {
--      return (+*this).RGBtoxyY();
--    }
--
--    //! Convert a (x,y,Y) image to a (R,G,B) one.
--    CImg get_xyYtoRGB() const {
--      return (+*this).xyYtoRGB();
--    }
--
--    //@}
--    //-------------------
--    //
--    //! \name Drawing
--    //@{
--    //-------------------
--
--    // Should be used only by member functions. Not an user-friendly function.
--    // Pre-requisites : x0<x1, y-coordinate is valid, col is valid.
--    CImg& draw_scanline(const int x0, const int x1, const int y, const T *const color,
--                        const float opacity=1, const float brightness=1, const bool init=false) {
--      static float nopacity=0, copacity=0;
--      static unsigned int whz=0;
--      static const T* col = 0;
--      if (init) {
--        nopacity = cimg::abs(opacity);
--        copacity = 1-cimg::max(opacity,0.0f);
--        whz = width*height*depth;
--        col = color;
--      } else {
--        const int nx0 = cimg::max(x0,0), nx1 = cimg::min(x1,(int)width-1), dx = nx1-nx0;
--        T *ptrd = ptr(0,y) + nx0;
--        if (dx>=0) {
--          if (opacity>=1) {
--            int off = whz-dx-1;
--            if (sizeof(T)!=1) cimg_forV(*this,k) {
--              const T val = (T)(*(col++)*brightness);
--              for (int x=dx; x>=0; x--) *(ptrd++)=val;
--              ptrd+=off;
--            } else cimg_forV(*this,k) { std::memset(ptrd,(int)(*(col++)*brightness),dx+1); ptrd+=whz; }
--            col-=dim;
--          } else {
--            int off = whz-dx-1;
--            cimg_forV(*this,k) {
--              const T val = (T)(*(col++)*brightness);
--              for (int x=dx; x>=0; x--) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ptrd++; }
--              ptrd+=off;
--            }
--            col-=dim;
--          }
--        }
--      }
--      return *this;
--    }
--
--    CImg& draw_scanline(const T *const color,const float opacity=1) { return draw_scanline(0,0,0,color,opacity,1.0f,true); }
--
--    //! Draw a colored point in the instance image, at coordinates (\c x0,\c y0,\c z0).
--    /**
--       \param x0 = X-coordinate of the vector-valued pixel to plot.
--       \param y0 = Y-coordinate of the vector-valued pixel to plot.
--       \param z0 = Z-coordinate of the vector-valued pixel to plot.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_point(const int x0,const int y0,const int z0,
--                     const T *const color,const float opacity=1) {
--      if (!is_empty()) {
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_point() : Specified color is (null)",pixel_type());
--        if (x0>=0 && y0>=0 && z0>=0 && x0<dimx() && y0<dimy() && z0<dimz()) {
--          const T *col=color;
--          const unsigned int whz = width*height*depth;
--          const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--          T *ptrd = ptr(x0,y0,z0,0);
--          if (opacity>=1) cimg_forV(*this,k) { *ptrd = *(col++); ptrd+=whz; }
--          else cimg_forV(*this,k) { *ptrd=(T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whz; }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a colored point in the instance image, at coordinates (\c x0,\c y0).
--    /**
--       \param x0 = X-coordinate of the vector-valued pixel to plot.
--       \param y0 = Y-coordinate of the vector-valued pixel to plot.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_point(const int x0,const int y0,const T *const color,const float opacity=1) {
--      return draw_point(x0,y0,0,color,opacity);
--    }
--
--    //! Draw a 2D colored line in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1).
--    /**
--       \param x0 = X-coordinate of the starting point of the line.
--       \param y0 = Y-coordinate of the starting point of the line.
--       \param x1 = X-coordinate of the ending point of the line.
--       \param y1 = Y-coordinate of the ending point of the line.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param pattern = An integer whose bits describes the line pattern.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_line(const int x0,const int y0,const int x1,const int y1,
--                    const T *const color,const unsigned int pattern=~0L,const float opacity=1) {
--      if (!is_empty()) {
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
--        const T* col=color;
--        int nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1;
--
--        if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1);
--        if (nx1<0 || nx0>=dimx()) return *this;
--        if (nx0<0) { ny0-=nx0*(ny1-ny0)/(nx1-nx0); nx0=0; }
--        if (nx1>=dimx()) { ny1+=(nx1-dimx())*(ny0-ny1)/(nx1-nx0); nx1=dimx()-1;}
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1);
--        if (ny1<0 || ny0>=dimy()) return *this;
--        if (ny0<0) { nx0-=ny0*(nx1-nx0)/(ny1-ny0); ny0=0; }
--        if (ny1>=dimy()) { nx1+=(ny1-dimy())*(nx0-nx1)/(ny1-ny0); ny1=dimy()-1;}
--
--        const bool steep = (ny1-ny0)>cimg::abs(nx1-nx0);
--        if (steep)   cimg::swap(nx0,ny0,nx1,ny1);
--        if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1);
--        const int
--          dx = nx1-nx0, dy = cimg::abs(ny1-ny0),
--          offx = steep?width:1,
--          offy = (ny0<ny1?1:-1)*(steep?1:width);
--
--        if (opacity>=1) cimg_forV(*this,k) {
--          unsigned int hatch=1;
--          T *ptrd = steep?ptr(ny0,nx0,0,k):ptr(nx0,ny0,0,k);
--          const T c = *(col++);
--          for (int error=0, x=nx0; x<=nx1; x++) {
--            if (!(~pattern) || (~pattern && pattern&hatch)) *ptrd=c;
--            ptrd+=offx;
--            if (((error+=dy)<<1)>=dx) { ptrd+=offy; error-=dx; }
--            if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
--          }
--        } else {
--          const float nopacity = cimg::abs(opacity), copacity=1-cimg::max(opacity,0.0f);
--          cimg_forV(*this,k) {
--            unsigned int hatch=1;
--            T *ptrd = steep?ptr(ny0,nx0,0,k):ptr(nx0,ny0,0,k);
--            const T c = *(col++);
--            for (int error=0, x=nx0; x<=nx1; x++) {
--              if (!(~pattern) || (~pattern && pattern&hatch)) *ptrd = (T)(c*nopacity + copacity*(*ptrd));
--              ptrd+=offx;
--              if (((error+=dy)<<1)>=dx) { ptrd+=offy; error-=dx; }
--              if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
--            }
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 3D colored line in the instance image, at coordinates (\c x0,\c y0,\c z0)-(\c x1,\c y1,\c z1).
--    /**
--       \param x0 = X-coordinate of the starting point of the line.
--       \param y0 = Y-coordinate of the starting point of the line.
--       \param z0 = Z-coordinate of the starting point of the line.
--       \param x1 = X-coordinate of the ending point of the line.
--       \param y1 = Y-coordinate of the ending point of the line.
--       \param z1 = Z-coordinate of the ending point of the line.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param pattern = An integer whose bits describes the line pattern.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_line(const int x0, const int y0, const int z0, const int x1, const int y1, const int z1,
--                    const T *const color, const unsigned int pattern=~0L, const float opacity=1) {
--      if (!is_empty()) {
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_line() : Specified color is (null)",pixel_type());
--        const T* col=color;
--        unsigned int hatch=1;
--        int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1;
--        if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
--        if (nx1<0 || nx0>=dimx()) return *this;
--        if (nx0<0) { const int D=1+nx1-nx0; ny0-=nx0*(1+ny1-ny0)/D; nz0-=nx0*(1+nz1-nz0)/D; nx0=0; }
--        if (nx1>=dimx()) { const int d=nx1-dimx(), D=1+nx1-nx0; ny1+=d*(1+ny0-ny1)/D; nz1+=d*(1+nz0-nz1)/D; nx1=dimx()-1;}
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
--        if (ny1<0 || ny0>=dimy()) return *this;
--        if (ny0<0) { const int D=1+ny1-ny0; nx0-=ny0*(1+nx1-nx0)/D; nz0-=ny0*(1+nz1-nz0)/D; ny0=0; }
--        if (ny1>=dimy()) { const int d=ny1-dimy(), D=1+ny1-ny0; nx1+=d*(1+nx0-nx1)/D; nz1+=d*(1+nz0-nz1)/D; ny1=dimy()-1;}
--        if (nz0>nz1) cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
--        if (nz1<0 || nz0>=dimz()) return *this;
--        if (nz0<0) { const int D=1+nz1-nz0; nx0-=nz0*(1+nx1-nx0)/D; ny0-=nz0*(1+ny1-ny0)/D; nz0=0; }
--        if (nz1>=dimz()) { const int d=nz1-dimz(), D=1+nz1-nz0; nx1+=d*(1+nx0-nx1)/D; ny1+=d*(1+ny0-ny1)/D; nz1=dimz()-1;}
--        const unsigned int dmax = cimg::max(cimg::abs(nx1-nx0),cimg::abs(ny1-ny0),nz1-nz0), whz = width*height*depth;
--        const float px = (nx1-nx0)/(float)dmax, py = (ny1-ny0)/(float)dmax, pz = (nz1-nz0)/(float)dmax;
--        float x = (float)nx0, y = (float)ny0, z = (float)nz0;
--        if (opacity>=1) for (unsigned int t=0; t<=dmax; t++) {
--          if (!(~pattern) || (~pattern && pattern&hatch)) {
--            T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
--            cimg_forV(*this,k) { *ptrd=*(col++); ptrd+=whz; }
--            col-=dim;
--          }
--          x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
--        } else {
--          const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--          for (unsigned int t=0; t<=dmax; t++) {
--            if (!(~pattern) || (~pattern && pattern&hatch)) {
--              T* ptrd = ptr((unsigned int)x,(unsigned int)y,(unsigned int)z,0);
--              cimg_forV(*this,k) { *ptrd = (T)(*(col++)*nopacity + copacity*(*ptrd)); ptrd+=whz; }
--              col-=dim;
--            }
--            x+=px; y+=py; z+=pz; if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 2D textured line in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1).
--    /**
--       \param x0 = X-coordinate of the starting point of the line.
--       \param y0 = Y-coordinate of the starting point of the line.
--       \param x1 = X-coordinate of the ending point of the line.
--       \param y1 = Y-coordinate of the ending point of the line.
--       \param texture = a colored texture image used to draw the line color.
--       \param tx0 = X-coordinate of the starting point of the texture.
--       \param ty0 = Y-coordinate of the starting point of the texture.
--       \param tx1 = X-coordinate of the ending point of the texture.
--       \param ty1 = Y-coordinate of the ending point of the texture.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported, but texture coordinates do not support clipping.
--    **/
--    template<typename t> CImg& draw_line(const int x0,const int y0,const int x1,const int y1,
--                                         const CImg<t>& texture,
--                                         const int tx0,const int ty0,const int tx1,const int ty1,
--                                         const float opacity=1) {
--      if (!is_empty()) {
--        if (texture.is_empty() || texture.dim<dim)
--          throw CImgArgumentException("CImg<%s>::draw_line() : specified texture (%u,%u,%u,%u,%p) has wrong dimensions.",
--                                      pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
--        int nx0=x0, ny0=y0, nx1=x1, ny1=y1, ntx0=tx0, nty0=ty0, ntx1=tx1, nty1=ty1;
--        if (nx0>nx1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
--        if (nx1<0 || nx0>=dimx()) return *this;
--        if (nx0<0) { const int D=nx1-nx0; ny0-=nx0*(ny1-ny0)/D; ntx0-=nx0*(ntx1-ntx0)/D; nty0-=nx0*(nty1-nty0)/D; nx0=0; }
--        if (nx1>=dimx()) { const int d=nx1-dimx(),D=nx1-nx0; ny1+=d*(ny0-ny1)/D; ntx1+=d*(ntx0-ntx1)/D; nty1+=d*(nty0-nty1)/D; nx1=dimx()-1; }
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
--        if (ny1<0 || ny0>=dimy()) return *this;
--        if (ny0<0) { const int D=ny1-ny0; nx0-=ny0*(nx1-nx0)/D; ntx0-=ny0*(ntx1-ntx0)/D; nty0-=ny0*(nty1-nty0)/D; ny0=0; }
--        if (ny1>=dimy()) { const int d=ny1-dimy(),D=ny1-ny0; nx1+=d*(nx0-nx1)/D; ntx1+=d*(ntx0-ntx1)/D; nty1+=d*(nty0-nty1)/D; ny1=dimy()-1; }
--        const unsigned int dmax = (unsigned int)cimg::max(cimg::abs(nx1-nx0),ny1-ny0),
--          whz = width*height*depth, twhz = texture.width*texture.height*texture.depth;
--        const float px = dmax?(nx1-nx0)/(float)dmax:0, py = dmax?(ny1-ny0)/(float)dmax:0,
--          tpx = dmax?(ntx1-ntx0)/(float)dmax:0, tpy = dmax?(nty1-nty0)/(float)dmax:0;
--        float x = (float)nx0, y = (float)ny0, tx = (float)ntx0, ty = (float)nty0;
--        if (opacity>=1) for (unsigned int tt=0; tt<=dmax; tt++) {
--          T *ptrd = ptr((unsigned int)x,(unsigned int)y,0,0);
--          const t *ptrs = texture.ptr((unsigned int)tx,(unsigned int)ty,0,0);
--          cimg_forV(*this,k) { *ptrd = (T)*ptrs; ptrd+=whz; ptrs+=twhz; }
--          x+=px; y+=py; tx+=tpx; ty+=tpy;
--        } else {
--          const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--          for (unsigned int tt=0; tt<=dmax; tt++) {
--            T *ptrd = ptr((unsigned int)x,(unsigned int)y,0,0);
--            const t *ptrs = texture.ptr((unsigned int)tx,(unsigned int)ty,0,0);
--            cimg_forV(*this,k) { *ptrd = (T)(nopacity*(*ptrs) + copacity*(*ptrd)); ptrd+=whz; ptrs+=twhz; }
--            x+=px; y+=py; tx+=tpx; ty+=tpy;
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 2D colored arrow in the instance image, at coordinates (\c x0,\c y0)->(\c x1,\c y1).
--    /**
--       \param x0 = X-coordinate of the starting point of the arrow (tail).
--       \param y0 = Y-coordinate of the starting point of the arrow (tail).
--       \param x1 = X-coordinate of the ending point of the arrow (head).
--       \param y1 = Y-coordinate of the ending point of the arrow (head).
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param angle = aperture angle of the arrow head
--       \param length = length of the arrow head. If <0, described as a percentage of the arrow length.
--       \param pattern = An integer whose bits describes the line pattern.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_arrow(const int x0,const int y0,const int x1,const int y1,
--                     const T *const color,
--                     const float angle=30,const float length=-10,const unsigned int pattern=~0L,const float opacity=1) {
--      if (!is_empty()) {
--        const float u = (float)(x0-x1), v = (float)(y0-y1), sq = u*u+v*v,
--          deg = (float)(angle*cimg::PI/180), ang = (sq>0)?(float)std::atan2(v,u):0.0f,
--          l = (length>=0)?length:-length*(float)std::sqrt(sq)/100;
--        if (sq>0) {
--          const double cl = std::cos(ang-deg), sl = std::sin(ang-deg), cr = std::cos(ang+deg), sr = std::sin(ang+deg);
--          const int
--            xl = x1+(int)(l*cl), yl = y1+(int)(l*sl),
--            xr = x1+(int)(l*cr), yr = y1+(int)(l*sr),
--            xc = x1+(int)((l+1)*(cl+cr))/2, yc = y1+(int)((l+1)*(sl+sr))/2;
--          draw_line(x0,y0,xc,yc,color,pattern,opacity).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity);
--        } else draw_point(x0,y0,color,opacity);
--      }
--      return *this;
--    }
--
--    //! Draw a sprite image in the instance image, at coordinates (\c x0,\c y0,\c z0,\c v0).
--    /**
--       \param sprite = sprite image.
--       \param x0 = X-coordinate of the sprite position in the instance image.
--       \param y0 = Y-coordinate of the sprite position in the instance image.
--       \param z0 = Z-coordinate of the sprite position in the instance image.
--       \param v0 = V-coordinate of the sprite position in the instance image.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    template<typename t> CImg& draw_image(const CImg<t>& sprite,
--                                          const int x0=0,const int y0=0,const int z0=0,const int v0=0,const float opacity=1) {
--      if (!is_empty()) {
--        if (sprite.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
--        const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
--        const int
--          lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
--          lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
--          lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
--          lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
--        const t *ptrs = sprite.ptr()-(bx?x0:0)-(by?y0*sprite.dimx():0)+(bz?z0*sprite.dimx()*sprite.dimy():0)+
--          (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
--        const unsigned int
--          offX = width-lX, soffX = sprite.width-lX,
--          offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
--          offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
--        if (lX>0 && lY>0 && lZ>0 && lV>0)
--          for (int v=0; v<lV; v++) {
--            for (int z=0; z<lZ; z++) {
--              for (int y=0; y<lY; y++) {
--                if (opacity>=1) for (int x=0; x<lX; x++) *(ptrd++) = (T)*(ptrs++);
--                else for (int x=0; x<lX; x++) { *ptrd = (T)(nopacity*(*(ptrs++)) + copacity*(*ptrd)); ptrd++; }
--                ptrd+=offX; ptrs+=soffX;
--              }
--              ptrd+=offY; ptrs+=soffY;
--            }
--            ptrd+=offZ; ptrs+=soffZ;
--          }
--      }
--      return *this;
--    }
--
--#ifndef cimg_use_visualcpp6
--    CImg& draw_image(const CImg& sprite,const int x0=0,const int y0=0,const int z0=0,const int v0=0,const float opacity=1) {
--      if (!is_empty()) {
--        if (sprite.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
--        if (this==&sprite) return draw_image(CImg<T>(sprite),x0,y0,z0,v0,opacity);
--        const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
--        const int
--          lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
--          lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
--          lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
--          lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
--        const T *ptrs = sprite.ptr()-(bx?x0:0)-(by?y0*sprite.dimx():0)+(bz?z0*sprite.dimx()*sprite.dimy():0)+
--          (bv?v0*sprite.dimx()*sprite.dimy()*sprite.dimz():0);
--        const unsigned int
--          offX = width-lX, soffX = sprite.width-lX,
--          offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
--          offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ),
--          slX = lX*sizeof(T);
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
--        if (lX>0 && lY>0 && lZ>0 && lV>0)
--          for (int v=0; v<lV; v++) {
--            for (int z=0; z<lZ; z++) {
--              if (opacity>=1) for (int y=0; y<lY; y++) { std::memcpy(ptrd,ptrs,slX); ptrd+=width; ptrs+=sprite.width; }
--              else for (int y=0; y<lY; y++) {
--                for (int x=0; x<lX; x++) { *ptrd = (T)(nopacity*(*(ptrs++)) + copacity*(*ptrd)); ptrd++; }
--                ptrd+=offX; ptrs+=soffX;
--              }
--              ptrd+=offY; ptrs+=soffY;
--            }
--            ptrd+=offZ; ptrs+=soffZ;
--          }
--      }
--      return *this;
--    }
--#endif
--
--    //! Draw a masked sprite image in the instance image, at coordinates (\c x0,\c y0,\c z0,\c v0).
--    /**
--       \param sprite = sprite image.
--       \param mask = mask image.
--       \param x0 = X-coordinate of the sprite position in the instance image.
--       \param y0 = Y-coordinate of the sprite position in the instance image.
--       \param z0 = Z-coordinate of the sprite position in the instance image.
--       \param v0 = V-coordinate of the sprite position in the instance image.
--       \param mask_valmax = Maximum pixel value of the mask image \c mask.
--       \param opacity = opacity of the drawing.
--       \note Pixel values of \c mask set the opacity of the corresponding pixels in \c sprite.
--       \note Clipping is supported.
--       \note Dimensions along x,y and z of \c sprite and \c mask must be the same.
--    **/
--    template<typename ti,typename tm> CImg& draw_image(const CImg<ti>& sprite, const CImg<tm>& mask,
--                                                       const int x0=0, const int y0=0, const int z0=0, const int v0=0,
--                                                       const tm mask_valmax='\1', const float opacity=1) {
--      if (!is_empty()) {
--        if (sprite.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_image() : Specified sprite image (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),sprite.width,sprite.height,sprite.depth,sprite.dim,sprite.data);
--        if (mask.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_image() : Specified mask image (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
--        if ((void*)this==(void*)&sprite) return draw_image(CImg<T>(sprite),mask,x0,y0,z0,v0);
--        if(mask.width!=sprite.width || mask.height!=sprite.height || mask.depth!=sprite.depth)
--          throw CImgArgumentException("CImg<%s>::draw_image() : Mask dimension is (%u,%u,%u,%u), while sprite is (%u,%u,%u,%u)",
--                                      pixel_type(),mask.width,mask.height,mask.depth,mask.dim,sprite.width,sprite.height,sprite.depth,sprite.dim);
--        const bool bx=(x0<0), by=(y0<0), bz=(z0<0), bv=(v0<0);
--        const int
--          lX = sprite.dimx() - (x0+sprite.dimx()>dimx()?x0+sprite.dimx()-dimx():0) + (bx?x0:0),
--          lY = sprite.dimy() - (y0+sprite.dimy()>dimy()?y0+sprite.dimy()-dimy():0) + (by?y0:0),
--          lZ = sprite.dimz() - (z0+sprite.dimz()>dimz()?z0+sprite.dimz()-dimz():0) + (bz?z0:0),
--          lV = sprite.dimv() - (v0+sprite.dimv()>dimv()?v0+sprite.dimv()-dimv():0) + (bv?v0:0);
--        const int coff = -(bx?x0:0)-(by?y0*mask.dimx():0)-(bz?z0*mask.dimx()*mask.dimy():0)-
--          (bv?v0*mask.dimx()*mask.dimy()*mask.dimz():0),
--          ssize = mask.dimx()*mask.dimy()*mask.dimz();
--        const ti *ptrs = sprite.ptr() + coff;
--        const tm *ptrm = mask.ptr() + coff;
--        const unsigned int
--          offX = width-lX, soffX = sprite.width-lX,
--          offY = width*(height-lY), soffY = sprite.width*(sprite.height-lY),
--          offZ = width*height*(depth-lZ), soffZ = sprite.width*sprite.height*(sprite.depth-lZ);
--        T *ptrd = ptr(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,v0<0?0:v0);
--        if (lX>0 && lY>0 && lZ>0 && lV>0)
--          for (int v=0; v<lV; v++) {
--            ptrm = mask.data + (ptrm - mask.data)%ssize;
--            for (int z=0; z<lZ; z++) {
--              for (int y=0; y<lY; y++) {
--                for (int x=0; x<lX; x++) {
--                  const float mopacity = *(ptrm++)*opacity,
--                    nopacity = cimg::abs(mopacity), copacity = mask_valmax-cimg::max(mopacity,0.0f);
--                  *ptrd = (T)((nopacity*(*(ptrs++))+copacity*(*ptrd))/mask_valmax);
--                  ptrd++;
--                }
--                ptrd+=offX; ptrs+=soffX; ptrm+=soffX;
--              }
--              ptrd+=offY; ptrs+=soffY; ptrm+=soffY;
--            }
--            ptrd+=offZ; ptrs+=soffZ; ptrm+=soffZ;
--          }
--      }
--      return *this;
--    }
--
--    //! Draw a 4D filled rectangle in the instance image, at coordinates (\c x0,\c y0,\c z0,\c v0)-(\c x1,\c y1,\c z1,\c v1).
--    /**
--       \param x0 = X-coordinate of the upper-left rectangle corner in the instance image.
--       \param y0 = Y-coordinate of the upper-left rectangle corner in the instance image.
--       \param z0 = Z-coordinate of the upper-left rectangle corner in the instance image.
--       \param v0 = V-coordinate of the upper-left rectangle corner in the instance image.
--       \param x1 = X-coordinate of the lower-right rectangle corner in the instance image.
--       \param y1 = Y-coordinate of the lower-right rectangle corner in the instance image.
--       \param z1 = Z-coordinate of the lower-right rectangle corner in the instance image.
--       \param v1 = V-coordinate of the lower-right rectangle corner in the instance image.
--       \param val = scalar value used to fill the rectangle area.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_rectangle(const int x0,const int y0,const int z0,const int v0,
--                         const int x1,const int y1,const int z1,const int v1,
--                         const T& val,const float opacity=1.0f) {
--      if (!is_empty()) {
--        const bool bx=(x0<x1), by=(y0<y1), bz=(z0<z1), bv=(v0<v1);
--        const int nx0=bx?x0:x1, nx1=bx?x1:x0, ny0=by?y0:y1, ny1=by?y1:y0, nz0=bz?z0:z1, nz1=bz?z1:z0, nv0=bv?v0:v1, nv1=bv?v1:v0;
--        const int
--          lX = (1+nx1-nx0) + (nx1>=dimx()?dimx()-1-nx1:0) + (nx0<0?nx0:0),
--          lY = (1+ny1-ny0) + (ny1>=dimy()?dimy()-1-ny1:0) + (ny0<0?ny0:0),
--          lZ = (1+nz1-nz0) + (nz1>=dimz()?dimz()-1-nz1:0) + (nz0<0?nz0:0),
--          lV = (1+nv1-nv0) + (nv1>=dimv()?dimv()-1-nv1:0) + (nv0<0?nv0:0);
--        const unsigned int offX = width-lX, offY = width*(height-lY), offZ = width*height*(depth-lZ);
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        T *ptrd = ptr(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nv0<0?0:nv0);
--        if (lX>0 && lY>0 && lZ>0 && lV>0)
--          for (int v=0; v<lV; v++) {
--            for (int z=0; z<lZ; z++) {
--              for (int y=0; y<lY; y++) {
--                if (opacity>=1) {
--                  if (sizeof(T)!=1) { for (int x=0; x<lX; x++) *(ptrd++) = val; ptrd+=offX; }
--                  else { std::memset(ptrd,(int)val,lX); ptrd+=width; }
--                } else { for (int x=0; x<lX; x++) { *ptrd = (T)(nopacity*val+copacity*(*ptrd)); ptrd++; } ptrd+=offX; }
--              }
--              ptrd+=offY;
--            }
--            ptrd+=offZ;
--          }
--      }
--      return *this;
--    }
--
--    //! Draw a 3D filled colored rectangle in the instance image, at coordinates (\c x0,\c y0,\c z0)-(\c x1,\c y1,\c z1).
--    /**
--       \param x0 = X-coordinate of the upper-left rectangle corner in the instance image.
--       \param y0 = Y-coordinate of the upper-left rectangle corner in the instance image.
--       \param z0 = Z-coordinate of the upper-left rectangle corner in the instance image.
--       \param x1 = X-coordinate of the lower-right rectangle corner in the instance image.
--       \param y1 = Y-coordinate of the lower-right rectangle corner in the instance image.
--       \param z1 = Z-coordinate of the lower-right rectangle corner in the instance image.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_rectangle(const int x0,const int y0,const int z0,
--                         const int x1,const int y1,const int z1,
--                         const T *const color,const float opacity=1) {
--      if (!color) throw CImgArgumentException("CImg<%s>::draw_rectangle : specified color is (null)",pixel_type());
--      cimg_forV(*this,k) draw_rectangle(x0,y0,z0,k,x1,y1,z1,k,color[k],opacity);
--      return *this;
--    }
--
--    //! Draw a 2D filled colored rectangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1).
--    /**
--       \param x0 = X-coordinate of the upper-left rectangle corner in the instance image.
--       \param y0 = Y-coordinate of the upper-left rectangle corner in the instance image.
--       \param x1 = X-coordinate of the lower-right rectangle corner in the instance image.
--       \param y1 = Y-coordinate of the lower-right rectangle corner in the instance image.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_rectangle(const int x0,const int y0,const int x1,const int y1,
--                         const T *const color,const float opacity=1) {
--      draw_rectangle(x0,y0,0,x1,y1,depth-1,color,opacity);
--      return *this;
--    }
--
--    //! Draw a 2D filled colored triangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing (<1)
--       \param brightness = brightness of the drawing (in [0,1])
--       \note Clipping is supported.
--    **/
--    CImg& draw_triangle(const int x0,const int y0,
--                        const int x1,const int y1,
--                        const int x2,const int y2,
--                        const T *const color,
--                        const float opacity=1,
--                        const float brightness=1) {
--      draw_scanline(color,opacity);
--      int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
--      if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1);
--      if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2);
--      if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2);
--      if (ny0>=dimy() || ny2<0) return *this;
--      const float
--        p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--        p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--        p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1);
--      float xleft = (float)nx0, xright = xleft, pleft = (p1<p2)?p1:p2, pright = (p1<p2)?p2:p1;
--      if (ny0<0) { xleft-=ny0*pleft; xright-=ny0*pright; }
--      const int ya = ny1>dimy()?height:ny1;
--      for (int y=ny0<0?0:ny0; y<ya; y++) {
--        draw_scanline((int)xleft,(int)xright,y,color,opacity,brightness);
--        xleft+=pleft; xright+=pright;
--      }
--      if (p1<p2) { xleft=(float)nx1;  pleft=p3;  if (ny1<0) xleft-=ny1*pleft; }
--      else       { xright=(float)nx1; pright=p3; if (ny1<0) xright-=ny1*pright; }
--      const int yb = ny2>=dimy()?height-1:ny2;
--      for (int yy=ny1<0?0:ny1; yy<=yb; yy++) {
--        draw_scanline((int)xleft,(int)xright,yy,color,opacity,brightness);
--        xleft+=pleft; xright+=pright;
--      }
--      return *this;
--    }
--
--    //! Draw a 2D Gouraud-filled triangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param color = array of dimv() values of type \c T, defining the global drawing color.
--       \param c0 = brightness of the first corner.
--       \param c1 = brightness of the second corner.
--       \param c2 = brightness of the third corner.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    CImg& draw_triangle(const int x0, const int y0,
--                        const int x1, const int y1,
--                        const int x2, const int y2,
--                        const T *const color,
--                        const float c0, const float c1, const float c2,
--                        const float opacity=1) {
--      if (!is_empty()) {
--        int nx0=x0,ny0=y0,nx1=x1,ny1=y1,nx2=x2,ny2=y2,whz=width*height*depth;
--        float nc0=c0,nc1=c1,nc2=c2;
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1);
--        if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2);
--        if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2);
--        if (ny0>=dimy() || ny2<0) return *this;
--        const float
--          p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--          p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--          p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1),
--          cp1 = (ny1-ny0)?(nc1-nc0)/(float)(ny1-ny0):0,
--          cp2 = (ny2-ny0)?(nc2-nc0)/(float)(ny2-ny0):0,
--          cp3 = (ny2-ny1)?(nc2-nc1)/(float)(ny2-ny1):0;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        float pleft,pright,cpleft,cpright,xleft=(float)nx0,xright=xleft,cleft=nc0,cright=cleft;
--        if (p1<p2) { pleft=p1; pright=p2; cpleft=cp1; cpright=cp2; }
--        else       { pleft=p2; pright=p1; cpleft=cp2; cpright=cp1; }
--        if (ny0<0) { xleft-=ny0*pleft; xright-=ny0*pright; cleft-=ny0*cpleft; cright-=ny0*cpright; }
--        const int ya = ny1<dimy()?ny1:height;
--        for (int y=(ny0<0?0:ny0); y<ya; y++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            cp = dx?(cright-cleft)/dx:0,
--            ci = (xleft>=0)?cleft:(cleft-xleft*cp);
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              const T col = color[k];
--              float c=ci;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(c*col); c+=cp; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              const T col = color[k];
--              float c=ci;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*c*col+copacity*(*ptrd)); ptrd++; c+=cp; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; cleft+=cpleft; cright+=cpright;
--        }
--
--        if (p1<p2) {
--          xleft=(float)nx1; pleft=p3; cleft=nc1; cpleft=cp3;
--          if (ny1<0) { xleft-=ny1*pleft; cleft-=ny1*cpleft; }
--        } else {
--          xright=(float)nx1; pright=p3; cright=nc1; cpright=cp3;
--          if (ny1<0) { xright-=ny1*pright; cright-=ny1*cpright; }
--        }
--        const int yb = ny2>=dimy()?(height-1):ny2;
--        for (int yy=(ny1<0?0:ny1); yy<=yb; yy++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            cp = dx?(cright-cleft)/dx:0,
--            ci = (xleft>=0)?cleft:(cleft-xleft*cp);
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,yy,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              const T col = color[k];
--              float c=ci;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(c*col); c+=cp; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              const T col = color[k];
--              float c=ci;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*c*col+copacity*(*ptrd)); ptrd++; c+=cp; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; cleft+=cpleft; cright+=cpright;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 2D phong-shaded triangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param color = array of dimv() values of type \c T, defining the global drawing color.
--       \param light = light image.
--       \param lx0 = X-coordinate of the first corner in the light image.
--       \param ly0 = Y-coordinate of the first corner in the light image.
--       \param lx1 = X-coordinate of the second corner in the light image.
--       \param ly1 = Y-coordinate of the second corner in the light image.
--       \param lx2 = X-coordinate of the third corner in the light image.
--       \param ly2 = Y-coordinate of the third corner in the light image.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported, but texture coordinates do not support clipping.
--    **/
--    template<typename t> CImg& draw_triangle(const int x0,const int y0,
--                                             const int x1,const int y1,
--                                             const int x2,const int y2,
--                                             const T *const color,
--                                             const CImg<t>& light,
--                                             const int lx0,const int ly0,
--                                             const int lx1,const int ly1,
--                                             const int lx2,const int ly2,
--                                             const float opacity=1.0f) {
--      if (!is_empty()) {
--        if (light.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light texture (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
--        int nx0=x0,ny0=y0,nx1=x1,ny1=y1,nx2=x2,ny2=y2,nlx0=lx0,nly0=ly0,nlx1=lx1,nly1=ly1,nlx2=lx2,nly2=ly2,whz=width*height*depth;
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1);
--        if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2);
--        if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2);
--        if (ny0>=dimy() || ny2<0) return *this;
--        const float
--          p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--          p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--          p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1),
--          lpx1 = (ny1-ny0)?(nlx1-nlx0)/(float)(ny1-ny0):0,
--          lpy1 = (ny1-ny0)?(nly1-nly0)/(float)(ny1-ny0):0,
--          lpx2 = (ny2-ny0)?(nlx2-nlx0)/(float)(ny2-ny0):0,
--          lpy2 = (ny2-ny0)?(nly2-nly0)/(float)(ny2-ny0):0,
--          lpx3 = (ny2-ny1)?(nlx2-nlx1)/(float)(ny2-ny1):0,
--          lpy3 = (ny2-ny1)?(nly2-nly1)/(float)(ny2-ny1):0;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        float pleft,pright,lpxleft,lpyleft,lpxright,lpyright,
--          xleft=(float)nx0,xright=xleft,lxleft=(float)nlx0,lyleft=(float)nly0,lxright=lxleft,lyright=lyleft;
--        if (p1<p2) { pleft=p1; pright=p2; lpxleft=lpx1; lpyleft=lpy1; lpxright=lpx2; lpyright=lpy2; }
--        else       { pleft=p2; pright=p1; lpxleft=lpx2; lpyleft=lpy2; lpxright=lpx1; lpyright=lpy1; }
--        if (ny0<0) { xleft-=ny0*pleft; xright-=ny0*pright; lxleft-=ny0*lpxleft; lyleft-=ny0*lpyleft;
--        lxright-=ny0*lpxright; lyright-=ny0*lpyright; }
--        const int ya = ny1<dimy()?ny1:height;
--        for (int y=(ny0<0?0:ny0); y<ya; y++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            lpx = dx?((int)lxright-(int)lxleft)/(float)dx:0,
--            lpy = dx?((int)lyright-(int)lyleft)/(float)dx:0,
--            lxi = (float)((xleft>=0)?(int)lxleft:(int)(lxleft-(int)xleft*lpx)),
--            lyi = (float)((xleft>=0)?(int)lyleft:(int)(lyleft-(int)xleft*lpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(light((unsigned int)lx,(unsigned int)ly)*color[k]); lx+=lpx; ly+=lpy; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*light((unsigned int)lx,(unsigned int)ly)*color[k]+copacity*(*ptrd)); ptrd++; lx+=lpx; ly+=lpy; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; lxleft+=lpxleft; lyleft+=lpyleft; lxright+=lpxright; lyright+=lpyright;
--        }
--
--        if (p1<p2) {
--          xleft=(float)nx1; pleft=p3; lxleft=(float)nlx1; lyleft=(float)nly1; lpxleft=lpx3; lpyleft=lpy3;
--          if (ny1<0) { xleft-=ny1*pleft; lxleft-=ny1*lpxleft; lyleft-=ny1*lpyleft; }
--        } else {
--          xright=(float)nx1; pright=p3; lxright=(float)nlx1; lyright=(float)nly1; lpxright=lpx3; lpyright=lpy3;
--          if (ny1<0) { xright-=ny1*pright; lxright-=ny1*lpxright; lyright-=ny1*lpyright; }
--        }
--        const int yb = ny2>=dimy()?(height-1):ny2;
--        for (int yy=(ny1<0?0:ny1); yy<=yb; yy++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            lpx = dx?((int)lxright-(int)lxleft)/(float)dx:0,
--            lpy = dx?((int)lyright-(int)lyleft)/(float)dx:0,
--            lxi = (float)((xleft>=0)?(int)lxleft:(int)(lxleft-(int)xleft*lpx)),
--            lyi = (float)((xleft>=0)?(int)lyleft:(int)(lyleft-(int)xleft*lpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,yy,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(light((unsigned int)lx,(unsigned int)ly)*color[k]); lx+=lpx; ly+=lpy; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*light((unsigned int)lx,(unsigned int)ly)*color[k]+copacity*(*ptrd)); ptrd++; lx+=lpx; ly+=lpy; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; lxleft+=lpxleft; lyleft+=lpyleft; lxright+=lpxright; lyright+=lpyright;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 2D textured triangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param texture = texture image used to fill the triangle.
--       \param tx0 = X-coordinate of the first corner in the texture image.
--       \param ty0 = Y-coordinate of the first corner in the texture image.
--       \param tx1 = X-coordinate of the second corner in the texture image.
--       \param ty1 = Y-coordinate of the second corner in the texture image.
--       \param tx2 = X-coordinate of the third corner in the texture image.
--       \param ty2 = Y-coordinate of the third corner in the texture image.
--       \param opacity = opacity of the drawing.
--       \param brightness = brightness of the drawing.
--       \note Clipping is supported, but texture coordinates do not support clipping.
--    **/
--    template<typename t> CImg& draw_triangle(const int x0,const int y0,
--                                             const int x1,const int y1,
--                                             const int x2,const int y2,
--                                             const CImg<t>& texture,
--                                             const int tx0,const int ty0,
--                                             const int tx1,const int ty1,
--                                             const int tx2,const int ty2,
--                                             const float opacity=1.0f, const float brightness=1.0f) {
--      if (!is_empty()) {
--        if (texture.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
--        int nx0=x0,ny0=y0,nx1=x1,ny1=y1,nx2=x2,ny2=y2,ntx0=tx0,nty0=ty0,ntx1=tx1,nty1=ty1,ntx2=tx2,nty2=ty2,whz=width*height*depth;
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
--        if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2);
--        if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2);
--        if (ny0>=dimy() || ny2<0) return *this;
--        const float
--          p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--          p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--          p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1),
--          tpx1 = (ny1-ny0)?(ntx1-ntx0)/(float)(ny1-ny0):0,
--          tpy1 = (ny1-ny0)?(nty1-nty0)/(float)(ny1-ny0):0,
--          tpx2 = (ny2-ny0)?(ntx2-ntx0)/(float)(ny2-ny0):0,
--          tpy2 = (ny2-ny0)?(nty2-nty0)/(float)(ny2-ny0):0,
--          tpx3 = (ny2-ny1)?(ntx2-ntx1)/(float)(ny2-ny1):0,
--          tpy3 = (ny2-ny1)?(nty2-nty1)/(float)(ny2-ny1):0;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        float pleft,pright,tpxleft,tpyleft,tpxright,tpyright,
--          xleft=(float)nx0,xright=xleft,txleft=(float)ntx0,tyleft=(float)nty0,txright=txleft,tyright=tyleft;
--        if (p1<p2) { pleft=p1; pright=p2; tpxleft=tpx1; tpyleft=tpy1; tpxright=tpx2; tpyright=tpy2; }
--        else       { pleft=p2; pright=p1; tpxleft=tpx2; tpyleft=tpy2; tpxright=tpx1; tpyright=tpy1; }
--        if (ny0<0) { xleft-=ny0*pleft; xright-=ny0*pright; txleft-=ny0*tpxleft; tyleft-=ny0*tpyleft;
--        txright-=ny0*tpxright; tyright-=ny0*tpyright; }
--        const int ya = ny1<dimy()?ny1:height;
--        for (int y=(ny0<0?0:ny0); y<ya; y++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(brightness*texture((unsigned int)tx,(unsigned int)ty,0,k)); tx+=tpx; ty+=tpy; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*brightness*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++; tx+=tpx; ty+=tpy; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright;
--        }
--
--        if (p1<p2) {
--          xleft=(float)nx1; pleft=p3; txleft=(float)ntx1; tyleft=(float)nty1; tpxleft=tpx3; tpyleft=tpy3;
--          if (ny1<0) { xleft-=ny1*pleft; txleft-=ny1*tpxleft; tyleft-=ny1*tpyleft; }
--        } else {
--          xright=(float)nx1; pright=p3; txright=(float)ntx1; tyright=(float)nty1; tpxright=tpx3; tpyright=tpy3;
--          if (ny1<0) { xright-=ny1*pright; txright-=ny1*tpxright; tyright-=ny1*tpyright; }
--        }
--        const int yb = ny2>=dimy()?(height-1):ny2;
--        for (int yy=(ny1<0?0:ny1); yy<=yb; yy++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,yy,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(brightness*texture((unsigned int)tx,(unsigned int)ty,0,k)); tx+=tpx; ty+=tpy; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*brightness*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++; tx+=tpx; ty+=tpy; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a 2D textured triangle with Gouraud-Shading in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param texture = texture image used to fill the triangle.
--       \param tx0 = X-coordinate of the first corner in the texture image.
--       \param ty0 = Y-coordinate of the first corner in the texture image.
--       \param tx1 = X-coordinate of the second corner in the texture image.
--       \param ty1 = Y-coordinate of the second corner in the texture image.
--       \param tx2 = X-coordinate of the third corner in the texture image.
--       \param ty2 = Y-coordinate of the third corner in the texture image.
--       \param c0 = brightness value of the first corner.
--       \param c1 = brightness value of the second corner.
--       \param c2 = brightness value of the third corner.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported, but texture coordinates do not support clipping.
--    **/
--    template<typename t> CImg& draw_triangle(const int x0,const int y0,
--                                             const int x1,const int y1,
--                                             const int x2,const int y2,
--                                             const CImg<t>& texture,
--                                             const int tx0,const int ty0,
--                                             const int tx1,const int ty1,
--                                             const int tx2,const int ty2,
--                                             const float c0,const float c1,const float c2,
--                                             const float opacity=1) {
--      if (!is_empty()) {
--        if (texture.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
--        int nx0=x0,ny0=y0,nx1=x1,ny1=y1,nx2=x2,ny2=y2,ntx0=tx0,nty0=ty0,ntx1=tx1,nty1=ty1,ntx2=tx2,nty2=ty2,whz=width*height*depth;
--        float nc0=c0,nc1=c1,nc2=c2;
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1);
--        if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2);
--        if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2);
--        if (ny0>=dimy() || ny2<0) return *this;
--        const float
--          p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--          p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--          p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1),
--          tpx1 = (ny1-ny0)?(ntx1-ntx0)/(float)(ny1-ny0):0,
--          tpy1 = (ny1-ny0)?(nty1-nty0)/(float)(ny1-ny0):0,
--          tpx2 = (ny2-ny0)?(ntx2-ntx0)/(float)(ny2-ny0):0,
--          tpy2 = (ny2-ny0)?(nty2-nty0)/(float)(ny2-ny0):0,
--          tpx3 = (ny2-ny1)?(ntx2-ntx1)/(float)(ny2-ny1):0,
--          tpy3 = (ny2-ny1)?(nty2-nty1)/(float)(ny2-ny1):0,
--          cp1 = (ny1-ny0)?(nc1-nc0)/(float)(ny1-ny0):0,
--          cp2 = (ny2-ny0)?(nc2-nc0)/(float)(ny2-ny0):0,
--          cp3 = (ny2-ny1)?(nc2-nc1)/(float)(ny2-ny1):0;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        float pleft,pright,tpxleft,tpyleft,tpxright,tpyright,cpleft,cpright,
--          xleft=(float)nx0,xright=xleft,txleft=(float)ntx0,tyleft=(float)nty0,txright=txleft,tyright=tyleft,cleft=nc0,cright=cleft;
--        if (p1<p2) { pleft=p1; pright=p2; tpxleft=tpx1; tpyleft=tpy1; tpxright=tpx2; tpyright=tpy2; cpleft=cp1; cpright=cp2; }
--        else       { pleft=p2; pright=p1; tpxleft=tpx2; tpyleft=tpy2; tpxright=tpx1; tpyright=tpy1; cpleft=cp2, cpright=cp1; }
--        if (ny0<0) {
--          xleft-=ny0*pleft; xright-=ny0*pright; txleft-=ny0*tpxleft; tyleft-=ny0*tpyleft; cleft-=ny0*cpleft;
--          txright-=ny0*tpxright; tyright-=ny0*tpyright; cright-=ny0*cpright;
--        }
--        const int ya = ny1<dimy()?ny1:height;
--        for (int y=(ny0<0?0:ny0); y<ya; y++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            cp = dx?(cright-cleft)/dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy)),
--            ci = (xleft>=0)?cleft:(cleft-xleft*cp);
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, c=ci;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(c*texture((unsigned int)tx,(unsigned int)ty,0,k)); tx+=tpx; ty+=tpy; c+=cp; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, c=ci;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*c*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++; tx+=tpx; ty+=tpy; c+=cp; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright; cleft+=cpleft; cright+=cpright;
--        }
--
--        if (p1<p2) {
--          xleft=(float)nx1; pleft=p3; txleft=(float)ntx1; tyleft=(float)nty1; tpxleft=tpx3; tpyleft=tpy3; cleft=nc1; cpleft=cp3;
--          if (ny1<0) { xleft-=ny1*pleft; txleft-=ny1*tpxleft; tyleft-=ny1*tpyleft; cleft-=ny1*cpleft; }
--        } else {
--          xright=(float)nx1; pright=p3; txright=(float)ntx1; tyright=(float)nty1; tpxright=tpx3; tpyright=tpy3; cright=nc1; cpright=cp3;
--          if (ny1<0) { xright-=ny1*pright; txright-=ny1*tpxright; tyright-=ny1*tpyright; cright-=ny1*cpright; }
--        }
--        const int yb = ny2>=dimy()?(height-1):ny2;
--        for (int yy=(ny1<0?0:ny1); yy<=yb; yy++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            cp = dx?(cright-cleft)/dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy)),
--            ci = (xleft>=0)?cleft:(cleft-xleft*cp);
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,yy,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, c=ci;
--              for (int x=xmin; x<=xmax; x++) { *(ptrd++)=(T)(c*texture((unsigned int)tx,(unsigned int)ty,0,k)); tx+=tpx; ty+=tpy; c+=cp; }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, c=ci;
--              for (int x=xmin; x<=xmax; x++) { *ptrd=(T)(nopacity*c*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++; tx+=tpx; ty+=tpy; c+=ci; }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright; txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright; cleft+=cpleft; cright+=cpright;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a phong-shaded 2D textured triangle in the instance image, at coordinates (\c x0,\c y0)-(\c x1,\c y1)-(\c x2,\c y2).
--    /**
--       \param x0 = X-coordinate of the first corner in the instance image.
--       \param y0 = Y-coordinate of the first corner in the instance image.
--       \param x1 = X-coordinate of the second corner in the instance image.
--       \param y1 = Y-coordinate of the second corner in the instance image.
--       \param x2 = X-coordinate of the third corner in the instance image.
--       \param y2 = Y-coordinate of the third corner in the instance image.
--       \param texture = texture image used to fill the triangle.
--       \param tx0 = X-coordinate of the first corner in the texture image.
--       \param ty0 = Y-coordinate of the first corner in the texture image.
--       \param tx1 = X-coordinate of the second corner in the texture image.
--       \param ty1 = Y-coordinate of the second corner in the texture image.
--       \param tx2 = X-coordinate of the third corner in the texture image.
--       \param ty2 = Y-coordinate of the third corner in the texture image.
--       \param light = light image.
--       \param lx0 = X-coordinate of the first corner in the light image.
--       \param ly0 = Y-coordinate of the first corner in the light image.
--       \param lx1 = X-coordinate of the second corner in the light image.
--       \param ly1 = Y-coordinate of the second corner in the light image.
--       \param lx2 = X-coordinate of the third corner in the light image.
--       \param ly2 = Y-coordinate of the third corner in the light image.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported, but texture coordinates do not support clipping.
--    **/
--    template<typename t, typename tl> CImg& draw_triangle(const int x0,const int y0,
--                                                          const int x1,const int y1,
--                                                          const int x2,const int y2,
--                                                          const CImg<t>& texture,
--                                                          const int tx0,const int ty0,
--                                                          const int tx1,const int ty1,
--                                                          const int tx2,const int ty2,
--                                                          const CImg<tl>& light,
--                                                          const int lx0,const int ly0,
--                                                          const int lx1,const int ly1,
--                                                          const int lx2,const int ly2,
--                                                          const float opacity=1.0f) {
--      if (!is_empty()) {
--        if (texture.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified texture (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),texture.width,texture.height,texture.depth,texture.dim,texture.data);
--        if (light.is_empty())
--          throw CImgArgumentException("CImg<%s>::draw_triangle() : Specified light (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),light.width,light.height,light.depth,light.dim,light.data);
--        int
--          nx0=x0,ny0=y0,nx1=x1,ny1=y1,nx2=x2,ny2=y2,
--          ntx0=tx0,nty0=ty0,ntx1=tx1,nty1=ty1,ntx2=tx2,nty2=ty2,
--          nlx0=lx0,nly0=ly0,nlx1=lx1,nly1=ly1,nlx2=lx2,nly2=ly2,
--          whz=width*height*depth;
--        if (ny0>ny1) cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1);
--        if (ny0>ny2) cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2);
--        if (ny1>ny2) cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2);
--        if (ny0>=dimy() || ny2<0) return *this;
--        const float
--          p1 = (ny1-ny0)?(nx1-nx0)/(float)(ny1-ny0):(nx1-nx0),
--          p2 = (ny2-ny0)?(nx2-nx0)/(float)(ny2-ny0):(nx2-nx0),
--          p3 = (ny2-ny1)?(nx2-nx1)/(float)(ny2-ny1):(nx2-nx1),
--          tpx1 = (ny1-ny0)?(ntx1-ntx0)/(float)(ny1-ny0):0,
--          tpy1 = (ny1-ny0)?(nty1-nty0)/(float)(ny1-ny0):0,
--          tpx2 = (ny2-ny0)?(ntx2-ntx0)/(float)(ny2-ny0):0,
--          tpy2 = (ny2-ny0)?(nty2-nty0)/(float)(ny2-ny0):0,
--          tpx3 = (ny2-ny1)?(ntx2-ntx1)/(float)(ny2-ny1):0,
--          tpy3 = (ny2-ny1)?(nty2-nty1)/(float)(ny2-ny1):0,
--          lpx1 = (ny1-ny0)?(nlx1-nlx0)/(float)(ny1-ny0):0,
--          lpy1 = (ny1-ny0)?(nly1-nly0)/(float)(ny1-ny0):0,
--          lpx2 = (ny2-ny0)?(nlx2-nlx0)/(float)(ny2-ny0):0,
--          lpy2 = (ny2-ny0)?(nly2-nly0)/(float)(ny2-ny0):0,
--          lpx3 = (ny2-ny1)?(nlx2-nlx1)/(float)(ny2-ny1):0,
--          lpy3 = (ny2-ny1)?(nly2-nly1)/(float)(ny2-ny1):0;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        float pleft,pright,tpxleft,tpyleft,tpxright,tpyright,lpxleft,lpyleft,lpxright,lpyright,
--          xleft=(float)nx0,xright=xleft,
--          txleft=(float)ntx0,tyleft=(float)nty0,txright=txleft,tyright=tyleft,
--          lxleft=(float)nlx0,lyleft=(float)nly0,lxright=lxleft,lyright=lyleft;
--        if (p1<p2) {
--          pleft=p1; pright=p2;
--          tpxleft=tpx1; tpyleft=tpy1; tpxright=tpx2; tpyright=tpy2;
--          lpxleft=lpx1; lpyleft=lpy1; lpxright=lpx2; lpyright=lpy2;
--        } else {
--          pleft=p2; pright=p1;
--          tpxleft=tpx2; tpyleft=tpy2; tpxright=tpx1; tpyright=tpy1;
--          lpxleft=tpx2; lpyleft=tpy2; lpxright=tpx1; lpyright=tpy1;
--        }
--        if (ny0<0) {
--          xleft-=ny0*pleft; xright-=ny0*pright;
--          txleft-=ny0*tpxleft; tyleft-=ny0*tpyleft; txright-=ny0*tpxright; tyright-=ny0*tpyright;
--          lxleft-=ny0*lpxleft; lyleft-=ny0*lpyleft; lxright-=ny0*lpxright; lyright-=ny0*lpyright;
--        }
--        const int ya = ny1<dimy()?ny1:height;
--        for (int y=(ny0<0?0:ny0); y<ya; y++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy)),
--            lpx = dx?((int)lxright-(int)lxleft)/(float)dx:0,
--            lpy = dx?((int)lyright-(int)lyleft)/(float)dx:0,
--            lxi = (float)((xleft>=0)?(int)lxleft:(int)(lxleft-(int)xleft*lpx)),
--            lyi = (float)((xleft>=0)?(int)lyleft:(int)(lyleft-(int)xleft*lpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) {
--                *(ptrd++)=(T)(light((unsigned int)lx,(unsigned int)ly)*texture((unsigned int)tx,(unsigned int)ty,0,k));
--                tx+=tpx; ty+=tpy; lx+=lpx; ly+=lpy;
--              }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) {
--                *ptrd=(T)(nopacity*light((unsigned int)lx,(unsigned int)ly)*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++;
--                tx+=tpx; ty+=tpy; lx+=lpx; ly+=lpy;
--              }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright;
--          txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright;
--          lxleft+=lpxleft; lyleft+=lpyleft; lxright+=lpxright; lyright+=lpyright;
--        }
--
--        if (p1<p2) {
--          xleft=(float)nx1; pleft=p3;
--          txleft=(float)ntx1; tyleft=(float)nty1; tpxleft=tpx3; tpyleft=tpy3;
--          lxleft=(float)nlx1; lyleft=(float)nly1; lpxleft=lpx3; lpyleft=lpy3;
--          if (ny1<0) { xleft-=ny1*pleft; txleft-=ny1*tpxleft; tyleft-=ny1*tpyleft; lxleft-=ny1*lpxleft; lyleft-=ny1*lpyleft; }
--        } else {
--          xright=(float)nx1; pright=p3;
--          txright=(float)ntx1; tyright=(float)nty1; tpxright=tpx3; tpyright=tpy3;
--          lxright=(float)nlx1; lyright=(float)nly1; lpxright=lpx3; lpyright=lpy3;
--          if (ny1<0) { xright-=ny1*pright; txright-=ny1*tpxright; tyright-=ny1*tpyright; lxright-=ny1*lpxright; lyright-=ny1*lpyright; }
--        }
--        const int yb = ny2>=dimy()?(height-1):ny2;
--        for (int yy=(ny1<0?0:ny1); yy<=yb; yy++) {
--          const int dx = (int)xright-(int)xleft;
--          const float
--            tpx = dx?((int)txright-(int)txleft)/(float)dx:0,
--            tpy = dx?((int)tyright-(int)tyleft)/(float)dx:0,
--            txi = (float)((xleft>=0)?(int)txleft:(int)(txleft-(int)xleft*tpx)),
--            tyi = (float)((xleft>=0)?(int)tyleft:(int)(tyleft-(int)xleft*tpy)),
--            lpx = dx?((int)lxright-(int)lxleft)/(float)dx:0,
--            lpy = dx?((int)lyright-(int)lyleft)/(float)dx:0,
--            lxi = (float)((xleft>=0)?(int)lxleft:(int)(lxleft-(int)xleft*lpx)),
--            lyi = (float)((xleft>=0)?(int)lyleft:(int)(lyleft-(int)xleft*lpy));
--          const int xmin=(xleft>=0)?(int)xleft:0, xmax=(xright<dimx())?(int)xright:(width-1);
--          if (xmin<=xmax) {
--            const int offx=whz-xmax+xmin-1;
--            T* ptrd = ptr(xmin,yy,0,0);
--            if (opacity>=1) cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) {
--                *(ptrd++)=(T)(light((unsigned int)lx,(unsigned int)ly)*texture((unsigned int)tx,(unsigned int)ty,0,k));
--                tx+=tpx; ty+=tpy; lx+=lpx; ly+=lpy;
--              }
--              ptrd+=offx;
--            } else cimg_forV(*this,k) {
--              float tx=txi, ty=tyi, lx=lxi, ly=lyi;
--              for (int x=xmin; x<=xmax; x++) {
--                *ptrd=(T)(nopacity*light((unsigned int)lx,(unsigned int)ly)*texture((unsigned int)tx,(unsigned int)ty,0,k)+copacity*(*ptrd)); ptrd++;
--                tx+=tpx; ty+=tpy; lx+=lpx; ly+=lpy;
--              }
--              ptrd+=offx;
--            }
--          }
--          xleft+=pleft; xright+=pright;
--          txleft+=tpxleft; tyleft+=tpyleft; txright+=tpxright; tyright+=tpyright;
--          lxleft+=lpxleft; lyleft+=lpyleft; lxright+=lpxright; lyright+=lpyright;
--        }
--      }
--      return *this;
--    }
--
--
--    //! Draw an ellipse on the instance image
--    /**
--       \param x0 = X-coordinate of the ellipse center.
--       \param y0 = Y-coordinate of the ellipse center.
--       \param r1 = First radius of the ellipse.
--       \param r2 = Second radius of the ellipse.
--       \param ru = X-coordinate of the orientation vector related to the first radius.
--       \param rv = Y-coordinate of the orientation vector related to the first radius.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param pattern = If zero, the ellipse is filled, else pattern is an integer whose bits describe the outline pattern.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_ellipse(const int x0,const int y0,const float r1,const float r2,const float ru,const float rv,
--                       const T *const color,const unsigned int pattern=0L, const float opacity=1) {
--      if (!is_empty()) {
--        draw_scanline(color,opacity);
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_ellipse : Specified color is (null).",pixel_type());
--        unsigned int hatch=1;
--        const float
--          nr1 = cimg::abs(r1), nr2 = cimg::abs(r2),
--          norm = (float)std::sqrt(ru*ru+rv*rv),
--          u = norm>0?ru/norm:1,
--          v = norm>0?rv/norm:0,
--          rmax = cimg::max(nr1,nr2),
--          l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2),
--          l2 = (float)std::pow(rmax/(nr2>0?nr2:1e-6),2),
--          a = l1*u*u + l2*v*v,
--          b = u*v*(l1-l2),
--          c = l1*v*v + l2*u*u;
--        const int
--          yb = (int)std::sqrt(a*rmax*rmax/(a*c-b*b)),
--          ymin = (y0-yb<0)?0:(y0-yb),
--          ymax = (1+y0+yb>=dimy())?height-1:(1+y0+yb);
--        int oxmin=0, oxmax=0;
--        bool first_line = true;
--        for (int y=ymin; y<ymax; y++) {
--          const float
--            Y = (float)(y-y0)+0.25f,
--            delta = b*b*Y*Y-a*(c*Y*Y-rmax*rmax),
--            sdelta = (float)((delta>0?std::sqrt(delta):0)),
--            fxmin = x0-(b*Y+sdelta)/a,
--            fxmax = x0-(b*Y-sdelta)/a;
--          const int xmin = (int)fxmin, xmax = (int)fxmax;
--          if (!pattern) draw_scanline(xmin,xmax,y,color,opacity);
--          else {
--            if (!(~pattern) || (~pattern && pattern&hatch)) {
--              if (first_line) { draw_scanline(xmin,xmax,y,color,opacity); first_line = false; }
--              else {
--                if (xmin<oxmin) draw_scanline(xmin,oxmin-1,y,color,opacity);
--                else draw_scanline(oxmin+(oxmin==xmin?0:1),xmin,y,color,opacity);
--                if (xmax<oxmax) draw_scanline(xmax,oxmax-1,y,color,opacity);
--                else draw_scanline(oxmax+(oxmax==xmax?0:1),xmax,y,color,opacity);
--              }
--            }
--          }
--          oxmin = xmin; oxmax = xmax;
--          if (pattern) hatch=(hatch<<1)+(hatch>>(sizeof(unsigned int)*8-1));
--        }
--      }
--      return *this;
--    }
--
--    //! Draw an ellipse on the instance image
--    /**
--       \param x0 = X-coordinate of the ellipse center.
--       \param y0 = Y-coordinate of the ellipse center.
--       \param tensor = Diffusion tensor describing the ellipse.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param pattern = If zero, the ellipse is filled, else pattern is an integer whose bits describe the outline pattern.
--       \param opacity = opacity of the drawing.
--    **/
--    template<typename t> CImg& draw_ellipse(const int x0,const int y0,const CImg<t> &tensor,
--                                            const T *color,const unsigned int pattern=0L,const float opacity=1) {
--      CImgList<t> eig = tensor.get_symmetric_eigen();
--      const CImg<t> &val = eig[0], &vec = eig[1];
--      return draw_ellipse(x0,y0,val(0),val(1),vec(0,0),vec(0,1),color,pattern,opacity);
--    }
--
--    //! Draw a circle on the instance image
--    /**
--       \param x0 = X-coordinate of the circle center.
--       \param y0 = Y-coordinate of the circle center.
--       \param r = radius of the circle.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param pattern = If zero, the circle is filled, else pattern is an integer whose bits describe the outline pattern.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_circle(const int x0,const int y0,float r,const T *const color,const unsigned int pattern=0L,const float opacity=1) {
--      return draw_ellipse(x0,y0,r,r,1,0,color,pattern,opacity);
--    }
--
--    //! Draw a text into the instance image.
--    /**
--       \param text = a C-string containing the text to display.
--       \param x0 = X-coordinate of the text in the instance image.
--       \param y0 = Y-coordinate of the text in the instance image.
--       \param fgcolor = an array of dimv() values of type \c T, defining the foreground color (0 means 'transparent').
--       \param bgcolor = an array of dimv() values of type \c T, defining the background color (0 means 'transparent').
--       \param font = List of font characters used for the drawing.
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--       \see get_font().
--    **/
--    template<typename t> CImg& draw_text(const char *const text,
--                                         const int x0,const int y0,
--                                         const T *const fgcolor,const T *const bgcolor,
--                                         const CImgList<t>& font,const float opacity=1) {
--      if (!text)
--        throw CImgArgumentException("CImg<%s>::draw_text() : Specified input string is (null).",pixel_type());
--      if (font.is_empty())
--        throw CImgArgumentException("CImg<%s>::draw_text() : Specified font (%u,%p) is empty.",
--                                    pixel_type(),font.size,font.data);
--
--      if (is_empty()) {
--        // If needed, pre-compute needed size of the image
--        int x=0, y=0, w=0;
--        for (int i=0; i<cimg::strlen(text); i++) {
--          const unsigned char c = text[i];
--          switch (c) {
--          case '\n': y+=font[' '].height; if (x>w) w=x; x=0; break;
--          case '\t': x+=4*font[' '].width; break;
--          default: if (c<font.size) x+=font[c].width;
--          }
--        }
--        if (x!=0) {
--          if (x>w) w=x;
--          y+=font[' '].height;
--        }
--        assign(x0+w,y0+y,1,font[' '].dim,0);
--        if (bgcolor) cimg_forV(*this,k) get_shared_channel(k).fill(bgcolor[k]);
--      }
--
--      int x = x0, y = y0;
--      CImg<T> letter;
--      for (int i=0; i<cimg::strlen(text); i++) {
--        const unsigned char c = text[i];
--        switch (c) {
--        case '\n': y+=font[' '].height; x=x0; break;
--        case '\t': x+=4*font[' '].width; break;
--        default: if (c<font.size) {
--          letter = font[c];
--          const CImg& mask = (c+256)<(int)font.size?font[c+256]:font[c];
--          if (fgcolor) for (unsigned int p=0; p<letter.width*letter.height; p++)
--            if (mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = (T)(letter(p,0,0,k)*fgcolor[k]);
--          if (bgcolor) for (unsigned int p=0; p<letter.width*letter.height; p++)
--            if (!mask(p)) cimg_forV(*this,k) letter(p,0,0,k) = bgcolor[k];
--          if (!bgcolor && font.size>=512) draw_image(letter,mask,x,y,0,0,(T)1,opacity);
--          else draw_image(letter,x,y,0,0,opacity);
--          x+=letter.width;
--        }
--          break;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a text into the instance image.
--    /**
--       \param text = a C-string containing the text to display.
--       \param x0 = X-coordinate of the text in the instance image.
--       \param y0 = Y-coordinate of the text in the instance image.
--       \param fgcolor = an array of dimv() values of type \c T, defining the foreground color (0 means 'transparent').
--       \param bgcolor = an array of dimv() values of type \c T, defining the background color (0 means 'transparent').
--       \param font_size = Height of the desired font (11,13,24,38 or 57)
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--       \see get_font().
--    **/
--    CImg& draw_text(const char *const text,
--                    const int x0,const int y0,
--                    const T *const fgcolor,const T *const bgcolor=0,
--                    const unsigned int font_size=11,const float opacity=1.0f) {
--      return draw_text(text,x0,y0,fgcolor,bgcolor,CImgList<T>::get_font(font_size),opacity);
--    }
--
--
--    //! Draw a text into the instance image.
--    /**
--       \param x0 = X-coordinate of the text in the instance image.
--       \param y0 = Y-coordinate of the text in the instance image.
--       \param fgcolor = an array of dimv() values of type \c T, defining the foreground color (0 means 'transparent').
--       \param bgcolor = an array of dimv() values of type \c T, defining the background color (0 means 'transparent').
--       \param opacity = opacity of the drawing.
--       \param format = a 'printf'-style format, followed by arguments.
--       \note Clipping is supported.
--    **/
--    CImg& draw_text(const int x0,const int y0,
--                    const T *const fgcolor,const T *const bgcolor, const unsigned int font_size,
--                    const float opacity,const char *format,...) {
--      char tmp[2048]={0};
--      std::va_list ap;
--      va_start(ap,format);
--      std::vsprintf(tmp,format,ap);
--      va_end(ap);
--      return draw_text(tmp,x0,y0,fgcolor,bgcolor,font_size,opacity);
--    }
--
--    template<typename t> CImg& draw_text(const int x0,const int y0,
--                                         const T *const fgcolor,const T *const bgcolor,
--                                         const CImgList<t>& font, const float opacity, const char *format,...) {
--      char tmp[2048]={0};
--      std::va_list ap;
--      va_start(ap,format);
--      std::vsprintf(tmp,format,ap);
--      va_end(ap);
--      return draw_text(tmp,x0,y0,fgcolor,bgcolor,font,opacity);
--    }
--
--
--    //! Draw a vector field in the instance image.
--    /**
--       \param flow = a 2d image of 2d vectors used as input data.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param sampling = length (in pixels) between each arrow.
--       \param factor = length factor of each arrow (if <0, computed as a percentage of the maximum length).
--       \param quiver_type = type of plot. Can be 0 (arrows) or 1 (segments).
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    template<typename t>
--    CImg& draw_quiver(const CImg<t>& flow, const T *const color,
--                      const unsigned int sampling=25, const float factor=-20,
--                      const int quiver_type=0, const float opacity=1) {
--      if (!is_empty()) {
--        if (flow.is_empty() || flow.dim!=2)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified flow (%u,%u,%u,%u,%p) has wrong dimensions.",
--                                      pixel_type(),flow.width,flow.height,flow.depth,flow.dim,flow.data);
--        if (!color)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified color is (null)",
--                                      pixel_type());
--        if (sampling<=0)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Incorrect sampling value = %g",
--                                      pixel_type(),sampling);
--
--        float vmax,fact;
--        if (factor<=0) {
--          const CImgStats st(flow.get_norm_pointwise(2),false);
--          vmax = (float)cimg::max(cimg::abs(st.min),cimg::abs(st.max));
--          fact = -factor;
--        } else { fact = factor; vmax = 1; }
--
--        for (unsigned int y=sampling/2; y<height; y+=sampling)
--          for (unsigned int x=sampling/2; x<width; x+=sampling) {
--            const unsigned int X = x*flow.width/width, Y = y*flow.height/height;
--            float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax;
--            if (!quiver_type) {
--              const int xx = x+(int)u, yy = y+(int)v;
--              draw_arrow(x,y,xx,yy,color,45.0f,sampling/5.0f,~0L,opacity);
--            } else draw_line((int)(x-0.5*u),(int)(y-0.5*v),(int)(x+0.5*u),(int)(y+0.5*v),color,~0L,opacity);
--          }
--      }
--      return *this;
--    }
--
--    //! Draw a vector field in the instance image, using a colormap.
--    /**
--       \param flow = a 2d image of 2d vectors used as input data.
--       \param color = a 2d image of dimv()-D vectors corresponding to the color of each arrow.
--       \param sampling = length (in pixels) between each arrow.
--       \param factor = length factor of each arrow (if <0, computed as a percentage of the maximum length).
--       \param quiver_type = type of plot. Can be 0 (arrows) or 1 (segments).
--       \param opacity = opacity of the drawing.
--       \note Clipping is supported.
--    **/
--    template<typename t1,typename t2>
--      CImg& draw_quiver(const CImg<t1>& flow, const CImg<t2>& color,
--                        const unsigned int sampling=25, const float factor=-20,
--                        const int quiver_type=0, const float opacity=1) {
--      if (!is_empty()) {
--        if (flow.is_empty() || flow.dim!=2)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified flow (%u,%u,%u,%u,%p) has wrong dimensions.",
--                                      pixel_type(),flow.width,flow.height,flow.depth,flow.dim,flow.data);
--        if (color.is_empty() || color.width!=flow.width || color.height!=flow.height)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Specified color (%u,%u,%u,%u,%p) has wrong dimensions.",
--                                      pixel_type(),color.width,color.height,color.depth,color.dim,color.data);
--        if (sampling<=0)
--          throw CImgArgumentException("CImg<%s>::draw_quiver() : Incorrect sampling value = %g",pixel_type(),sampling);
--
--        float vmax,fact;
--        if (factor<=0) {
--          const CImgStats st(flow.get_norm_pointwise(2),false);
--          vmax = (float)cimg::max(cimg::abs(st.min),cimg::abs(st.max));
--          fact = -factor;
--        } else { fact = factor; vmax = 1; }
--
--        for (unsigned int y=sampling/2; y<height; y+=sampling)
--          for (unsigned int x=sampling/2; x<width; x+=sampling) {
--            const unsigned int X = x*flow.width/width, Y = y*flow.height/height;
--            float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax;
--            if (!quiver_type) {
--              const int xx = x+(int)u, yy = y+(int)v;
--              draw_arrow(x,y,xx,yy,color.get_vector_at(X,Y).data,45.0f,sampling/5.0f,~0L,opacity);
--            } else draw_line((int)(x-0.5*u),(int)(y-0.5*v),(int)(x+0.5*u),(int)(y+0.5*v),color.get_vector_at(X,Y).data,~0L,opacity);
--          }
--      }
--      return *this;
--    }
--
--    //! Draw a 1D graph on the instance image.
--    /**
--       \param data = an image containing the graph values I = f(x).
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param gtype = define the type of the plot :
--                      - 0 = Plot using linear interpolation (segments).
--                      - 1 = Plot with bars.
--                      - 2 = Plot using cubic interpolation (3-polynomials).
--       \param ymin = lower bound of the y-range.
--       \param ymax = upper bound of the y-range.
--       \param opacity = opacity of the drawing.
--       \note
--         - if \c ymin==ymax==0, the y-range is computed automatically from the input sample.
--       \see draw_axis().
--    **/
--    template<typename t>
--    CImg& draw_graph(const CImg<t>& data, const T *const color, const unsigned int gtype=0,
--                     const double ymin=0, const double ymax=0, const float opacity=1) {
--      if (!is_empty()) {
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_graph() : Specified color is (null)",pixel_type());
--        T *color1 = new T[dim], *color2 = new T[dim];
--        cimg_forV(*this,k) { color1[k]=(T)(color[k]*0.6f); color2[k]=(T)(color[k]*0.3f); }
--        CImgStats st;
--        if (ymin==ymax) { st = CImgStats(data,false); cimg::swap(st.min,st.max); } else { st.min = ymin; st.max = ymax; }
--        if (st.min==st.max) { st.min--; st.max++; }
--        const float ca = height>1?(float)(st.max-st.min)/(height-1):0, cb = (float)st.min;
--        const int Y0 = (int)(-cb/ca);
--        int pY=0;
--        cimg_foroff(data,off) {
--          const int Y = (int)((data[off]-cb)/ca);
--          switch (gtype) {
--          case 0: // plot with segments
--            if (off>0) draw_line((int)((off-1)*width/data.size()),pY,(int)(off*width/data.size()),Y,color,~0L,opacity);
--            break;
--          case 1: { // plot with bars
--            const unsigned int X = off*width/data.size(), nX = (off+1)*width/data.size()-1;
--            draw_rectangle(X,(int)Y0,nX,Y,color1,opacity);
--            draw_line(X,Y,X,(int)Y0,color2,~0L,opacity);
--            draw_line(X,(int)Y0,nX,(int)Y0,Y<=Y0?color2:color,~0L,opacity);
--            draw_line(nX,Y,nX,(int)Y0,color,~0L,opacity);
--            draw_line(X,Y,nX,Y,Y<=Y0?color:color2,~0L,opacity);
--          } break;
--          }
--          pY=Y;
--        }
--        if (gtype==2) { // plot with cubic interpolation
--          const CImg<t> ndata = data.get_shared_points(0,data.size()-1);
--          cimg_forX(*this,x) {
--            const int Y = (int)((ndata.cubic_pix1d((float)x*ndata.width/width)-cb)/ca);
--            if (x>0) draw_line(x,pY,x+1,Y,color,~0L,opacity);
--            pY=Y;
--          }
--        }
--        delete[] color1; delete[] color2;
--      }
--      return *this;
--    }
--
--    //! Draw a labelled horizontal axis on the instance image.
--    /**
--       \param x0 = lower bound of the x-range.
--       \param x1 = upper bound of the x-range.
--       \param y = Y-coordinate of the horizontal axis in the instance image.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param precision = precision of the labels.
--       \param grid_pattern = pattern of the grid
--       \param opacity = opacity of the drawing.
--       \note if \c precision==0, precision of the labels is automatically computed.
--       \see draw_graph().
--    **/
--    template<typename t> CImg& draw_axis(const CImg<t>& xvalues, const int y, const T *const color,
--                                         const int precision=-1, const float opacity=1.0f) {
--      if (!is_empty()) {
--        int siz = (int)xvalues.size()-1;
--        if (siz<=0) draw_line(0,y,width-1,y,color,~0L,opacity);
--        else {
--          if (xvalues[0]<xvalues[siz]) draw_arrow(0,y,width-1,y,color,30,5,~0L,opacity);
--          else draw_arrow(width-1,y,0,y,color,30,5,~0L,opacity);
--          const int yt = (y+14)<dimy()?(y+3):(y-14);
--          char txt[32];
--          cimg_foroff(xvalues,x) {
--            if (precision>=0) std::sprintf(txt,"%.*g",precision,(double)xvalues(x));
--            else std::sprintf(txt,"%g",(double)xvalues(x));
--            const int xi=(int)(x*(width-1)/siz), xt = xi-(int)std::strlen(txt)*3;
--            draw_point(xi,y-1,color,opacity).draw_point(xi,y+1,color,opacity).
--              draw_text(txt,xt<0?0:xt,yt,color,0,11,opacity);
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a labelled vertical axis on the instance image.
--    template<typename t> CImg& draw_axis(const int x, const CImg<t>& yvalues, const T *const color,
--                                         const int precision=-1, const float opacity=1.0f) {
--      if (!is_empty()) {
--        int siz = (int)yvalues.size()-1;
--        if (siz<=0) draw_line(x,0,x,height-1,color,~0L,opacity);
--        else {
--          if (yvalues[0]<yvalues[siz]) draw_arrow(x,0,x,height-1,color,30,5,~0L,opacity);
--          else draw_arrow(x,height-1,x,0,color,30,5,~0L,opacity);
--          char txt[32];
--          cimg_foroff(yvalues,y) {
--            if (precision>=0) std::sprintf(txt,"%.*g",precision,(double)yvalues(y));
--            else std::sprintf(txt,"%g",(double)yvalues(y));
--            const int
--              yi = (int)(y*(height-1)/siz),
--              tmp = yi-5,
--              nyi = tmp<0?0:(tmp>=(int)height-11?(int)height-11:tmp),
--              xt = x-(int)std::strlen(txt)*7;
--            draw_point(x-1,yi,color,opacity).draw_point(x+1,yi,color,opacity);
--            if (xt>0) draw_text(txt,xt,nyi,color,0,11,opacity);
--            else draw_text(txt,x+3,nyi,color,0,11,opacity);
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a labelled horizontal+vertical axis on the instance image.
--    template<typename tx, typename ty> CImg& draw_axis(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const T *const color,
--                                                       const int precisionx=-1, const int precisiony=-1,
--                                                       const float opacity=1.0f) {
--      if (!is_empty()) {
--        const CImg<tx> nxvalues(xvalues.data,xvalues.size(),1,1,1,true);
--        const int sizx = (int)xvalues.size()-1, wm1 = (int)(width)-1;
--        if (sizx>0) {
--          float ox = (float)nxvalues[0];
--          for (unsigned int x=1; x<width; x++) {
--            const float nx = (float)nxvalues.linear_pix1d((float)x*sizx/wm1);
--            if (nx*ox<=0) { draw_axis(nx==0?x:x-1,yvalues,color,precisiony,opacity); break; }
--            ox = nx;
--          }
--        }
--        const CImg<ty> nyvalues(yvalues.data,yvalues.size(),1,1,1,true);
--        const int sizy = (int)yvalues.size()-1, hm1 = (int)(height)-1;
--        if (sizy>0) {
--          float oy = (float)nyvalues[0];
--          for (unsigned int y=1; y<height; y++) {
--            const float ny = (float)nyvalues.linear_pix1d((float)y*sizy/hm1);
--            if (ny*oy<=0) { draw_axis(xvalues,ny==0?y:y-1,color,precisionx,opacity); break; }
--            oy = ny;
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a labelled horizontal+vertical axis on the instance image.
--    template<typename tx, typename ty> CImg& draw_axis(const tx& x0, const tx& x1, const ty& y0, const ty& y1,
--                                                       const T *const color,
--                                                       const int subdivisionx=-60, const int subdivisiony=-60,
--                                                       const int precisionx=-1, const int precisiony=-1,
--                                                       const float opacity=1.0f) {
--      return draw_axis(CImg<tx>::sequence(subdivisionx>0?subdivisionx:1-(int)width/subdivisionx,x0,x1),
--                       CImg<ty>::sequence(subdivisiony>0?subdivisiony:1-(int)height/subdivisiony,y0,y1),
--                       color,precisionx,precisiony,opacity);
--    }
--
--    //! Draw grid on the instance image
--    template<typename tx, typename ty>
--      CImg& draw_grid(const CImg<tx>& xvalues, const CImg<ty>& yvalues, const T *const color,
--                      const unsigned int patternx=~0U, const unsigned int patterny=~0U,
--                      const float opacity=1.0f) {
--      if (!is_empty()) {
--        if (!xvalues.is_empty()) cimg_foroff(xvalues,x) {
--          const int xi = (int)xvalues[x];
--          if (xi>=0 && xi<(int)width) draw_line(xi,0,xi,height-1,color,patternx,opacity);
--        }
--        if (!yvalues.is_empty()) cimg_foroff(yvalues,y) {
--          const int yi = (int)yvalues[y];
--          if (yi>=0 && yi<(int)height) draw_line(0,yi,width-1,yi,color,patterny,opacity);
--        }
--      }
--      return *this;
--    }
--
--    //! Draw grid on the instance image
--    CImg& draw_grid(const float deltax,  const float deltay,
--                    const float offsetx, const float offsety,
--                    const T *const color,
--                    const unsigned int patternx=~0U, const unsigned int patterny=~0U,
--                    const bool invertx=false, const bool inverty=false,
--                    const float opacity=1.0f) {
--
--      CImg<unsigned int> seqx, seqy;
--
--      if (deltax!=0) {
--        const float dx = deltax>0?deltax:width*-deltax/100;
--        const unsigned int nx = (unsigned int)(width/dx);
--        seqx = CImg<unsigned int>::sequence(1+nx,0,(unsigned int)(dx*nx));
--        if (offsetx) cimg_foroff(seqx,x) seqx(x) = (unsigned int)cimg::mod(seqx(x)+offsetx,(float)width);
--        if (invertx) cimg_foroff(seqx,x) seqx(x) = width-1-seqx(x);
--      }
--
--      if (deltay!=0) {
--        const float dy = deltay>0?deltay:height*-deltay/100;
--        const unsigned int ny = (unsigned int)(height/dy);
--        seqy = CImg<unsigned int>::sequence(1+ny,0,(unsigned int)(dy*ny));
--        if (offsety) cimg_foroff(seqy,y) seqy(y) = (unsigned int)cimg::mod(seqy(y)+offsety,(float)height);
--        if (inverty) cimg_foroff(seqy,y) seqy(y) = height-1-seqy(y);
--     }
--
--      return draw_grid(seqx,seqy,color,patternx,patterny,opacity);
--    }
--
--    // INNER CLASS used by function CImg<>::draw_fill()
--    template<typename T1,typename T2> struct _draw_fill {
--      const T1 *const color;
--      const float sigma,opacity;
--      const CImg<T1> value;
--      CImg<T2> region;
--
--      _draw_fill(const CImg<T1>& img,const int x,const int y,const int z,
--                 const T *const pcolor,const float psigma,const float popacity):
--        color(pcolor),sigma(psigma),opacity(popacity),
--        value(img.get_vector_at(x,y,z)), region(CImg<T2>(img.width,img.height,img.depth,1,(T2)false)) {
--      }
--
--      _draw_fill& operator=(const _draw_fill& d) {
--        color = d.color;
--        sigma = d.sigma;
--        opacity = d.opacity;
--        value = d.value;
--        region = d.region;
--        return *this;
--      }
--
--      bool comp(const CImg<T1>& A,const CImg<T1>& B) const {
--        bool res=true;
--        const T *pA=A.data+A.size();
--        for (const T *pB=B.data+B.size(); res && pA>A.data; res=(cimg::abs(*(--pA)-(*(--pB)))<=sigma) );
--        return res;
--      }
--
--      void fill(CImg<T1>& img,const int x,const int y,const int z) {
--        if (x<0 || x>=img.dimx() || y<0 || y>=img.dimy() || z<0 || z>=img.dimz()) return;
--        if (!region(x,y,z) && comp(value,img.get_vector_at(x,y,z))) {
--          const T *col=color;
--          const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--          int xmin,xmax;
--          if (opacity>=1) cimg_forV(img,k) img(x,y,z,k)=*(col++);
--          else cimg_forV(img,k) img(x,y,z,k)=(T1)(*(col++)*opacity+copacity*img(x,y,z,k));
--          col-=img.dim;
--          region(x,y,z) = (T2)true;
--          for (xmin=x-1; xmin>=0 && comp(value,img.get_vector_at(xmin,y,z)); xmin--) {
--            if (opacity>=1) cimg_forV(img,k) img(xmin,y,z,k) = *(col++);
--            else cimg_forV(img,k) img(xmin,y,z,k)=(T1)(*(col++)*nopacity+copacity*img(xmin,y,z,k));
--            col-=img.dim;
--            region(xmin,y,z)=(T2)true;
--          }
--          for (xmax=x+1; xmax<img.dimx() && comp(value,img.get_vector_at(xmax,y,z)); xmax++) {
--            if (opacity>=1) cimg_forV(img,k) img(xmax,y,z,k) = *(col++);
--            else cimg_forV(img,k) img(xmax,y,z,k)=(T1)(*(col++)*nopacity+copacity*img(xmax,y,z,k));
--            col-=img.dim;
--            region(xmax,y,z)=(T2)true;
--          }
--          xmin++; xmax--;
--          for (; xmin<=xmax; xmin++) {
--            fill(img,xmin,y-1,z);
--            fill(img,xmin,y+1,z);
--            fill(img,xmin,y,z-1);
--            fill(img,xmin,y,z+1);
--          }
--        }
--      }
--    };
--
--    //! Draw a 3D filled region starting from a point (\c x,\c y,\ z) in the instance image.
--    /**
--       \param x = X-coordinate of the starting point of the region to fill.
--       \param y = Y-coordinate of the starting point of the region to fill.
--       \param z = Z-coordinate of the starting point of the region to fill.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param region = image that will contain the mask of the filled region mask, as an output.
--       \param sigma = tolerance concerning neighborhood values.
--       \param opacity = opacity of the drawing.
--
--       \return \p region is initialized with the binary mask of the filled region.
--    **/
--    template<typename t> CImg& draw_fill(const int x,const int y,const int z,
--                                         const T *const color, CImg<t>& region,const float sigma=0,
--                                         const float opacity=1) {
--      _draw_fill<T,t> F(*this,x,y,z,color,sigma,opacity);
--      F.fill(*this,x,y,z);
--      region = F.region;
--      return *this;
--    }
--
--    //! Draw a 3D filled region starting from a point (\c x,\c y,\ z) in the instance image.
--    /**
--       \param x = X-coordinate of the starting point of the region to fill.
--       \param y = Y-coordinate of the starting point of the region to fill.
--       \param z = Z-coordinate of the starting point of the region to fill.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param sigma = tolerance concerning neighborhood values.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_fill(const int x,const int y,const int z,const T *const color,const float sigma=0,const float opacity=1) {
--      CImg<bool> tmp;
--      return draw_fill(x,y,z,color,tmp,sigma,opacity);
--    }
--
--    //! Draw a 2D filled region starting from a point (\c x,\c y) in the instance image.
--    /**
--       \param x = X-coordinate of the starting point of the region to fill.
--       \param y = Y-coordinate of the starting point of the region to fill.
--       \param color = an array of dimv() values of type \c T, defining the drawing color.
--       \param sigma = tolerance concerning neighborhood values.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_fill(const int x,const int y,const T *const color,const float sigma=0,const float opacity=1) {
--      CImg<bool> tmp;
--      return draw_fill(x,y,0,color,tmp,sigma,opacity);
--    }
--
--    //! Draw a plasma square in the instance image.
--    /**
--       \param x0 = X-coordinate of the upper-left corner of the plasma.
--       \param y0 = Y-coordinate of the upper-left corner of the plasma.
--       \param x1 = X-coordinate of the lower-right corner of the plasma.
--       \param y1 = Y-coordinate of the lower-right corner of the plasma.
--       \param alpha = Alpha-parameter of the plasma.
--       \param beta = Beta-parameter of the plasma.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_plasma(const int x0, const int y0, const int x1, const int y1,
--                      const double alpha=1.0, const double beta=1.0, const float opacity=1) {
--      if (!is_empty()) {
--        int nx0=x0,nx1=x1,ny0=y0,ny1=y1;
--        if (nx1<nx0) cimg::swap(nx0,nx1);
--        if (ny1<ny0) cimg::swap(ny0,ny1);
--        if (nx0<0) nx0=0;
--        if (nx1>=dimx()) nx1=width-1;
--        if (ny0<0) ny0=0;
--        if (ny1>=dimy()) ny1=height-1;
--        const int xc = (nx0+nx1)/2, yc = (ny0+ny1)/2, dx=(xc-nx0), dy=(yc-ny0);
--        const double dc = std::sqrt((double)(dx*dx+dy*dy))*alpha + beta;
--        float val = 0;
--        cimg_forV(*this,k) {
--          if (opacity>=1) {
--            (*this)(xc,ny0,0,k) = (T)(0.5f*((*this)(nx0,ny0,0,k)+(*this)(nx1,ny0,0,k)));
--            (*this)(xc,ny1,0,k) = (T)(0.5f*((*this)(nx0,ny1,0,k)+(*this)(nx1,ny1,0,k)));
--            (*this)(nx0,yc,0,k) = (T)(0.5f*((*this)(nx0,ny0,0,k)+(*this)(nx0,ny1,0,k)));
--            (*this)(nx1,yc,0,k) = (T)(0.5f*((*this)(nx1,ny0,0,k)+(*this)(nx1,ny1,0,k)));
--            do {
--              val = (float)(0.25f*((*this)(nx0,ny0,0,k)+(*this)(nx1,ny0,0,k) +
--                                   (*this)(nx1,ny1,0,k)+(*this)(nx0,ny1,0,k)) + dc*cimg::grand());
--            } while (val<(float)cimg::type<T>::min() || val>(float)cimg::type<T>::max());
--            (*this)(xc,yc,0,k)  = (T)val;
--          } else {
--            const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--            (*this)(xc,ny0,0,k) = (T)(0.5f*((*this)(nx0,ny0,0,k)+(*this)(nx1,ny0,0,k))*nopacity + copacity*(*this)(xc,ny0,0,k));
--            (*this)(xc,ny1,0,k) = (T)(0.5f*((*this)(nx0,ny1,0,k)+(*this)(nx1,ny1,0,k))*nopacity + copacity*(*this)(xc,ny1,0,k));
--            (*this)(nx0,yc,0,k) = (T)(0.5f*((*this)(nx0,ny0,0,k)+(*this)(nx0,ny1,0,k))*nopacity + copacity*(*this)(nx0,yc,0,k));
--            (*this)(nx1,yc,0,k) = (T)(0.5f*((*this)(nx1,ny0,0,k)+(*this)(nx1,ny1,0,k))*nopacity + copacity*(*this)(nx1,yc,0,k));
--            do {
--              val = (float)(0.25f*(((*this)(nx0,ny0,0,k)+(*this)(nx1,ny0,0,k) +
--                                             (*this)(nx1,ny1,0,k)+(*this)(nx0,ny1,0,k)) + dc*cimg::grand())*nopacity
--                            + copacity*(*this)(xc,yc,0,k));
--            } while (val<(float)cimg::type<T>::min() || val>(float)cimg::type<T>::max());
--            (*this)(xc,yc,0,k)  = (T)val;
--          }
--        }
--        if (xc!=nx0 || yc!=ny0) {
--          draw_plasma(nx0,ny0,xc,yc,alpha,beta,opacity);
--          draw_plasma(xc,ny0,nx1,yc,alpha,beta,opacity);
--          draw_plasma(nx0,yc,xc,ny1,alpha,beta,opacity);
--          draw_plasma(xc,yc,nx1,ny1,alpha,beta,opacity);
--        }
--      }
--      return *this;
--    }
--
--    //! Draw a plasma in the instance image.
--    /**
--       \param alpha = Alpha-parameter of the plasma.
--       \param beta = Beta-parameter of the plasma.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_plasma(const double alpha=1.0,const double beta=1.0,const float opacity=1) {
--      return draw_plasma(0,0,width-1,height-1,alpha,beta,opacity);
--    }
--
--    //! Draw a 1D gaussian function in the instance image.
--    /**
--       \param xc = X-coordinate of the gaussian center.
--       \param sigma = Standard variation of the gaussian distribution.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_gaussian(const float xc,const double sigma,const T *const color,const float opacity=1) {
--      if (!is_empty()) {
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
--        const double sigma2 = 2*sigma*sigma;
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        const unsigned int whz = width*height*depth;
--        const T *col = color;
--        cimg_forX(*this,x) {
--          const float dx = (x-xc);
--          const double val = std::exp( -dx*dx/sigma2 );
--          T *ptrd = ptr(x,0,0,0);
--          if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
--          else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + copacity*(*ptrd)); ptrd+=whz; }
--          col-=dim;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw an anisotropic 2D gaussian function in the instance image.
--    /**
--       \param xc = X-coordinate of the gaussian center.
--       \param yc = Y-coordinate of the gaussian center.
--       \param tensor = 2x2 covariance matrix.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--    **/
--    template<typename t> CImg& draw_gaussian(const float xc,const float yc,const CImg<t>& tensor,
--                                             const T *const color,const float opacity=1) {
--      if (!is_empty()) {
--        if (tensor.width!=2 || tensor.height!=2 || tensor.depth!=1 || tensor.dim!=1)
--          throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 2x2 matrix.",
--                                      pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
--        if (!color) throw CImgArgumentException("CImg<%s>::draw_gaussian() : Specified color is (null)",pixel_type());
--        const CImg<t> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
--        const t &a=invT2(0,0), &b=2*invT2(1,0), &c=invT2(1,1);
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        const unsigned int whz = width*height*depth;
--        const T *col = color;
--        float dy = -yc;
--        cimg_forY(*this,y) {
--          float dx = -xc;
--          cimg_forX(*this,x) {
--            const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy);
--            T *ptrd = ptr(x,y,0,0);
--            if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
--            else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + copacity*(*ptrd)); ptrd+=whz; }
--            col-=dim;
--            dx++;
--          }
--          dy++;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw an isotropic 2D gaussian function in the instance image
--    /**
--       \param xc = X-coordinate of the gaussian center.
--       \param yc = Y-coordinate of the gaussian center.
--       \param sigma = standard variation of the gaussian distribution.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_gaussian(const float xc,const float yc,const float sigma,const T *const color,const float opacity=1) {
--      return draw_gaussian(xc,yc,CImg<float>::diagonal(sigma,sigma),color,opacity);
--    }
--
--    //! Draw an anisotropic 3D gaussian function in the instance image.
--    /**
--       \param xc = X-coordinate of the gaussian center.
--       \param yc = Y-coordinate of the gaussian center.
--       \param zc = Z-coordinate of the gaussian center.
--       \param tensor = 3x3 covariance matrix.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--    **/
--    template<typename t> CImg& draw_gaussian(const float xc,const float yc,const float zc,const CImg<t>& tensor,
--                                             const T *const color,const float opacity=1) {
--      if (!is_empty()) {
--        if (tensor.width!=3 || tensor.height!=3 || tensor.depth!=1 || tensor.dim!=1)
--          throw CImgArgumentException("CImg<%s>::draw_gaussian() : Tensor parameter (%u,%u,%u,%u,%p) is not a 3x3 matrix.",
--                                      pixel_type(),tensor.width,tensor.height,tensor.depth,tensor.dim,tensor.data);
--        const CImg<t> invT = tensor.get_inverse(), invT2 = (invT*invT)/(-2.0);
--        const t a=invT(0,0), b=2*invT(1,0), c=2*invT(2,0), d=invT(1,1), e=2*invT(2,1), f=invT(2,2);
--        const float nopacity = cimg::abs(opacity), copacity = 1-cimg::max(opacity,0.0f);
--        const unsigned int whz = width*height*depth;
--        const T *col = color;
--        cimg_forXYZ(*this,x,y,z) {
--          const float dx = (x-xc), dy = (y-yc), dz = (z-zc);
--          const double val = std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz);
--          T *ptrd = ptr(x,y,z,0);
--          if (opacity>=1) cimg_forV(*this,k) { *ptrd = (T)(val*(*col++)); ptrd+=whz; }
--          else cimg_forV(*this,k) { *ptrd = (T)(nopacity*val*(*col++) + copacity*(*ptrd)); ptrd+=whz; }
--          col-=dim;
--        }
--      }
--      return *this;
--    }
--
--    //! Draw an isotropic 3D gaussian function in the instance image
--   /**
--       \param xc = X-coordinate of the gaussian center.
--       \param yc = Y-coordinate of the gaussian center.
--       \param zc = Z-coordinate of the gaussian center.
--       \param sigma = standard variation of the gaussian distribution.
--       \param color = array of dimv() values of type \c T, defining the drawing color.
--       \param opacity = opacity of the drawing.
--    **/
--    CImg& draw_gaussian(const float xc,const float yc,const float zc,
--                        const double sigma,const T *const color,const float opacity=1) {
--      return draw_gaussian(xc,yc,zc,CImg<float>::diagonal(sigma,sigma,sigma),color,opacity);
--    }
--
--    //! Draw a 3D object in the instance image
--    /**
--       \param X = X-coordinate of the 3d object position
--       \param Y = Y-coordinate of the 3d object position
--       \param Z = Z-coordinate of the 3d object position
--       \param points = Image N*3 describing 3D point coordinates
--       \param primitives = List of P primitives
--       \param colors = List of P color (or textures)
--       \param opacities = Image of P opacities
--       \param render_type = Render type (0=Points, 1=Lines, 2=Faces (no light), 3=Faces (flat), 4=Faces(Gouraud)
--       \param double_sided = Tell if object faces have two sides or are oriented.
--       \param focale = length of the focale
--       \param lightx = X-coordinate of the light
--       \param lighty = Y-coordinate of the light
--       \param lightz = Z-coordinate of the light
--       \param ambiant_light = Brightness (between 0..1) of the ambiant light
--    **/
--    template<typename tp, typename tf, typename to>
--      CImg& draw_object3d(const float X, const float Y, const float Z,
--                          const CImg<tp>& points, const CImgList<tf>& primitives,
--                          const CImgList<T>& colors, const CImgList<to>& opacities,
--                          const unsigned int render_type=4,
--                          const bool double_sided=false, const float focale=500,
--                          const float lightx=0, const float lighty=0, const float lightz=-5000,
--                          const float ambiant_light = 0.05f) {
--
--      static CImg<float> light_texture;
--      if (is_empty() || points.is_empty() || primitives.is_empty()) return *this;
--      if (colors.is_empty() || opacities.is_empty())
--        throw CImgArgumentException("CImg<%s>::draw_object3d() : Undefined colors or opacities",pixel_type());
--
--      if (points.height<3)
--        return draw_object3d(X,Y,Z,points.get_resize(-100,3,1,1,0),primitives,colors,opacities,
--                             render_type,double_sided,focale,lightx,lighty,lightz,ambiant_light);
--
--      // Create light texture for phong-like rendering
--      if (render_type==5) {
--        if (colors.size>primitives.size) light_texture = colors[primitives.size];
--        else {
--          static float olightx=0, olighty=0, olightz=0, oambiant_light=0;
--          if (light_texture.is_empty() || lightx!=olightx || lighty!=olighty || lightz!=olightz || ambiant_light!=oambiant_light) {
--            light_texture.assign(512,512);
--            const float white[1]={ 1.0f },
--              dlx = lightx-X, dly = lighty-Y, dlz = lightz-Z,
--                nl = (float)std::sqrt(dlx*dlx+dly*dly+dlz*dlz),
--                nlx = light_texture.width/2*(1+dlx/nl),
--                nly = light_texture.height/2*(1+dly/nl);
--              (light_texture.draw_gaussian(nlx,nly,light_texture.width/3.0f,white)+=ambiant_light).cut(0.0f,1.0f);
--              olightx = lightx; olighty = lighty; olightz = lightz; oambiant_light = ambiant_light;
--          }
--        }
--      }
--
--      // Compute 3D to 2D projection
--      CImg<float> projections(points.width,2);
--      cimg_forX(points,l) {
--        const float
--          x = (float)points(l,0),
--          y = (float)points(l,1),
--          z = (float)points(l,2);
--        const float projectedz = z + Z + focale;
--        projections(l,1) = Y + focale*y/projectedz;
--        projections(l,0) = X + focale*x/projectedz;
--      }
--
--      // Compute and sort visible primitives
--      CImg<unsigned int> visibles(primitives.size);
--      CImg<float> zrange(primitives.size);
--      unsigned int nb_visibles = 0;
--      const float zmin = -focale+1.5f;
--      { cimglist_for(primitives,l) {
--        const CImg<tf>& primitive = primitives[l];
--        switch (primitive.size()) {
--        case 1: { // Point
--          const unsigned int i0 = (unsigned int)primitive(0);
--          const float x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2));
--          if (z0>zmin && x0>=0 && x0<width && y0>=0 && y0<height) {
--            visibles(nb_visibles) = (unsigned int)l;
--            zrange(nb_visibles++) = z0;
--          }
--        } break;
--        case 2: // Line or textured line
--        case 6: {
--          const unsigned int
--            i0 = (unsigned int)primitive(0),
--            i1 = (unsigned int)primitive(1);
--          const float
--            x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
--            x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2));
--          float xm, xM, ym, yM;
--          if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
--          if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
--          if (z0>zmin && z1>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
--            visibles(nb_visibles) = (unsigned int)l;
--            zrange(nb_visibles++) = 0.5f*(z0+z1);
--          }
--        } break;
--        case 3:  // Triangle or textured triangle
--        case 9: {
--          const unsigned int
--            i0 = (unsigned int)primitive(0),
--            i1 = (unsigned int)primitive(1),
--            i2 = (unsigned int)primitive(2);
--          const float
--            x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
--            x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
--            x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2));
--          float xm, xM, ym, yM;
--          if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
--          if (x2<xm) xm = x2;
--          if (x2>xM) xM = x2;
--          if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
--          if (y2<ym) ym = y2;
--          if (y2>yM) yM = y2;
--          if (z0>zmin && z1>zmin && z2>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
--            if (double_sided || (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)<0) {
--              visibles(nb_visibles) = (unsigned int)l;
--              zrange(nb_visibles++) = (z0+z1+z2)/3;
--            }
--          }
--        } break;
--        case 4: // Rectangle or textured rectangle
--        case 12: {
--          const unsigned int
--            i0 = (unsigned int)primitive(0),
--            i1 = (unsigned int)primitive(1),
--            i2 = (unsigned int)primitive(2),
--            i3 = (unsigned int)primitive(3);
--          const float
--            x0 = projections(i0,0), y0 = projections(i0,1), z0 = (float)(Z+points(i0,2)),
--            x1 = projections(i1,0), y1 = projections(i1,1), z1 = (float)(Z+points(i1,2)),
--            x2 = projections(i2,0), y2 = projections(i2,1), z2 = (float)(Z+points(i2,2)),
--            x3 = projections(i3,0), y3 = projections(i3,1), z3 = (float)(Z+points(i3,2));
--          float xm, xM, ym, yM;
--          if (x0<x1) { xm = x0; xM = x1; } else { xm = x1; xM = x0; }
--          if (x2<xm) xm = x2;
--          if (x2>xM) xM = x2;
--          if (x3<xm) xm = x3;
--          if (x3>xM) xM = x3;
--          if (y0<y1) { ym = y0; yM = y1; } else { ym = y1; yM = y0; }
--          if (y2<ym) ym = y2;
--          if (y2>yM) yM = y2;
--          if (y3<ym) ym = y3;
--          if (y3>yM) yM = y3;
--          if (z0>zmin && z1>zmin && z2>zmin && z3>zmin && xM>=0 && xm<width && yM>=0 && ym<height) {
--            if (double_sided || (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)<0) {
--              visibles(nb_visibles) = (unsigned int)l;
--              zrange(nb_visibles++) = (z0+z1+z2+z3)/4;
--            }
--          }
--        } break;
--        default:
--          throw CImgArgumentException("CImg<%s>::draw_object3d() : Primitive %u is invalid (size = %u, can be 1,2,3,4,6,9 or 12)",
--                                      pixel_type(),l,primitive.size());
--        }}
--      }
--      if (nb_visibles<=0) return *this;
--      CImg<unsigned int> permutations;
--      CImg<float>(zrange.data,nb_visibles,1,1,1,true).sort(permutations,false);
--
--      // Compute light properties
--      CImg<float> lightprops;
--      switch (render_type) {
--      case 3: { // Flat Shading
--        lightprops.assign(nb_visibles);
--        cimg_forX(lightprops,l) {
--          const CImg<tf>& primitive = primitives(visibles(permutations(l)));
--          const unsigned int psize = primitive.size();
--          if (psize==3 || psize==4 || psize==9 || psize==12) {
--            const unsigned int
--              i0 = (unsigned int)primitive(0),
--              i1 = (unsigned int)primitive(1),
--              i2 = (unsigned int)primitive(2);
--            const float
--              x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
--              x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
--              x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
--              dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
--              dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
--              nx = dy1*dz2-dz1*dy2,
--              ny = dz1*dx2-dx1*dz2,
--              nz = dx1*dy2-dy1*dx2,
--              norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
--              lx = X+(x0+x1+x2)/3-lightx,
--              ly = Y+(y0+y1+y2)/3-lighty,
--              lz = Z+(z0+z1+z2)/3-lightz,
--              nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
--              factor = (-lx*nx-ly*ny-lz*nz)/(norm*nl),
--              nfactor = double_sided?cimg::abs(factor):cimg::max(factor,0.0f);
--            lightprops[l] = cimg::min(nfactor+ambiant_light,1.0f);
--          } else lightprops[l] = 1.0f;
--        }
--      } break;
--
--      case 4: // Gouraud Shading
--      case 5: { // Phong-Shading
--        CImg<float> points_normals(points.width,3,1,1,0);
--        cimglist_for(primitives,l) {
--          const CImg<tf>& primitive = primitives[l];
--          const unsigned int psize = primitive.size();
--          const bool
--            triangle_flag = (psize==3) || (psize==9),
--            rectangle_flag = (psize==4) || (psize==12);
--          if (triangle_flag || rectangle_flag) {
--            const unsigned int
--              i0 = (unsigned int)primitive(0),
--              i1 = (unsigned int)primitive(1),
--              i2 = (unsigned int)primitive(2),
--              i3 = rectangle_flag?(unsigned int)primitive(3):0;
--            const float
--              x0 = (float)points(i0,0), y0 = (float)points(i0,1), z0 = (float)points(i0,2),
--              x1 = (float)points(i1,0), y1 = (float)points(i1,1), z1 = (float)points(i1,2),
--              x2 = (float)points(i2,0), y2 = (float)points(i2,1), z2 = (float)points(i2,2),
--              dx1 = x1-x0, dy1 = y1-y0, dz1 = z1-z0,
--              dx2 = x2-x0, dy2 = y2-y0, dz2 = z2-z0,
--              nx = dy1*dz2-dz1*dy2,
--              ny = dz1*dx2-dx1*dz2,
--              nz = dx1*dy2-dy1*dx2,
--              norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
--              nnx = nx/norm,
--              nny = ny/norm,
--              nnz = nz/norm;
--            points_normals(i0,0)+=nnx; points_normals(i0,1)+=nny; points_normals(i0,2)+=nnz;
--            points_normals(i1,0)+=nnx; points_normals(i1,1)+=nny; points_normals(i1,2)+=nnz;
--            points_normals(i2,0)+=nnx; points_normals(i2,1)+=nny; points_normals(i2,2)+=nnz;
--            if (rectangle_flag) {
--              points_normals(i3,0)+=nnx; points_normals(i3,1)+=nny; points_normals(i3,2)+=nnz;
--            }
--          }
--        }
--
--        if (render_type==4) {
--          lightprops.assign(points.width);
--          cimg_forX(points,ll) {
--            const float
--              nx = points_normals(ll,0),
--              ny = points_normals(ll,1),
--              nz = points_normals(ll,2),
--              norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
--              lx = (float)(X+points(ll,0)-lightx),
--              ly = (float)(Y+points(ll,1)-lighty),
--              lz = (float)(Z+points(ll,2)-lightz),
--              nl = (float)std::sqrt(1e-5f+lx*lx+ly*ly+lz*lz),
--              factor = (-lx*nx-ly*ny-lz*nz)/(norm*nl),
--              nfactor = double_sided?cimg::abs(factor):cimg::max(factor,0.0f);
--            lightprops[ll] = cimg::min(nfactor+ambiant_light,1.0f);
--          }
--        } else {
--          lightprops.assign(points.width,2);
--          cimg_forX(points,ll) {
--            const float
--              nx = points_normals(ll,0),
--              ny = points_normals(ll,1),
--              nz = points_normals(ll,2),
--              norm = (float)std::sqrt(1e-5f+nx*nx+ny*ny+nz*nz),
--              nnx = nx/norm, nny = ny/norm;
--            lightprops(ll,0) = (light_texture.width/2-1)*(1+nnx);
--            lightprops(ll,1) = (light_texture.height/2-1)*(1+nny);
--          }
--        }
--      } break;
--      }
--
--      // Draw visible primitives
--      const unsigned int opacsize = opacities.size;
--      { for (unsigned int l=0; l<nb_visibles; l++) {
--        const unsigned int n_primitive = visibles(permutations(l));
--        const CImg<tf>& primitive = primitives[n_primitive];
--        const CImg<T>& color = colors[n_primitive%colors.size];
--        const CImg<to>& opacity = opacities[n_primitive%opacsize];
--        const float opac = opacity.size()?(float)opacity(0):1.0f;
--
--        switch (primitive.size()) {
--        case 1: { // colored point or sprite
--          const unsigned int n0 = (unsigned int)primitive[0];
--          const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
--          if (color.size()==dim) draw_point(x0,y0,color.ptr(),opac);
--          else {
--            const float z = Z + points(n0,2);
--            const int factor = (int)(focale*100/(z+focale));
--            const int sw = color.width*factor/200, sh = color.height*factor/200;
--            if (x0+sw>=0 && x0-sw<(int)width && y0+sh>=0 && y0-sh<(int)height) {
--              const CImg<T> sprite = color.get_resize(-factor,-factor,1,-100,render_type<=3?1:3);
--              if (opacity.width==color.width && opacity.height==color.height)
--                draw_image(sprite,opacity.get_resize(sprite.width,sprite.height,1,sprite.dim,1),x0-sw,y0-sh,0,0);
--              else draw_image(sprite,x0-sw,y0-sh,0,0,opac);
--            }
--          }
--        } break;
--        case 2: { // colored line
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
--          if (render_type) draw_line(x0,y0,x1,y1,color.ptr(),~0L,opac);
--          else draw_point(x0,y0,color.ptr(),opac).draw_point(x1,y1,color.ptr(),opac);
--        } break;
--        case 6: { // textured line
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1],
--            tx0 = (unsigned int)primitive[2],
--            ty0 = (unsigned int)primitive[3],
--            tx1 = (unsigned int)primitive[4],
--            ty1 = (unsigned int)primitive[5];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
--          if (render_type) draw_line(x0,y0,x1,y1,color,tx0,ty0,tx1,ty1,opac);
--          else draw_point(x0,y0,color.get_vector_at(tx0,ty0).ptr(),opac).
--                 draw_point(x1,y1,color.get_vector_at(tx1,ty1).ptr(),opac);
--        } break;
--        case 3: { // colored triangle
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1],
--            n2 = (unsigned int)primitive[2];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
--            x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
--          switch(render_type) {
--          case 0:
--            draw_point(x0,y0,color.ptr(),opac).draw_point(x1,y1,color.ptr(),opac).draw_point(x2,y2,color.ptr(),opac);
--            break;
--          case 1:
--            draw_line(x0,y0,x1,y1,color.ptr(),~0L,opac).draw_line(x0,y0,x2,y2,color.ptr(),~0L,opac).
--              draw_line(x1,y1,x2,y2,color.ptr(),~0L,opac);
--            break;
--          case 2:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),opac);
--            break;
--          case 3:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),opac,lightprops(l));
--            break;
--          case 4:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),lightprops(n0),lightprops(n1),lightprops(n2),opac);
--            break;
--          case 5:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),light_texture,
--                          (unsigned int)lightprops(n0,0), (unsigned int)lightprops(n0,1),
--                          (unsigned int)lightprops(n1,0), (unsigned int)lightprops(n1,1),
--                          (unsigned int)lightprops(n2,0), (unsigned int)lightprops(n2,1),
--                          opac);
--            break;
--          }
--        } break;
--        case 4: { // colored rectangle
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1],
--            n2 = (unsigned int)primitive[2],
--            n3 = (unsigned int)primitive[3];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
--            x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
--            x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
--          switch(render_type) {
--          case 0:
--            draw_point(x0,y0,color.ptr(),opac).draw_point(x1,y1,color.ptr(),opac).
--              draw_point(x2,y2,color.ptr(),opac).draw_point(x3,y3,color.ptr(),opac);
--            break;
--          case 1:
--            draw_line(x0,y0,x1,y1,color.ptr(),~0L,opac).draw_line(x1,y1,x2,y2,color.ptr(),~0L,opac).
--              draw_line(x2,y2,x3,y3,color.ptr(),~0L,opac).draw_line(x3,y3,x0,y0,color.ptr(),~0L,opac);
--            break;
--          case 2:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),opac).draw_triangle(x0,y0,x2,y2,x3,y3,color.ptr(),opac);
--            break;
--          case 3:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),opac,lightprops(l)).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color.ptr(),opac,lightprops(l));
--            break;
--          case 4: {
--            const float
--              lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
--              lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),lightprop0,lightprop1,lightprop2,opac).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color.ptr(),lightprop0,lightprop2,lightprop3,opac);
--          } break;
--          case 5: {
--            const unsigned int
--              lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
--              lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
--              lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
--              lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
--            draw_triangle(x0,y0,x1,y1,x2,y2,color.ptr(),light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color.ptr(),light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
--          } break;
--          }
--        } break;
--        case 9: { // Textured triangle
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1],
--            n2 = (unsigned int)primitive[2],
--            tx0 = (unsigned int)primitive[3],
--            ty0 = (unsigned int)primitive[4],
--            tx1 = (unsigned int)primitive[5],
--            ty1 = (unsigned int)primitive[6],
--            tx2 = (unsigned int)primitive[7],
--            ty2 = (unsigned int)primitive[8];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
--            x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
--          switch(render_type) {
--          case 0:
--            draw_point(x0,y0,color.get_vector_at(tx0,ty0).ptr(),opac).
--              draw_point(x1,y1,color.get_vector_at(tx1,ty1).ptr(),opac).
--              draw_point(x2,y2,color.get_vector_at(tx2,ty2).ptr(),opac);
--            break;
--          case 1:
--            draw_line(x0,y0,x1,y1,color,tx0,ty0,tx1,ty1,opac).
--              draw_line(x0,y0,x2,y2,color,tx0,ty0,tx2,ty2,opac).
--              draw_line(x1,y1,x2,y2,color,tx1,ty1,tx2,ty2,opac);
--            break;
--          case 2:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac);
--            break;
--          case 3:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l));
--            break;
--          case 4:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprops(n0),lightprops(n1),lightprops(n2),opac);
--            break;
--          case 5:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,
--                          (unsigned int)lightprops(n0,0), (unsigned int)lightprops(n0,1),
--                          (unsigned int)lightprops(n1,0), (unsigned int)lightprops(n1,1),
--                          (unsigned int)lightprops(n2,0), (unsigned int)lightprops(n2,1),
--                          opac);
--            break;
--          }
--        } break;
--        case 12: { // Textured rectangle
--          const unsigned int
--            n0 = (unsigned int)primitive[0],
--            n1 = (unsigned int)primitive[1],
--            n2 = (unsigned int)primitive[2],
--            n3 = (unsigned int)primitive[3],
--            tx0 = (unsigned int)primitive[4],
--            ty0 = (unsigned int)primitive[5],
--            tx1 = (unsigned int)primitive[6],
--            ty1 = (unsigned int)primitive[7],
--            tx2 = (unsigned int)primitive[8],
--            ty2 = (unsigned int)primitive[9],
--            tx3 = (unsigned int)primitive[10],
--            ty3 = (unsigned int)primitive[11];
--          const int
--            x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
--            x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
--            x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
--            x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
--          switch(render_type) {
--          case 0:
--            draw_point(x0,y0,color.get_vector_at(tx0,ty0).ptr(),opac).
--              draw_point(x1,y1,color.get_vector_at(tx1,ty1).ptr(),opac).
--              draw_point(x2,y2,color.get_vector_at(tx2,ty2).ptr(),opac).
--              draw_point(x3,y3,color.get_vector_at(tx3,ty3).ptr(),opac);
--            break;
--          case 1:
--            draw_line(x0,y0,x1,y1,color,tx0,ty0,tx1,ty1,opac).
--              draw_line(x1,y1,x2,y2,color,tx1,ty1,tx2,ty2,opac).
--              draw_line(x2,y2,x3,y3,color,tx2,ty2,tx3,ty3,opac).
--              draw_line(x3,y3,x0,y0,color,tx3,ty3,tx0,ty0,opac);
--            break;
--          case 2:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac);
--            break;
--          case 3:
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l));
--            break;
--          case 4: {
--            const float
--              lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
--              lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac);
--          } break;
--          case 5: {
--            const unsigned int
--              lx0 = (unsigned int)lightprops(n0,0), ly0 = (unsigned int)lightprops(n0,1),
--              lx1 = (unsigned int)lightprops(n1,0), ly1 = (unsigned int)lightprops(n1,1),
--              lx2 = (unsigned int)lightprops(n2,0), ly2 = (unsigned int)lightprops(n2,1),
--              lx3 = (unsigned int)lightprops(n3,0), ly3 = (unsigned int)lightprops(n3,1);
--            draw_triangle(x0,y0,x1,y1,x2,y2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
--              draw_triangle(x0,y0,x2,y2,x3,y3,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
--          } break;
--          }
--        } break;
--      }
--      }
--      }
--      return *this;
--    }
--
--    //! Draw a 3D object in the instance image
--    template<typename tp, typename tf, typename to>
--    CImg& draw_object3d(const float X, const float Y, const float Z,
--                        const CImgList<tp>& points, const CImgList<tf>& primitives,
--                        const CImgList<T>& colors, const CImgList<to>& opacities,
--                        const unsigned int render_type=4,
--                        const bool double_sided=false, const float focale=500,
--                        const float lightx=0, const float lighty=0, const float lightz=-5000,
--                        const float ambiant_light = 0.05f) {
--      if (points.is_empty()) return *this;
--      CImg<tp> npoints(points.size,3,1,1,0);
--      tp *ptrX = npoints.ptr(), *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
--      cimg_forX(npoints,l) {
--        const CImg<tp>& point = points[l];
--        const unsigned int siz = point.size();
--        if (!siz)
--          throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
--                                      "position %u.",pixel_type(),points.size,l);
--        *(ptrZ++) = (siz>2)?point(2):0;
--        *(ptrY++) = (siz>1)?point(1):0;
--        *(ptrX++) = point(0);
--      }
--      return draw_object3d(X,Y,Z,npoints,primitives,colors,opacities,
--                           render_type,double_sided,focale,lightx,lighty,lightz,ambiant_light);
--    }
--
--    //! Draw a 3D object in the instance image
--      template<typename tp, typename tf, typename to>
--    CImg& draw_object3d(const float X, const float Y, const float Z,
--                        const CImg<tp>& points, const CImgList<tf>& primitives,
--                        const CImgList<T>& colors, const CImg<to>& opacities,
--                        const unsigned int render_type=4,
--                        const bool double_sided=false, const float focale=500,
--                        const float lightx=0, const float lighty=0, const float lightz=-5000,
--                        const float ambiant_light = 0.05f) {
--      CImgList<to> nopacities(opacities.size(),1);
--      cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
--      return draw_object3d(X,Y,Z,points,primitives,colors,nopacities,
--                           render_type,double_sided,focale,lightx,lighty,lightz,ambiant_light);
--    }
--
--    //! Draw a 3D object in the instance image
--    template<typename tp, typename tf, typename to>
--    CImg& draw_object3d(const float X, const float Y, const float Z,
--                        const CImgList<tp>& points, const CImgList<tf>& primitives,
--                        const CImgList<T>& colors, const CImg<to>& opacities,
--                        const unsigned int render_type=4,
--                        const bool double_sided=false, const float focale=500,
--                        const float lightx=0, const float lighty=0, const float lightz=-5000,
--                        const float ambiant_light = 0.05f) {
--      CImgList<to> nopacities(opacities.size(),1);
--      { cimglist_for(nopacities,l) nopacities(l,0) = opacities(l); }
--      if (points.is_empty()) return *this;
--      CImg<tp> npoints(points.size,3,1,1,0);
--      tp *ptrX = npoints.ptr(), *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
--      cimg_forX(npoints,l) {
--        const CImg<tp>& point = points[l];
--        const unsigned int siz = point.size();
--        if (!siz)
--          throw CImgArgumentException("CImg<%s>::draw_object3d() : Given points (size=%u) contains a null element at "
--                                      "position %u.",pixel_type(),points.size,l);
--        *(ptrZ++) = (siz>2)?point(2):0;
--        *(ptrY++) = (siz>1)?point(1):0;
--        *(ptrX++) = point(0);
--      }
--      return draw_object3d(X,Y,Z,npoints,primitives,colors,nopacities,
--                           render_type,double_sided,focale,lightx,lighty,lightz,ambiant_light);
--    }
--
--   //! Draw a 3D object in the instance image
--    template<typename tp, typename tf>
--    CImg& draw_object3d(const float X, const float Y, const float Z,
--                        const tp& points, const CImgList<tf>& primitives,
--                        const CImgList<T>& colors,
--                        const unsigned int render_type=4,
--                        const bool double_sided=false, const float focale=500,
--                        const float lightx=0, const float lighty=0, const float lightz=-5000,
--                        const float ambiant_light = 0.05f, const float opacity=1.0f) {
--      return draw_object3d(X,Y,Z,points,primitives,colors,
--                           CImg<float>(primitives.size,1,1,1,opacity),
--                           render_type,double_sided,focale,lightx,lighty,lightz,
--                           ambiant_light);
--    }
--
--    //! Rescale and center a 3D object
--    CImg& resize_object3d(const float siz=100, const bool centering=true) {
--      T *ptrx = ptr(0,0), *ptry = ptr(0,1), *ptrz = ptr(0,2);
--      float xm = (float)*(ptrx++), ym = (float)*(ptry++), zm = (float)*(ptrz++), xM = xm, yM = ym, zM = zm;
--      for (unsigned int p=1; p<width; p++) {
--         const float x = (float)*(ptrx++), y = (float)*(ptry++), z = (float)*(ptrz++);
--         if (x<xm) xm = x;
--         if (y<ym) ym = y;
--         if (z<zm) zm = z;
--         if (x>xM) xM = x;
--         if (y>yM) yM = y;
--         if (z>zM) zM = z;
--      }
--      const float
--        cx = 0.5f*(xm+xM),
--        cy = 0.5f*(ym+yM),
--        cz = 0.5f*(zm+zM),
--        delta = cimg::max(xM-xm,yM-ym,zM-zm),
--        ratio = (siz>=0)?(delta<=0?0:(siz/delta)):-siz/100;
--      ptrx = ptr(0,0);
--      ptry = ptr(0,1);
--      ptrz = ptr(0,2);
--      if (centering) cimg_forX(*this,l) {
--        T &x = *(ptrx++), &y = *(ptry++), &z = *(ptrz++);
--        x = (T)((x-cx)*ratio);
--        y = (T)((y-cy)*ratio);
--        z = (T)((z-cz)*ratio);
--      } else cimg_forX(*this,l) {
--        T &x = *(ptrx++), &y = *(ptry++), &z = *(ptrz++);
--        x = (T)(cx+(x-cx)*ratio);
--        y = (T)(cy+(y-cy)*ratio);
--        z = (T)(cz+(z-cz)*ratio);
--      }
--      return *this;
--    }
--
--    //! Get a rescaled and centered version of the 3D object
--    CImg get_resize_object3d(const float siz=100, const bool centering=true) const {
--      return CImg<T>(*this,false).resize_object3d(siz,centering);
--    }
--
--    //@}
--    //----------------------------
--    //
--    //! \name Image Filtering
--    //@{
--    //----------------------------
--
--    //! Return the correlation of the image by a mask.
--    /**
--       The result \p res of the correlation of an image \p img by a mask \p mask is defined to be :
--
--       res(x,y,z) = sum_{i,j,k} img(x+i,y+j,z+k)*mask(i,j,k)
--
--       \param mask = the correlation kernel.
--       \param cond = the border condition type (0=zero, 1=dirichlet)
--       \param weighted_correl = enable local normalization.
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type>
--    get_correlate(const CImg<t>& mask,const unsigned int cond=1,const bool weighted_correl=false) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      typedef typename cimg::largest<t,float>::type fftype;
--      typedef typename cimg::largest<T,fftype>::type ftype;
--
--      if (is_empty()) return CImg<restype>();
--      if (mask.is_empty() || mask.dim!=1)
--        throw CImgArgumentException("CImg<%s>::get_correlate() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
--                                    pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
--      CImg<restype> dest(width,height,depth,dim);
--      if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) {
--        // A special optimization is done for 2x2,3x3,4x4,5x5,2x2x2 and 3x3x3 mask (with cond=1)
--        switch (mask.depth) {
--        case 3: {
--          CImg_3x3x3(I,T);
--          if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr3x3x3(I,mask);
--          else cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) {
--            const double norm = (double)cimg_squaresum3x3x3(I);
--            dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr3x3x3(I,mask)/std::sqrt(norm)):0;
--          }
--        } break;
--        case 2: {
--          CImg_2x2x2(I,T);
--          if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr2x2x2(I,mask);
--          else cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) {
--            const double norm = (double)cimg_squaresum2x2x2(I);
--            dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr2x2x2(I,mask)/std::sqrt(norm)):0;
--          }
--        } break;
--        default:
--        case 1:
--          switch (mask.width) {
--          case 5: {
--            CImg_5x5(I,T);
--            if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr5x5(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum5x5(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr5x5(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 4: {
--            CImg_4x4(I,T);
--            if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr4x4(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum4x4(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr4x4(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 3: {
--            CImg_3x3(I,T);
--            if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr3x3(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum3x3(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr3x3(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 2: {
--            CImg_2x2(I,T);
--            if (!weighted_correl) cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_corr2x2(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum2x2(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_corr2x2(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 1: dest = mask(0)*(*this); break;
--          }
--        }
--      } else {
--        // Generic version for other masks
--        const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2, fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
--        cimg_forV(*this,v)
--          if (!weighted_correl) {       // Classical correlation
--            for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--              ftype val = 0;
--              for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                val+= (*this)(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
--              dest(x,y,z,v)=(restype)val;
--            }
--            if (cond) cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                  val+= pix3d(x+xm,y+ym,z+zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
--                dest(x,y,z,v)=(restype)val;
--              }
--            else cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++)  for (int xm=-cxm; xm<=fxm; xm++)
--                  val+= pix3d(x+xm,y+ym,z+zm,v,0)*mask(cxm+xm,cym+ym,czm+zm,0);
--                dest(x,y,z,v)=(restype)val;
--              }
--          } else {      // Weighted correlation
--            for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--              ftype val = 0, norm = 0;
--              for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++) {
--                const T cval = (*this)(x+xm,y+ym,z+zm,v);
--                val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                norm+= cval*cval;
--              }
--              dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt((double)norm)):0;
--            }
--            if (cond) cimg_forYZV(*this,y,z,v)
--             for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0, norm = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++) {
--                  const T cval = pix3d(x+xm,y+ym,z+zm,v);
--                  val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                  norm+=cval*cval;
--                }
--                dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt((double)norm)):0;
--              }
--            else cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0, norm = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++) {
--                  const T cval = pix3d(x+xm,y+ym,z+zm,v,0);
--                  val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                  norm+= cval*cval;
--                }
--                dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt((double)norm)):0;
--              }
--          }
--      }
--      return dest;
--    }
--
--
--    //! Correlate the image by a mask
--    /**
--       This is the in-place version of get_correlate.
--       \see get_correlate
--    **/
--    template<typename t> CImg& correlate(const CImg<t>& mask,const unsigned int cond=1,const bool weighted_correl=false) {
--      return get_correlate(mask,cond,weighted_correl).swap(*this);
--    }
--
--    //! Return the convolution of the image by a mask
--    /**
--       The result \p res of the convolution of an image \p img by a mask \p mask is defined to be :
--
--       res(x,y,z) = sum_{i,j,k} img(x-i,y-j,z-k)*mask(i,j,k)
--
--       \param mask = the correlation kernel.
--       \param cond = the border condition type (0=zero, 1=dirichlet)
--       \param weighted_convol = enable local normalization.
--    **/
--    template<typename t> CImg<typename cimg::largest<T,t>::type>
--    get_convolve(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_convol=false) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      typedef typename cimg::largest<t,float>::type fftype;
--      typedef typename cimg::largest<T,fftype>::type ftype;
--
--      if (is_empty()) return CImg<restype>();
--      if (mask.is_empty() || mask.dim!=1)
--        throw CImgArgumentException("CImg<%s>::get_convolve() : Specified mask (%u,%u,%u,%u,%p) is not scalar.",
--                                    pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
--      CImg<restype> dest(width,height,depth,dim);
--      if (cond && mask.width==mask.height && ((mask.depth==1 && mask.width<=5) || (mask.depth==mask.width && mask.width<=3))) { // optimized version
--        switch (mask.depth) {
--        case 3: {
--          CImg_3x3x3(I,T);
--          if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_conv3x3x3(I,mask);
--          else cimg_forZV(*this,z,v) cimg_for3x3x3(*this,x,y,z,v,I) {
--            const double norm = (double)cimg_squaresum3x3x3(I);
--            dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv3x3x3(I,mask)/std::sqrt(norm)):0;
--          }
--        } break;
--        case 2: {
--          CImg_2x2x2(I,T);
--          if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_conv2x2x2(I,mask);
--          else cimg_forZV(*this,z,v) cimg_for2x2x2(*this,x,y,z,v,I) {
--            const double norm = (double)cimg_squaresum2x2x2(I);
--            dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv2x2x2(I,mask)/std::sqrt(norm)):0;
--          }
--        } break;
--        default:
--        case 1:
--          switch (mask.width) {
--          case 5: {
--            CImg_5x5(I,T);
--            if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) dest(x,y,z,v) = cimg_conv5x5(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for5x5(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum5x5(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv5x5(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 4: {
--            CImg_4x4(I,T);
--            if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) dest(x,y,z,v) = (T)cimg_conv4x4(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for4x4(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum4x4(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv4x4(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 3: {
--            CImg_3x3(I,T);
--            if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) dest(x,y,z,v) = (T)cimg_conv3x3(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for3x3(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum3x3(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv3x3(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 2: {
--            CImg_2x2(I,T);
--            if (!weighted_convol) cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) dest(x,y,z,v) = (T)cimg_conv2x2(I,mask);
--            else cimg_forZV(*this,z,v) cimg_for2x2(*this,x,y,z,v,I) {
--              const double norm = (double)cimg_squaresum2x2(I);
--              dest(x,y,z,v) = (norm!=0)?(restype)(cimg_conv2x2(I,mask)/std::sqrt(norm)):0;
--            }
--          } break;
--          case 1: dest = mask(0)*(*this); break;
--          }
--        }
--      } else { // generic version
--
--        const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2, fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
--        cimg_forV(*this,v)
--          if (!weighted_convol) {       // Classical convolution
--            for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--              ftype val = 0;
--              for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                val+= (*this)(x-xm,y-ym,z-zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
--              dest(x,y,z,v)=(restype)val;
--            }
--            if (cond) cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                  val+= pix3d(x-xm,y-ym,z-zm,v)*mask(cxm+xm,cym+ym,czm+zm,0);
--                dest(x,y,z,v)=(restype)val;
--              }
--            else cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++)  for (int xm=-cxm; xm<=fxm; xm++)
--                  val+= pix3d(x-xm,y-ym,z-zm,v,0)*mask(cxm+xm,cym+ym,czm+zm,0);
--                dest(x,y,z,v)=(restype)val;
--              }
--          } else {      // Weighted convolution
--            for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--              ftype val = 0, norm = 0;
--              for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++) {
--                const T cval = (*this)(x-xm,y-ym,z-zm,v);
--                val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                norm+= cval*cval;
--              }
--              dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt(norm)):0;
--            }
--            if (cond) cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                ftype val = 0, norm = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++) {
--                  const T cval = pix3d(x-xm,y-ym,z-zm,v);
--                  val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                  norm+=cval*cval;
--                }
--                dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt(norm)):0;
--              }
--            else cimg_forYZV(*this,y,z,v)
--              for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                double val = 0, norm = 0;
--                for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++)  for (int xm=-cxm; xm<=fxm; xm++) {
--                  const T cval = pix3d(x-xm,y-ym,z-zm,v,0);
--                  val+= cval*mask(cxm+xm,cym+ym,czm+zm,0);
--                  norm+= cval*cval;
--                }
--                dest(x,y,z,v)=(norm!=0)?(restype)(val/std::sqrt(norm)):0;
--              }
--          }
--      }
--      return dest;
--    }
--
--    //! Convolve the image by a mask
--    /**
--       This is the in-place version of get_convolve().
--       \see get_convolve()
--    **/
--    template<typename t> CImg& convolve(const CImg<t>& mask,const unsigned int cond=1,const bool weighted_convol=false) {
--      return get_convolve(mask,cond,weighted_convol).swap(*this);
--    }
--
--    //! Return the erosion of the image by a structuring element.
--    template<typename t> CImg<typename cimg::largest<T,t>::type>
--    get_erode(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_erosion=false) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      if (is_empty()) return CImg<restype>();
--      if (mask.is_empty() || mask.dim!=1)
--        throw CImgArgumentException("CImg<%s>::get_erosion() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
--                                    pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
--      CImg<restype> dest(width,height,depth,dim);
--      const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
--        fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
--      cimg_forV(*this,v)
--        if (!weighted_erosion) {        // Classical erosion
--          for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--            restype min_val = cimg::type<restype>::max();
--            for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--              if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)(*this)(x+xm,y+ym,z+zm,v),min_val);
--            dest(x,y,z,v)=min_val;
--          }
--          if (cond) cimg_forYZV(*this,y,z,v)
--                      for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                        restype min_val = cimg::type<restype>::max();
--                        for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                          if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)pix3d(x+xm,y+ym,z+zm,v),min_val);
--                        dest(x,y,z,v)=min_val;
--                      }
--          else cimg_forYZV(*this,y,z,v)
--                 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                   restype min_val = cimg::type<restype>::max();
--                   for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                     if (mask(cxm+xm,cym+ym,czm+zm,0)) min_val = cimg::min((restype)pix3d(x+xm,y+ym,z+zm,v,0),min_val);
--                   dest(x,y,z,v)=min_val;
--                 }
--        } else { // Weighted erosion
--          t mval=0;
--          for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--            restype min_val = cimg::type<restype>::max();
--            for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--              if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)((*this)(x+xm,y+ym,z+zm,v)+mval),min_val);
--            dest(x,y,z,v)=min_val;
--          }
--          if (cond) cimg_forYZV(*this,y,z,v)
--                      for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                        restype min_val = cimg::type<restype>::max();
--                        for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                          if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)(pix3d(x+xm,y+ym,z+zm,v)+mval),min_val);
--                        dest(x,y,z,v)=min_val;
--                      }
--          else cimg_forYZV(*this,y,z,v)
--                 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                   restype min_val = cimg::type<restype>::max();
--                   for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                     if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) min_val = cimg::min((restype)(pix3d(x+xm,y+ym,z+zm,v,0)+mval),min_val);
--                   dest(x,y,z,v)=min_val;
--                 }
--        }
--      return dest;
--    }
--
--    //! Erode the image by a structuring element
--    /**
--       This is the in-place version of get_erode().
--       \see get_erode()
--    **/
--    template<typename t> CImg& erode(const CImg<t>& mask,const unsigned int cond=1,const bool weighted_erosion=false) {
--      return get_erode(mask,cond,weighted_erosion).swap(*this);
--    }
--
--    //! Erode the image by a square structuring element of size n
--    CImg get_erode(const unsigned int n, const unsigned int cond=1) const {
--      static CImg<T> mask;
--      if (mask.width!=n) mask.assign(n,n,1,1,1);
--      const CImg<T> res = get_erode(mask,cond,false);
--      if (n>20) mask.assign();
--      return res;
--    }
--
--    //! Erode the image by a square structuring element of size n
--    CImg& erode(const unsigned int n, const unsigned int cond=1) {
--      return get_erode(n,cond).swap(*this);
--    }
--
--    //! Return the dilatation of the image by a structuring element.
--    template<typename t> CImg<typename cimg::largest<T,t>::type>
--    get_dilate(const CImg<t>& mask, const unsigned int cond=1, const bool weighted_dilatation=false) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      if (is_empty()) return CImg<restype>();
--      if (mask.is_empty() || mask.dim!=1)
--        throw CImgArgumentException("CImg<%s>::get_dilate() : Specified mask (%u,%u,%u,%u,%p) is not a scalar image.",
--                                    pixel_type(),mask.width,mask.height,mask.depth,mask.dim,mask.data);
--      CImg<restype> dest(width,height,depth,dim);
--      const int cxm=mask.width/2, cym=mask.height/2, czm=mask.depth/2,
--        fxm=cxm-1+(mask.width%2), fym=cym-1+(mask.height%2), fzm=czm-1+(mask.depth%2);
--      cimg_forV(*this,v)
--        if (!weighted_dilatation) { // Classical dilatation
--          for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--            restype max_val = cimg::type<restype>::min();
--            for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--              if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)(*this)(x+xm,y+ym,z+zm,v),max_val);
--            dest(x,y,z,v)=max_val;
--          }
--          if (cond) cimg_forYZV(*this,y,z,v)
--                      for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                        restype max_val = cimg::type<restype>::min();
--                        for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                          if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)pix3d(x+xm,y+ym,z+zm,v),max_val);
--                        dest(x,y,z,v)=max_val;
--                      }
--          else cimg_forYZV(*this,y,z,v)
--                 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                   restype max_val = cimg::type<restype>::min();
--                   for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                     if (mask(cxm+xm,cym+ym,czm+zm,0)) max_val = cimg::max((restype)pix3d(x+xm,y+ym,z+zm,v,0),max_val);
--                   dest(x,y,z,v)=max_val;
--                 }
--        } else { // Weighted dilatation
--          t mval=0;
--          for (int z=czm; z<dimz()-czm; z++) for (int y=cym; y<dimy()-cym; y++) for (int x=cxm; x<dimx()-cxm; x++) {
--            restype max_val = cimg::type<restype>::min();
--            for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--              if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)((*this)(x+xm,y+ym,z+zm,v)-mval),max_val);
--            dest(x,y,z,v)=max_val;
--          }
--          if (cond) cimg_forYZV(*this,y,z,v)
--                      for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                        restype max_val = cimg::type<restype>::min();
--                        for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                          if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)(pix3d(x+xm,y+ym,z+zm,v)-mval),max_val);
--                        dest(x,y,z,v)=max_val;
--                      }
--          else cimg_forYZV(*this,y,z,v)
--                 for (int x=0; x<dimx(); (y<cym || y>=dimy()-cym || z<czm || z>=dimz()-czm)?x++:((x<cxm-1 || x>=dimx()-cxm)?x++:(x=dimx()-cxm))) {
--                   restype max_val = cimg::type<restype>::min();
--                   for (int zm=-czm; zm<=fzm; zm++) for (int ym=-cym; ym<=fym; ym++) for (int xm=-cxm; xm<=fxm; xm++)
--                     if ((mval=mask(cxm+xm,cym+ym,czm+zm,0))!=0) max_val = cimg::max((restype)(pix3d(x+xm,y+ym,z+zm,v,0)-mval),max_val);
--                   dest(x,y,z,v)=max_val;
--                 }
--        }
--      return dest;
--    }
--
--    //! Dilate the image by a structuring element
--    /**
--       This is the in-place version of get_dilate().
--       \see get_dilate()
--    **/
--    template<typename t> CImg& dilate(const CImg<t>& mask,const unsigned int cond=1,const bool weighted_dilatation=false) {
--      return get_dilate(mask,cond,weighted_dilatation).swap(*this);
--    }
--
--    //! Dilate the image by a square structuring element of size n
--    CImg get_dilate(const unsigned int n, const unsigned int cond=1) const {
--      static CImg<T> mask;
--      if (mask.width!=n) mask.assign(n,n,1,1,1);
--      const CImg<T> res = get_dilate(mask,cond,false);
--      if (n>20) mask.assign();
--      return res;
--    }
--
--    //! Dilate the image by a square structuring element of size n
--    CImg& dilate(const unsigned int n, const unsigned int cond=1) {
--      return get_dilate(n,cond).swap(*this);
--    }
--
--    //! Add noise to the image
--    /**
--       This is the in-place version of get_noise.
--       \see get_noise.
--    **/
--    CImg& noise(const double sigma=-20, const unsigned int ntype=0) {
--      if (!is_empty()) {
--        double nsigma = sigma, max = (double)cimg::type<T>::max(), min = (double)cimg::type<T>::min();
--        static bool first_time = true;
--        if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--        CImgStats st;
--        if (nsigma==0) return *this;
--        if (nsigma<0 || ntype==2) st = CImgStats(*this,false);
--        if (nsigma<0) nsigma = -nsigma*(st.max-st.min)/100.0;
--        switch (ntype) {
--        case 0: { // Gaussian noise
--          cimg_for(*this,ptr,T) {
--            double val = *ptr+nsigma*cimg::grand();
--            if (val>max) val = max;
--            if (val<min) val = min;
--            *ptr = (T)val;
--          }
--        } break;
--        case 1: { // Uniform noise
--          cimg_for(*this,ptr,T) {
--            double val = *ptr+nsigma*cimg::crand();
--            if (val>max) val = max;
--            if (val<min) val = min;
--            *ptr = (T)val;
--          }
--        } break;
--        case 2: { // Salt & Pepper noise
--          if (st.max==st.min) { st.min=0; st.max=255; }
--          cimg_for(*this,ptr,T) if (cimg::rand()*100<nsigma) *ptr=(T)(cimg::rand()<0.5?st.max:st.min);
--        } break;
--        case 3: { // Poisson Noise
--          cimg_for(*this,ptr,T) {
--            const double z = (double)*ptr;
--            if (z<=1.0e-10) *ptr=(T)0;
--            else {
--              if (z>100.0) *ptr = (T)(unsigned int)((std::sqrt(z) * cimg::grand()) + z);
--              else {
--                unsigned int k = 0;
--                const double y=std::exp(-z);
--                for (double s=1.0; s>=y; k++) s *= cimg::rand();
--                *ptr=(T)(k-1);
--              }
--            }
--          }
--        } break;
--        case 4: { // Rice noise
--          const double sqrt2 = (double)std::sqrt(2.0);
--          cimg_for(*this,ptr,T) {
--            const double
--              val0 = (double)*ptr/sqrt2,
--              re = val0 + nsigma*cimg::grand(),
--              im = val0 + nsigma*cimg::grand();
--            double val = std::sqrt(re*re + im*im);
--            if (val>max) val = max;
--            if (val<min) val = min;
--            *ptr = (T)val;
--          }
--        } break;
--        }
--      }
--      return *this;
--    }
--
--    //! Return a noisy image
--    /**
--       \param sigma = power of the noise. if sigma<0, it corresponds to the percentage of the maximum image value.
--       \param ntype = noise type. can be 0=gaussian, 1=uniform or 2=Salt and Pepper.
--       \return A noisy version of the instance image.
--    **/
--    CImg get_noise(const double sigma=-20,const unsigned int ntype=0) const {
--      return (+*this).noise(sigma,ntype);
--    }
--
--#define cimg_deriche_apply(x0,y0,z0,k0,nb,offset,T) { \
--    ima = ptr(x0,y0,z0,k0); \
--    I2 = *ima; ima+=offset; I1 = *ima; ima+=offset; \
--    Y2 = *(Y++) = sumg0*I2; Y1 = *(Y++) = g0*I1 + sumg1*I2; \
--    for (i=2; i<(nb); i++) { I1 = *ima; ima+=offset; \
--        Y0 = *(Y++) = a1*I1 + a2*I2 + b1*Y1 + b2*Y2; \
--        I2=I1; Y2=Y1; Y1=Y0; } \
--    ima-=offset; I2 = *ima; Y2 = Y1 = parity*sumg1*I2; *ima = (T)(*(--Y)+Y2); \
--    ima-=offset; I1 = *ima; *ima = (T)(*(--Y)+Y1); \
--    for (i=(nb)-3; i>=0; i--) { Y0=a3*I1+a4*I2+b1*Y1+b2*Y2; ima-=offset; \
--      I2=I1; I1=*ima; *ima=(T)(*(--Y)+Y0); Y2=Y1; Y1=Y0; } \
--  }
--
--    //! Apply a deriche filter on the image
--    /**
--       This is the in-place version of get_deriche
--       \see get_deriche.
--    **/
--    CImg& deriche(const float sigma=1,const int order=0,const char axe='x',const unsigned int cond=1) {
--      if (!is_empty()) {
--        if (sigma<0 || order<0 || order>2)
--          throw CImgArgumentException("CImg<%s>::deriche() : Bad arguments (sigma=%g, order=%d)",pixel_type(),sigma,order);
--        const float alpha=sigma>0?(1.695f/sigma):20,ea=(float)std::exp(alpha),ema=(float)std::exp(-alpha),em2a=ema*ema,b1=2*ema,b2=-em2a;
--        float ek,ekn,parity,a1,a2,a3,a4,g0,sumg1,sumg0;
--        double *Y,Y0,Y1,Y2;
--        int i,offset,nb;
--        T *ima,I1,I2;
--        switch(order) {
--        case 1:                 // first derivative
--          ek = -(1-ema)*(1-ema)*(1-ema)/(2*(ema+1)*ema); a1 = a4 = 0;  a2 = ek*ema; a3 = -ek*ema; parity =-1;
--          if (cond) { sumg1 = (ek*ea) / ((ea-1)*(ea-1)); g0 = 0; sumg0 = g0+sumg1; }
--          else g0 = sumg0 = sumg1 = 0;
--          break;
--        case 2:               // second derivative
--          ekn = ( -2*(-1+3*ea-3*ea*ea+ea*ea*ea)/(3*ea+1+3*ea*ea+ea*ea*ea) );
--          ek = -(em2a-1)/(2*alpha*ema); a1 = ekn;  a2 = -ekn*(1+ek*alpha)*ema; a3 = ekn*(1-ek*alpha)*ema; a4 = -ekn*em2a; parity =1;
--          if (cond) { sumg1 = ekn/2; g0 = ekn; sumg0 = g0+sumg1; }
--          else g0=sumg0=sumg1=0;
--          break;
--        default:              // smoothing
--          ek = (1-ema)*(1-ema) / (1+2*alpha*ema - em2a); a1 = ek;  a2 = ek*ema*(alpha-1); a3 = ek*ema*(alpha+1); a4 = -ek*em2a; parity = 1;
--          if (cond) { sumg1 = ek*(alpha*ea+ea-1) / ((ea-1)*(ea-1)); g0 = ek; sumg0 = g0+sumg1; }
--          else  g0=sumg0=sumg1=0;
--          break;
--        }
--        // filter init
--        Y = new double[cimg::max(width,height,depth)];
--        switch(cimg::uncase(axe)) {
--        case 'x': if (width>1)  { offset = 1;            nb = width;  cimg_forYZV(*this,y,z,k) cimg_deriche_apply(0,y,z,k,nb,offset,T); }       break;
--        case 'y': if (height>1) { offset = width;        nb = height; cimg_forXZV(*this,x,z,k) cimg_deriche_apply(x,0,z,k,nb,offset,T); }       break;
--        case 'z': if (depth>1)  { offset = width*height; nb = depth;  cimg_forXYV(*this,x,y,k) cimg_deriche_apply(x,y,0,k,nb,offset,T); }       break;
--        default: throw CImgArgumentException("CImg<%s>::deriche() : unknow axe '%c', must be 'x','y' or 'z'",pixel_type(),axe);
--        }
--        delete[] Y;
--      }
--      return *this;
--    }
--
--    //! Return the result of the Deriche filter
--    /**
--       The Canny-Deriche filter is a recursive algorithm allowing to compute blurred derivatives of
--       order 0,1 or 2 of an image.
--       \see blur
--    **/
--    CImg get_deriche(const float sigma=1,const int order=0,const char axe='x',const unsigned int cond=1) const {
--      return (+*this).deriche(sigma,order,axe,cond);
--    }
--
--    //! Blur the image with a Deriche filter (anisotropically)
--    /**
--       This is the in-place version of get_blur().
--       \see get_blur().
--    **/
--    CImg& blur(const float sigmax,const float sigmay,const float sigmaz,const unsigned int cond=1) {
--      if (!is_empty()) {
--        if (width>1  && sigmax>0) deriche(sigmax,0,'x',cond);
--        if (height>1 && sigmay>0) deriche(sigmay,0,'y',cond);
--        if (depth>1  && sigmaz>0) deriche(sigmaz,0,'z',cond);
--      }
--      return *this;
--    }
--
--    //! Blur the image with a Canny-Deriche filter.
--    /** This is the in-place version of get_blur(). **/
--    CImg& blur(const float sigma,const unsigned int cond=1) { return blur(sigma,sigma,sigma,cond); }
--
--    //! Return a blurred version of the image, using a Canny-Deriche filter.
--    /**
--       Blur the image with an anisotropic exponential filter (Deriche filter of order 0).
--    **/
--    CImg get_blur(const float sigmax,const float sigmay,const float sigmaz,const unsigned int cond=1) const {
--      return (+*this).blur(sigmax,sigmay,sigmaz,cond);
--    }
--
--    //! Return a blurred version of the image, using a Canny-Deriche filter.
--    CImg get_blur(const float sigma,const unsigned int cond=1) const {
--      return (+*this).blur(sigma,cond);
--    }
--
--    //! Blur an image following a field of diffusion tensors.
--    /** This is the in-place version of get_blur_anisotropic(). **/
--    template<typename t>
--    CImg& blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f,const float da=30.0f,
--                           const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) {
--#define cimg_valign2d(i,j) \
--    { ftype &u = W(i,j,0,0), &v = W(i,j,0,1); \
--    if (u*curru + v*currv<0) { u=-u; v=-v; }}
--#define cimg_valign3d(i,j,k) \
--    { ftype &u = W(i,j,k,0), &v = W(i,j,k,1), &w = W(i,j,k,2); \
--    if (u*curru + v*currv + w*currw<0) { u=-u; v=-v; w=-w; }}
--
--      // Check arguments and init variables
--      typedef typename cimg::largest<T,float>::type ftype;
--      if (!is_empty() && amplitude>0) {
--        if (G.is_empty() || (G.dim!=3 && G.dim!=6) || G.width!=width || G.height!=height || G.depth!=depth)
--          throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Specified tensor field (%u,%u,%u,%u) is not valid.",
--                                      pixel_type(),G.width,G.height,G.depth,G.dim);
--
--        const float sqrt2amplitude = (float)std::sqrt(2*amplitude);
--        const bool threed = (G.dim>=6);
--        const int
--          dx1 = dimx()-1,
--          dy1 = dimy()-1,
--          dz1 = dimz()-1;
--        CImg<ftype>
--          dest(width,height,depth,dim,0),
--          W(width,height,depth,threed?4:3),
--          tmp(dim);
--        int N = 0;
--
--        if (threed)
--          // 3D version of the algorithm
--          for (float phi=(180%(int)da)/2.0f; phi<=180; phi+=da) {
--            const float
--              phir = (float)(phi*cimg::PI/180),
--              datmp = (float)(da/std::cos(phir)),
--              da2 = datmp<1?360.0f:datmp;
--
--            for (float theta=0; theta<360; (theta+=da2),N++) {
--              const float
--                thetar = (float)(theta*cimg::PI/180),
--                vx = (float)(std::cos(thetar)*std::cos(phir)),
--                vy = (float)(std::sin(thetar)*std::cos(phir)),
--                vz = (float)std::sin(phir);
--              const t
--                *pa = G.ptr(0,0,0,0),
--                *pb = G.ptr(0,0,0,1),
--                *pc = G.ptr(0,0,0,2),
--                *pd = G.ptr(0,0,0,3),
--                *pe = G.ptr(0,0,0,4),
--                *pf = G.ptr(0,0,0,5);
--              ftype
--                *pd0 = W.ptr(0,0,0,0),
--                *pd1 = W.ptr(0,0,0,1),
--                *pd2 = W.ptr(0,0,0,2),
--                *pd3 = W.ptr(0,0,0,3);
--              cimg_forXYZ(G,xg,yg,zg) {
--                const t
--                  a = *(pa++), b = *(pb++), c = *(pc++),
--                  d = *(pd++), e = *(pe++), f = *(pf++);
--                const float
--                  u = (float)(a*vx + b*vy + c*vz),
--                  v = (float)(b*vx + d*vy + e*vz),
--                  w = (float)(c*vx + e*vy + f*vz),
--                  n = (float)std::sqrt(1e-5+u*u+v*v+w*w),
--                  dln = dl/n;
--                *(pd0++) = (ftype)(u*dln);
--                *(pd1++) = (ftype)(v*dln);
--                *(pd2++) = (ftype)(w*dln);
--                *(pd3++) = (ftype)n;
--              }
--
--              cimg_forXYZ(*this,x,y,z) {
--                tmp.fill(0);
--                const float
--                  cu = (float)W(x,y,z,0),
--                  cv = (float)W(x,y,z,1),
--                  cw = (float)W(x,y,z,2),
--                  n  = (float)W(x,y,z,3),
--                  fsigma = (float)(n*sqrt2amplitude),
--                  length = gauss_prec*fsigma,
--                  fsigma2 = 2*fsigma*fsigma;
--                float
--                  S = 0,
--                  pu = cu,
--                  pv = cv,
--                  pw = cw,
--                  X = (float)x,
--                  Y = (float)y,
--                  Z = (float)z;
--
--                switch (interpolation) {
--                case 0:
--                  // Nearest neighbor
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
--                    const int
--                      cx = (int)(X+0.5f),
--                      cy = (int)(Y+0.5f),
--                      cz = (int)(Z+0.5f);
--                    float
--                      u = (float)W(cx,cy,cz,0),
--                      v = (float)W(cx,cy,cz,1),
--                      w = (float)W(cx,cy,cz,2);
--                    if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,cz,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,cz,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
--                  } break;
--
--                case 1:
--                  // Linear interpolation
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
--                    const int
--                      cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
--                      cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
--                      cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
--                    const float
--                      curru = (float)W(cx,cy,cz,0),
--                      currv = (float)W(cx,cy,cz,1),
--                      currw = (float)W(cx,cy,cz,2);
--                    cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
--                    cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
--                    cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
--                    cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
--                    cimg_valign3d(px,cy,cz);                          cimg_valign3d(nx,cy,cz);
--                    cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
--                    cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
--                    cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
--                    cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
--                    float
--                      u = (float)(W.linear_pix3d(X,Y,Z,0)),
--                      v = (float)(W.linear_pix3d(X,Y,Z,1)),
--                      w = (float)(W.linear_pix3d(X,Y,Z,2));
--                    if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
--                  } break;
--
--                default:
--                  // 2nd order Runge Kutta
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
--                    const int
--                      cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
--                      cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1,
--                      cz = (int)Z, pz = (cz-1<0)?0:cz-1, nz = (cz+1>dz1)?dz1:cz+1;
--                    const float
--                      curru = (float)W(cx,cy,cz,0),
--                      currv = (float)W(cx,cy,cz,1),
--                      currw = (float)W(cx,cy,cz,2);
--                    cimg_valign3d(px,py,pz); cimg_valign3d(cx,py,pz); cimg_valign3d(nx,py,pz);
--                    cimg_valign3d(px,cy,pz); cimg_valign3d(cx,cy,pz); cimg_valign3d(nx,cy,pz);
--                    cimg_valign3d(px,ny,pz); cimg_valign3d(cx,ny,pz); cimg_valign3d(nx,ny,pz);
--                    cimg_valign3d(px,py,cz); cimg_valign3d(cx,py,cz); cimg_valign3d(nx,py,cz);
--                    cimg_valign3d(px,cy,cz);                          cimg_valign3d(nx,cy,cz);
--                    cimg_valign3d(px,ny,cz); cimg_valign3d(cx,ny,cz); cimg_valign3d(nx,ny,cz);
--                    cimg_valign3d(px,py,nz); cimg_valign3d(cx,py,nz); cimg_valign3d(nx,py,nz);
--                    cimg_valign3d(px,cy,nz); cimg_valign3d(cx,cy,nz); cimg_valign3d(nx,cy,nz);
--                    cimg_valign3d(px,ny,nz); cimg_valign3d(cx,ny,nz); cimg_valign3d(nx,ny,nz);
--                    const float
--                      u0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,0)),
--                      v0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,1)),
--                      w0 = (float)(0.5f*W.linear_pix3d(X,Y,Z,2));
--                    float
--                      u = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,0)),
--                      v = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,1)),
--                      w = (float)(W.linear_pix3d(X+u0,Y+v0,Z+w0,2));
--                    if ((pu*u + pv*v + pw*w)<0) { u=-u; v=-v; w=-w; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix3d(X,Y,Z,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix3d(X,Y,Z,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v); Z+=(pw=w);
--                  } break;
--                }
--                if (S>0) cimg_forV(dest,k) dest(x,y,z,k)+=tmp[k]/S;
--                else cimg_forV(dest,k) dest(x,y,z,k)+=(ftype)((*this)(x,y,z,k));
--#ifdef cimg_plugin_greycstoration
--                if (!*(greycstoration_params->stop_request)) (*greycstoration_params->counter)++;
--                else return *this;
--#endif
--              }
--            }
--          } else
--            // 2D version of the algorithm
--            for (float theta=(360%(int)da)/2.0f; theta<360; (theta+=da),N++) {
--              const float
--                thetar = (float)(theta*cimg::PI/180),
--                vx = (float)(std::cos(thetar)),
--                vy = (float)(std::sin(thetar));
--              const t
--                *pa = G.ptr(0,0,0,0),
--                *pb = G.ptr(0,0,0,1),
--                *pc = G.ptr(0,0,0,2);
--              ftype
--                *pd0 = W.ptr(0,0,0,0),
--                *pd1 = W.ptr(0,0,0,1),
--                *pd2 = W.ptr(0,0,0,2);
--              cimg_forXY(G,xg,yg) {
--                const t a = *(pa++), b = *(pb++), c = *(pc++);
--                const float
--                  u = (float)(a*vx + b*vy),
--                  v = (float)(b*vx + c*vy),
--                  n = (float)std::sqrt(1e-5+u*u+v*v),
--                  dln = dl/n;
--                *(pd0++) = (ftype)(u*dln);
--                *(pd1++) = (ftype)(v*dln);
--                *(pd2++) = (ftype)n;
--              }
--
--              cimg_forXY(*this,x,y) {
--                tmp.fill(0);
--                const float
--                  cu = (float)W(x,y,0,0),
--                  cv = (float)W(x,y,0,1),
--                  n  = (float)W(x,y,0,2),
--                  fsigma = (float)(n*sqrt2amplitude),
--                  length = gauss_prec*fsigma,
--                  fsigma2 = 2*fsigma*fsigma;
--                float
--                  S = 0,
--                  pu = cu,
--                  pv = cv,
--                  X = (float)x,
--                  Y = (float)y;
--
--                switch (interpolation) {
--
--                case 0:
--                  // Nearest-neighbor interpolation for 2D images
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
--                    const int
--                      cx = (int)(X+0.5f),
--                      cy = (int)(Y+0.5f);
--                    float
--                      u = (float)W(cx,cy,0,0),
--                      v = (float)W(cx,cy,0,1);
--                    if ((pu*u + pv*v)<0) { u=-u; v=-v; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)(*this)(cx,cy,0,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*(*this)(cx,cy,0,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v);
--                  } break;
--
--                case 1:
--                  // Linear interpolation for 2D images
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
--                    const int
--                      cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
--                      cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
--                    const float
--                      curru = (float)W(cx,cy,0,0),
--                      currv = (float)W(cx,cy,0,1);
--                    cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
--                    cimg_valign2d(px,cy);                       cimg_valign2d(nx,cy);
--                    cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
--                    float
--                      u = (float)(W.linear_pix2d(X,Y,0,0)),
--                      v = (float)(W.linear_pix2d(X,Y,0,1));
--                    if ((pu*u + pv*v)<0) { u=-u; v=-v; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v);
--                  } break;
--
--                default:
--                  // 2nd-order Runge-kutta interpolation for 2D images
--                  for (float l=0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
--                    const int
--                      cx = (int)X, px = (cx-1<0)?0:cx-1, nx = (cx+1>dx1)?dx1:cx+1,
--                      cy = (int)Y, py = (cy-1<0)?0:cy-1, ny = (cy+1>dy1)?dy1:cy+1;
--                    const float
--                      curru = (float)W(cx,cy,0,0),
--                      currv = (float)W(cx,cy,0,1);
--                    cimg_valign2d(px,py); cimg_valign2d(cx,py); cimg_valign2d(nx,py);
--                    cimg_valign2d(px,cy);                       cimg_valign2d(nx,cy);
--                    cimg_valign2d(px,ny); cimg_valign2d(cx,ny); cimg_valign2d(nx,ny);
--                    const float
--                      u0 = (float)(0.5f*W.linear_pix2d(X,Y,0,0)),
--                      v0 = (float)(0.5f*W.linear_pix2d(X,Y,0,1));
--                    float
--                      u = (float)(W.linear_pix2d(X+u0,Y+v0,0,0)),
--                      v = (float)(W.linear_pix2d(X+u0,Y+v0,0,1));
--                    if ((pu*u + pv*v)<0) { u=-u; v=-v; }
--                    if (fast_approx) { cimg_forV(*this,k) tmp[k]+=(ftype)linear_pix2d(X,Y,0,k); S++; }
--                    else {
--                      const float coef = (float)std::exp(-l*l/fsigma2);
--                      cimg_forV(*this,k) tmp[k]+=(ftype)(coef*linear_pix2d(X,Y,0,k));
--                      S+=coef;
--                    }
--                    X+=(pu=u); Y+=(pv=v);
--                  } break;
--                }
--                if (S>0) cimg_forV(dest,k) dest(x,y,0,k)+=tmp[k]/S;
--                else cimg_forV(dest,k) dest(x,y,0,k)+=(ftype)((*this)(x,y,0,k));
--#ifdef cimg_plugin_greycstoration
--                if (!*(greycstoration_params->stop_request)) (*greycstoration_params->counter)++;
--                else return *this;
--#endif
--              }
--            }
--        const ftype *ptrs = dest.data+dest.size();
--        const T m = cimg::type<T>::min(), M = cimg::type<T>::max();
--        cimg_for(*this,ptrd,T) { const ftype val = *(--ptrs)/N; *ptrd = val<m?m:(val>M?M:(T)val); }
--      }
--      return *this;
--    }
--
--    //! Get a blurred version of an image following a field of diffusion tensors.
--    /**
--       \param G = Field of square roots of diffusion tensors used to drive the smoothing.
--       \param amplitude = amplitude of the smoothing.
--       \param dl = spatial discretization.
--       \param da = angular discretization.
--       \param gauss_prec = precision of the gaussian function.
--       \param interpolation Used interpolation scheme (0 = nearest-neighbor, 1 = linear, 2 = Runge-Kutta)
--       \param fast_approx = Tell to use the fast approximation or not.
--    **/
--    template<typename t>
--      CImg get_blur_anisotropic(const CImg<t>& G, const float amplitude=60.0f, const float dl=0.8f,const float da=30.0f,
--                                const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true) const {
--      return (+*this).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
--    }
--
--    //! Blur an image following a field of diffusion tensors.
--    template<typename tm>
--      CImg& blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
--                             const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,const float da=30.0f,
--                             const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
--                           const float geom_factor=1.0f) {
--      if (!is_empty() && amplitude>0) {
--        if (amplitude==0) return *this;
--        if (amplitude<0 || sharpness<0 || anisotropy<0 || anisotropy>1 || alpha<0 || sigma<0 || dl<0 || da<0 || gauss_prec<0)
--          throw CImgArgumentException("CImg<%s>::blur_anisotropic() : Given parameters are amplitude(%g), sharpness(%g), "
--                                      "anisotropy(%g), alpha(%g), sigma(%g), dl(%g), da(%g), gauss_prec(%g).\n"
--                                      "Admissible parameters are in the range : amplitude>0, sharpness>0, anisotropy in [0,1], "
--                                      "alpha>0, sigma>0, dl>0, da>0, gauss_prec>0.",
--                                      pixel_type(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec);
--        const bool threed = (depth>1), no_mask = mask.is_empty();
--        const float nsharpness = cimg::max(sharpness,1e-5f), power1 = 0.5f*nsharpness, power2 = power1/(1e-7f+1.0f-anisotropy);
--
--        CImg<float> blurred = CImg<float>(*this,false).blur(alpha);
--        if (geom_factor>0) blurred*=geom_factor;
--        else blurred.normalize(0,-geom_factor);
--
--        if (threed) { // Field for 3D volumes
--          CImg<float> val(3), vec(3,3), G(blurred.get_structure_tensorXYZ());
--          if (sigma>0) G.blur(sigma);
--          cimg_forXYZ(*this,x,y,z) {
--            if (no_mask || mask(x,y,z)) {
--              G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
--              const float l1 = val[2], l2 = val[1], l3 = val[0],
--                ux = vec(0,0), uy = vec(0,1), uz = vec(0,2),
--                vx = vec(1,0), vy = vec(1,1), vz = vec(1,2),
--                wx = vec(2,0), wy = vec(2,1), wz = vec(2,2),
--                n1 = (float)std::pow(1.0f+l1+l2+l3,-power1),
--                n2 = (float)std::pow(1.0f+l1+l2+l3,-power2);
--              G(x,y,z,0) = n1*(ux*ux + vx*vx) + n2*wx*wx;
--              G(x,y,z,1) = n1*(ux*uy + vx*vy) + n2*wx*wy;
--              G(x,y,z,2) = n1*(ux*uz + vx*vz) + n2*wx*wz;
--              G(x,y,z,3) = n1*(uy*uy + vy*vy) + n2*wy*wy;
--              G(x,y,z,4) = n1*(uy*uz + vy*vz) + n2*wy*wz;
--              G(x,y,z,5) = n1*(uz*uz + vz*vz) + n2*wz*wz;
--            } else G(x,y,z,0) = G(x,y,z,1) = G(x,y,z,2) = G(x,y,z,3) = G(x,y,z,4) = G(x,y,z,5) = 0;
--#ifdef cimg_plugin_greycstoration
--            if (!*(greycstoration_params->stop_request)) (*greycstoration_params->counter)++;
--            else return *this;
--#endif
--          }
--          blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
--        } else { // Field for 2D images
--          CImg<float> val(2), vec(2,2), G(blurred.get_structure_tensorXY());
--          if (sigma>0) G.blur(sigma);
--          cimg_forXY(*this,x,y) {
--            if (no_mask || mask(x,y)) {
--              G.get_tensor_at(x,y).symmetric_eigen(val,vec);
--              const float l1 = val[1], l2 = val[0],
--                ux = vec(1,0), uy = vec(1,1),
--                vx = vec(0,0), vy = vec(0,1),
--                n1 = (float)std::pow(1.0f+l1+l2,-power1),
--                n2 = (float)std::pow(1.0f+l1+l2,-power2);
--              G(x,y,0,0) = n1*ux*ux + n2*vx*vx;
--              G(x,y,0,1) = n1*ux*uy + n2*vx*vy;
--              G(x,y,0,2) = n1*uy*uy + n2*vy*vy;
--            } else G(x,y,0,0) = G(x,y,0,1) = G(x,y,0,2) = 0;
--#ifdef cimg_plugin_greycstoration
--            if (!*(greycstoration_params->stop_request)) (*greycstoration_params->counter)++;
--            else return *this;
--#endif
--          }
--          blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation,fast_approx);
--        }
--      }
--      return *this;
--    }
--
--    //! Blur an image in an anisotropic way.
--    /**
--       \param amplitude = amplitude of the anisotropic blur.
--       \param sharpness = define the contour preservation.
--       \param anisotropy = define the smoothing anisotropy.
--       \param alpha = image pre-blurring (gaussian).
--       \param sigma = regularity of the tensor-valued geometry.
--       \param dl = spatial discretization.
--       \param da = angular discretization.
--       \param gauss_prec = precision of the gaussian function.
--       \param interpolation Used interpolation scheme (0 = nearest-neighbor, 1 = linear, 2 = Runge-Kutta)
--       \param fast_approx = Tell to use the fast approximation or not
--    **/
--    template<typename tm>
--      CImg get_blur_anisotropic(const CImg<tm>& mask, const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
--                                const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
--                                const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
--                                const bool fast_approx=true, const float geom_factor=1.0f) const {
--      return (+*this).blur_anisotropic(mask,amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
--    }
--
--    //! Blur an image following in an anistropic way.
--    CImg& blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
--                           const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,const float da=30.0f,
--                           const float gauss_prec=2.0f, const unsigned int interpolation=0, const bool fast_approx=true,
--                           const float geom_factor=1.0f) {
--      return blur_anisotropic(CImg<T>(),amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
--    }
--
--    //! Blur an image following in an anistropic way.
--    CImg get_blur_anisotropic(const float amplitude, const float sharpness=0.7f, const float anisotropy=0.3f,
--                              const float alpha=0.6f, const float sigma=1.1f, const float dl=0.8f,
--                              const float da=30.0f, const float gauss_prec=2.0f, const unsigned int interpolation=0,
--                              const bool fast_approx=true, const float geom_factor=1.0f) const {
--      return (+*this).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor);
--    }
--
--    //! Return the Fast Fourier Transform of an image (along a specified axis)
--    CImgList<typename cimg::largest<T,float>::type> get_FFT(const char axe, const bool inverse=false) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImgList<restype>(*this).FFT(axe,inverse);
--    }
--
--    //! Return the Fast Fourier Transform on an image
--    CImgList<typename cimg::largest<T,float>::type> get_FFT(const bool inverse=false) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImgList<restype>(*this).FFT(inverse);
--    }
--
--    //! Apply a median filter.
--    CImg get_blur_median(const unsigned int n=3) {
--      CImg<T> res(width,height,depth,dim);
--      if (!n || n==1) return *this;
--      const int hl=n/2, hr=hl-1+n%2;
--      if (res.depth!=1) {  // 3D median filter
--        CImg<T> vois;
--        cimg_forXYZV(*this,x,y,z,k) {
--          vois = get_crop(x-hl,y-hl,z-hl,k,x+hr,y+hr,z+hr,k);
--          res(x,y,z,k) = vois.median();
--        }
--      } else { // 2D median filter
--#define _median_sort(a,b) if ((a)>(b)) cimg::swap(a,b)
--        switch (n) {
--        case 3: {
--          CImg_3x3(I,T);
--          CImg_3x3(J,T);
--          cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
--            cimg_copy3x3(I,J);
--            _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
--            _median_sort(Jpp, Jcp); _median_sort(Jpc, Jcc); _median_sort(Jpn, Jcn);
--            _median_sort(Jcp, Jnp); _median_sort(Jcc, Jnc); _median_sort(Jcn, Jnn);
--            _median_sort(Jpp, Jpc); _median_sort(Jnc, Jnn); _median_sort(Jcc, Jcn);
--            _median_sort(Jpc, Jpn); _median_sort(Jcp, Jcc); _median_sort(Jnp, Jnc);
--            _median_sort(Jcc, Jcn); _median_sort(Jcc, Jnp); _median_sort(Jpn, Jcc);
--            _median_sort(Jcc, Jnp);
--            res(x,y,0,k) = Jcc;
--          }
--        } break;
--        case 5: {
--          CImg_5x5(I,T);
--          CImg_5x5(J,T);
--          cimg_forV(*this,k) cimg_for5x5(*this,x,y,0,k,I) {
--            cimg_copy5x5(I,J);
--            _median_sort(Jbb, Jpb); _median_sort(Jnb, Jab); _median_sort(Jcb, Jab); _median_sort(Jcb, Jnb);
--            _median_sort(Jpp, Jcp); _median_sort(Jbp, Jcp); _median_sort(Jbp, Jpp); _median_sort(Jap, Jbc);
--            _median_sort(Jnp, Jbc); _median_sort(Jnp, Jap); _median_sort(Jcc, Jnc); _median_sort(Jpc, Jnc);
--            _median_sort(Jpc, Jcc); _median_sort(Jbn, Jpn); _median_sort(Jac, Jpn); _median_sort(Jac, Jbn);
--            _median_sort(Jnn, Jan); _median_sort(Jcn, Jan); _median_sort(Jcn, Jnn); _median_sort(Jpa, Jca);
--            _median_sort(Jba, Jca); _median_sort(Jba, Jpa); _median_sort(Jna, Jaa); _median_sort(Jcb, Jbp);
--            _median_sort(Jnb, Jpp); _median_sort(Jbb, Jpp); _median_sort(Jbb, Jnb); _median_sort(Jab, Jcp);
--            _median_sort(Jpb, Jcp); _median_sort(Jpb, Jab); _median_sort(Jpc, Jac); _median_sort(Jnp, Jac);
--            _median_sort(Jnp, Jpc); _median_sort(Jcc, Jbn); _median_sort(Jap, Jbn); _median_sort(Jap, Jcc);
--            _median_sort(Jnc, Jpn); _median_sort(Jbc, Jpn); _median_sort(Jbc, Jnc); _median_sort(Jba, Jna);
--            _median_sort(Jcn, Jna); _median_sort(Jcn, Jba); _median_sort(Jpa, Jaa); _median_sort(Jnn, Jaa);
--            _median_sort(Jnn, Jpa); _median_sort(Jan, Jca); _median_sort(Jnp, Jcn); _median_sort(Jap, Jnn);
--            _median_sort(Jbb, Jnn); _median_sort(Jbb, Jap); _median_sort(Jbc, Jan); _median_sort(Jpb, Jan);
--            _median_sort(Jpb, Jbc); _median_sort(Jpc, Jba); _median_sort(Jcb, Jba); _median_sort(Jcb, Jpc);
--            _median_sort(Jcc, Jpa); _median_sort(Jnb, Jpa); _median_sort(Jnb, Jcc); _median_sort(Jnc, Jca);
--            _median_sort(Jab, Jca); _median_sort(Jab, Jnc); _median_sort(Jac, Jna); _median_sort(Jbp, Jna);
--            _median_sort(Jbp, Jac); _median_sort(Jbn, Jaa); _median_sort(Jpp, Jaa); _median_sort(Jpp, Jbn);
--            _median_sort(Jcp, Jpn); _median_sort(Jcp, Jan); _median_sort(Jnc, Jpa); _median_sort(Jbn, Jna);
--            _median_sort(Jcp, Jnc); _median_sort(Jcp, Jbn); _median_sort(Jpb, Jap); _median_sort(Jnb, Jpc);
--            _median_sort(Jbp, Jcn); _median_sort(Jpc, Jcn); _median_sort(Jap, Jcn); _median_sort(Jab, Jbc);
--            _median_sort(Jpp, Jcc); _median_sort(Jcp, Jac); _median_sort(Jab, Jpp); _median_sort(Jab, Jcp);
--            _median_sort(Jcc, Jac); _median_sort(Jbc, Jac); _median_sort(Jpp, Jcp); _median_sort(Jbc, Jcc);
--            _median_sort(Jpp, Jbc); _median_sort(Jpp, Jcn); _median_sort(Jcc, Jcn); _median_sort(Jcp, Jcn);
--            _median_sort(Jcp, Jbc); _median_sort(Jcc, Jnn); _median_sort(Jcp, Jcc); _median_sort(Jbc, Jnn);
--            _median_sort(Jcc, Jba); _median_sort(Jbc, Jba); _median_sort(Jbc, Jcc);
--            res(x,y,0,k) = Jcc;
--          }
--        } break;
--        default: {
--          CImg<T> vois;
--          cimg_forXYV(*this,x,y,k) {
--            vois = get_crop(x-hl,y-hl,0,k,x+hr,y+hr,0,k);
--            res(x,y,0,k) = vois.median();
--          }
--        } break;
--        }
--      }
--      return res;
--    }
--
--    //! Apply a median filter
--    CImg& blur_median(const unsigned int n=3) {
--      return get_blur_median(n).swap(*this);
--    }
--
--    //! Sharpen image using anisotropic shock filters
--    CImg& sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) {
--      if (is_empty()) return *this;
--      const bool threed = (depth>1);
--      const float nedge = 0.5f*edge;
--      typedef typename cimg::largest<T,float>::type ftype;
--      CImg<ftype> val, vec, veloc(width,height,depth,dim);
--
--      if (threed) {
--        CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXYZ():get_structure_tensorXYZ());
--        if (sigma>0) G.blur(sigma);
--        CImg_3x3x3(I,float);
--        cimg_forXYZ(G,x,y,z) {
--          G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
--          G(x,y,z,0) = vec(0,0);
--          G(x,y,z,1) = vec(0,1);
--          G(x,y,z,2) = vec(0,2);
--          G(x,y,z,3) = 1.0f-(float)std::pow(1.0f+val[0]+val[1]+val[2],-nedge);
--        }
--        cimg_forV(*this,k) cimg_for3x3x3(*this,x,y,z,k,I) {
--          const float
--            u = G(x,y,z,0),
--            v = G(x,y,z,1),
--            w = G(x,y,z,2),
--            amp = G(x,y,z,3),
--            ixx = Incc+Ipcc-2*Iccc,
--            ixy = 0.25f*(Innc+Ippc-Inpc-Ipnc),
--            ixz = 0.25f*(Incn+Ipcp-Incp-Ipcn),
--            iyy = Icnc+Icpc-2*Iccc,
--            iyz = 0.25f*(Icnn+Icpp-Icnp-Icpn),
--            izz = Iccn+Iccp-2*Iccc,
--            ixf = Incc-Iccc,
--            ixb = Iccc-Ipcc,
--            iyf = Icnc-Iccc,
--            iyb = Iccc-Icpc,
--            izf = Iccn-Iccc,
--            izb = Iccc-Iccp,
--            itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz,
--            it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb) + w*cimg::minmod(izf,izb);
--          veloc(x,y,z,k) = -amp*cimg::sign(itt)*cimg::abs(it);
--        }
--      } else {
--        CImg<ftype> G = (alpha>0?get_blur(alpha).get_structure_tensorXY():get_structure_tensorXY());
--        if (sigma>0) G.blur(sigma);
--        CImg_3x3(I,float);
--        cimg_forXY(G,x,y) {
--          G.get_tensor_at(x,y).symmetric_eigen(val,vec);
--          G(x,y,0) = vec(0,0);
--          G(x,y,1) = vec(0,1);
--          G(x,y,2) = 1.0f-(float)std::pow(1.0f+val[0]+val[1],-nedge);
--        }
--        cimg_forV(*this,k) cimg_for3x3(*this,x,y,0,k,I) {
--          const float
--            u = G(x,y,0),
--            v = G(x,y,1),
--            amp = G(x,y,2),
--            ixx = Inc+Ipc-2*Icc,
--            ixy = 0.25f*(Inn+Ipp-Inp-Ipn),
--            iyy = Icn+Icp-2*Icc,
--            ixf = Inc-Icc,
--            ixb = Icc-Ipc,
--            iyf = Icn-Icc,
--            iyb = Icc-Icp,
--            itt = u*u*ixx + v*v*iyy + 2*u*v*ixy,
--            it = u*cimg::minmod(ixf,ixb) + v*cimg::minmod(iyf,iyb);
--          veloc(x,y,k) = -amp*cimg::sign(itt)*cimg::abs(it);
--        }
--      }
--      const CImgStats stats(veloc);
--      const float vmax = (float)cimg::max(cimg::abs(stats.min),cimg::abs(stats.max));
--      if (vmax!=0) { veloc*=amplitude/vmax; (*this)+=veloc; }
--      return *this;
--    }
--
--    CImg get_sharpen(const float amplitude=50.0f, const float edge=1.0f, const float alpha=0.0f, const float sigma=0.0f) const {
--      return (+*this).sharpen(amplitude,edge,alpha,sigma);
--    }
--
--    //@}
--    //-----------------------------
--    //
--    //! \name Matrix and Vectors
--    //@{
--    //-----------------------------
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1) {
--      return CImg<T>(1,1).fill(a1);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2) {
--      return CImg<T>(1,2).fill(a1,a2);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3) {
--      return CImg<T>(1,3).fill(a1,a2,a3);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4) {
--      return CImg<T>(1,4).fill(a1,a2,a3,a4);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,const T& a5) {
--      return CImg<T>(1,5).fill(a1,a2,a3,a4,a5);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,const T& a5,const T& a6) {
--      return CImg<T>(1,6).fill(a1,a2,a3,a4,a5,a6);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7) {
--      return CImg<T>(1,7).fill(a1,a2,a3,a4,a5,a6,a7);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8) {
--      return CImg<T>(1,8).fill(a1,a2,a3,a4,a5,a6,a7,a8);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,const T& a9) {
--      return CImg<T>(1,9).fill(a1,a2,a3,a4,a5,a6,a7,a8,a9);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,
--                       const T& a9,const T& a10) {
--      return CImg<T>(1,10).fill(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,
--                       const T& a9,const T& a10, const T& a11) {
--      return CImg<T>(1,11).fill(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,
--                       const T& a9,const T& a10, const T& a11, const T& a12) {
--      return CImg<T>(1,12).fill(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
--    }
--
--    //! Return a vector with specified coefficients
--    static CImg vector(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,
--                       const T& a9,const T& a10, const T& a11, const T& a12,
--                       const T& a13) {
--      return CImg<T>(1,13).fill(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13);
--    }
--
--    //! Return a 1x1 square matrix with specified coefficients
--    static CImg matrix(const T& a1) {
--      return vector(a1);
--    }
--
--    //! Return a 2x2 square matrix with specified coefficients
--    static CImg matrix(const T& a1,const T& a2,
--                       const T& a3,const T& a4) {
--      return CImg<T>(2,2).fill(a1,a2,
--                               a3,a4);
--    }
--
--    //! Return a 3x3 square matrix with specified coefficients
--    static CImg matrix(const T& a1,const T& a2,const T& a3,
--                       const T& a4,const T& a5,const T& a6,
--                       const T& a7,const T& a8,const T& a9) {
--      return CImg<T>(3,3).fill(a1,a2,a3,
--                               a4,a5,a6,
--                               a7,a8,a9);
--    }
--
--    //! Return a 4x4 square matrix with specified coefficients
--    static CImg matrix(const T& a1,const T& a2,const T& a3,const T& a4,
--                       const T& a5,const T& a6,const T& a7,const T& a8,
--                       const T& a9,const T& a10,const T& a11,const T& a12,
--                       const T& a13,const T& a14,const T& a15,const T& a16) {
--      return CImg<T>(4,4).fill(a1,a2,a3,a4,
--                               a5,a6,a7,a8,
--                               a9,a10,a11,a12,
--                               a13,a14,a15,a16);
--    }
--
--    //! Return a 5x5 square matrix with specified coefficients
--    static CImg matrix(const T& a1,const T& a2,const T& a3,const T& a4,const T& a5,
--                       const T& a6,const T& a7,const T& a8,const T& a9,const T& a10,
--                       const T& a11,const T& a12,const T& a13,const T& a14,const T& a15,
--                       const T& a16,const T& a17,const T& a18,const T& a19,const T& a20,
--                       const T& a21,const T& a22,const T& a23,const T& a24,const T& a25) {
--      return CImg<T>(5,5).fill(a1,a2,a3,a4,a5,
--                               a6,a7,a8,a9,a10,
--                               a11,a12,a13,a14,a15,
--                               a16,a17,a18,a19,a20,
--                               a21,a22,a23,a24,a25);
--    }
--
--    //! In-place version of get_matrix().
--    CImg& matrix() {
--      const unsigned int siz = size();
--      switch (siz) {
--      case 1: break;
--      case 4: width = height = 2; break;
--      case 9: width = height = 3; break;
--      case 16: width = height = 4; break;
--      case 25: width = height = 5; break;
--      case 36: width = height = 6; break;
--      case 49: width = height = 7; break;
--      case 64: width = height = 8; break;
--      case 81: width = height = 9; break;
--      case 100: width = height = 10; break;
--      default: {
--        unsigned int i=11, i2=i*i;
--        while (i2<siz) { i2+=2*i+1; i++; }
--        if (i2==siz) width = height = i;
--        else throw CImgInstanceException("CImg<%s>::matrix() : Image size = %u is not a square number",pixel_type(),siz);
--      } break;
--      }
--      return *this;
--    }
--
--    //! Realign pixel values of the instance image as a square matrix
--    CImg get_matrix() const {
--      return (+*this).matrix();
--    }
--
--    //! Return a 1x1 symmetric matrix with specified coefficients
--    static CImg tensor(const T& a1) {
--      return matrix(a1);
--    }
--
--    //! Return a 2x2 symmetric matrix tensor with specified coefficients
--    static CImg tensor(const T& a1,const T& a2,const T& a3) {
--      return matrix(a1,a2,
--                    a2,a3);
--    }
--
--    //! Return a 3x3 symmetric matrix with specified coefficients
--    static CImg tensor(const T& a1,const T& a2,const T& a3,const T& a4,const T& a5,const T& a6) {
--      return matrix(a1,a2,a3,
--                    a2,a4,a5,
--                    a3,a5,a6);
--    }
--
--    CImg get_tensor() const {
--      CImg<T> res;
--      const unsigned int siz = size();
--      switch (siz) {
--      case 1: break;
--      case 3:
--        res.assign(2,2);
--        res(0,0) = (*this)(0);
--        res(1,0) = res(0,1) = (*this)(1);
--        res(1,1) = (*this)(2);
--        break;
--      case 6:
--        res.assign(3,3);
--        res(0,0) = (*this)(0);
--        res(1,0) = res(0,1) = (*this)(1);
--        res(2,0) = res(0,2) = (*this)(2);
--        res(1,1) = (*this)(3);
--        res(2,1) = res(1,2) = (*this)(4);
--        res(2,2) = (*this)(5);
--        break;
--      default:
--        throw CImgInstanceException("CImg<%s>::get_tensor() : Wrong vector dimension = %u in instance image.",
--                                    pixel_type(), dim);
--        break;
--      }
--      return res;
--    }
--
--    //! In-place version of get_tensor().
--    CImg& tensor() {
--      return get_tensor().swap(*this);
--    }
--
--    //! Return a 1x1 diagonal matrix with specified coefficients
--    static CImg diagonal(const T& a1) {
--      return matrix(a1);
--    }
--
--    //! Return a 2x2 diagonal matrix with specified coefficients
--    static CImg diagonal(const T& a1,const T& a2) {
--      return matrix(a1,0,
--                    0,a2);
--    }
--
--    //! Return a 3x3 diagonal matrix with specified coefficients
--    static CImg diagonal(const T& a1,const T& a2,const T& a3) {
--      return matrix(a1,0,0,
--                    0,a2,0,
--                    0,0,a3);
--    }
--
--    //! Return a 4x4 diagonal matrix with specified coefficients
--    static CImg diagonal(const T& a1,const T& a2,const T& a3,const T& a4) {
--      return matrix(a1,0,0,0,
--                    0,a2,0,0,
--                    0,0,a3,0,
--                    0,0,0,a4);
--    }
--
--    //! Return a 5x5 diagonal matrix with specified coefficients
--    static CImg diagonal(const T& a1,const T& a2,const T& a3,const T& a4,const T& a5) {
--      return matrix(a1,0,0,0,0,
--                    0,a2,0,0,0,
--                    0,0,a3,0,0,
--                    0,0,0,a4,0,
--                    0,0,0,0,a5);
--    }
--
--    //! Unroll all images values into specified axis.
--    CImg& unroll(const char axe='x') {
--      const unsigned int siz = size();
--      if (siz) switch (axe) {
--      case 'x': width = siz; height=depth=dim=1; break;
--      case 'y': height = siz; width=depth=dim=1; break;
--      case 'z': depth = siz; width=height=dim=1; break;
--      case 'v': dim = siz; width=height=depth=1; break;
--      default: throw CImgArgumentException("CImg<%s>::unroll() : Given axe is '%c' which is not 'x','y','z' or 'v'",
--                                           pixel_type(),axe);
--      }
--      return *this;
--    }
--
--    CImg get_unroll(const char axe='x') const {
--      return (+*this).unroll(axe);
--    }
--
--    CImg& vector() {
--      return unroll('y');
--    }
--
--    CImg get_vector() const {
--      return get_unroll('y');
--    }
--
--    //! Get a diagonal matrix, whose diagonal coefficients are the coefficients of the input image
--    CImg get_diagonal() const {
--      if (is_empty()) return CImg<T>();
--      CImg res(size(),size(),1,1,0);
--      cimg_foroff(*this,off) res(off,off)=(*this)(off);
--      return res;
--    }
--
--    //! Replace a vector by a diagonal matrix containing the original vector coefficients.
--    CImg& diagonal() {
--      return get_diagonal().swap(*this);
--    }
--
--    //! Return a NxN identity matrix
--    static CImg identity_matrix(const unsigned int N) {
--      CImg<T> res(N,N,1,1,0);
--      cimg_forX(res,x) res(x,x)=1;
--      return res;
--    }
--
--    CImg& identity_matrix() {
--      return get_identity_matrix(cimg::max(width,height)).swap(*this);
--    }
--
--    CImg get_identity_matrix() const {
--      return identity_matrix(cimg::max(width,height));
--    }
--
--    //! Return a N-numbered sequence vector from \p a0 to \p a1
--    CImg& sequence(const T& a0, const T& a1) {
--      if (!is_empty()) {
--        const unsigned int siz = size()-1;
--        const float delta = (float)((float)a1-a0);
--        T* ptr = data;
--        cimg_foroff(*this,l) *(ptr++) = (T)(a0 + delta*l/siz);
--      }
--      return *this;
--    }
--
--    CImg get_sequence(const T& a0, const T& a1) const {
--      return (+*this).sequence(a0,a1);
--    }
--
--    static CImg sequence(const unsigned int N, const T& a0, const T& a1) {
--      if (N) return CImg<T>(1,N).sequence(a0,a1);
--      return CImg<T>();
--    }
--
--    //! Return a 3x3 rotation matrix along the (x,y,z)-axis with an angle w.
--    static CImg rotation_matrix(const float x, const float y, const float z, const float w, const bool quaternion_data=false) {
--      float X,Y,Z,W;
--      if (!quaternion_data) {
--        const float norm = (float)std::sqrt(x*x + y*y + z*z),
--          nx = norm>0?x/norm:0,
--          ny = norm>0?y/norm:0,
--          nz = norm>0?z/norm:1,
--          nw = norm>0?w:0,
--          sina = (float)std::sin(nw/2),
--          cosa = (float)std::cos(nw/2);
--        X = nx*sina;
--        Y = ny*sina;
--        Z = nz*sina;
--        W = cosa;
--      } else {
--        const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w);
--        if (norm>0) { X=x/norm; Y=y/norm; Z=z/norm; W=w/norm; }
--        else { X=Y=Z=0; W=1; }
--      }
--      const float xx=X*X, xy=X*Y, xz=X*Z, xw=X*W, yy=Y*Y, yz=Y*Z, yw=Y*W, zz=Z*Z, zw=Z*W;
--      return CImg<T>::matrix(1-2*(yy+zz),   2*(xy+zw),   2*(xz-yw),
--                             2*(xy-zw), 1-2*(xx+zz),   2*(yz+xw),
--                             2*(xz+yw),   2*(yz-xw), 1-2*(xx+yy));
--    }
--
--    //! Return a new image corresponding to the vector located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg get_vector_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
--      CImg dest(1,dim);
--      cimg_forV(*this,k) dest[k]=(*this)(x,y,z,k);
--      return dest;
--    }
--
--    //! Return a new image corresponding to the \a square \a matrix located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg get_matrix_at(const unsigned int x=0, const unsigned int y=0, const unsigned int z=0) const {
--      const int n = (int)std::sqrt((double)dim);
--      CImg dest(n,n);
--      cimg_forV(*this,k) dest[k]=(*this)(x,y,z,k);
--      return dest;
--    }
--
--    //! Return a new image corresponding to the \a diffusion \a tensor located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg get_tensor_at(const unsigned int x=0,const unsigned int y=0,const unsigned int z=0) const {
--      if (dim==6) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2),
--                                          (*this)(x,y,z,3),(*this)(x,y,z,4),(*this)(x,y,z,5));
--      if (dim==3) return tensor((*this)(x,y,z,0),(*this)(x,y,z,1),(*this)(x,y,z,2));
--      return tensor((*this)(x,y,z,0));
--    }
--
--    //! Set the image \p vec as the \a vector \a valued pixel located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg& set_vector_at(const CImg& vec,const unsigned int x=0,const unsigned int y=0,const unsigned int z=0) {
--      return draw_point(x,y,z,vec.data,1);
--    }
--
--    //! Set the image \p vec as the \a square \a matrix-valued pixel located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg& set_matrix_at(const CImg& mat,const unsigned int x=0,const unsigned int y=0,const unsigned int z=0) {
--      return set_vector_at(mat,x,y,z);
--    }
--
--    //! Set the image \p vec as the \a tensor \a valued pixel located at (\p x,\p y,\p z) of the current vector-valued image.
--    CImg& set_tensor_at(const CImg& ten,const unsigned int x=0,const unsigned int y=0,const unsigned int z=0) {
--      if (ten.height==2) {
--        (*this)(x,y,z,0)=ten[0];
--        (*this)(x,y,z,1)=ten[1];
--        (*this)(x,y,z,2)=ten[3];
--      }
--      else {
--        (*this)(x,y,z,0)=ten[0];
--        (*this)(x,y,z,1)=ten[1];
--        (*this)(x,y,z,2)=ten[2];
--        (*this)(x,y,z,3)=ten[4];
--        (*this)(x,y,z,4)=ten[5];
--        (*this)(x,y,z,5)=ten[8];
--      }
--      return *this;
--    }
--
--    //! Return the transpose version of the current matrix.
--    CImg get_transpose() const {
--      CImg<T> res(height,width,depth,dim);
--      cimg_forXYZV(*this,x,y,z,v) res(y,x,z,v) = (*this)(x,y,z,v);
--      return res;
--    }
--
--    //! Replace the current matrix by its transpose.
--    CImg& transpose() {
--      if (width==1) { width=height; height=1; return *this; }
--      if (height==1) { height=width; width=1; return *this; }
--      if (width==height) {
--        cimg_forYZV(*this,y,z,v) for (int x=y; x<(int)width; x++) cimg::swap((*this)(x,y,z,v),(*this)(y,x,z,v));
--        return *this;
--      }
--      return (*this)=get_transpose();
--    }
--
--    //! Inverse the current matrix.
--    CImg& inverse(const bool use_LU=true) {
--      if (!is_empty()) {
--        if (width!=height || depth!=1 || dim!=1)
--          throw CImgInstanceException("CImg<%s>::inverse() : Instance matrix (%u,%u,%u,%u,%p) is not square.",
--                                      pixel_type(),width,height,depth,dim,data);
--        const double dete = width>3?-1.0:det();
--        if (dete!=0.0 && width==2) {
--          const double
--            a = data[0], c = data[1],
--            b = data[2], d = data[3];
--          data[0] = (T)(d/dete);  data[1] = (T)(-c/dete);
--          data[2] = (T)(-b/dete), data[3] = (T)(a/dete);
--        } else if (dete!=0.0 && width==3) {
--          const double
--            a = data[0], d = data[1], g = data[2],
--            b = data[3], e = data[4], h = data[5],
--            c = data[6], f = data[7], i = data[8];
--          data[0] = (T)((i*e-f*h)/dete), data[1] = (T)((g*f-i*d)/dete), data[2] = (T)((d*h-g*e)/dete);
--          data[3] = (T)((h*c-i*b)/dete), data[4] = (T)((i*a-c*g)/dete), data[5] = (T)((g*b-a*h)/dete);
--          data[6] = (T)((b*f-e*c)/dete), data[7] = (T)((d*c-a*f)/dete), data[8] = (T)((a*e-d*b)/dete);
--        } else {
--          if (use_LU) { // LU-based inverse computation
--            CImg<T> A(*this), indx, col(1,width);
--            bool d;
--            A._LU(indx,d);
--            cimg_forX(*this,j) {
--              col.fill(0); col(j)=1;
--              col._solve(A,indx);
--              cimg_forX(*this,i) (*this)(j,i) = col(i);
--            }
--          } else { // SVD-based inverse computation
--            CImg<T> U(width,width),S(1,width),V(width,width);
--            SVD(U,S,V,false);
--            U.transpose();
--            cimg_forY(S,k) if (S[k]!=0) S[k]=1/S[k];
--            S.diagonal();
--            *this = V*S*U;
--          }
--        }
--      }
--      return *this;
--    }
--
--    //! Return the inverse of the current matrix.
--    CImg<typename cimg::largest<T,float>::type> get_inverse(const bool use_LU=true) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).inverse(use_LU);
--    }
--
--    //! Return the pseudo-inverse (Moore-Penrose) of the matrix
--    CImg<typename cimg::largest<T,float>::type> get_pseudoinverse() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      CImg<restype> At = get_transpose(), At2(At);
--      return (((At*=*this).inverse())*=At2);
--    }
--
--    //! Replace the matrix by its pseudo-inverse
--    CImg& pseudoinverse() {
--      typedef typename cimg::largest<T,float>::type restype;
--      CImg<restype> At = get_transpose(), At2(At);
--      ((At*=*this).inverse())*=At2;
--      return ((*this)=At);
--    }
--
--    //! Return the trace of the current matrix.
--    double trace() const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::trace() : Instance matrix (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      double res=0;
--      cimg_forX(*this,k) res+=(*this)(k,k);
--      return res;
--    }
--
--    //! Return the kth smallest element of the image
--    // (Adapted from the numerical recipies for CImg)
--    const T kth_smallest(const unsigned int k) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::kth_smallest() : Instance image (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      CImg<T> arr(*this);
--      unsigned long l=0,ir=size()-1;
--      for (;;) {
--        if (ir<=l+1) {
--          if (ir==l+1 && arr[ir]<arr[l]) cimg::swap(arr[l],arr[ir]);
--          return arr[k];
--        } else {
--          const unsigned long mid = (l+ir)>>1;
--          cimg::swap(arr[mid],arr[l+1]);
--          if (arr[l]>arr[ir]) cimg::swap(arr[l],arr[ir]);
--          if (arr[l+1]>arr[ir]) cimg::swap(arr[l+1],arr[ir]);
--          if (arr[l]>arr[l+1]) cimg::swap(arr[l],arr[l+1]);
--          unsigned long i = l+1, j = ir;
--          const T pivot = arr[l+1];
--          for (;;) {
--            do i++; while (arr[i]<pivot);
--            do j--; while (arr[j]>pivot);
--            if (j<i) break;
--            cimg::swap(arr[i],arr[j]);
--          }
--          arr[l+1] = arr[j];
--          arr[j] = pivot;
--          if (j>=k) ir=j-1;
--          if (j<=k) l=i;
--        }
--      }
--      return 0;
--    }
--
--    //! Return the median of the image
--    const T median() const {
--      const unsigned int s = size();
--      const T res = kth_smallest(s>>1);
--      return (s%2)?res:((res+kth_smallest((s>>1)-1))/2);
--    }
--
--    //! Return the dot product of the current vector/matrix with the vector/matrix \p img.
--    double dot(const CImg& img) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::dot() : Instance object (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      if (img.is_empty())
--        throw CImgArgumentException("CImg<%s>::trace() : Specified argument (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),img.width,img.height,img.depth,img.dim,img.data);
--      const unsigned long nb = cimg::min(size(),img.size());
--      double res=0;
--      for (unsigned long off=0; off<nb; off++) res+=data[off]*img[off];
--      return res;
--    }
--
--    //! Return the cross product between two 3d vectors
--    CImg& cross(const CImg& img) {
--      if (width!=1 || height<3 || img.width!=1 || img.height<3)
--        throw CImgInstanceException("CImg<%s>::cross() : Arguments (%u,%u,%u,%u,%p) and (%u,%u,%u,%u,%p) must be both 3d vectors.",
--                                    pixel_type(),width,height,depth,dim,data,img.width,img.height,img.depth,img.dim,img.data);
--      const T x = (*this)[0], y = (*this)[1], z = (*this)[2];
--      (*this)[0] = y*img[2]-z*img[1];
--      (*this)[1] = z*img[0]-x*img[2];
--      (*this)[2] = x*img[1]-y*img[0];
--      return *this;
--    }
--
--    //! Return the cross product between two 3d vectors
--    CImg get_cross(const CImg& img) const {
--      return (+*this).cross(img);
--    }
--
--    //! Return the determinant of the current matrix.
--    double det() const {
--      if (is_empty() || width!=height || depth!=1 || dim!=1)
--        throw CImgInstanceException("CImg<%s>::det() : Instance matrix (%u,%u,%u,%u,%p) is not square or is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      switch (width) {
--      case 1: return (*this)(0,0);
--      case 2: return (*this)(0,0)*(*this)(1,1)-(*this)(0,1)*(*this)(1,0);
--      case 3: {
--        const double
--          a = data[0], d = data[1], g = data[2],
--          b = data[3], e = data[4], h = data[5],
--          c = data[6], f = data[7], i = data[8];
--        return i*a*e-a*h*f-i*b*d+b*g*f+c*d*h-c*g*e;
--      }
--      default: {
--        typedef typename cimg::largest<T,float>::type ftype;
--        CImg<ftype> lu(*this);
--        CImg<unsigned int> indx;
--        bool d;
--        lu._LU(indx,d);
--        double res = d?1.0:-1.0;
--        cimg_forX(lu,i) res*=lu(i,i);
--        return res;
--      }
--      }
--      return 0;
--    }
--
--    //! Return the norm of the current vector/matrix. \p ntype = norm type (0=L2, 1=L1, -1=Linf).
--    double norm(const int ntype=2) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::norm() : Instance object (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      double res = 0;
--      switch (ntype) {
--      case -1: {
--        cimg_foroff(*this,off) {
--          const double tmp = cimg::abs((double)data[off]);
--          if (tmp>res) res = tmp;
--        }
--        return res;
--      } break;
--      case 1 : {
--        cimg_foroff(*this,off) res+=cimg::abs((double)data[off]);
--        return res;
--      } break;
--      default: { return std::sqrt(dot(*this)); }
--      }
--      return 0;
--    }
--
--    //! Return the sum of all the pixel values in an image.
--    double sum() const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::sum() : Instance object (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      double res=0;
--      cimg_for(*this,ptr,T) res+=*ptr;
--      return res;
--    }
--
--    //! Compute the SVD of a general matrix.
--    template<typename t> const CImg& SVD(CImg<t>& U, CImg<t>& S, CImg<t>& V,
--                                         const bool sorting=true, const unsigned int max_iter=40) const {
--      if (is_empty()) { U.assign(); S.assign(); V.assign(); }
--      else {
--        U = *this;
--        if (S.size()<width) S.assign(1,width);
--        if (V.width<width || V.height<height) V.assign(width,width);
--        CImg<t> rv1(width);
--        t anorm=0,c,f,g=0,h,s,scale=0;
--        int l=0, nm=0;
--
--        cimg_forX(U,i) {
--          l = i+1; rv1[i] = scale*g; g = s = scale = 0;
--          if (i<dimy()) {
--            for (int k=i; k<dimy(); k++) scale+= cimg::abs(U(i,k));
--            if (scale) {
--              for (int k=i; k<dimy(); k++) { U(i,k)/=scale; s+= U(i,k)*U(i,k); }
--              f = U(i,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i)=f-g;
--              for (int j=l; j<dimx(); j++) {
--                s = 0; for (int k=i; k<dimy(); k++) s+= U(i,k)*U(j,k);
--                f = s/h;
--                { for (int k=i; k<dimy(); k++) U(j,k)+= f*U(i,k); }
--              }
--              { for (int k=i; k<dimy(); k++) U(i,k)*= scale; }
--            }
--          }
--          S[i]=scale*g;
--
--          g = s = scale = 0;
--          if (i<dimy() && i!=dimx()-1) {
--            for (int k=l; k<dimx(); k++) scale += cimg::abs(U(k,i));
--            if (scale) {
--              for (int k=l; k<dimx(); k++) { U(k,i)/= scale; s+= U(k,i)*U(k,i); }
--              f = U(l,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g;
--              { for (int k=l; k<dimx(); k++) rv1[k]=U(k,i)/h; }
--              for (int j=l; j<dimy(); j++) {
--                s=0; for (int k=l; k<dimx(); k++) s+= U(k,j)*U(k,i);
--                { for (int k=l; k<dimx(); k++) U(k,j)+= s*rv1[k]; }
--              }
--              { for (int k=l; k<dimx(); k++) U(k,i)*= scale; }
--            }
--          }
--          anorm=cimg::max((t)anorm,(cimg::abs(S[i])+cimg::abs(rv1[i])));
--        }
--
--        { for (int i=dimx()-1; i>=0; i--) {
--          if (i<dimx()-1) {
--            if (g) {
--              { for (int j=l; j<dimx(); j++) V(i,j) =(U(j,i)/U(l,i))/g; }
--              for (int j=l; j<dimx(); j++) {
--                s=0; for (int k=l; k<dimx(); k++) s+= U(k,i)*V(j,k);
--                { for (int k=l; k<dimx(); k++) V(j,k)+= s*V(i,k); }
--              }
--            }
--            for (int j=l; j<dimx(); j++) V(j,i)=V(i,j)=0.0;
--          }
--          V(i,i) = 1.0; g = rv1[i]; l = i;
--        }
--        }
--
--        { for (int i=cimg::min(dimx(),dimy())-1; i>=0; i--) {
--          l = i+1; g = S[i];
--          for (int j=l; j<dimx(); j++) U(j,i) = 0;
--          if (g) {
--            g = 1/g;
--            for (int j=l; j<dimx(); j++) {
--              s=0; for (int k=l; k<dimy(); k++) s+= U(i,k)*U(j,k);
--              f = (s/U(i,i))*g;
--              { for (int k=i; k<dimy(); k++) U(j,k)+= f*U(i,k); }
--            }
--            { for (int j=i; j<dimy(); j++) U(i,j)*= g; }
--          } else for (int j=i; j<dimy(); j++) U(i,j)=0;
--          U(i,i)++;
--        }
--        }
--
--        for (int k=dimx()-1; k>=0; k--) {
--          for (unsigned int its=0; its<max_iter; its++) {
--            bool flag = true;
--            for (l=k; l>=1; l--) {
--              nm = l-1;
--              if ((cimg::abs(rv1[l])+anorm)==anorm) { flag = false; break; }
--              if ((cimg::abs(S[nm])+anorm)==anorm) break;
--            }
--            if (flag) {
--              c = 0; s = 1;
--              for (int i=l; i<=k; i++) {
--                f = s*rv1[i]; rv1[i] = c*rv1[i];
--                if ((cimg::abs(f)+anorm)==anorm) break;
--                g = S[i]; h = (t)cimg::pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h;
--                cimg_forY(U,j) { const t y = U(nm,j), z = U(i,j); U(nm,j) = y*c+z*s; U(i,j) = z*c-y*s; }
--              }
--            }
--            const t& z = S[k];
--            if (l==k) { if (z<0) { S[k] = -z; cimg_forX(U,j) V(k,j) = -V(k,j); } break; }
--            nm = k-1;
--            t x = S[l], y = S[nm];
--            g = rv1[nm]; h = rv1[k];
--            f = ((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y);
--            g = (t)cimg::pythagore(f,1.0);
--            f = ((x-z)*(x+z)+h*((y/(f+ (f>=0?g:-g)))-h))/x;
--            c = s = 1;
--            for (int j=l; j<=nm; j++) {
--              const int i = j+1;
--              g = rv1[i]; h = s*g; g = c*g;
--              t y = S[i];
--              t z = (t)cimg::pythagore(f,h);
--              rv1[j] = z; c = f/z; s = h/z;
--              f = x*c+g*s; g = g*c-x*s; h = y*s; y*=c;
--              cimg_forX(U,jj) { const t x = V(j,jj), z = V(i,jj); V(j,jj) = x*c+z*s; V(i,jj) = z*c-x*s; }
--              z = (t)cimg::pythagore(f,h); S[j] = z;
--              if (z) { z = 1/z; c = f*z; s = h*z; }
--              f = c*g+s*y; x = c*y-s*g;
--              { cimg_forY(U,jj) { const t y = U(j,jj); z = U(i,jj); U(j,jj) = y*c+z*s; U(i,jj) = z*c-y*s; }}
--            }
--            rv1[l] = 0; rv1[k]=f; S[k]=x;
--          }
--        }
--
--        if (sorting) {
--          CImg<int> permutations(width);
--          CImg<t> tmp(width);
--          S.sort(permutations,false);
--          cimg_forY(U,k) {
--            cimg_forX(permutations,x) tmp(x) = U(permutations(x),k);
--            std::memcpy(U.ptr(0,k),tmp.data,sizeof(t)*width);
--          }
--          { cimg_forY(V,k) {
--            cimg_forX(permutations,x) tmp(x) = V(permutations(x),k);
--            std::memcpy(V.ptr(0,k),tmp.data,sizeof(t)*width);
--          }}
--        }
--      }
--      return *this;
--    }
--
--    //! Compute the SVD of a general matrix.
--    template<typename t> const CImg& SVD(CImgList<t>& USV) const {
--      if (USV.size<3) USV.assign(3);
--      return SVD(USV[0],USV[1],USV[2]);
--    }
--
--    //! Compute the SVD of a general matrix.
--    CImgList<typename cimg::largest<T,float>::type> get_SVD(const bool sorting=true) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      CImgList<restype> res(3);
--      SVD(res[0],res[1],res[2],sorting);
--      return res;
--    }
--
--    // INNER ROUTINE : Compute the LU decomposition of a permuted matrix (c.f. numerical recipies)
--    template<typename t> CImg& _LU(CImg<t>& indx, bool& d) {
--      typedef typename cimg::largest<T,float>::type ftype;
--      const int N = dimx();
--      int imax=0;
--      CImg<ftype> vv(N);
--      indx.assign(N);
--      d=true;
--      cimg_forX(*this,i) {
--        ftype vmax=0.0;
--        cimg_forX(*this,j) {
--          const ftype tmp = cimg::abs((*this)(j,i));
--          if (tmp>vmax) vmax = tmp;
--        }
--        if (vmax==0) return fill(0);
--        vv[i] = 1/vmax;
--      }
--      cimg_forX(*this,j) {
--        for (int i=0; i<j; i++) {
--          ftype sum=(*this)(j,i);
--          for (int k=0; k<i; k++) sum-=(*this)(k,i)*(*this)(j,k);
--          (*this)(j,i) = (T)sum;
--        }
--        ftype vmax=0;
--        { for (int i=j; i<dimx(); i++) {
--          ftype sum=(*this)(j,i);
--          for (int k=0; k<j; k++) sum-=(*this)(k,i)*(*this)(j,k);
--          (*this)(j,i) = (T)sum;
--          const ftype tmp = vv[i]*cimg::abs(sum);
--          if (tmp>=vmax) { vmax=tmp; imax=i; }
--        }}
--        if (j!=imax) {
--          cimg_forX(*this,k) cimg::swap((*this)(k,imax),(*this)(k,j));
--          d =!d;
--          vv[imax] = vv[j];
--        }
--        indx[j] = (t)imax;
--        if ((*this)(j,j)==0) (*this)(j,j)=(T)1e-20;
--        if (j<N) {
--          const ftype tmp = 1/(ftype)(*this)(j,j);
--          for (int i=j+1; i<N; i++) (*this)(j,i)*=tmp;
--        }
--      }
--      return *this;
--    }
--
--    // INNER ROUTINE : Solve a linear system, using the LU decomposition
--    template<typename t> CImg& _solve(const CImg<T>& A, const CImg<t>& indx) {
--      typedef typename cimg::largest<T,float>::type ftype;
--      const int N = size();
--      int ii=-1;
--      ftype sum;
--      for (int i=0; i<N; i++) {
--        const int ip = (int)indx[i];
--        ftype sum = (*this)(ip);
--        (*this)(ip) = (*this)(i);
--        if (ii>=0) for (int j=ii; j<=i-1; j++) sum-=A(j,i)*(*this)(j);
--        else if (sum!=0) ii=i;
--        (*this)(i)=sum;
--      }
--      { for (int i=N-1; i>=0; i--) {
--        sum = (*this)(i);
--        for (int j=i+1; j<N; j++) sum-=A(j,i)*(*this)(j);
--        (*this)(i)=sum/A(i,i);
--      }}
--      return *this;
--    }
--
--    //! Solve a linear system AX=B where B=*this. (in-place version)
--    CImg& solve(const CImg& A) {
--      if (width!=1 || depth!=1 || dim!=1 || height!=A.height || A.depth!=1 || A.dim!=1)
--        throw CImgArgumentException("CImg<%s>::solve() : Instance matrix size is (%u,%u,%u,%u) while "
--                                    "size of given matrix A is (%u,%u,%u,%u).",
--                                    pixel_type(),width,height,depth,dim,A.width,A.height,A.depth,A.dim);
--      if (A.width==A.height) {
--        CImg<T> lu(A);
--        CImg<T> indx;
--        bool d;
--        lu._LU(indx,d);
--        _solve(lu,indx);
--      } else assign(A.get_pseudoinverse()*(*this));
--      return *this;
--    }
--
--    //! Solve a linear system AX=B where B=*this.
--    CImg<typename cimg::largest<T,float>::type> get_solve(const CImg& A) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImg<restype>(*this,false).solve(A);
--    }
--
--    //! Compute the eigenvalues and eigenvectors of a matrix.
--    template<typename t> const CImg<T>& eigen(CImg<t>& val, CImg<t> &vec) const {
--      if (is_empty()) { val.assign(); vec.assign(); }
--      else {
--        if (width!=height || depth>1 || dim>1)
--          throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),width,height,depth,dim,data);
--        if (val.size()<width) val.assign(1,width);
--        if (vec.size()<width*width) vec.assign(width,width);
--        switch(width) {
--        case 1: { val[0]=(t)(*this)[0]; vec[0]=(t)1; } break;
--        case 2: {
--          const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a+d;
--          double f = e*e-4*(a*d-b*c);
--          cimg::warn(f<0,"CImg<%s>::eigen() : Complex eigenvalues",pixel_type());
--          f = std::sqrt(f);
--          const double l1 = 0.5*(e-f), l2 = 0.5*(e+f);
--          const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b);
--          val[0]=(t)l2;
--          val[1]=(t)l1;
--          vec(0,0) = (t)std::cos(theta1);
--          vec(0,1) = (t)std::sin(theta1);
--          vec(1,0) = (t)std::cos(theta2);
--          vec(1,1) = (t)std::sin(theta2);
--        } break;
--        default:
--          throw CImgInstanceException("CImg<%s>::eigen() : Eigenvalues computation of general matrices is limited"
--                                      "to 2x2 matrices (given is %ux%u)", pixel_type(),width,height);
--        }
--      }
--      return *this;
--    }
--
--    //! Return the eigenvalues and eigenvectors of a matrix.
--    CImgList<typename cimg::largest<T,float>::type> get_eigen() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      CImgList<restype> res(2);
--      eigen(res[0],res[1]);
--      return res;
--    }
--
--    //! Compute the eigenvalues and eigenvectors of a matrix.
--    template<typename t> const CImg<T>& eigen(CImgList<t>& eig) const {
--      if (eig.size<2) eig.assign(2);
--      eigen(eig[0],eig[1]);
--      return *this;
--    }
--
--    //! Compute the eigenvalues and eigenvectors of a symmetric matrix.
--    template<typename t> const CImg<T>& symmetric_eigen(CImg<t>& val, CImg<t>& vec) const {
--      if (is_empty()) { val.assign(); vec.assign(); }
--      else {
--        if (width!=height || depth>1 || dim>1)
--          throw CImgInstanceException("CImg<%s>::eigen() : Instance object (%u,%u,%u,%u,%p) is empty.",
--                                      pixel_type(),width,height,depth,dim,data);
--
--        if (val.size()<width) val.assign(1,width);
--        if (vec.data && vec.size()<width*width) vec.assign(width,width);
--        if (width<3) return eigen(val,vec);
--        CImg<t> V(width,width);
--        SVD(vec,val,V,false);
--        cimg_forX(vec,x) {       // check for negative eigenvalues
--          t scal=0;
--          cimg_forY(vec,y) scal+=vec(x,y)*V(x,y);
--          if (scal<0) val[x]=-val[x];
--        }
--        CImg<int> permutations(width);  // sort eigenvalues in decreasing order
--        CImg<t> tmp(width);
--        val.sort(permutations,false);
--        cimg_forY(vec,k) {
--          cimg_forX(permutations,x) tmp(x) = vec(permutations(x),k);
--          std::memcpy(vec.ptr(0,k),tmp.data,sizeof(t)*width);
--        }
--      }
--      return *this;
--    }
--
--    //! Compute the eigenvalues and eigenvectors of a symmetric matrix.
--    CImgList<typename cimg::largest<T,float>::type> get_symmetric_eigen() const {
--      typedef typename cimg::largest<T,float>::type restype;
--      CImgList<restype> res(2);
--      symmetric_eigen(res[0],res[1]);
--      return res;
--    }
--
--    //! Compute the eigenvalues and eigenvectors of a symmetric matrix.
--    template<typename t> const CImg<T>& symmetric_eigen(CImgList<t>& eig) const {
--      if (eig.size<2) eig.assign(2);
--      symmetric_eigen(eig[0],eig[1]);
--      return *this;
--    }
--
--    template<typename t> CImg<T>& _quicksort(const int min,const int max,CImg<t>& permutations,const bool increasing) {
--      if (min<max) {
--        const int mid = (min+max)/2;
--        if (increasing) {
--          if ((*this)[min]>(*this)[mid]) {
--            cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
--          if ((*this)[mid]>(*this)[max]) {
--            cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
--          if ((*this)[min]>(*this)[mid]) {
--            cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
--        } else {
--          if ((*this)[min]<(*this)[mid]) {
--            cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
--          if ((*this)[mid]<(*this)[max]) {
--            cimg::swap((*this)[max],(*this)[mid]); cimg::swap(permutations[max],permutations[mid]); }
--          if ((*this)[min]<(*this)[mid]) {
--            cimg::swap((*this)[min],(*this)[mid]); cimg::swap(permutations[min],permutations[mid]); }
--        }
--        if (max-min>=3) {
--          const T pivot = (*this)[mid];
--          int i = min, j = max;
--          if (increasing) {
--            do {
--              while ((*this)[i]<pivot) i++;
--              while ((*this)[j]>pivot) j--;
--              if (i<=j) {
--                cimg::swap((*this)[i],(*this)[j]);
--                cimg::swap(permutations[i++],permutations[j--]);
--              }
--            } while (i<=j);
--          } else {
--            do {
--              while ((*this)[i]>pivot) i++;
--              while ((*this)[j]<pivot) j--;
--              if (i<=j) {
--                cimg::swap((*this)[i],(*this)[j]);
--                cimg::swap(permutations[i++],permutations[j--]);
--              }
--            } while (i<=j);
--          }
--          if (min<j) _quicksort(min,j,permutations,increasing);
--          if (i<max) _quicksort(i,max,permutations,increasing);
--        }
--      }
--      return *this;
--    }
--
--    //! Sort values of a vector and get permutations.
--    template<typename t>
--    CImg<T>& sort(CImg<t>& permutations,const bool increasing=true) {
--      if (is_empty()) permutations.assign();
--      else {
--        if (permutations.size()!=size()) permutations.assign(size());
--        cimg_foroff(permutations,off) permutations[off] = (t)off;
--        _quicksort(0,size()-1,permutations,increasing);
--      }
--      return *this;
--    }
--
--    //! Sort values of a vector.
--    CImg<T>& sort(const bool increasing=true) { CImg<T> foo; return sort(foo,increasing); }
--
--    //! Get a sorted version a of vector, with permutations.
--    template<typename t> CImg<T> get_sort(CImg<t>& permutations,const bool increasing=true) {
--      return (+*this).sort(permutations,increasing);
--    }
--
--    //! Get a sorted version of a vector.
--    CImg<T> get_sort(const bool increasing=true) {
--      return (+*this).sort(increasing);
--    }
--
--    //! Get a permutation of the pixels
--    template<typename t> CImg<T> get_permute(const CImg<t>& permutation) const {
--      if (permutation.size()!=size())
--        throw CImgArgumentException("CImg<%s>::get_permute() : Instance image (%u,%u,%u,%u,%p) and permutation (%u,%u,%u,%u,%p)"
--                                    "have different sizes.",pixel_type(),
--                                    width,height,depth,dim,data,
--                                    permutation.width,permutation.height,permutation.depth,permutation.dim,permutation.data);
--      CImg<T> res(width,height,depth,dim);
--      const t *p = permutation.ptr(permutation.size());
--      cimg_for(res,ptr,T) *ptr = (*this)[*(--p)];
--      return res;
--    }
--
--    //! In-place version of the previous function
--    template<typename t> CImg<T>& permute(const CImg<t>& permutation) {
--      return get_permute(permutation).swap(*this);
--    }
--
--    //@}
--    //-------------------
--    //
--    //! \name Display
--    //@{
--    //-------------------
--
--    //! Display an image into a CImgDisplay window.
--    const CImg& display(CImgDisplay& disp) const {
--      disp.display(*this);
--      return *this;
--    }
--
--    //! Display an image in a window with a title \p title, and wait a 'is_closed' or 'keyboard' event.\n
--    //! Parameters \p min_size and \p max_size set the minimum and maximum dimensions of the display window.
--    //! If negative, they corresponds to a percentage of the original image size.
--    const CImg& display(const char* title, const int min_size=128, const int max_size=1024) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::display() : Instance image (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--      CImgDisplay *disp;
--      unsigned int w = width+(depth>1?depth:0), h = height+(depth>1?depth:0), XYZ[3];
--      print(title);
--      const unsigned int dmin = cimg::min(w,h), minsiz = min_size>=0?min_size:(-min_size)*dmin/100;
--      if (dmin<minsiz) { w=w*minsiz/dmin; w+=(w==0); h=h*minsiz/dmin; h+=(h==0); }
--      const unsigned int dmax = cimg::max(w,h), maxsiz = max_size>=0?max_size:(-max_size)*dmax/100;
--      if (dmax>maxsiz) { w=w*maxsiz/dmax; w+=(w==0); h=h*maxsiz/dmax; h+=(h==0); }
--      disp = new CImgDisplay(w,h,title,3,3);
--      XYZ[0] = width/2; XYZ[1] = height/2; XYZ[2] = depth/2;
--      while (!disp->is_closed && !disp->key) feature_selection(0,1,*disp,XYZ);
--      delete disp;
--      return *this;
--    }
--
--    //! Display an image in a window, with a default title. See also \see display() for details on parameters.
--    const CImg& display(const int min_size=128, const int max_size=1024) const {
--      char title[256]={0};
--      std::sprintf(title,"CImg<%s>",pixel_type());
--      return display(title,min_size,max_size);
--    }
--
--    //! High-level interface to select features from images
--    const CImg& feature_selection(int* const selection, const int feature_type, CImgDisplay &disp,
--                                  unsigned int *const XYZ=0,const unsigned char *const color=0) const {
--      if (is_empty())
--        throw CImgInstanceException("CImg<%s>::feature_selection() : Instance image (%u,%u,%u,%u,%p) is empty.",
--                                    pixel_type(),width,height,depth,dim,data);
--
--      const unsigned int
--        old_events = disp.events,
--        old_normalization = disp.normalization,
--        hatch = 0x55555555;
--
--      bool old_is_resized = disp.is_resized;
--      disp.events = 3;
--      disp.normalization = 0;
--      disp.show().key = 0;
--
--      unsigned char fgcolor[3] = { 255,255,105 }, bgcolor[3] = { 0,0,0 };
--      if (color) std::memcpy(fgcolor,color,sizeof(unsigned char)*cimg::min(3,dimv()));
--
--      int area = 0, clicked_area = 0, phase = 0,
--        X0 = (int)((XYZ?XYZ[0]:width/2)%width), Y0 = (int)((XYZ?XYZ[1]:height/2)%height), Z0 = (int)((XYZ?XYZ[2]:depth/2)%depth),
--        X1 =-1, Y1 = -1, Z1 = -1,
--        X = -1, Y = -1, Z = -1,
--        oX = X, oY = Y, oZ = Z;
--      unsigned int old_button = 0, key = 0;
--
--      bool feature_selected = false, text_down = false;
--      CImg<unsigned char> visu, visu0;
--      char text[1024] = { 0 };
--
--      while (!key && !disp.is_closed && !feature_selected) {
--
--        // Handle mouse motion and selection
--        oX = X; oY = Y; oZ = Z;
--        int mx = disp.mouse_x, my = disp.mouse_y;
--        const int mX = mx*(width+(depth>1?depth:0))/disp.width, mY = my*(height+(depth>1?depth:0))/disp.height;
--
--        area = 0;
--        if (mX<dimx() && mY<dimy())  { area = 1; X = mX; Y = mY; Z = phase?Z1:Z0; }
--        if (mX<dimx() && mY>=dimy()) { area = 2; X = mX; Z = mY-height; Y = phase?Y1:Y0; }
--        if (mX>=dimx() && mY<dimy()) { area = 3; Y = mY; Z = mX-width; X = phase?X1:X0; }
--
--      key = disp.key;
--        if (key && key!=cimg::keyCTRLLEFT) {
--          if (disp.is_pressed(cimg::keyCTRLLEFT)) {
--            switch (key) {
--            case cimg::keyARROWLEFT:
--            case cimg::keyARROWDOWN: disp.wheel--; break;
--            case cimg::keyARROWRIGHT:
--            case cimg::keyARROWUP: disp.wheel++; break;
--            case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
--            case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
--            case cimg::keyF:
--              disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen();
--              disp.is_resized = true;
--              break;
--            case cimg::keyS: {
--              static unsigned int snap_number = 0;
--              char filename[32] = {0};
--              std::FILE *file;
--              do {
--                std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
--                if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
--              } while (file);
--              if (!visu0.is_empty()) visu0.save(filename);
--            } break;
--          default: break;
--            }
--          key = disp.key = 0;
--          }
--        } else key = 0;
--
--        if (!area) mx = my = X = Y = Z = -1;
--        else {
--          if (disp.button&1 && phase<2) { X1 = X; Y1 = Y; Z1 = Z; }
--          if (!(disp.button&1) && phase>=2) {
--            switch (clicked_area) {
--            case 1: Z1 = Z; break;
--            case 2: Y1 = Y; break;
--            case 3: X1 = X; break;
--            }
--          }
--          if (disp.button&2) { if (phase) { X1 = X; Y1 = Y; Z1 = Z; } else { X0 = X; Y0 = Y; Z0 = Z; } }
--          if (disp.button&4) { oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = 0; visu.assign(); }
--          if (disp.wheel) {
--            switch (area) {
--            case 1: if (phase) Z = (Z1+=disp.wheel); else Z = (Z0+=disp.wheel); break;
--            case 2: if (phase) Y = (Y1+=disp.wheel); else Y = (Y0+=disp.wheel); break;
--            case 3: if (phase) X = (X1+=disp.wheel); else X = (X0+=disp.wheel); break;
--            default: break;
--            }
--            disp.wheel = 0;
--          }
--          if ((disp.button&1)!=old_button) {
--            switch (phase++) {
--            case 0: X0 = X1 = X; Y0 = Y1 = Y; Z0 = Z1 = Z; clicked_area = area; break;
--            case 1: X1 = X; Y1 = Y; Z1 = Z; break;
--            default: break;
--            }
--            old_button = disp.button&1;
--          }
--          if (depth>1 && (X!=oX || Y!=oY || Z!=oZ)) visu0.assign();
--        }
--
--        if (phase) {
--          if (!feature_type) feature_selected = phase?true:false;
--          else {
--            if (depth>1) feature_selected = (phase==3)?true:false;
--            else feature_selected = (phase==2)?true:false;
--          }
--        }
--
--        if (X0<0) X0 = 0; if (X0>=(int)width) X0 = (int)width-1; if (Y0<0) Y0 = 0; if (Y0>=(int)height) Y0 = (int)height-1;
--        if (Z0<0) Z0 = 0; if (Z0>=(int)depth) Z0 = (int)depth-1;
--        if (X1<1) X1 = 0; if (X1>=(int)width) X1 = (int)width-1; if (Y1<0) Y1 = 0; if (Y1>=(int)height) Y1 = (int)height-1;
--        if (Z1<0) Z1 = 0; if (Z1>=(int)depth) Z1 = (int)depth-1;
--
--        // Draw visualization image on the display
--        if (oX!=X || oY!=Y || oZ!=Z || visu0.is_empty()) {
--          if (visu0.is_empty()) {
--            CImg<T> tmp;
--            if (depth==1) tmp = get_resize(disp.width,disp.height,1,cimg::min(3,dimv()));
--            else tmp = (!phase?get_projections2d(X0,Y0,Z0):get_projections2d(X1,Y1,Z1)).get_resize(disp.width,disp.height,1,cimg::min(3,dimv()));
--            if (old_normalization) {
--              if (old_normalization<3 || cimg::type<T>::is_float()) {
--                if (sizeof(T)>1) visu0.assign(tmp.normalize(0,255));
--                else visu0.assign(tmp).normalize(0,255);
--              } else {
--                if (cimg::type<T>::id()!=cimg::type<unsigned char>::id()) {
--                  const float m = cimg::type<T>::min(), M = cimg::type<T>::max();
--                  visu0.assign((CImg<float>(tmp)-=m)*=255.0f/(M-m));
--                } else visu0.assign(tmp);
--              }
--            } else visu0.assign(tmp);
--          }
--          visu = visu0;
--
--          const int d=(depth>1)?depth:0;
--          if (phase) switch (feature_type) {
--          case 1: {
--            const int
--              x0=(int)((X0+0.5f)*disp.width/(width+d)), y0=(int)((Y0+0.5f)*disp.height/(height+d)),
--              x1=(int)((X1+0.5f)*disp.width/(width+d)), y1=(int)((Y1+0.5f)*disp.height/(height+d));
--            visu.draw_arrow(x0,y0,x1,y1,fgcolor,30.0f,5.0f,hatch);
--            if (d) {
--              const int zx0=(int)((width+Z0+0.5f)*disp.width/(width+d)), zx1=(int)((width+Z1+0.5f)*disp.width/(width+d)),
--                zy0=(int)((height+Z0+0.5f)*disp.height/(height+d)), zy1=(int)((height+Z1+0.5f)*disp.height/(height+d));
--              visu.draw_arrow(zx0,y0,zx1,y1,fgcolor,30.0f,5.0f,hatch).draw_arrow(x0,zy0,x1,zy1,fgcolor,30.0f,5.0f,hatch);
--            }
--          } break;
--          case 2: {
--            const int
--              x0=(X0<X1?X0:X1)*disp.width/(width+d),
--              y0=(Y0<Y1?Y0:Y1)*disp.height/(height+d),
--              x1=((X0<X1?X1:X0)+1)*disp.width/(width+d)-1,
--              y1=((Y0<Y1?Y1:Y0)+1)*disp.height/(height+d)-1;
--            visu.draw_rectangle(x0,y0,x1,y1,fgcolor,0.2f).draw_line(x0,y0,x1,y0,fgcolor,hatch).
--              draw_line(x1,y0,x1,y1,fgcolor,hatch).draw_line(x1,y1,x0,y1,fgcolor,hatch).draw_line(x0,y1,x0,y0,fgcolor,hatch);
--            if (d) {
--              const int
--                zx0=(int)((width+(Z0<Z1?Z0:Z1))*disp.width/(width+d)),
--                zy0=(int)((height+(Z0<Z1?Z0:Z1))*disp.height/(height+d)),
--                zx1=(int)((width+(Z0<Z1?Z1:Z0)+1)*disp.width/(width+d))-1,
--                zy1=(int)((height+(Z0<Z1?Z1:Z0)+1)*disp.height/(height+d))-1;
--              visu.draw_rectangle(zx0,y0,zx1,y1,fgcolor,0.2f).draw_line(zx0,y0,zx1,y0,fgcolor,hatch).
--                draw_line(zx1,y0,zx1,y1,fgcolor,hatch).draw_line(zx1,y1,zx0,y1,fgcolor,hatch).draw_line(zx0,y1,zx0,y0,fgcolor,hatch);
--              visu.draw_rectangle(x0,zy0,x1,zy1,fgcolor,0.2f).draw_line(x0,zy0,x1,zy0,fgcolor,hatch).
--                draw_line(x1,zy0,x1,zy1,fgcolor,hatch).draw_line(x1,zy1,x0,zy1,fgcolor,hatch).draw_line(x0,zy1,x0,zy0,fgcolor,hatch);
--            }
--          } break;
--          case 3: {
--            const int
--              x0=X0*disp.width/(width+d),
--              y0=Y0*disp.height/(height+d),
--              x1=X1*disp.width/(width+d)-1,
--              y1=Y1*disp.height/(height+d)-1;
--            visu.draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,0L,0.2f).
--              draw_ellipse(x0,y0,(float)(x1-x0),(float)(y1-y0),1.0f,0.0f,fgcolor,hatch);
--            if (d) {
--              const int
--                zx0=(int)((width+Z0)*disp.width/(width+d)),
--                zy0=(int)((height+Z0)*disp.height/(height+d)),
--                zx1=(int)((width+Z1+1)*disp.width/(width+d))-1,
--                zy1=(int)((height+Z1+1)*disp.height/(height+d))-1;
--              visu.draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,0L,0.2f).
--                draw_ellipse(zx0,y0,(float)(zx1-zx0),(float)(y1-y0),1.0f,0.0f,fgcolor,hatch).
--                draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,0L,0.2f).
--                draw_ellipse(x0,zy0,(float)(x1-x0),(float)(zy1-zy0),1.0f,0.0f,fgcolor,hatch);
--            }
--          } break;
--          }
--
--          if (my<12) text_down = true;
--          if (my>=visu.dimy()-11) text_down = false;
--          if (!feature_type || !phase) {
--            if (X>=0 && Y>=0 && Z>=0 && X<(int)width && Y<(int)height && Z<(int)depth) {
--              if (depth>1) std::sprintf(text,"Coords (%d,%d,%d)={ ",X,Y,Z); else std::sprintf(text,"Coords (%d,%d)={ ",X,Y);
--              char *ctext = text + cimg::strlen(text), *const ltext = text+512;
--              for (unsigned int k=0; k<dim && ctext<ltext; k++) {
--                std::sprintf(ctext,"%g ",(double)(*this)(X,Y,Z,k));
--                ctext = text + cimg::strlen(text);
--              }
--              std::sprintf(text+cimg::strlen(text),"}");
--            }
--          } else switch (feature_type) {
--          case 1: {
--            const double dX=(double)(X0-X1), dY=(double)(Y0-Y1), dZ=(double)(Z0-Z1), norm = std::sqrt(dX*dX+dY*dY+dZ*dZ);
--            if (depth>1) std::sprintf(text,"Vect (%d,%d,%d)-(%d,%d,%d), norm=%g",X0,Y0,Z0,X1,Y1,Z1,norm);
--            else std::sprintf(text,"Vect (%d,%d)-(%d,%d), norm=%g",X0,Y0,X1,Y1,norm);
--          } break;
--          case 2:
--            if (depth>1) std::sprintf(text,"Box (%d,%d,%d)-(%d,%d,%d), Size=(%d,%d,%d)",
--                                      X0<X1?X0:X1,Y0<Y1?Y0:Y1,Z0<Z1?Z0:Z1,
--                                      X0<X1?X1:X0,Y0<Y1?Y1:Y0,Z0<Z1?Z1:Z0,
--                                      1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
--            else  std::sprintf(text,"Box (%d,%d)-(%d,%d), Size=(%d,%d)",
--                               X0<X1?X0:X1,Y0<Y1?Y0:Y1,X0<X1?X1:X0,Y0<Y1?Y1:Y0,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
--            break;
--          default:
--            if (depth>1) std::sprintf(text,"Ellipse (%d,%d,%d)-(%d,%d,%d), Radii=(%d,%d,%d)",
--                                      X0,Y0,Z0,X1,Y1,Z1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
--            else  std::sprintf(text,"Ellipse (%d,%d)-(%d,%d), Radii=(%d,%d)",
--                               X0,Y0,X1,Y1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
--
--            break;
--          }
--          if (phase || (mx>=0 && my>=0)) visu.draw_text(text,0,text_down?visu.dimy()-11:0,fgcolor,bgcolor,11,0.7f);
--          disp.display(visu).wait(25);
--        } else disp.wait();
--
--        if (disp.is_resized) { disp.resize(false); old_is_resized = true; disp.is_resized = false; visu0.assign(); }
--      }
--
--      // Return result
--      if (XYZ) { XYZ[0] = (unsigned int)X0; XYZ[1] = (unsigned int)Y0; XYZ[2] = (unsigned int)Z0; }
--      if (feature_selected) {
--        if (feature_type==2) {
--          if (X0>X1) cimg::swap(X0,X1);
--          if (Y0>Y1) cimg::swap(Y0,Y1);
--          if (Z0>Z1) cimg::swap(Z0,Z1);
--        }
--        if (selection) {
--          if (X1<0 || Y1<0 || Z1<0) X0=Y0=Z0=X1=Y1=Z1=-1;
--          switch(feature_type) {
--          case 1:
--          case 2:  selection[3] = X1; selection[4] = Y1; selection[5] = Z1;
--          default: selection[0] = X0; selection[1] = Y0; selection[2] = Z0;
--          }
--        }
--      } else if (selection) selection[0]=selection[1]=selection[2]=selection[3]=selection[4]=selection[5]=-1;
--      disp.button = 0;
--      disp.events = old_events;
--      disp.normalization = old_normalization;
--      disp.is_resized = old_is_resized;
--      disp.key = key;
--      return *this;
--    }
--
--    //! High-level interface to select features in images
--    const CImg& feature_selection(int *const selection, const int feature_type,
--                                  unsigned int *const XYZ=0,const unsigned char *const color=0) const {
--      unsigned int w = width + (depth>1?depth:0), h = height + (depth>1?depth:0);
--      const unsigned int dmin = cimg::min(w,h), minsiz = 256;
--      if (dmin<minsiz) { w=w*minsiz/dmin; h=h*minsiz/dmin; }
--      const unsigned int dmax = cimg::max(w,h), maxsiz = 1024;
--      if (dmax>maxsiz) { w=w*maxsiz/dmax; h=h*maxsiz/dmax; }
--      CImgDisplay disp(w,h," ",1,3);
--      return feature_selection(selection,feature_type,disp,XYZ,color);
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf, typename to>
--    const CImg& display_object3d(const CImg<tp>& points,const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, const CImgList<to>& opacities, CImgDisplay& disp,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const bool display_axes=true, float *const pose_matrix=0) const {
--
--      // Check input arguments
--      if (points.is_empty() || primitives.is_empty() || opacities.is_empty())
--        throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (%u), primitives (%u) or opacities (%u) are empty.",
--                                    pixel_type(),points.size()/3,primitives.size,opacities.size);
--      if (is_empty())
--        return CImg<T>(disp.width,disp.height,1,colors[0].size(),0).
--          display_object3d(points,primitives,colors,opacities,disp,centering,
--                           render_static,render_motion,double_sided,focale,ambiant_light);
--      if (points.height<3)
--        return display_object3d(points.get_resize(-100,3,1,1,0),primitives,colors,opacities,disp,
--                                centering,render_static,render_motion,double_sided,focale,ambiant_light);
--
--      // Init 3D objects and compute object statistics
--      CImg<float> pose, rot_mat,
--        centered_points = centering?CImg<float>(points.width,3):CImg<float>(),
--        rotated_points(points.width,3),
--        bbox_points, rotated_bbox_points,
--        axes_points, rotated_axes_points;
--      CImgList<to> bbox_opacities, axes_opacities;
--      CImgList<T> bbox_colors, axes_colors;
--      CImgList<tf> bbox_primitives, axes_primitives;
--      float dx=0, dy=0, dz=0, ratio=1;
--      const T valmax = cimg::type<T>::max();
--
--      const CImgStats
--        sx(points.get_shared_line(0),false),
--        sy(points.get_shared_line(1),false),
--        sz(points.get_shared_line(2),false);
--      const float
--        xm = (float)sx.min, xM = (float)sx.max,
--        ym = (float)sy.min, yM = (float)sy.max,
--      zm = (float)sz.min, zM = (float)sz.max,
--        delta = cimg::max(xM-xm,yM-ym,zM-zm);
--
--      if (display_axes) {
--        axes_points.assign(7,3);
--        rotated_axes_points.assign(7,3);
--        axes_opacities.assign(3,1,1,1,1,1.0f);
--        axes_colors.assign(3,dim,1,1,1,valmax);
--        axes_points(0,0) = 0; axes_points(0,1) = 0; axes_points(0,2) = 0;
--        axes_points(1,0) = 20; axes_points(1,1) = 0; axes_points(1,2) = 0;
--        axes_points(2,0) = 0; axes_points(2,1) = 20; axes_points(2,2) = 0;
--        axes_points(3,0) = 0; axes_points(3,1) = 0; axes_points(3,2) = 20;
--        axes_points(4,0) = 22; axes_points(4,1) = -6; axes_points(4,2) = 0;
--        axes_points(5,0) = -6; axes_points(5,1) = 22; axes_points(5,2) = 0;
--        axes_points(6,0) = -6; axes_points(6,1) = -6; axes_points(6,2) = 22;
--        axes_primitives.insert(CImg<tf>::vector(0,1));
--        axes_primitives.insert(CImg<tf>::vector(0,2));
--        axes_primitives.insert(CImg<tf>::vector(0,3));
--      }
--
--      // Begin user interaction loop
--      CImg<T> visu0(*this), visu;
--      bool init = true, clicked = false, redraw = true;
--      unsigned int key = 0;
--      int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
--      const unsigned int old_events = disp.events;
--      disp.show().button = disp.key = 0;
--      disp.events = 3;
--
--      while (!disp.is_closed && !key) {
--
--        // Init object position and scale if necessary
--        if (init) {
--          ratio = delta>0?(2.0f*cimg::min(disp.width,disp.height)/(3.0f*delta)):0;
--          dx = 0.5f*(xM+xm); dy = 0.5f*(yM+ym); dz = 0.5f*(zM+zm);
--          if (centering) {
--            cimg_forX(centered_points,l) {
--              centered_points(l,0) = (float)((points(l,0)-dx)*ratio);
--              centered_points(l,1) = (float)((points(l,1)-dy)*ratio);
--              centered_points(l,2) = (float)((points(l,2)-dz)*ratio);
--            }
--          }
--
--          if (render_static<0 || render_motion<0) {
--            bbox_colors.assign(12,dim,1,1,1,valmax);
--            bbox_primitives.assign(12,1,2);
--            bbox_points.assign(8,3);
--            rotated_bbox_points.assign(8,3);
--            bbox_points(0,0) = xm; bbox_points(0,1) = ym; bbox_points(0,2) = zm;
--            bbox_points(1,0) = xM; bbox_points(1,1) = ym; bbox_points(1,2) = zm;
--            bbox_points(2,0) = xM; bbox_points(2,1) = yM; bbox_points(2,2) = zm;
--            bbox_points(3,0) = xm; bbox_points(3,1) = yM; bbox_points(3,2) = zm;
--            bbox_points(4,0) = xm; bbox_points(4,1) = ym; bbox_points(4,2) = zM;
--            bbox_points(5,0) = xM; bbox_points(5,1) = ym; bbox_points(5,2) = zM;
--            bbox_points(6,0) = xM; bbox_points(6,1) = yM; bbox_points(6,2) = zM;
--            bbox_points(7,0) = xm; bbox_points(7,1) = yM; bbox_points(7,2) = zM;
--            bbox_primitives[0].fill(0,1); bbox_primitives[1].fill(1,2); bbox_primitives[2].fill(2,3);  bbox_primitives[3].fill(3,0);
--            bbox_primitives[4].fill(4,5); bbox_primitives[5].fill(5,6); bbox_primitives[6].fill(6,7);  bbox_primitives[7].fill(7,4);
--            bbox_primitives[8].fill(0,4); bbox_primitives[9].fill(1,5); bbox_primitives[10].fill(2,6); bbox_primitives[11].fill(3,7);
--            bbox_opacities.assign(bbox_primitives.size,1,1,1,1,1.0f);
--          }
--
--          if (pose_matrix) pose = CImg<float>(pose_matrix,4,4,1,1,false); else pose = CImg<float>::identity_matrix(4);
--          init = false;
--          redraw = true;
--        }
--
--        // Rotate and Draw 3D object
--        if (redraw) {
--          const float
--            r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0),
--            r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1),
--            r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2);
--          if ((clicked && render_motion>=0) || (!clicked && render_static>=0)) {
--            if (centering) cimg_forX(centered_points,l) {
--              const float x = centered_points(l,0), y = centered_points(l,1), z = centered_points(l,2);
--              rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
--              rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
--              rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
--            } else cimg_forX(points,l) {
--              const float x = (float)points(l,0), y = (float)points(l,1), z = (float)points(l,2);
--              rotated_points(l,0) = r00*x + r10*y + r20*z + r30;
--              rotated_points(l,1) = r01*x + r11*y + r21*z + r31;
--              rotated_points(l,2) = r02*x + r12*y + r22*z + r32;
--            }
--          } else {
--            if (!centering) cimg_forX(bbox_points,l) {
--              const float x = bbox_points(l,0), y = bbox_points(l,1), z = bbox_points(l,2);
--              rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
--              rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
--              rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
--            } else cimg_forX(bbox_points,l) {
--              const float x = (bbox_points(l,0)-dx)*ratio, y = (bbox_points(l,1)-dy)*ratio, z = (bbox_points(l,2)-dz)*ratio;
--              rotated_bbox_points(l,0) = r00*x + r10*y + r20*z + r30;
--              rotated_bbox_points(l,1) = r01*x + r11*y + r21*z + r31;
--              rotated_bbox_points(l,2) = r02*x + r12*y + r22*z + r32;
--            }
--          }
--
--          // Draw object
--          visu = visu0;
--          if ((clicked && render_motion<0) || (!clicked && render_static<0))
--            visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
--                               rotated_bbox_points,bbox_primitives,bbox_colors,bbox_opacities,1,
--                               false,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,0.2f);
--          else visu.draw_object3d(visu.width/2.0f, visu.height/2.0f, 0,
--                                  rotated_points,primitives,colors,opacities,clicked?render_motion:render_static,
--                                  double_sided,focale,visu.dimx()/2.0f,visu.dimy()/2.0f,-5000.0f,ambiant_light);
--
--          // Draw axes
--          if (display_axes) {
--            const float Xaxes = 25.0f, Yaxes = visu.height-35.0f;
--            cimg_forX(axes_points,l) {
--              const float x = axes_points(l,0), y = axes_points(l,1), z = axes_points(l,2);
--              rotated_axes_points(l,0) = r00*x + r10*y + r20*z;
--              rotated_axes_points(l,1) = r01*x + r11*y + r21*z;
--              rotated_axes_points(l,2) = r02*x + r12*y + r22*z;
--            }
--            axes_opacities(0,0) = (rotated_axes_points(1,2)>0)?0.5f:1.0f;
--            axes_opacities(1,0) = (rotated_axes_points(2,2)>0)?0.5f:1.0f;
--            axes_opacities(2,0) = (rotated_axes_points(3,2)>0)?0.5f:1.0f;
--            visu.draw_object3d(Xaxes, Yaxes, 0, rotated_axes_points,axes_primitives,axes_colors,axes_opacities,1,false,focale,0,0,0,0).
--              draw_text("X",(int)(Xaxes+rotated_axes_points(4,0)), (int)(Yaxes+rotated_axes_points(4,1)), axes_colors[0].ptr(), 0, 11, axes_opacities(0,0)).
--              draw_text("Y",(int)(Xaxes+rotated_axes_points(5,0)), (int)(Yaxes+rotated_axes_points(5,1)), axes_colors[1].ptr(), 0, 11, axes_opacities(1,0)).
--              draw_text("Z",(int)(Xaxes+rotated_axes_points(6,0)), (int)(Yaxes+rotated_axes_points(6,1)), axes_colors[2].ptr(), 0, 11, axes_opacities(2,0));
--          }
--
--          visu.display(disp);
--          if (!clicked || render_motion==render_static) redraw = false;
--        }
--
--        // Handle user interaction
--        if ((disp.button || disp.wheel) && disp.mouse_x>=0 && disp.mouse_y>=0) {
--          redraw = true;
--          if (!clicked) { x0 = x1 = disp.mouse_x; y0 = y1 = disp.mouse_y; if (!disp.wheel) clicked = true; }
--          else { x1 = disp.mouse_x; y1 = disp.mouse_y; }
--          if (disp.button&1) {
--            const float
--              R = 0.4f*cimg::min(disp.width,disp.height),
--              R2 = R*R,
--              u0 = (float)(x0-disp.dimx()/2),
--              v0 = (float)(y0-disp.dimy()/2),
--              u1 = (float)(x1-disp.dimx()/2),
--              v1 = (float)(y1-disp.dimy()/2),
--              n0 = (float)std::sqrt(u0*u0+v0*v0),
--              n1 = (float)std::sqrt(u1*u1+v1*v1),
--              nu0 = n0>R?(u0*R/n0):u0,
--              nv0 = n0>R?(v0*R/n0):v0,
--              nw0 = (float)std::sqrt(cimg::max(0.0f,R2-nu0*nu0-nv0*nv0)),
--              nu1 = n1>R?(u1*R/n1):u1,
--              nv1 = n1>R?(v1*R/n1):v1,
--              nw1 = (float)std::sqrt(cimg::max(0.0f,R2-nu1*nu1-nv1*nv1)),
--              u = nv0*nw1-nw0*nv1,
--              v = nw0*nu1-nu0*nw1,
--              w = nv0*nu1-nu0*nv1,
--              n = (float)std::sqrt(u*u+v*v+w*w),
--              alpha = (float)std::asin(n/R2);
--            rot_mat = CImg<float>::rotation_matrix(u,v,w,alpha);
--            rot_mat *= pose.get_crop(0,0,2,2);
--            pose.draw_image(rot_mat,0,0);
--            x0=x1; y0=y1;
--          }
--          if (disp.button&2) { pose(3,2)+=(y1-y0); x0=x1; y0=y1; }
--          if (disp.wheel) { pose(3,2)-=15*disp.wheel; disp.wheel=0; }
--          if (disp.button&4) { pose(3,0)+=(x1-x0); pose(3,1)+=(y1-y0); x0=x1; y0=y1; }
--          if ((disp.button&1) && (disp.button&2)) { init = true; disp.button = 0; x0 = x1; y0 = y1; pose = CImg<float>::identity_matrix(4); }
--        } else if (clicked) { x0=x1; y0=y1; clicked = false; redraw = true; }
--
--        key = disp.key;
--        if (key && key!=cimg::keyCTRLLEFT) {
--          if (disp.is_pressed(cimg::keyCTRLLEFT)) {
--            switch (key) {
--            case cimg::keyD: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-200,-200); disp.is_resized = true; break;
--            case cimg::keyC: if (disp.is_fullscreen) disp.toggle_fullscreen(); disp.resize(-50,-50); disp.is_resized = true; break;
--            case cimg::keyF: disp.resize(disp.screen_dimx(),disp.screen_dimy()).toggle_fullscreen().is_resized = true; break;
--            case cimg::keyS: { // Save snapshot
--              static unsigned int snap_number = 0;
--              char filename[32] = {0};
--              std::FILE *file;
--              do {
--                std::sprintf(filename,"CImg_%.4u.bmp",snap_number++);
--                if ((file=std::fopen(filename,"r"))!=0) std::fclose(file);
--              } while (file);
--              visu.save(filename);
--            } break;
--            }
--            disp.key = key = 0;
--          }
--        } else key = 0;
--        if (disp.is_resized) { disp.resize(false); visu0 = get_resize(disp,1); redraw = true; }
--      }
--      if (pose_matrix) std::memcpy(pose_matrix,pose.data,16*sizeof(float));
--      disp.events = old_events;
--      disp.button = 0;
--      return *this;
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf, typename to>
--    const CImg& display_object3d(const CImgList<tp>& points,const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, const CImgList<to>& opacities, CImgDisplay &disp,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const bool display_axes=true, float *const pose_matrix=0) const {
--      CImg<tp> npoints(points.size,3,1,1,0);
--      tp *ptrX = npoints.ptr(), *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
--      cimg_forX(npoints,l) {
--        const CImg<tp>& point = points[l];
--        const unsigned int siz = point.size();
--        if (!siz)
--          throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
--                                      "position %u.",pixel_type(),points.size,l);
--        *(ptrZ++) = (siz>2)?point(2):0;
--        *(ptrY++) = (siz>1)?point(1):0;
--        *(ptrX++) = point(0);
--      }
--      return display_object3d(npoints,primitives,colors,opacities,disp,centering,
--                              render_static,render_motion,double_sided,focale,ambiant_light,display_axes,pose_matrix);
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf, typename to>
--    const CImg& display_object3d(const CImg<tp>& points, const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, const CImg<to>& opacities, CImgDisplay& disp,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const bool display_axes=true, float *const pose_matrix=0) const {
--      CImgList<to> nopacities(opacities.size(),1);
--      cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
--      return display_object3d(points,primitives,colors,nopacities,disp,centering,
--                              render_static,render_motion,double_sided,focale,ambiant_light,display_axes,pose_matrix);
--
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf, typename to>
--    const CImg& display_object3d(const CImgList<tp>& points,const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, const CImg<to>& opacities, CImgDisplay& disp,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const bool display_axes=true, float *const pose_matrix=0) const {
--      CImgList<to> nopacities(opacities.size(),1);
--      cimglist_for(nopacities,l) nopacities(l,0) = opacities(l);
--      if (points.is_empty()) throw CImgArgumentException("CImg<%s>::display_object3d() : Given points are empty.",
--                                                         pixel_type());
--      CImg<tp> npoints(points.size,3,1,1,0);
--      tp *ptrX = npoints.ptr(), *ptrY = npoints.ptr(0,1), *ptrZ = npoints.ptr(0,2);
--      { cimg_forX(npoints,l) {
--        const CImg<tp>& point = points[l];
--        const unsigned int siz = point.size();
--        if (!siz)
--          throw CImgArgumentException("CImg<%s>::display_object3d() : Given points (size=%u) contains a null element at "
--                                      "position %u.",pixel_type(),points.size,l);
--        *(ptrZ++) = (siz>2)?point(2):0;
--        *(ptrY++) = (siz>1)?point(1):0;
--        *(ptrX++) = point(0);
--      }
--      }
--      return display_object3d(npoints,primitives,colors,nopacities,disp,centering,
--                              render_static,render_motion,double_sided,focale,ambiant_light,display_axes,pose_matrix);
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf, typename to>
--    const CImg& display_object3d(const tp& points, const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, const to& opacities,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const bool display_axes=true, float *const pose_matrix=0) const {
--      CImgDisplay disp(width,height," ",0);
--      return display_object3d(points,primitives,colors,opacities,disp,centering,
--                              render_static,render_motion,double_sided,focale,ambiant_light,display_axes,pose_matrix);
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf>
--    const CImg& display_object3d(const tp& points, const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const float opacity=1.0f, const bool display_axes=true, float *const pose_matrix=0) const {
--      CImgDisplay disp(width,height," ",0);
--      return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
--                              disp,centering,render_static,render_motion,double_sided,
--                              focale,ambiant_light,display_axes,pose_matrix);
--    }
--
--    //! High-level interface for displaying a 3d object
--    template<typename tp, typename tf>
--    const CImg& display_object3d(const tp& points, const CImgList<tf>& primitives,
--                                 const CImgList<T>& colors, CImgDisplay &disp,
--                                 const bool centering=true,
--                                 const int render_static=4, const int render_motion=1,
--                                 const bool double_sided=false,
--                                 const float focale=500.0f, const float ambiant_light=0.05f,
--                                 const float opacity=1.0f, const bool display_axes=true, float *const pose_matrix=0) const {
--      return display_object3d(points,primitives,colors,CImg<float>::vector(opacity),
--                              disp,centering,render_static,render_motion,double_sided,
--                              focale,ambiant_light,display_axes,pose_matrix);
--    }
--
--    //@}
--    //----------------------
--    //
--    //! \name Input-Output
--    //@{
--    //----------------------
--
--    //! Load an image from a file.
--    /**
--       \param filename = name of the image file to load.
--       \return A CImg<T> instance containing the pixel data defined in the image file.
--       \note The extension of \c filename defines the file format. If no filename
--       extension is provided, CImg<T>::get_load() will try to load a CRAW file (CImg Raw file).
--    **/
--    static CImg get_load(const char *const filename) {
--      const char *ext = cimg::filename_split(filename);
--      if (!cimg::strncasecmp(ext,"asc",3))   return get_load_ascii(filename);
--      if (!cimg::strncasecmp(ext,"dlm",3) ||
--          !cimg::strncasecmp(ext,"txt",3))   return get_load_dlm(filename);
--      if (!cimg::strncasecmp(ext,"inr",3))   return get_load_inr(filename);
--      if (!cimg::strncasecmp(ext,"hdr",3))   return get_load_analyze(filename);
--      if (!cimg::strncasecmp(ext,"par",3) ||
--          !cimg::strncasecmp(ext,"rec",3))   return get_load_parrec(filename);
--      if (!cimg::strncasecmp(ext,"pan",3))   return get_load_pandore(filename);
--      if (!cimg::strncasecmp(ext,"bmp",3))   return get_load_bmp(filename);
--      if (!cimg::strncasecmp(ext,"png",3))   return get_load_png(filename);
--      if (!cimg::strncasecmp(ext,"tif",3))   return get_load_tiff(filename);
--      if (!cimg::strncasecmp(ext,"jpg",3) ||
--          !cimg::strncasecmp(ext,"jpeg",4))  return get_load_jpeg(filename);
--      if (!cimg::strncasecmp(ext,"ppm",3) ||
--          !cimg::strncasecmp(ext,"pgm",3) ||
--          !cimg::strncasecmp(ext,"pnm",3))   return get_load_pnm(filename);
--      if (!cimg::strncasecmp(ext,"cimg",4) ||
--          ext[0]=='\0')                      return get_load_cimg(filename);
--      if (!cimg::strncasecmp(ext,"dcm",3) ||
--          !cimg::strncasecmp(ext,"dicom",5)) return get_load_dicom(filename);
--      return get_load_other(filename);
--    }
--
--    //! Load an image from a file
--    /** This is the in-place version of get_load(). **/
--    CImg& load(const char *const filename) {
--      return get_load(filename).swap(*this);
--    }
--
--    //! Load an image from an ASCII file.
--    static CImg get_load_ascii(std::FILE *const file, const char *const filename=0) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      char line[256] = {0};
--      std::fscanf(nfile,"%255[^\n]",line);
--      unsigned int off, dx = 0, dy = 1, dz = 1, dv = 1;
--      int err = 1;
--      std::sscanf(line,"%u %u %u %u",&dx,&dy,&dz,&dv);
--      if (!dx || !dy || !dz || !dv) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_ascii() : File '%s' is not a valid .ASC file.\n"
--                              "Specified image dimensions are (%u,%u,%u,%u).",
--                              pixel_type(),filename?filename:"(FILE*)",dx,dy,dz,dv);
--      }
--      CImg dest(dx,dy,dz,dv);
--      double val;
--      T *ptr = dest.data;
--      for (off=0; off<dest.size() && err==1; off++) {
--        err = std::fscanf(nfile,"%lf%*[^0-9.eE+-]",&val);
--        *(ptr++)=(T)val;
--      }
--      cimg::warn(off<dest.size(),"CImg<%s>::get_load_ascii() : File '%s', only %u/%u values read.",
--                 pixel_type(),filename?filename:"(FILE*)",off,dest.size());
--      if (!file) cimg::fclose(nfile);
--      return dest;
--    }
--
--    //! Load an image from an ASCII file.
--    static CImg get_load_ascii(const char *const filename) {
--      return get_load_ascii(0,filename);
--    }
--
--    //! Load an image from an ASCII file (in-place version).
--    CImg& load_ascii(std::FILE *const file, const char *const filename=0) {
--      return get_load_ascii(file,filename).swap(*this);
--    }
--
--    //! Load an image from an ASCII file (in-place version).
--    CImg& load_ascii(const char *const filename) {
--      return get_load_ascii(filename).swap(*this);
--    }
--
--    //! Load an image from a DLM file
--    static CImg get_load_dlm(std::FILE *const file, const char *const filename=0) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"r");
--      CImg dest(256,256);
--      char c, delimiter[256]={0}, tmp[256];
--      unsigned int cdx=0,dx=0,dy=0;
--      int oerr=0, err;
--      double val;
--      while ((err = std::fscanf(nfile,"%lf%255[^0-9.eE+-]",&val,delimiter))!=EOF) {
--        oerr = err;
--        if (err>0) dest(cdx++,dy) = (T)val;
--        if (cdx>=dest.width) dest.resize(dest.width+256,1,1,1,0);
--        c=0; if (!std::sscanf(delimiter,"%255[^\n]%c",tmp,&c) || c=='\n') {
--          dx = cimg::max(cdx,dx);
--          dy++;
--          if (dy>=dest.height) dest.resize(dest.width,dest.height+256,1,1,0);
--          cdx=0;
--        }
--      }
--      if (cdx && oerr==1) { dx=cdx; dy++; }
--      if (!dx || !dy) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_dlm() : File '%s' is not a valid DLM file.\n"
--                              "Specified image dimensions are (%u,%u).",
--                              pixel_type(),filename?filename:"(FILE*)",dx,dy);
--      }
--      dest.resize(dx,dy,1,1,0);
--      if (!file) cimg::fclose(nfile);
--      return dest;
--    }
--
--    //! Load an image from a DLM file
--    static CImg get_load_dlm(const char *const filename=0) {
--      return get_load_dlm(0,filename);
--    }
--
--    //! Load an image from a DLM file (in-place version).
--    CImg& load_dlm(std::FILE *const file, const char *const filename=0) {
--      return get_load_dlm(file,filename).swap(*this);
--    }
--
--    //! Load an image from a DLM file (in-place version).
--    CImg& load_dlm(const char *const filename) {
--      return get_load_dlm(filename).swap(*this);
--    }
--
--    //! Load an image from a PNM file
--    static CImg get_load_pnm(std::FILE *const file, const char *const filename=0) {
--      std::FILE *const nfile=file?file:cimg::fopen(filename,"rb");
--      unsigned int ppm_type,width,height,colormax=255;
--      char item[1024]={0};
--      int err;
--      while ((err=std::fscanf(nfile,"%1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
--      if(std::sscanf(item," P%u",&ppm_type)!=1) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_pnm() : File '%s', PNM header 'P?' not found.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
--      if ((err=std::sscanf(item," %u %u %u",&width,&height,&colormax))<2) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_pnm() : File '%s', WIDTH and HEIGHT fields are not defined in PNM header.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      if (err==2) {
--        while ((err=std::fscanf(nfile," %1023[^\n]",item))!=EOF && (item[0]=='#' || !err)) std::fgetc(nfile);
--        cimg::warn(std::sscanf(item,"%u",&colormax)!=1,
--                   "CImg<%s>::get_load_pnm() : File '%s', COLORMAX field is not defined in PNM header.",
--                   pixel_type(),filename?filename:"(FILE*)");
--      }
--      std::fgetc(nfile);
--
--      CImg dest;
--      int rval,gval,bval;
--
--      switch (ppm_type) {
--      case 2: { // Grey Ascii
--        dest.assign(width,height,1,1);
--        T* rdata = dest.ptr();
--        cimg_foroff(dest,off) { std::fscanf(nfile,"%d",&rval); *(rdata++)=(T)rval; }
--      } break;
--      case 3: { // Color Ascii
--        dest.assign(width,height,1,3);
--        T *rdata = dest.ptr(0,0,0,0), *gdata = dest.ptr(0,0,0,1), *bdata = dest.ptr(0,0,0,2);
--        cimg_forXY(dest,x,y) {
--          std::fscanf(nfile,"%d %d %d",&rval,&gval,&bval);
--          *(rdata++)=(T)rval;
--          *(gdata++)=(T)gval;
--          *(bdata++)=(T)bval; }
--      } break;
--      case 5: { // Grey Binary
--        if (colormax<256) { // 8 bits
--          CImg<unsigned char> raw(width,height,1,1);
--          cimg::fread(raw.data,width*height,nfile);
--          dest=raw;
--        } else { // 16 bits
--          CImg<unsigned short> raw(width,height,1,1);
--          cimg::fread(raw.data,width*height,nfile);
--          if (!cimg::endian()) cimg::endian_swap(raw.data,width*height);
--          dest=raw;
--        }
--      } break;
--      case 6: { // Color Binary
--        if (colormax<256) { // 8 bits
--          CImg<unsigned char> raw(width,height,1,3);
--          cimg::fread(raw.data,width*height*3,nfile);
--          dest.assign(width,height,1,3);
--          T *rdata = dest.ptr(0,0,0,0), *gdata = dest.ptr(0,0,0,1), *bdata = dest.ptr(0,0,0,2);
--          const unsigned char *ptrs = raw.ptr();
--          for (unsigned int off = raw.width*raw.height; off; --off) {
--            *(rdata++) = (T)*(ptrs++);
--            *(gdata++) = (T)*(ptrs++);
--            *(bdata++) = (T)*(ptrs++);
--          }
--        } else { // 16 bits
--          CImg<unsigned short> raw(width,height,1,3);
--          cimg::fread(raw.data,width*height*3,nfile);
--          if (!cimg::endian()) cimg::endian_swap(raw.data,width*height*3);
--          dest.assign(width,height,1,3);
--          T *rdata = dest.ptr(0,0,0,0), *gdata = dest.ptr(0,0,0,1), *bdata = dest.ptr(0,0,0,2);
--          const unsigned short *ptrs = raw.ptr();
--          for (unsigned int off = raw.width*raw.height; off; --off) {
--            *(rdata++) = (T)*(ptrs++);
--            *(gdata++) = (T)*(ptrs++);
--            *(bdata++) = (T)*(ptrs++);
--          }
--        }
--      } break;
--      default:
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_pnm() : File '%s', PPM type 'P%d' not supported.",
--                              pixel_type(),filename?filename:"(FILE*)",ppm_type);
--      }
--      if (!file) cimg::fclose(nfile);
--      return dest;
--    }
--
--    //! Load an image from a PNM file.
--    static CImg get_load_pnm(const char *const filename) {
--      return get_load_pnm(0,filename);
--    }
--
--    //! Load an image from a PNM file (in-place version).
--    CImg& load_pnm(std::FILE *const file, const char *const filename=0) {
--      return get_load_pnm(file,filename).swap(*this);
--    }
--
--    //! Load an image from a PNM file (in-place version).
--    CImg& load_pnm(const char *const filename) {
--      return get_load_pnm(filename).swap(*this);
--    }
--
--    //! Load a YUV image sequence file.
--    static CImg get_load_yuv(std::FILE *const file, const char *const filename,
--                             const unsigned int sizex, const unsigned int sizey=1,
--                             const unsigned int first_frame=0, const int last_frame=-1,
--                             const bool yuv2rgb = false) {
--      return CImgList<T>::get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append('z','c');
--    }
--
--    //! Load a YUV image sequence file.
--    static CImg get_load_yuv(const char *const filename,
--                             const unsigned int sizex, const unsigned int sizey=1,
--                             const unsigned int first_frame=0, const int last_frame=-1,
--                             const bool yuv2rgb = false) {
--      return CImgList<T>::get_load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).get_append('z','c');
--    }
--
--    //! Load a YUV image sequence file (in-place).
--    CImg& load_yuv(std::FILE *const file, const char *const filename,
--                   const unsigned int sizex, const unsigned int sizey=1,
--                   const unsigned int first_frame=0, const int last_frame=-1,
--                   const bool yuv2rgb = false) {
--      return get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).swap(*this);
--    }
--
--    //! Load a YUV image sequence file (in-place).
--    CImg& load_yuv(const char *const filename,
--                   const unsigned int sizex, const unsigned int sizey=1,
--                   const unsigned int first_frame=0, const int last_frame=-1,
--                   const bool yuv2rgb = false) {
--      return get_load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).swap(*this);
--    }
--
--    //! Load an image from a BMP file.
--    static CImg get_load_bmp(std::FILE *const file, const char *const filename=0) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      unsigned char header[64];
--      cimg::fread(header,54,nfile);
--      if (header[0]!='B' || header[1]!='M') {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_bmp() : File '%s' is not a valid BMP file.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--
--      // Read header and pixel buffer
--      int
--        file_size   = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24),
--        offset      = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24),
--        dx          = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24),
--        dy          = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24),
--        compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24),
--        nb_colors   = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24),
--        bpp         = header[0x1C] + (header[0x1D]<<8),
--        *palette    = 0;
--      const int
--        dx_bytes   = (bpp==1)?(dx/8+(dx%8?1:0)):((bpp==4)?(dx/2+(dx%2?1:0)):(dx*bpp/8)),
--        align      = (4-dx_bytes%4)%4,
--        buf_size   = cimg::min(cimg::abs(dy)*(dx_bytes+align),file_size-offset);
--
--      if (bpp<16) { if (!nb_colors) nb_colors=1<<bpp; } else nb_colors=0;
--      if (nb_colors) { palette = new int[nb_colors]; cimg::fread(palette,nb_colors,nfile); }
--      const int xoffset = offset-54-4*nb_colors;
--      if (xoffset>0) std::fseek(nfile,xoffset,SEEK_CUR);
--      unsigned char *buffer  = new unsigned char[buf_size], *ptrs = buffer;
--      cimg::fread(buffer,buf_size,nfile);
--      if (!file) cimg::fclose(nfile);
--
--      // Decompress buffer (if necessary)
--      if (compression) {
--        delete[] buffer;
--        if (file) {
--          throw CImgIOException("CImg<%s>::get_load_bmp() : Not able to read a compressed BMP file using a *FILE input",pixel_type());
--        } else return get_load_other(filename);
--      }
--
--      // Read pixel data
--      CImg res(dx,cimg::abs(dy),1,3);
--      switch (bpp) {
--      case 1: { // Monochrome
--        for (int y=res.height-1; y>=0; y--) {
--          unsigned char mask = 0x80, val = 0;
--          cimg_forX(res,x) {
--            if (mask==0x80) val = *(ptrs++);
--            const unsigned char *col = (unsigned char*)(palette+(val&mask?1:0));
--            res(x,y,2) = (T)*(col++);
--            res(x,y,1) = (T)*(col++);
--            res(x,y,0) = (T)*(col++);
--            mask = cimg::ror(mask);
--          } ptrs+=align; }
--      } break;
--      case 4: { // 16 colors
--        for (int y=res.height-1; y>=0; y--) {
--          unsigned char mask = 0xF0, val = 0;
--          cimg_forX(res,x) {
--            if (mask==0xF0) val = *(ptrs++);
--            const unsigned char color = (mask<16)?(val&mask):((val&mask)>>4);
--            unsigned char *col = (unsigned char*)(palette+color);
--            res(x,y,2) = (T)*(col++);
--            res(x,y,1) = (T)*(col++);
--            res(x,y,0) = (T)*(col++);
--            mask = cimg::ror(mask,4);
--          } ptrs+=align; }
--      } break;
--      case 8: { //  256 colors
--        for (int y=res.height-1; y>=0; y--) { cimg_forX(res,x) {
--          const unsigned char *col = (unsigned char*)(palette+*(ptrs++));
--          res(x,y,2) = (T)*(col++);
--          res(x,y,1) = (T)*(col++);
--          res(x,y,0) = (T)*(col++);
--        } ptrs+=align; }
--      } break;
--      case 16: { // 16 bits colors
--        for (int y=res.height-1; y>=0; y--) { cimg_forX(res,x) {
--          const unsigned char c1 = *(ptrs++), c2 = *(ptrs++);
--          const unsigned short col = c1+(c2<<8);
--          res(x,y,2) = (T)(col&0x1F);
--          res(x,y,1) = (T)((col>>5)&0x1F);
--          res(x,y,0) = (T)((col>>10)&0x1F);
--        } ptrs+=align; }
--      } break;
--      case 24: { // 24 bits colors
--        for (int y=res.height-1; y>=0; y--) { cimg_forX(res,x) {
--          res(x,y,2) = (T)*(ptrs++);
--          res(x,y,1) = (T)*(ptrs++);
--          res(x,y,0) = (T)*(ptrs++);
--        } ptrs+=align; }
--      } break;
--      case 32: { // 32 bits colors
--        for (int y=res.height-1; y>=0; y--) { cimg_forX(res,x) {
--          res(x,y,2) = (T)*(ptrs++);
--          res(x,y,1) = (T)*(ptrs++);
--          res(x,y,0) = (T)*(ptrs++);
--          ptrs++;
--        } ptrs+=align; }
--      } break;
--      }
--      if (palette) delete[] palette;
--      delete[] buffer;
--      if (dy<0) res.mirror('y');
--      return res;
--    }
--
--    //! Load an image from a BMP file
--    static CImg get_load_bmp(const char *const filename) {
--      return get_load_bmp(0,filename);
--    }
--
--    //! Load an image from a BMP file
--    CImg& load_bmp(std::FILE *const file, const char *const filename=0) {
--      return get_load_bmp(file,filename).swap(*this);
--    }
--
--    //! Load an image from a BMP file
--    CImg& load_bmp(const char *const filename) {
--      return get_load_bmp(filename).swap(*this);
--    }
--
--    //! Load an image from a PNG file.
--    // Note : Most of this function has been written by Eric Fausett
--    static CImg get_load_png(std::FILE *const file, const char *const filename=0) {
--#ifndef cimg_use_png
--      if (file)
--        throw CImgIOException("CImg<%s>::get_load_png() : File '(FILE*)' cannot be read without using libpng.",pixel_type());
--      else return get_load_other(filename);
--#else
--      // Open file and check for PNG validity
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      unsigned char pngCheck[8];
--      cimg::fread(pngCheck,8,nfile);
--      if (png_sig_cmp(pngCheck,0,8)) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s' is not a valid PNG file.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--
--      // Setup PNG structures for read
--      png_voidp user_error_ptr=0;
--      png_error_ptr user_error_fn=0, user_warning_fn=0;
--      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,       // Verifies libpng version correct
--                                                   user_error_ptr, user_error_fn, user_warning_fn);
--      if(!png_ptr){
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', trouble initializing 'png_ptr' data structure.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      png_infop info_ptr = png_create_info_struct(png_ptr);
--      if(!info_ptr){
--        if (!file) cimg::fclose(nfile);
--        png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', trouble initializing 'info_ptr' data structure.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      png_infop end_info = png_create_info_struct(png_ptr);
--      if(!end_info){
--        if (!file) cimg::fclose(nfile);
--        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', trouble initializing 'end_info' data structure.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--
--      // Error handling callback for png file reading
--      if (setjmp(png_jmpbuf(png_ptr))){
--        if (!file) cimg::fclose(nfile);
--        png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', unknown fatal error.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      png_init_io(png_ptr, nfile);
--      png_set_sig_bytes(png_ptr, 8);
--
--      // Get PNG Header Info up to data block
--      png_read_info(png_ptr, info_ptr);
--      png_uint_32 width, height;
--      int bit_depth, color_type, interlace_type;
--      png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type,
--                   int_p_NULL, int_p_NULL);
--      int new_bit_depth = bit_depth;
--      int new_color_type = color_type;
--
--      // Transforms to unify image data
--      if (new_color_type == PNG_COLOR_TYPE_PALETTE){
--        png_set_palette_to_rgb(png_ptr);
--        new_color_type -= PNG_COLOR_MASK_PALETTE;
--        new_bit_depth = 8;
--      }
--      if (new_color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8){
--        png_set_gray_1_2_4_to_8(png_ptr);
--        new_bit_depth = 8;
--      }
--      if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
--        png_set_tRNS_to_alpha(png_ptr);
--      if (new_color_type == PNG_COLOR_TYPE_GRAY || new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
--        png_set_gray_to_rgb(png_ptr);
--        new_color_type |= PNG_COLOR_MASK_COLOR;
--      }
--      if (new_color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 0xffffU, PNG_FILLER_AFTER);
--      png_read_update_info(png_ptr, info_ptr);
--      if (!(new_bit_depth==8 || new_bit_depth==16)) {
--        if (!file) cimg::fclose(nfile);
--        png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', wrong bit coding (bit_depth=%u)",
--                              pixel_type(),filename?filename:"(FILE*)",new_bit_depth);
--      }
--      const int byte_depth = new_bit_depth>>3;
--
--      // Allocate Memory for Image Read
--      png_bytep *imgData = new png_bytep[height];
--      for (unsigned int row=0; row < height; row++) imgData[row] = new png_byte[byte_depth * 4 * width];
--      png_read_image(png_ptr, imgData);
--      png_read_end(png_ptr, end_info);
--
--      // Read pixel data
--      if (!(new_color_type==PNG_COLOR_TYPE_RGB || new_color_type==PNG_COLOR_TYPE_RGB_ALPHA)) {
--        if (!file) cimg::fclose(nfile);
--        png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
--        throw CImgIOException("CImg<%s>::get_load_png() : File '%s', wrong color coding (new_color_type=%u)",
--                              pixel_type(),filename?filename:"(FILE*)",new_color_type);
--      }
--      const bool no_alpha_channel = (new_color_type==PNG_COLOR_TYPE_RGB);
--      CImg res(width,height,1,no_alpha_channel?3:4);
--      const unsigned long off = width*height;
--      T *ptr1 = res.data, *ptr2 = ptr1+off, *ptr3 = ptr2+off, *ptr4 = ptr3+off;
--      switch(new_bit_depth){
--      case 8: {
--        cimg_forY(res,y){
--          const unsigned char *ptrs = (unsigned char*)imgData[y];
--          cimg_forX(res,x){
--            *(ptr1++) = (T)*(ptrs++);
--            *(ptr2++) = (T)*(ptrs++);
--            *(ptr3++) = (T)*(ptrs++);
--            if (no_alpha_channel) ptrs++; else *(ptr4++) = (T)*(ptrs++);
--          }
--        }
--      } break;
--      case 16: {
--        cimg_forY(res,y){
--          const unsigned short *ptrs = (unsigned short*)(imgData[y]);
--          cimg_forX(res,x){
--            *(ptr1++) = (T)*(ptrs++);
--            *(ptr2++) = (T)*(ptrs++);
--            *(ptr3++) = (T)*(ptrs++);
--            if (no_alpha_channel) ptrs++; else *(ptr4++) = (T)*(ptrs++);
--          }
--        }
--      } break;
--      }
--      png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
--
--      // Deallocate Image Read Memory
--      for (unsigned int n=0; n<height; n++) delete[] imgData[n];
--      delete[] imgData;
--      if (!file) cimg::fclose(nfile);
--      return res;
--#endif
--    }
--
--    //! Load an image from a PNG file
--    static CImg get_load_png(const char *const filename) {
--      return get_load_png(0,filename);
--    }
--
--    //! Load an image from a PNG file
--    CImg& load_png(std::FILE *const file, const char *const filename=0) {
--      return get_load_png(file,filename).swap(*this);
--    }
--
--    //! Load an image from a PNG file
--    CImg& load_png(const char *const filename) {
--      return get_load_png(filename).swap(*this);
--    }
--
--    //! Load an image in TIFF format
--    // Original contribution by Jerome Boulanger.
--    static CImg get_load_tiff(const char *const filename=0) {
--#ifndef cimg_use_tiff
--      return get_load_other(filename);
--#else
--      CImg dest;
--      TIFF *tif = TIFFOpen(filename,"r");
--#if cimg_debug>=3
--      TIFFSetWarningHandler(0);
--      TIFFSetErrorHandler(0);
--#endif
--      if (tif) {
--        unsigned int number_of_directories = 0;
--        do number_of_directories++; while (TIFFReadDirectory(tif));
--        uint16 samplesperpixel, bitspersample;
--        uint32 nx,ny;
--        TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&nx);
--        TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ny);
--        TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&samplesperpixel);
--        if (samplesperpixel!=1 && samplesperpixel!=3 && samplesperpixel!=4) {
--          cimg::warn(true,"CImg<%s>::get_load_tiff() : File '%s', unknow value for tag : TIFFTAG_SAMPLESPERPIXEL, will force it to 1.",
--                     pixel_type(),filename?filename:"(FILE*)");
--          samplesperpixel=1;
--        }
--        TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
--        TIFFClose(tif);
--        tif = TIFFOpen(filename,"r");
--        dest.assign(nx,ny,number_of_directories,samplesperpixel);
--
--        unsigned  int dir=0;
--        do {
--          if (bitspersample!=8 || !(samplesperpixel == 1 || samplesperpixel == 3 || samplesperpixel == 4)){ //if !rgba 8bit
--            uint16 photo, config;
--            TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&config);
--            TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photo);
--            if (TIFFIsTiled(tif)) {
--            uint32 tw, th;
--            TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
--            TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
--              if (config==PLANARCONFIG_CONTIG) {
--              switch(bitspersample){
--              case 8:{
--                unsigned char *buf;
--                buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      unsigned char * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              case 16:{
--                unsigned short *buf;
--                buf = (unsigned short *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      unsigned short * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              case 32:{
--                float *buf;
--                buf = (float *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      float * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              }
--              }
--              else {
--              switch(bitspersample){
--              case 8:{
--                unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      unsigned char * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              case 16:{
--                unsigned short *buf = (unsigned short *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      unsigned short * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              case 32:{
--                float *buf = (float *)_TIFFmalloc(TIFFTileSize(tif));
--                if (buf) {
--                for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                  for (unsigned int row = 0; row<ny; row+=th) {
--                    for (unsigned int col = 0; col<nx; col+=tw) {
--                      if (TIFFReadTile(tif,buf,col,row,0,vv)<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a tile.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                      } else {
--                      float * ptr = buf;
--                      for (unsigned int rr=row;rr<cimg::min( row+th,(unsigned int)ny);rr++)
--                        for (unsigned int cc=col;cc<cimg::min( col+tw,(unsigned int)nx);cc++)
--                            dest(cc,rr,dir,vv)= (T)(float)*(ptr++);
--                        }
--                    }
--                  }
--                  _TIFFfree(buf);
--                }
--              break;
--              }
--              }
--              }
--            } else {
--              if (config==PLANARCONFIG_CONTIG) {
--              switch(bitspersample){
--              case 8 :{
--                unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (row = 0; row<ny; row+= rowsperstrip) {
--                    uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                    tstrip_t strip = TIFFComputeStrip(tif, row, 0);
--                    if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a strip.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                    }
--                      unsigned char * ptr = buf;
--                      for (unsigned int rr=0; rr<nrow; rr++)
--                        for (unsigned int cc=0;cc<nx;cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--
--                  }
--                  _TIFFfree(buf);
--                }
--                break;
--              }
--              case 16:{
--                unsigned short *buf = (unsigned  short *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (row = 0; row<ny; row+= rowsperstrip) {
--                    uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                    tstrip_t strip = TIFFComputeStrip(tif, row, 0);
--                    if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', error while reading a strip.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                    }
--                    unsigned short * ptr = buf;
--                      for (unsigned int rr=0; rr<nrow; rr++)
--                        for (unsigned int cc=0;cc<nx;cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--                  }
--                  _TIFFfree(buf);
--                }
--                break;
--              }
--              case 32:{
--                float *buf  = (float *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (row = 0; row<ny; row+= rowsperstrip) {
--                    uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                    tstrip_t strip = TIFFComputeStrip(tif, row, 0);
--                    if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', error while reading a strip.",
--                                          pixel_type(),filename?filename:"(FILE*)");
--                    }
--                    float * ptr = buf;
--                      for (unsigned int rr=0; rr<nrow; rr++)
--                        for (unsigned int cc=0;cc<nx;cc++)
--                          for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                            dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--                  }
--                  _TIFFfree(buf);
--                }
--                break;
--      }
--
--              }
--            }
--            else {
--              switch(bitspersample){
--              case 8 :{
--                unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (unsigned int vv=0;vv<samplesperpixel;vv++){
--                  for (row = 0; row<ny; row+= rowsperstrip) {
--                    uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                    tstrip_t strip = TIFFComputeStrip(tif, row, vv);
--                    if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                      _TIFFfree(buf);
--                      TIFFClose(tif);
--                      throw CImgException("CImg<%s>::get_load_tiff() : File '%s', an error occure while reading a strip.",
--                                            pixel_type(),filename?filename:"(FILE*)");
--                    }
--                      unsigned char * ptr = buf;
--                        for (unsigned int rr=0;rr<nrow; rr++)
--                          for (unsigned int cc=0;cc<nx;cc++)
--                            dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--                      }}
--                  _TIFFfree(buf);
--                }
--                break;
--              }
--              case 16:{
--                unsigned short *buf = (unsigned  short *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                    for (row = 0; row<ny; row+= rowsperstrip) {
--                      uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                      tstrip_t strip = TIFFComputeStrip(tif, row, vv);
--                      if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                        _TIFFfree(buf);
--                        TIFFClose(tif);
--                        throw CImgException("CImg<%s>::get_load_tiff() : File '%s', error while reading a strip.",
--                                            pixel_type(),filename?filename:"(FILE*)");
--                      }
--                      unsigned short * ptr = buf;
--                      for (unsigned int rr=0;rr<nrow;rr++)
--                        for (unsigned int cc=0;cc<nx;cc++)
--                          dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--                    }
--                  _TIFFfree(buf);
--                }
--                break;
--              }
--               case 32:{
--                float *buf = (float *)_TIFFmalloc(TIFFStripSize(tif));
--                if (buf) {
--                  uint32 row, rowsperstrip = (uint32)-1;
--                  TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
--                  for (unsigned int vv=0;vv<samplesperpixel;vv++)
--                    for (row = 0; row<ny; row+= rowsperstrip) {
--                      uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
--                      tstrip_t strip = TIFFComputeStrip(tif, row, vv);
--                      if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
--                        _TIFFfree(buf);
--                        TIFFClose(tif);
--                        throw CImgException("CImg<%s>::get_load_tiff() : File '%s', error while reading a strip.",
--                                            pixel_type(),filename?filename:"(FILE*)");
--                      }
--                      float * ptr = buf;
--                      for (unsigned int rr=0;rr<nrow;rr++)
--                        for (unsigned int cc=0;cc<nx;cc++)
--                          dest(cc,row+rr,dir,vv)= (T)(float)*(ptr++);
--                    }
--                  _TIFFfree(buf);
--                }
--                break;
--              }
--              }
--              }
--            }
--          }
--          else {
--          uint32* raster = (uint32*)_TIFFmalloc(nx * ny * sizeof (uint32));
--          if (!raster) {
--            _TIFFfree(raster);
--            TIFFClose(tif);
--            throw CImgException("CImg<%s>::get_load_tiff() : File '%s', not enough memory for buffer allocation.",
--                                pixel_type(),filename?filename:"(FILE*)");
--          }
--            TIFFReadRGBAImage(tif,nx,ny,raster,0);
--            switch (samplesperpixel){
--            case 1:{
--              cimg_forXY(dest,x,y) dest(x,y,dir)=(T)(float)((raster[nx*(ny-1-y)+x]+ 128) / 257);
--            break;
--          }
--        case 3:{
--          cimg_forXY(dest,x,y) {
--            dest(x,y,dir,0)=(T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
--            dest(x,y,dir,1)=(T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
--            dest(x,y,dir,2)=(T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
--              }
--          break;
--        }
--        case 4:{
--           cimg_forXY(dest,x,y) {
--            dest(x,y,dir,0)=(T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
--            dest(x,y,dir,1)=(T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
--            dest(x,y,dir,2)=(T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
--            dest(x,y,dir,3)=(T)(float)TIFFGetA(raster[nx*(ny-1-y)+x]);
--              }
--           break;
--        }
--        }
--          _TIFFfree(raster);
--          }
--          dir++;
--        } while (TIFFReadDirectory(tif));
--        TIFFClose(tif);
--      } else
--        throw CImgException("CImg<%s>::get_load_tiff() : File '%s', error while loading the image.",
--                            pixel_type(),filename?filename:"(FILE*)");
--      return dest;
--#endif
--    }
--
--    //! Load an image from a TIFF file
--    CImg& load_tiff(const char *const filename) {
--      return get_load_tiff(filename).swap(*this);
--    }
--
--    //! Load a file in JPEG format.
--    static CImg get_load_jpeg(std::FILE *const file, const char *const filename=0) {
--#ifndef cimg_use_jpeg
--      if (file)
--        throw CImgIOException("CImg<%s>::get_load_jpeg() : File '(FILE*)' cannot be read without using libjpeg.",
--                              pixel_type());
--      else return get_load_other(filename);
--#else
--      struct jpeg_decompress_struct cinfo;
--      struct jpeg_error_mgr jerr;
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--
--      cinfo.err = jpeg_std_error(&jerr);
--      jpeg_create_decompress(&cinfo);
--      jpeg_stdio_src(&cinfo,nfile);
--      jpeg_read_header(&cinfo,TRUE);
--      jpeg_start_decompress(&cinfo);
--
--      if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) {
--        cimg::warn(true,"CImg<%s>::get_load_jpeg() : Don't know how to read image '%s' with libpeg, trying ImageMagick's convert",
--                   pixel_type(),filename?filename:"(unknown)");
--        if (!file) return get_load_other(filename);
--        else {
--          if (!file) cimg::fclose(nfile);
--          throw CImgIOException("CImg<%s>::get_load_jpeg() : Cannot read JPEG image '%s' using a *FILE input.",
--                                pixel_type(),filename?filename:"(FILE*)");
--        }
--      }
--
--      const unsigned int row_stride = cinfo.output_width * cinfo.output_components;
--      unsigned char *buf = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components], *buf2 = buf;
--      JSAMPROW row_pointer[1];
--      while (cinfo.output_scanline < cinfo.output_height) {
--        row_pointer[0] = &buf[cinfo.output_scanline*row_stride];
--        jpeg_read_scanlines(&cinfo,row_pointer,1);
--      }
--      jpeg_finish_decompress(&cinfo);
--      jpeg_destroy_decompress(&cinfo);
--      if (!file) cimg::fclose(nfile);
--
--      CImg<T> dest(cinfo.output_width,cinfo.output_height,1,cinfo.output_components);
--      switch (dest.dim) {
--      case 1: {
--        T *ptr_g = dest.ptr();
--        cimg_forXY(dest,x,y) *(ptr_g++) = (T)*(buf2++);
--      } break;
--      case 3: {
--        T *ptr_r = dest.ptr(0,0,0,0), *ptr_g = dest.ptr(0,0,0,1), *ptr_b = dest.ptr(0,0,0,2);
--        cimg_forXY(dest,x,y) {
--          *(ptr_r++) = (T)*(buf2++);
--          *(ptr_g++) = (T)*(buf2++);
--          *(ptr_b++) = (T)*(buf2++);
--        }
--      } break;
--      case 4: {
--        T *ptr_r = dest.ptr(0,0,0,0), *ptr_g = dest.ptr(0,0,0,1),
--          *ptr_b = dest.ptr(0,0,0,2), *ptr_a = dest.ptr(0,0,0,3);
--        cimg_forXY(dest,x,y) {
--          *(ptr_r++) = (T)*(buf2++);
--          *(ptr_g++) = (T)*(buf2++);
--          *(ptr_b++) = (T)*(buf2++);
--          *(ptr_a++) = (T)*(buf2++);
--        }
--      } break;
--      }
--      delete[] buf;
--      return dest;
--#endif
--    }
--
--    //! Load an image from a JPEG file
--    static CImg get_load_jpeg(const char *const filename) {
--      return get_load_jpeg(0,filename);
--    }
--
--    //! Load an image from a JPEG file
--    CImg& load_jpeg(std::FILE *const file, const char *const filename=0) {
--      return get_load_jpeg(file,filename).swap(*this);
--    }
--
--    //! Load an image from a JPEG file
--    CImg& load_jpeg(const char *const filename) {
--      return get_load_jpeg(filename).swap(*this);
--    }
--
--    //! Load an image using builtin ImageMagick++ Library
--    /**
--       Added April/may 2006 by Christoph Hormann <chris_hormann@gmx.de>
--       This is experimental code, not much tested, use with care.
--    **/
--    static CImg get_load_magick(const char *const filename) {
--      CImg dest;
--#ifdef cimg_use_magick
--      Magick::Image image(filename);
--      const unsigned int width = image.size().width(), height = image.size().height();
--      switch (image.type()) {
--      case Magick::PaletteMatteType:
--      case Magick::TrueColorMatteType:
--      case Magick::ColorSeparationType: {
--        dest.assign(width,height,1,4);
--        T *rdata = dest.ptr(0,0,0,0), *gdata = dest.ptr(0,0,0,1), *bdata = dest.ptr(0,0,0,2), *adata = dest.ptr(0,0,0,3);
--        Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
--        for (unsigned int off = width*height; off; --off) {
--          *(rdata++) = (T)(pixels->red);
--          *(gdata++) = (T)(pixels->green);
--          *(bdata++) = (T)(pixels->blue);
--          *(adata++) = (T)(pixels->opacity);
--          pixels++;
--        }
--      } break;
--      case Magick::PaletteType:
--      case Magick::TrueColorType: {
--        dest.assign(width,height,1,3);
--        T *rdata = dest.ptr(0,0,0,0), *gdata = dest.ptr(0,0,0,1), *bdata = dest.ptr(0,0,0,2);
--        Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
--        for (unsigned int off = width*height; off; --off) {
--          *(rdata++) = (T)(pixels->red);
--          *(gdata++) = (T)(pixels->green);
--          *(bdata++) = (T)(pixels->blue);
--          pixels++;
--        }
--      } break;
--      case Magick::GrayscaleMatteType: {
--        dest.assign(width,height,1,2);
--        T *data = dest.ptr(0,0,0,0), *adata = dest.ptr(0,0,0,1);
--        Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
--        for (unsigned int off = width*height; off; --off) {
--          *(data++) = (T)(pixels->red);
--          *(adata++) = (T)(pixels->opacity);
--          pixels++;
--        }
--      } break;
--      default: {
--        dest.assign(width,height,1,1);
--        T *data = dest.ptr(0,0,0,0);
--        Magick::PixelPacket *pixels = image.getPixels(0,0,width,height);
--        for (unsigned int off = width*height; off; --off) {
--          *(data++) = (T)(pixels->red);
--          pixels++;
--        }
--      } break;
--      }
--      return dest;
--#else
--      throw CImgIOException("CImg<%s>::get_load_magick() : File '%s', Magick++ has not been linked during compilation.",
--                            pixel_type(),filename?filename:"(null)");
--      return dest;
--#endif
--    }
--
--    //! Load an image using builtin ImageMagick++ Library (in-place version).
--    CImg& load_magick(const char *const filename) {
--      return get_load_magick(filename).swap(*this);
--    }
--
--    //! Load an image from a RAW file.
--    static CImg get_load_raw(std::FILE *const file, const char *const filename,
--                             const unsigned int sizex, const unsigned int sizey=1,
--                             const unsigned int sizez=1, const unsigned int sizev=1,
--                             const bool multiplexed=false, const bool endian_swap=false) {
--      CImg<T> res(sizex,sizey,sizez,sizev,0);
--      if (res.is_empty()) return res;
--
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      if (!multiplexed) {
--        cimg::fread(res.ptr(),res.size(),nfile);
--        if (endian_swap) cimg::endian_swap(res.ptr(),res.size());
--      }
--      else {
--        CImg<T> buf(1,1,1,sizev);
--        cimg_forXYZ(res,x,y,z) {
--          cimg::fread(buf.ptr(),sizev,nfile);
--          if (endian_swap) cimg::endian_swap(buf.ptr(),sizev);
--          res.set_vector_at(buf,x,y,z); }
--      }
--      if (!file) cimg::fclose(nfile);
--      return res;
--    }
--
--    //! Load an image from a RAW file.
--    static CImg get_load_raw(const char *const filename,
--                             const unsigned int sizex, const unsigned int sizey=1,
--                             const unsigned int sizez=1, const unsigned int sizev=1,
--                             const bool multiplexed = false, const bool endian_swap = false) {
--      return get_load_raw(0,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap);
--    }
--
--    //! In-place version of get_load_raw()
--    CImg& load_raw(std::FILE *const file, const char *const filename,
--                   const unsigned int sizex, const unsigned int sizey=1,
--                   const unsigned int sizez=1, const unsigned int sizev=1,
--                   const bool multiplexed = false, const bool endian_swap = false) {
--      return get_load_raw(file,filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap).swap(*this);
--    }
--
--    //! In-place version of get_load_raw()
--    CImg& load_raw(const char *const filename,
--                   const unsigned int sizex, const unsigned int sizey=1,
--                   const unsigned int sizez=1, const unsigned int sizev=1,
--                   const bool multiplexed = false, const bool endian_swap = false) {
--      return get_load_raw(filename,sizex,sizey,sizez,sizev,multiplexed,endian_swap).swap(*this);
--    }
--
--    //! Load an image from a RGBA file.
--    static CImg get_load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      unsigned char *buffer = new unsigned char[dimw*dimh*4];
--      cimg::fread(buffer,dimw*dimh*4,nfile);
--      if (!file) cimg::fclose(nfile);
--      CImg res(dimw,dimh,1,4);
--      T *pR = res.ptr(0,0,0,0), *pG = res.ptr(0,0,0,1), *pB = res.ptr(0,0,0,2), *pA = res.ptr(0,0,0,3);
--      const unsigned char *ptrs = buffer;
--      for (unsigned int off=res.width*res.height; off>0; --off) {
--        *(pR++) = (T)*(ptrs++);
--        *(pG++) = (T)*(ptrs++);
--        *(pB++) = (T)*(ptrs++);
--        *(pA++) = (T)*(ptrs++);
--      }
--      delete[] buffer;
--      return res;
--    }
--
--    //! Load an image from a RGBA file.
--    static CImg get_load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgba(0,filename,dimw,dimh);
--    }
--
--    //! In-place version of get_load_rgba()
--    CImg& load_rgba(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgba(file, filename,dimw,dimh).swap(*this);
--    }
--
--    //! In-place version of get_load_rgba()
--    CImg& load_rgba(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgba(filename,dimw,dimh).swap(*this);
--    }
--
--    //! Load an image from a RGB file.
--    static CImg get_load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      unsigned char *buffer = new unsigned char[dimw*dimh*3];
--      cimg::fread(buffer,dimw*dimh*3,nfile);
--      if (!file) cimg::fclose(nfile);
--      CImg res(dimw,dimh,1,3);
--      T *pR = res.ptr(0,0,0,0), *pG = res.ptr(0,0,0,1), *pB=res.ptr(0,0,0,2);
--      const unsigned char *ptrs = buffer;
--      for (unsigned int off=res.width*res.height; off>0; --off) {
--        *(pR++) = (T)*(ptrs++);
--        *(pG++) = (T)*(ptrs++);
--        *(pB++) = (T)*(ptrs++);
--      }
--      delete[] buffer;
--      return res;
--    }
--
--    //! Load an image from a RGB file.
--    static CImg get_load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgb(0,filename,dimw,dimh);
--    }
--
--    //! In-place version of get_load_rgb()
--    CImg& load_rgb(std::FILE *const file, const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgb(file, filename,dimw,dimh).swap(*this);
--    }
--
--    //! In-place version of get_load_rgb()
--    CImg& load_rgb(const char *const filename, const unsigned int dimw, const unsigned int dimh) {
--      return get_load_rgb(filename,dimw,dimh).swap(*this);
--    }
--
--#define cimg_load_inr_case(Tf,sign,pixsize,Ts) \
--  if (!loaded && fopt[6]==pixsize && fopt[4]==Tf && fopt[5]==sign) { \
--      Ts *xval, *val = new Ts[fopt[0]*fopt[3]]; \
--      cimg_forYZ(dest,y,z) { \
--          cimg::fread(val,fopt[0]*fopt[3],nfile); \
--          if (fopt[7]!=endian) cimg::endian_swap(val,fopt[0]*fopt[3]); \
--          xval = val; cimg_forX(dest,x) cimg_forV(dest,k) \
--                          dest(x,y,z,k) = (T)*(xval++); \
--        } \
--      delete[] val; \
--      loaded = true; \
--    }
--
--    static void _load_inr(std::FILE *file, int out[8], float *const voxsize=0) {
--      char item[1024],tmp1[64],tmp2[64];
--      out[0]=out[1]=out[2]=out[3]=out[5]=1; out[4]=out[6]=out[7]=-1;
--      std::fscanf(file,"%63s",item);
--      if(cimg::strncasecmp(item,"#INRIMAGE-4#{",13)!=0)
--        throw CImgIOException("CImg<%s>::get_load_inr() : File does not appear to be a valid INR file.\n"
--                              "(INRIMAGE-4 identifier not found)",pixel_type());
--      while (std::fscanf(file," %63[^\n]%*c",item)!=EOF && cimg::strncmp(item,"##}",3)) {
--        std::sscanf(item," XDIM%*[^0-9]%d",out);
--        std::sscanf(item," YDIM%*[^0-9]%d",out+1);
--        std::sscanf(item," ZDIM%*[^0-9]%d",out+2);
--        std::sscanf(item," VDIM%*[^0-9]%d",out+3);
--        std::sscanf(item," PIXSIZE%*[^0-9]%d",out+6);
--        if (voxsize) {
--          std::sscanf(item," VX%*[^0-9.eE+-]%f",voxsize);
--          std::sscanf(item," VY%*[^0-9.eE+-]%f",voxsize+1);
--          std::sscanf(item," VZ%*[^0-9.eE+-]%f",voxsize+2);
--        }
--        if (std::sscanf(item," CPU%*[ =]%s",tmp1)) out[7]=cimg::strncasecmp(tmp1,"sun",3)?0:1;
--        switch(std::sscanf(item," TYPE%*[ =]%s %s",tmp1,tmp2)) {
--        case 0: break;
--        case 2: out[5] = cimg::strncasecmp(tmp1,"unsigned",8)?1:0; std::strcpy(tmp1,tmp2);
--        case 1:
--          if (!cimg::strncasecmp(tmp1,"int",3)   || !cimg::strncasecmp(tmp1,"fixed",5))  out[4]=0;
--          if (!cimg::strncasecmp(tmp1,"float",5) || !cimg::strncasecmp(tmp1,"double",6)) out[4]=1;
--          if (!cimg::strncasecmp(tmp1,"packed",6))                                       out[4]=2;
--          if (out[4]>=0) break;
--        default: throw CImgIOException("cimg::inr_header_read() : Invalid TYPE '%s'",tmp2);
--        }
--      }
--      if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0)
--        throw CImgIOException("CImg<%s>::get_load_inr() : Bad dimensions in .inr file = ( %d , %d , %d , %d )",
--                              pixel_type(),out[0],out[1],out[2],out[3]);
--      if(out[4]<0 || out[5]<0) throw CImgIOException("CImg<%s>::get_load_inr() : TYPE is not fully defined",pixel_type());
--      if(out[6]<0) throw CImgIOException("CImg<%s>::get_load_inr() : PIXSIZE is not fully defined",pixel_type());
--      if(out[7]<0) throw CImgIOException("CImg<%s>::get_load_inr() : Big/Little Endian coding type is not defined",pixel_type());
--    }
--
--    //! Load an image from an INRIMAGE-4 file.
--    static CImg get_load_inr(std::FILE *const file, const char *const filename=0, float *voxsize=0) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      int fopt[8], endian=cimg::endian()?1:0;
--      bool loaded = false;
--      if (voxsize) voxsize[0]=voxsize[1]=voxsize[2]=1;
--      _load_inr(nfile,fopt,voxsize);
--      CImg<T> dest(fopt[0],fopt[1],fopt[2],fopt[3]);
--      cimg_load_inr_case(0,0,8, unsigned char);
--      cimg_load_inr_case(0,1,8, char);
--      cimg_load_inr_case(0,0,16,unsigned short);
--      cimg_load_inr_case(0,1,16,short);
--      cimg_load_inr_case(0,0,32,unsigned int);
--      cimg_load_inr_case(0,1,32,int);
--      cimg_load_inr_case(1,0,32,float);
--      cimg_load_inr_case(1,1,32,float);
--      cimg_load_inr_case(1,0,64,double);
--      cimg_load_inr_case(1,1,64,double);
--      if (!loaded) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_inr() : File '%s', cannot read images of the type specified in the file",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      if (!file) cimg::fclose(nfile);
--      return dest;
--    }
--
--    //! Load an image from an INRIMAGE-4 file.
--    static CImg get_load_inr(const char *const filename, float *const voxsize=0) {
--      return get_load_inr(0,filename,voxsize);
--    }
--
--    //! In-place version of get_load_inr()
--    CImg& load_inr(std::FILE *const file, const char *const filename=0, float *const voxsize=0) {
--      return get_load_inr(file,filename,voxsize).swap(*this);
--    }
--
--    //! In-place version of get_load_inr()
--    CImg& load_inr(const char *const filename, float *const voxsize=0) {
--      return get_load_inr(filename,voxsize).swap(*this);
--    }
--
--#define cimg_load_pandore_case(nid,nbdim,nwidth,nheight,ndepth,ndim,stype) \
--  case nid: { \
--    cimg::fread(dims,nbdim,nfile); \
--    if (endian) cimg::endian_swap(dims,nbdim); \
--    dest.assign(nwidth,nheight,ndepth,ndim); \
--    stype *buffer = new stype[dest.size()]; \
--    cimg::fread(buffer,dest.size(),nfile); \
--    if (endian) cimg::endian_swap(buffer,dest.size()); \
--    T *ptrd = dest.ptr(); \
--    cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++); \
--    buffer-=dest.size(); \
--    delete[] buffer; \
--   } \
--   break;
--
--    //! Load an image from a PANDORE-5 file.
--    static CImg get_load_pandore(std::FILE *const file, const char *const filename=0) {
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      typedef unsigned char uchar;
--      /* Don't use these two and they cause warnings.
--       *
--      typedef unsigned short ushort;
--      typedef unsigned int uint;
--       */
--      typedef unsigned long ulong;
--      CImg dest;
--      char tmp[32];
--      cimg::fread(tmp,12,nfile);
--      if (cimg::strncasecmp("PANDORE",tmp,7)) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_pandore() : File '%s' is not a valid PANDORE file.\n"
--                              "(PANDORE identifier not found).",pixel_type(),filename?filename:"(FILE*)");
--      }
--      unsigned int imageid,dims[8];
--      int ptbuf[4];
--      cimg::fread(&imageid,1,nfile);
--      const bool endian = (imageid>255);
--      if (endian) cimg::endian_swap(imageid);
--
--      cimg::fread(tmp,20,nfile);
--      switch (imageid) {
--        cimg_load_pandore_case(2,2,dims[1],1,1,1,uchar);
--        cimg_load_pandore_case(3,2,dims[1],1,1,1,long);
--        cimg_load_pandore_case(4,2,dims[1],1,1,1,float);
--        cimg_load_pandore_case(5,3,dims[2],dims[1],1,1,uchar);
--        cimg_load_pandore_case(6,3,dims[2],dims[1],1,1,long);
--        cimg_load_pandore_case(7,3,dims[2],dims[1],1,1,float);
--        cimg_load_pandore_case(8,4,dims[3],dims[2],dims[1],1,uchar);
--        cimg_load_pandore_case(9,4,dims[3],dims[2],dims[1],1,long);
--        cimg_load_pandore_case(10,4,dims[3],dims[2],dims[1],1,float);
--
--      case 11: { // Region 1D
--        cimg::fread(dims,3,nfile);
--        if (endian) cimg::endian_swap(dims,3);
--        dest.assign(dims[1],1,1,1);
--        if (dims[2]<256) {
--          unsigned char *buffer = new unsigned char[dest.size()];
--          cimg::fread(buffer,dest.size(),nfile);
--          T *ptrd = dest.ptr();
--          cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--          buffer-=dest.size();
--          delete[] buffer;
--        } else {
--          if (dims[2]<65536) {
--            unsigned short *buffer = new unsigned short[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          } else {
--            unsigned int *buffer = new unsigned int[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          }
--        }
--      }
--        break;
--      case 12: { // Region 2D
--        cimg::fread(dims,4,nfile);
--        if (endian) cimg::endian_swap(dims,4);
--        dest.assign(dims[2],dims[1],1,1);
--        if (dims[3]<256) {
--          unsigned char *buffer = new unsigned char[dest.size()];
--          cimg::fread(buffer,dest.size(),nfile);
--          T *ptrd = dest.ptr();
--          cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--          buffer-=dest.size();
--          delete[] buffer;
--        } else {
--          if (dims[3]<65536) {
--            unsigned short *buffer = new unsigned short[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          } else {
--            unsigned long *buffer = new unsigned long[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          }
--        }
--      }
--        break;
--      case 13: { // Region 3D
--        cimg::fread(dims,5,nfile);
--        if (endian) cimg::endian_swap(dims,5);
--        dest.assign(dims[3],dims[2],dims[1],1);
--        if (dims[4]<256) {
--          unsigned char *buffer = new unsigned char[dest.size()];
--          cimg::fread(buffer,dest.size(),nfile);
--          T *ptrd = dest.ptr();
--          cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--          buffer-=dest.size();
--          delete[] buffer;
--        } else {
--          if (dims[4]<65536) {
--            unsigned short *buffer = new unsigned short[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          } else {
--            unsigned int *buffer = new unsigned int[dest.size()];
--            cimg::fread(buffer,dest.size(),nfile);
--            if (endian) cimg::endian_swap(buffer,dest.size());
--            T *ptrd = dest.ptr();
--            cimg_foroff(dest,off) *(ptrd++) = (T)*(buffer++);
--            buffer-=dest.size();
--            delete[] buffer;
--          }
--        }
--      }
--        break;
--        cimg_load_pandore_case(16,4,dims[2],dims[1],1,3,uchar);
--        cimg_load_pandore_case(17,4,dims[2],dims[1],1,3,long);
--        cimg_load_pandore_case(18,4,dims[2],dims[1],1,3,float);
--        cimg_load_pandore_case(19,5,dims[3],dims[2],dims[1],3,uchar);
--        cimg_load_pandore_case(20,5,dims[3],dims[2],dims[1],3,long);
--        cimg_load_pandore_case(21,5,dims[3],dims[2],dims[1],3,float);
--        cimg_load_pandore_case(22,2,dims[1],1,1,dims[0],uchar);
--        cimg_load_pandore_case(23,2,dims[1],1,1,dims[0],long);
--        cimg_load_pandore_case(24,2,dims[1],1,1,dims[0],ulong);
--        cimg_load_pandore_case(25,2,dims[1],1,1,dims[0],float);
--        cimg_load_pandore_case(26,3,dims[2],dims[1],1,dims[0],uchar);
--        cimg_load_pandore_case(27,3,dims[2],dims[1],1,dims[0],long);
--        cimg_load_pandore_case(28,3,dims[2],dims[1],1,dims[0],ulong);
--        cimg_load_pandore_case(29,3,dims[2],dims[1],1,dims[0],float);
--        cimg_load_pandore_case(30,4,dims[3],dims[2],dims[1],dims[0],uchar);
--        cimg_load_pandore_case(31,4,dims[3],dims[2],dims[1],dims[0],long);
--        cimg_load_pandore_case(32,4,dims[3],dims[2],dims[1],dims[0],ulong);
--        cimg_load_pandore_case(33,4,dims[3],dims[2],dims[1],dims[0],float);
--      case 34: // Points 1D
--        cimg::fread(ptbuf,1,nfile);
--        if (endian) cimg::endian_swap(ptbuf,1);
--        dest.assign(1); dest[0]=(T)ptbuf[0];
--        break;
--      case 35: // Points 2D
--        cimg::fread(ptbuf,2,nfile);
--        if (endian) cimg::endian_swap(ptbuf,2);
--        dest.assign(2); dest[0]=(T)ptbuf[1]; dest[1]=(T)ptbuf[0];
--        break;
--      case 36: // Points 3D
--        cimg::fread(ptbuf,3,nfile);
--        if (endian) cimg::endian_swap(ptbuf,3);
--        dest.assign(3); dest[0]=(T)ptbuf[2]; dest[1]=(T)ptbuf[1]; dest[2]=(T)ptbuf[0];
--        break;
--      default:
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::get_load_pandore() : File '%s', cannot read images with ID_type=%u",
--                              pixel_type(),filename?filename:"(FILE*)",imageid);
--      }
--      if (!file) cimg::fclose(nfile);
--      return dest;
--    }
--
--    //! Load an image from a PANDORE-5 file.
--    static CImg get_load_pandore(const char *const filename) {
--      return get_load_pandore(0,filename);
--    }
--
--    //! In-place version of get_load_pandore()
--    CImg& load_pandore(std::FILE *const file, const char *const filename) {
--      return get_load_pandore(file,filename).swap(*this);
--    }
--
--    //! In-place version of get_load_pandore()
--    CImg& load_pandore(const char *const filename) {
--      return get_load_pandore(filename).swap(*this);
--    }
--
--    //! Load an image from an ANALYZE7.5 file
--    static CImg get_load_analyze(const char *const filename, float *const voxsize=0) {
--
--      // Open header and data files
--      std::FILE *file_header=0, *file=0;
--      char body[1024];
--      const char *ext = cimg::filename_split(filename,body);
--      if (!cimg::strncasecmp(ext,"hdr",3) ||
--          !cimg::strncasecmp(ext,"img",3)) {
--        std::sprintf(body+cimg::strlen(body),".hdr");
--        file_header = cimg::fopen(body,"rb");
--        if (!file_header) return CImg<T>();
--        std::sprintf(body+cimg::strlen(body)-3,"img");
--        file = cimg::fopen(body,"rb");
--        if (!file) { cimg::fclose(file_header); return CImg<T>(); }
--      } else throw CImgIOException("CImg<%s>::get_load_analyze() : Filename '%s', not recognized as an Analyze 7.5 file.",
--                                   pixel_type(),filename);
--
--      // Read header
--      bool endian = false;
--      unsigned int header_size;
--      cimg::fread(&header_size,1,file_header);
--      if (header_size>=4096) { endian = true; cimg::endian_swap(header_size); }
--      unsigned char *header = new unsigned char[header_size];
--      cimg::fread(header+4,header_size-4,file_header);
--      cimg::fclose(file_header);
--      if (endian) {
--        cimg::endian_swap((short*)(header+40),5);
--        cimg::endian_swap((short*)(header+70),1);
--        cimg::endian_swap((short*)(header+72),1);
--        cimg::endian_swap((float*)(header+76),4);
--        cimg::endian_swap((float*)(header+112),1);
--      }
--      unsigned short *dim = (unsigned short*)(header+40), dimx=1, dimy=1, dimz=1, dimv=1;
--      cimg::warn(!dim[0],"CImg<%s>::get_load_analyze() : Specified image has zero dimensions.",pixel_type());
--      cimg::warn(dim[0]>4,"CImg<%s>::get_load_analyze() : Number of image dimension is %d, reading only the 4 first dimensions",
--                 pixel_type(),dim[0]);
--      if (dim[0]>=1) dimx = dim[1];
--      if (dim[0]>=2) dimy = dim[2];
--      if (dim[0]>=3) dimz = dim[3];
--      if (dim[0]>=4) dimv = dim[4];
--
--      float scalefactor = *(float*)(header+112); if (scalefactor==0) scalefactor=1;
--      const unsigned short datatype = *(short*)(header+70);
--      if (voxsize) { const float *vsize = (float*)(header+76); voxsize[0] = vsize[1]; voxsize[1] = vsize[2]; voxsize[2] = vsize[3]; }
--      delete[] header;
--
--      // Read pixel data
--      CImg dest(dimx,dimy,dimz,dimv);
--      switch (datatype) {
--      case 2: {
--        unsigned char *buffer = new unsigned char[dimx*dimy*dimz*dimv];
--        cimg::fread(buffer,dimx*dimy*dimz*dimv,file);
--        cimg_foroff(dest,off) dest.data[off] = (T)(buffer[off]*scalefactor);
--        delete[] buffer;
--      } break;
--      case 4: {
--        short *buffer = new short[dimx*dimy*dimz*dimv];
--        cimg::fread(buffer,dimx*dimy*dimz*dimv,file);
--        if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
--        cimg_foroff(dest,off) dest.data[off] = (T)(buffer[off]*scalefactor);
--        delete[] buffer;
--      } break;
--      case 8: {
--        int *buffer = new int[dimx*dimy*dimz*dimv];
--        cimg::fread(buffer,dimx*dimy*dimz*dimv,file);
--        if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
--        cimg_foroff(dest,off) dest.data[off] = (T)(buffer[off]*scalefactor);
--        delete[] buffer;
--      } break;
--      case 16: {
--        float *buffer = new float[dimx*dimy*dimz*dimv];
--        cimg::fread(buffer,dimx*dimy*dimz*dimv,file);
--        if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
--        cimg_foroff(dest,off) dest.data[off] = (T)(buffer[off]*scalefactor);
--        delete[] buffer;
--      } break;
--      case 64: {
--        double *buffer = new double[dimx*dimy*dimz*dimv];
--        cimg::fread(buffer,dimx*dimy*dimz*dimv,file);
--        if (endian) cimg::endian_swap(buffer,dimx*dimy*dimz*dimv);
--        cimg_foroff(dest,off) dest.data[off] = (T)(buffer[off]*scalefactor);
--        delete[] buffer;
--      } break;
--      default:
--        cimg::fclose(file);
--        throw CImgIOException("CImg<%s>::get_load_analyze() : File '%s, cannot read images width 'datatype = %d'",
--                              pixel_type(),filename,datatype);
--      }
--      cimg::fclose(file);
--      return dest;
--    }
--
--    //! In-place version of get_load_analyze()
--    CImg& load_analyze(const char *const filename, float *const voxsize = 0) {
--      return get_load_analyze(filename,voxsize).swap(*this);
--    }
--
--    //! Load PAR-REC (Philips) image file
--    static CImg get_load_parrec(const char *const filename, const char axe='v', const char align='p') {
--      return CImgList<T>::get_load_parrec(filename).get_append(axe,align);
--    }
--
--    //! In-place version of get_load_parrec()
--    CImg& load_parrec(const char *const filename, const char axis='v', const char align='p') {
--      return get_load_parrec(filename,axis,align).swap(*this);
--    }
--
--    //! Load an image from a CImg RAW file
--    static CImg get_load_cimg(std::FILE *const file, const char *const filename=0, const char axis='v', const char align='p') {
--      return CImgList<T>::get_load_cimg(file,filename).get_append(axis,align);
--    }
--
--    //! Load an image from a CImg RAW file
--    static CImg get_load_cimg(const char *const filename, const char axis='v', const char align='p') {
--      return get_load_cimg(0,filename,axis,align);
--    }
--
--    //! In-place version of get_load_cimg()
--    CImg& load_cimg(std::FILE *const file, const char *const filename=0, const char axis='v', const char align='p') {
--      return get_load_cimg(file,filename,axis,align).swap(*this);
--    }
--
--    //! In-place version of get_load_cimg()
--    CImg& load_cimg(const char *const filename, const char axis='v', const char align='p') {
--      return get_load_cimg(filename,axis,align).swap(*this);
--    }
--
--    //! Function that loads the image for other file formats that are not natively handled by CImg.
--    //! This is the case for all compressed image formats (GIF,PNG,JPG,TIF,...).
--    static CImg get_load_imagemagick(const char *const filename) {
--      static bool first_time = true;
--      char command[1024], filetmp[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      std::FILE *file = 0;
--      do {
--        std::sprintf(filetmp,"%s%sCImg%.4d.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      std::sprintf(command,"%s \"%s\" %s",cimg::imagemagick_path(),filename,filetmp);
--      cimg::system(command,cimg::imagemagick_path());
--      if (!(file = std::fopen(filetmp,"rb"))) {
--        cimg::fclose(cimg::fopen(filename,"r"));
--        throw CImgIOException("CImg<%s>::get_load_imagemagick() : Failed to open image '%s'.\n\n"
--                              "Path of 'ImageMagick's convert' : \"%s\"\n"
--                              "Path of temporary filename : \"%s\"",
--                              pixel_type(),filename,cimg::imagemagick_path(),filetmp);
--      } else cimg::fclose(file);
--      const CImg dest = CImg<T>::get_load_pnm(filetmp);
--      std::remove(filetmp);
--      return dest;
--    }
--
--    //! In-place version of get_load_imagemagick()
--    CImg& load_imagemagick(const char *const filename) {
--      return get_load_imagemagick(filename).swap(*this);
--    }
--
--    //! Function that loads the image for other file formats that are not natively handled by CImg.
--    //! This is the case for all compressed image formats (GIF,PNG,JPG,TIF,...).
--    static CImg get_load_graphicsmagick(const char *const filename) {
--      static bool first_time = true;
--      char command[1024], filetmp[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      std::FILE *file = 0;
--      do {
--        std::sprintf(filetmp,"%s%sCImg%.4d.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      std::sprintf(command,"%s convert \"%s\" %s",cimg::graphicsmagick_path(),filename,filetmp);
--      cimg::system(command,cimg::graphicsmagick_path());
--      if (!(file = std::fopen(filetmp,"rb"))) {
--        cimg::fclose(cimg::fopen(filename,"r"));
--        throw CImgIOException("CImg<%s>::get_load_graphicsmagick() : Failed to open image '%s'.\n\n"
--                              "Path of 'GraphicsMagick's gm' : \"%s\"\n"
--                              "Path of temporary filename : \"%s\"",
--                              pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
--      } else cimg::fclose(file);
--      const CImg dest = CImg<T>::get_load_pnm(filetmp);
--      std::remove(filetmp);
--      return dest;
--    }
--
--    //! In-place version of get_load_graphicsmagick()
--    CImg& load_graphicsmagick(const char *const filename) {
--      return get_load_graphicsmagick(filename).swap(*this);
--    }
--
--    //! Function that loads the image for other file formats that are not natively handled by CImg.
--    //! This is the case for all compressed image formats (GIF,PNG,JPG,TIF,...).
--    static CImg get_load_other(const char *const filename) {
--      CImg<T> res;
--      const unsigned int odebug = cimg::exception_mode();
--      cimg::exception_mode() = 0;
--      try { res.load_magick(filename); }
--      catch (CImgException&) {
--      try { res.load_imagemagick(filename); }
--      catch (CImgException&) {
--        try { res.load_graphicsmagick(filename); }
--        catch (CImgException&) {
--          res.assign();
--        }
--      }
--      }
--      cimg::exception_mode()=odebug;
--      if (res.is_empty())
--        throw CImgIOException("CImg<%s>::get_load_other() : Failed to open image '%s'.\n"
--                              "Check you have either the ImageMagick or GraphicsMagick package installed.",
--                              pixel_type(),filename);
--      return res;
--    }
--
--    //! In-place version of get_load_graphicsmagick()
--    CImg& load_other(const char *const filename) {
--      return get_load_other(filename).swap(*this);
--    }
--
--    //! Load an image from a Dicom file (need '(X)Medcon' : http://xmedcon.sourceforge.net )
--    static CImg get_load_dicom(const char *const filename) {
--      static bool first_time = true;
--      char command[1024], filetmp[512], body[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      cimg::fclose(cimg::fopen(filename,"r"));
--      std::FILE *file;
--      do {
--        std::sprintf(filetmp,"CImg%.4d.hdr",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      std::sprintf(command,"%s -w -c anlz -o %s -f %s",cimg::medcon_path(),filetmp,filename);
--      cimg::system(command);
--      cimg::filename_split(filetmp,body);
--      std::sprintf(command,"m000-%s.hdr",body);
--      file = std::fopen(command,"rb");
--      if (!file) {
--        throw CImgIOException("CImg<%s>::get_load_dicom() : Failed to open image '%s'.\n\n"
--                              "Path of 'medcon' : \"%s\"\n"
--                              "Path of temporary filename : \"%s\"",
--                              pixel_type(),filename,cimg::medcon_path,filetmp);
--      } else cimg::fclose(file);
--      const CImg dest = CImg<T>::get_load_analyze(command);
--      std::remove(command);
--      std::sprintf(command,"m000-%s.img",body);
--      std::remove(command);
--      return dest;
--    }
--
--    //! In-place version of get_load_dicom()
--    CImg& load_dicom(const char *const filename) {
--      return get_load_dicom(filename).swap(*this);
--    }
--
--    //! Load OFF files (GeomView 3D object files)
--    template<typename tf,typename tc>
--    static CImg<T> get_load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
--                                const bool invert_faces=false) {
--      std::FILE *file=cimg::fopen(filename,"r");
--      unsigned int nb_points=0, nb_triangles=0;
--      int err;
--      if ((err = std::fscanf(file,"OFF%u%u%*[^\n]",&nb_points,&nb_triangles))!=2) {
--        cimg::fclose(file);
--        throw CImgIOException("CImg<%s>::get_load_off() : File '%s' is not a valid OFF file.",pixel_type(),filename);
--      }
--
--      // Read points data
--      CImg<T> points(nb_points,3);
--      float X=0,Y=0,Z=0;
--      cimg_forX(points,l) {
--        if ((err = std::fscanf(file,"%f%f%f%*[^\n]",&X,&Y,&Z))!=3) {
--          cimg::fclose(file);
--          throw CImgIOException("CImg<%s>::get_load_off() : File '%s', cannot read point %u.\n",pixel_type(),filename,l);
--        }
--        points(l,0) = (T)X; points(l,1) = (T)Y; points(l,2) = (T)Z;
--      }
--
--      // Read primitive data
--      primitives.assign();
--      colors.assign();
--      bool stopflag = false;
--      while (!stopflag) {
--        unsigned int prim=0, i0=0, i1=0, i2=0, i3=0;
--        char s_colors[256] = {'\0'};
--        if ((err = std::fscanf(file,"%u",&prim))!=1) stopflag=true;
--        else switch (prim) {
--        case 3: {
--          if ((err = std::fscanf(file,"%u%u%u%255[^\n]",&i0,&i1,&i2,s_colors))<3) stopflag = true;
--          else {
--            float c0=0.5, c1=0.5, c2=0.5;
--            std::sscanf(s_colors,"%f%f%f",&c0,&c1,&c2);
--            if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2));
--            else primitives.insert(CImg<tf>::vector(i0,i2,i1));
--            colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
--          }
--        } break;
--        case 4: {
--          if ((err = std::fscanf(file,"%u%u%u%u%255[^\n]",&i0,&i1,&i2,&i3,s_colors))<4) stopflag = true;
--          else {
--            float c0=0.5, c1=0.5, c2=0.5;
--            std::sscanf(s_colors,"%f%f%f",&c0,&c1,&c2);
--            if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2,i3));
--            else primitives.insert(CImg<tf>::vector(i0,i3,i2,i1));
--            colors.insert(CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255),(tc)(c2*255)));
--          }
--        } break;
--        default: stopflag = true;
--        }
--      }
--      cimg::fclose(file);
--      cimg::warn(primitives.size!=nb_triangles,
--                 "CImg<%s>::get_load_off() : File '%s' contained %u triangles instead of %u as claimed in the header.",
--                 pixel_type(),filename,primitives.size,nb_triangles);
--      return points;
--    }
--
--    //! In-place version of get_load_off()
--    template<typename tf,typename tc>
--    CImg& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors, const bool invert_faces=false) {
--      return get_load_off(filename,primitives,colors,invert_faces).swap(*this);
--    }
--
--    //! Save the image as a file.
--    /**
--       The used file format is defined by the file extension in the filename \p filename.\n
--       Parameter \p number can be used to add a 6-digit number to the filename before saving.\n
--       If \p normalize is true, a normalized version of the image (between [0,255]) is saved.
--    **/
--    const CImg& save(const char *const filename, const int number=-1) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      const char *ext = cimg::filename_split(filename);
--      char nfilename[1024];
--      const char *const fn = (number>=0)?cimg::filename_number(filename,number,6,nfilename):filename;
--      if (!cimg::strncasecmp(ext,"asc",3)) return save_ascii(fn);
--      if (!cimg::strncasecmp(ext,"dlm",3) ||
--          !cimg::strncasecmp(ext,"txt",3)) return save_dlm(fn);
--      if (!cimg::strncasecmp(ext,"inr",3)) return save_inr(fn);
--      if (!cimg::strncasecmp(ext,"hdr",3)) return save_analyze(fn);
--      if (!cimg::strncasecmp(ext,"dcm",3)) return save_dicom(fn);
--      if (!cimg::strncasecmp(ext,"pan",3)) return save_pandore(fn);
--      if (!cimg::strncasecmp(ext,"bmp",3)) return save_bmp(fn);
--      if (!cimg::strncasecmp(ext,"png",3)) return save_png(fn);
--      if (!cimg::strncasecmp(ext,"tif",3)) return save_tiff(fn);
--      if (!cimg::strncasecmp(ext,"jpg",3) ||
--          !cimg::strncasecmp(ext,"jpeg",4)) return save_jpeg(fn);
--      if (!cimg::strncasecmp(ext,"rgba",4)) return save_rgba(fn);
--      if (!cimg::strncasecmp(ext,"rgb",3)) return save_rgb(fn);
--      if (!cimg::strncasecmp(ext,"raw",3)) return save_raw(fn);
--      if (!cimg::strncasecmp(ext,"cimg",4) || ext[0]=='\0') return save_cimg(fn);
--      if (!cimg::strncasecmp(ext,"pgm",3) ||
--          !cimg::strncasecmp(ext,"ppm",3) ||
--          !cimg::strncasecmp(ext,"pnm",3)) return save_pnm(fn);
--      if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(fn,true);
--      return save_other(fn);
--    }
--
--    //! Save the image as an ASCII file (ASCII Raw + simple header).
--    const CImg& save_ascii(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_ascii() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
--      std::fprintf(nfile,"%u %u %u %u\n",width,height,depth,dim);
--      const T* ptrs = data;
--      cimg_forYZV(*this,y,z,v) {
--        cimg_forX(*this,x) std::fprintf(nfile,"%g ",(double)*(ptrs++));
--        std::fputc('\n',nfile);
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as an ASCII file (ASCII Raw + simple header).
--    const CImg& save_ascii(const char *const filename) const {
--      return save_ascii(0,filename);
--    }
--
--    //! Save the image as a DLM file.
--    const CImg& save_dlm(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      cimg::warn(depth>1,
--                 "CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Pixel values along Z will be unrolled (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      cimg::warn(dim>1,
--                 "CImg<%s>::save_dlm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Pixel values along V will be unrolled (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
--      const T* ptrs = data;
--      cimg_forYZV(*this,y,z,v) {
--        cimg_forX(*this,x) std::fprintf(nfile,"%g%s",(double)*(ptrs++),(x==(int)width-1)?"":",");
--        std::fputc('\n',nfile);
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as a DLM file.
--    const CImg& save_dlm(const char *const filename) const {
--      return save_dlm(0,filename);
--    }
--
--    //! Save the image as a PNM file.
--    const CImg& save_pnm(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      const CImgStats st(*this,false);
--      cimg::warn(depth>1,
--                 "CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      cimg::warn(dim>3,
--                 "CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) is multispectral. Only the three first channels will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      const double stmin = st.min, stmax = st.max;
--      cimg::warn(stmin<0 || stmax>65535,"CImg<%s>::save_pnm() : Instance image (%u,%u,%u,%u,%p) has pixel values in [%g,%g]. Probable type overflow (file '%s').",pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      const T
--        *ptrR = ptr(0,0,0,0),
--        *ptrG = (dim>=2)?ptr(0,0,0,1):ptrR,
--        *ptrB = (dim>=3)?ptr(0,0,0,2):ptrR;
--      const unsigned int buf_size = width*height*(dim==1?1:3);
--
--      std::fprintf(nfile,"P%c\n# CREATOR: CImg : Original size=%ux%ux%ux%u\n%u %u\n%u\n",
--                   (dim==1?'5':'6'),width,height,depth,dim,width,height,(st.max)<256?255:65535);
--
--      switch(dim) {
--      case 1: {
--        if ((st.max)<256) { // Binary PGM 8 bits
--          unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
--          cimg_forXY(*this,x,y) *(xptrd++) = (unsigned char)*(ptrR++);
--          cimg::fwrite(ptrd,buf_size,nfile);
--          delete[] ptrd;
--        } else {             // Binary PGM 16 bits
--          unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
--          cimg_forXY(*this,x,y) *(xptrd++) = (unsigned short)*(ptrR++);
--          if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
--          cimg::fwrite(ptrd,buf_size,nfile);
--          delete[] ptrd;
--        }
--      } break;
--      default: {
--        if ((st.max)<256) { // Binary PPM 8 bits
--          unsigned char *ptrd = new unsigned char[buf_size], *xptrd = ptrd;
--          cimg_forXY(*this,x,y) {
--            *(xptrd++) = (unsigned char)*(ptrR++);
--            *(xptrd++) = (unsigned char)*(ptrG++);
--            *(xptrd++) = (unsigned char)*(ptrB++);
--          }
--          cimg::fwrite(ptrd,buf_size,nfile);
--          delete[] ptrd;
--        } else {             // Binary PPM 16 bits
--          unsigned short *ptrd = new unsigned short[buf_size], *xptrd = ptrd;
--          cimg_forXY(*this,x,y) {
--            *(xptrd++) = (unsigned short)*(ptrR++);
--            *(xptrd++) = (unsigned short)*(ptrG++);
--            *(xptrd++) = (unsigned short)*(ptrB++);
--          }
--          if (!cimg::endian()) cimg::endian_swap(ptrd,buf_size);
--          cimg::fwrite(ptrd,buf_size,nfile);
--          delete[] ptrd;
--        }
--      } break;
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as a PNM file.
--    const CImg& save_pnm(const char *const filename) const {
--      return save_pnm(0,filename);
--    }
--
--    //! Save an image as a Dicom file (need '(X)Medcon' : http://xmedcon.sourceforge.net )
--    const CImg& save_dicom(const char *const filename) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_dicom() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      static bool first_time = true;
--      char command[1024], filetmp[512], body[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      std::FILE *file;
--      do {
--        std::sprintf(filetmp,"CImg%.4d.hdr",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      save_analyze(filetmp);
--      std::sprintf(command,"%s -w -c dicom -o %s -f %s",cimg::medcon_path(),filename,filetmp);
--      cimg::system(command);
--      std::remove(filetmp);
--      cimg::filename_split(filetmp,body);
--      std::sprintf(filetmp,"%s.img",body);
--      std::remove(filetmp);
--      std::sprintf(command,"m000-%s",filename);
--      file = std::fopen(command,"rb");
--      if (!file) {
--        cimg::fclose(cimg::fopen(filename,"r"));
--        throw CImgIOException("CImg<%s>::save_dicom() : Failed to save image '%s'.\n\n"
--                              "Path of 'medcon' : \"%s\"\n"
--                              "Path of temporary filename : \"%s\"",
--                              pixel_type(),filename,cimg::medcon_path(),filetmp);
--      } else cimg::fclose(file);
--      std::rename(command,filename);
--      return *this;
--    }
--
--    //! Save the image as an ANALYZE7.5 file.
--    const CImg& save_analyze(const char *const filename, const float *const voxsize=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_analyze() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_analyze() :  Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      std::FILE *file;
--      char header[348],hname[1024],iname[1024];
--      const char *ext = cimg::filename_split(filename);
--      short datatype=-1;
--      std::memset(header,0,348);
--      if (!ext[0]) { std::sprintf(hname,"%s.hdr",filename); std::sprintf(iname,"%s.img",filename); }
--      if (!cimg::strncasecmp(ext,"hdr",3)) {
--        std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(iname+cimg::strlen(iname)-3,"img");
--      }
--      if (!cimg::strncasecmp(ext,"img",3)) {
--        std::strcpy(hname,filename); std::strcpy(iname,filename); std::sprintf(hname+cimg::strlen(iname)-3,"hdr");
--      }
--      ((int*)(header))[0] = 348;
--      std::sprintf(header+4,"CImg");
--      std::sprintf(header+14," ");
--      ((short*)(header+36))[0] = 4096;
--      ((char*)(header+38))[0] = 114;
--      ((short*)(header+40))[0] = 4;
--      ((short*)(header+40))[1] = width;
--      ((short*)(header+40))[2] = height;
--      ((short*)(header+40))[3] = depth;
--      ((short*)(header+40))[4] = dim;
--      if (!cimg::strcasecmp(pixel_type(),"bool"))           datatype = 2;
--      if (!cimg::strcasecmp(pixel_type(),"unsigned char"))  datatype = 2;
--      if (!cimg::strcasecmp(pixel_type(),"char"))           datatype = 2;
--      if (!cimg::strcasecmp(pixel_type(),"unsigned short")) datatype = 4;
--      if (!cimg::strcasecmp(pixel_type(),"short"))          datatype = 4;
--      if (!cimg::strcasecmp(pixel_type(),"unsigned int"))   datatype = 8;
--      if (!cimg::strcasecmp(pixel_type(),"int"))            datatype = 8;
--      if (!cimg::strcasecmp(pixel_type(),"unsigned long"))  datatype = 8;
--      if (!cimg::strcasecmp(pixel_type(),"long"))           datatype = 8;
--      if (!cimg::strcasecmp(pixel_type(),"float"))          datatype = 16;
--      if (!cimg::strcasecmp(pixel_type(),"double"))         datatype = 64;
--      if (datatype<0)
--        throw CImgIOException("CImg<%s>::save_analyze() : Cannot save image '%s' since pixel type (%s)"
--                              "is not handled in Analyze7.5 specifications.\n",
--                              pixel_type(),filename,pixel_type());
--      ((short*)(header+70))[0] = datatype;
--      ((short*)(header+72))[0] = sizeof(T);
--      ((float*)(header+112))[0] = 1;
--      ((float*)(header+76))[0] = 0;
--      if (voxsize) {
--        ((float*)(header+76))[1] = voxsize[0];
--        ((float*)(header+76))[2] = voxsize[1];
--        ((float*)(header+76))[3] = voxsize[2];
--      } else ((float*)(header+76))[1] = ((float*)(header+76))[2] = ((float*)(header+76))[3] = 1;
--      file = cimg::fopen(hname,"wb");
--      cimg::fwrite(header,348,file);
--      cimg::fclose(file);
--      file = cimg::fopen(iname,"wb");
--      cimg::fwrite(data,size(),file);
--      cimg::fclose(file);
--      return *this;
--    }
--
--    //! Save the image as a CImg file (Binary RAW + simple header)
--    const CImg& save_cimg(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      CImgList<T> tmp(1);
--      tmp[0].width = width;
--      tmp[0].height = height;
--      tmp[0].depth = depth;
--      tmp[0].dim = dim;
--      tmp[0].data = data;
--      tmp.save_cimg(file,filename);
--      tmp[0].width = tmp[0].height = tmp[0].depth = tmp[0].dim = 0;
--      tmp[0].data = 0;
--      return *this;
--    }
--
--    //! Save the image as a CImg file (Binary RAW + simple header)
--    const CImg& save_cimg(const char *const filename) const {
--      return save_cimg(0,filename);
--    }
--
--    //! Save the image as a RAW file
--    const CImg& save_raw(std::FILE *const file, const char *const filename=0, const bool multiplexed=false) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_raw() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      if (!multiplexed) cimg::fwrite(data,size(),nfile);
--      else {
--        CImg<T> buf(dim);
--        cimg_forXYZ(*this,x,y,z) {
--          cimg_forV(*this,k) buf[k] = (*this)(x,y,z,k);
--          cimg::fwrite(buf.data,dim,nfile);
--        }
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as a RAW file
--    const CImg& save_raw(const char *const filename=0, const bool multiplexed=false) const {
--      return save_raw(0,filename,multiplexed);
--    }
--
--    //! Save the image using ImageMagick's convert.
--    /** Function that saves the image for other file formats that are not natively handled by CImg,
--        using the tool 'convert' from the ImageMagick package.\n
--        This is the case for all compressed image formats (GIF,PNG,JPG,TIF,...). You need to install
--        the ImageMagick package in order to get
--        this function working properly (see http://www.imagemagick.org ).
--    **/
--    const CImg& save_imagemagick(const char *const filename, const unsigned int quality=100) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_imagemagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      static bool first_time = true;
--      char command[512],filetmp[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      std::FILE *file;
--      do {
--        if (dim==1) std::sprintf(filetmp,"%s%sCImg%.4d.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        else std::sprintf(filetmp,"%s%sCImg%.4d.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      save_pnm(filetmp);
--      std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::imagemagick_path(),quality,filetmp,filename);
--      cimg::system(command);
--      file = std::fopen(filename,"rb");
--      if (!file) throw CImgIOException("CImg<%s>::save_imagemagick() : Failed to save image '%s'.\n\n"
--                                       "Path of 'convert' : \"%s\"\n"
--                                       "Path of temporary filename : \"%s\"\n",
--                                       pixel_type(),filename,cimg::imagemagick_path(),filetmp);
--      if (file) cimg::fclose(file);
--      std::remove(filetmp);
--      return *this;
--    }
--
--    //! Save the image using GraphicsMagick's gm.
--    /** Function that saves the image for other file formats that are not natively handled by CImg,
--        using the tool 'gm' from the GraphicsMagick package.\n
--        This is the case for all compressed image formats (GIF,PNG,JPG,TIF,...). You need to install
--        the GraphicsMagick package in order to get
--        this function working properly (see http://www.graphicsmagick.org ).
--    **/
--    const CImg& save_graphicsmagick(const char *const filename, const unsigned int quality=100) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s')",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_graphicsmagick() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      static bool first_time = true;
--      char command[512],filetmp[512];
--      if (first_time) { std::srand((unsigned int)::time(0)); first_time = false; }
--      std::FILE *file;
--      do {
--        if (dim==1) std::sprintf(filetmp,"%s%sCImg%.4d.pgm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        else std::sprintf(filetmp,"%s%sCImg%.4d.ppm",cimg::temporary_path(),cimg_OS==2?"\\":"/",std::rand()%10000);
--        if ((file=std::fopen(filetmp,"rb"))!=0) std::fclose(file);
--      } while (file);
--      save_pnm(filetmp);
--      std::sprintf(command,"%s -quality %u%% %s \"%s\"",cimg::graphicsmagick_path(),quality,filetmp,filename);
--      cimg::system(command);
--      file = std::fopen(filename,"rb");
--      if (!file) throw CImgIOException("CImg<%s>::save_graphicsmagick() : Failed to save image '%s'.\n\n"
--                                       "Path of 'gm' : \"%s\"\n"
--                                       "Path of temporary filename : \"%s\"\n",
--                                       pixel_type(),filename,cimg::graphicsmagick_path(),filetmp);
--      if (file) cimg::fclose(file);
--      std::remove(filetmp);
--      return *this;
--    }
--
--    const CImg& save_other(const char *const filename, const unsigned int quality=100) const {
--      const unsigned int odebug = cimg::exception_mode();
--      bool is_saved = true;
--      cimg::exception_mode() = 0;
--      try { save_magick(filename); }
--      catch (CImgException&) {
--      try { save_imagemagick(filename,quality); }
--      catch (CImgException&) {
--        try { save_graphicsmagick(filename,quality); }
--        catch (CImgException&) {
--          is_saved = false;
--        }
--      }
--      }
--      cimg::exception_mode() = odebug;
--      if (!is_saved) throw CImgIOException("CImg<%s>::save_other() : File '%s' cannot be saved.\n"
--                                           "Check you have either the ImageMagick or GraphicsMagick package installed.",
--                                           pixel_type(),filename);
--      return *this;
--    }
--
--    //! Save the image as an INRIMAGE-4 file.
--    const CImg& save_inr(std::FILE *const file, const char *const filename=0, const float *const voxsize=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_inr() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      int inrpixsize=-1;
--      const char *inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0";
--      if (!cimg::strcasecmp(pixel_type(),"unsigned char"))  { inrtype = "unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
--      if (!cimg::strcasecmp(pixel_type(),"char"))           { inrtype = "fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
--      if (!cimg::strcasecmp(pixel_type(),"unsigned short")) { inrtype = "unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; }
--      if (!cimg::strcasecmp(pixel_type(),"short"))          { inrtype = "fixed\nPIXSIZE=16 bits\nSCALE=2**0"; inrpixsize = 2; }
--      if (!cimg::strcasecmp(pixel_type(),"unsigned int"))   { inrtype = "unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; }
--      if (!cimg::strcasecmp(pixel_type(),"int"))            { inrtype = "fixed\nPIXSIZE=32 bits\nSCALE=2**0"; inrpixsize = 4; }
--      if (!cimg::strcasecmp(pixel_type(),"float"))          { inrtype = "float\nPIXSIZE=32 bits"; inrpixsize = 4; }
--      if (!cimg::strcasecmp(pixel_type(),"double"))         { inrtype = "float\nPIXSIZE=64 bits"; inrpixsize = 8; }
--      if (inrpixsize<=0) throw CImgIOException("CImg<%s>::save_inr() : Don't know how to save images of '%s'",pixel_type(),pixel_type());
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      char header[257];
--      int err = std::sprintf(header,"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n",width,height,depth,dim);
--      if (voxsize) err += std::sprintf(header+err,"VX=%g\nVY=%g\nVZ=%g\n",voxsize[0],voxsize[1],voxsize[2]);
--      err += std::sprintf(header+err,"TYPE=%s\nCPU=%s\n",inrtype,cimg::endian()?"sun":"decm");
--      std::memset(header+err,'\n',252-err);
--      std::memcpy(header+252,"##}\n",4);
--      cimg::fwrite(header,256,nfile);
--      cimg_forXYZ(*this,x,y,z) cimg_forV(*this,k) cimg::fwrite(&((*this)(x,y,z,k)),1,nfile);
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as an INRIMAGE-4 file.
--    const CImg& save_inr(const char *const filename, const float *const voxsize=0) const {
--      return save_inr(0,filename,voxsize);
--    }
--
--#define cimg_save_pandore_case(sy,sz,sv,stype,id) \
--   if (!saved && (sy?(sy==height):true) && (sz?(sz==depth):true) && (sv?(sv==dim):true) && !strcmp(stype,pixel_type())) { \
--      unsigned int *iheader = (unsigned int*)(header+12); \
--      nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \
--      cimg::fwrite(header,36,nfile); \
--      cimg::fwrite(dims,nbdims,nfile); \
--      if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \
--        unsigned char *buffer = new unsigned char[size()]; \
--        const T *ptrs = ptr(); \
--        cimg_foroff(*this,off) *(buffer++)=(unsigned char)(*(ptrs++)); \
--        buffer-=size(); \
--        cimg::fwrite(buffer,size(),nfile); \
--        delete[] buffer; \
--      } \
--      if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \
--        unsigned long *buffer = new unsigned long[size()]; \
--        const T *ptrs = ptr(); \
--        cimg_foroff(*this,off) *(buffer++)=(long)(*(ptrs++)); \
--        buffer-=size(); \
--        cimg::fwrite(buffer,size(),nfile); \
--        delete[] buffer; \
--      } \
--      if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \
--        float *buffer = new float[size()]; \
--        const T *ptrs = ptr(); \
--        cimg_foroff(*this,off) *(buffer++)=(float)(*(ptrs++)); \
--        buffer-=size(); \
--        cimg::fwrite(buffer,size(),nfile); \
--        delete[] buffer; \
--      } \
--      saved = true; \
--    }
--
--    unsigned int _save_pandore_header_length(unsigned int id,unsigned int *dims,const unsigned int colorspace=0) const {
--      unsigned int nbdims=0;
--      if (id==2 || id==3 || id==4)    { dims[0]=1; dims[1]=width; nbdims=2; }
--      if (id==5 || id==6 || id==7)    { dims[0]=1; dims[1]=height; dims[2]=width; nbdims=3; }
--      if (id==8 || id==9 || id==10)   { dims[0]=dim; dims[1]=depth; dims[2]=height; dims[3]=width; nbdims=4; }
--      if (id==16 || id==17 || id==18) { dims[0]=3; dims[1]=height; dims[2]=width; dims[3]=colorspace; nbdims=4; }
--      if (id==19 || id==20 || id==21) { dims[0]=3; dims[1]=depth; dims[2]=height; dims[3]=width; dims[4]=colorspace; nbdims=5; }
--      if (id==22 || id==23 || id==25) { dims[0]=dim; dims[1]=width; nbdims=2; }
--      if (id==26 || id==27 || id==29) { dims[0]=dim; dims[1]=height; dims[2]=width; nbdims=3; }
--      if (id==30 || id==31 || id==33) { dims[0]=dim; dims[1]=depth; dims[2]=height; dims[3]=width; nbdims=4; }
--      return nbdims;
--    }
--
--    //! Save the image as a PANDORE-5 file.
--    const CImg& save_pandore(std::FILE *const file, const char *const filename=0, const unsigned int colorspace=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_pandore() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0,
--                                   0,0,0,0,
--                                   'C','I','m','g',0,0,0,0,0,
--                                   'N','o',' ','d','a','t','e',0,0,0,
--                                   0 };
--      unsigned int nbdims,dims[5];
--      bool saved=false;
--      cimg_save_pandore_case(1,1,1,"unsigned char",2);
--      cimg_save_pandore_case(1,1,1,"char",3);
--      cimg_save_pandore_case(1,1,1,"short",3);
--      cimg_save_pandore_case(1,1,1,"unsigned short",3);
--      cimg_save_pandore_case(1,1,1,"unsigned int",3);
--      cimg_save_pandore_case(1,1,1,"int",3);
--      cimg_save_pandore_case(1,1,1,"unsigned long",4);
--      cimg_save_pandore_case(1,1,1,"long",3);
--      cimg_save_pandore_case(1,1,1,"float",4);
--      cimg_save_pandore_case(1,1,1,"double",4);
--
--      cimg_save_pandore_case(0,1,1,"unsigned char",5);
--      cimg_save_pandore_case(0,1,1,"char",6);
--      cimg_save_pandore_case(0,1,1,"short",6);
--      cimg_save_pandore_case(0,1,1,"unsigned short",6);
--      cimg_save_pandore_case(0,1,1,"unsigned int",6);
--      cimg_save_pandore_case(0,1,1,"int",6);
--      cimg_save_pandore_case(0,1,1,"unsigned long",7);
--      cimg_save_pandore_case(0,1,1,"long",6);
--      cimg_save_pandore_case(0,1,1,"float",7);
--      cimg_save_pandore_case(0,1,1,"double",7);
--
--      cimg_save_pandore_case(0,0,1,"unsigned char",8);
--      cimg_save_pandore_case(0,0,1,"char",9);
--      cimg_save_pandore_case(0,0,1,"short",9);
--      cimg_save_pandore_case(0,0,1,"unsigned short",9);
--      cimg_save_pandore_case(0,0,1,"unsigned int",9);
--      cimg_save_pandore_case(0,0,1,"int",9);
--      cimg_save_pandore_case(0,0,1,"unsigned long",10);
--      cimg_save_pandore_case(0,0,1,"long",9);
--      cimg_save_pandore_case(0,0,1,"float",10);
--      cimg_save_pandore_case(0,0,1,"double",10);
--
--      cimg_save_pandore_case(0,1,3,"unsigned char",16);
--      cimg_save_pandore_case(0,1,3,"char",17);
--      cimg_save_pandore_case(0,1,3,"short",17);
--      cimg_save_pandore_case(0,1,3,"unsigned short",17);
--      cimg_save_pandore_case(0,1,3,"unsigned int",17);
--      cimg_save_pandore_case(0,1,3,"int",17);
--      cimg_save_pandore_case(0,1,3,"unsigned long",18);
--      cimg_save_pandore_case(0,1,3,"long",17);
--      cimg_save_pandore_case(0,1,3,"float",18);
--      cimg_save_pandore_case(0,1,3,"double",18);
--
--      cimg_save_pandore_case(0,0,3,"unsigned char",19);
--      cimg_save_pandore_case(0,0,3,"char",20);
--      cimg_save_pandore_case(0,0,3,"short",20);
--      cimg_save_pandore_case(0,0,3,"unsigned short",20);
--      cimg_save_pandore_case(0,0,3,"unsigned int",20);
--      cimg_save_pandore_case(0,0,3,"int",20);
--      cimg_save_pandore_case(0,0,3,"unsigned long",21);
--      cimg_save_pandore_case(0,0,3,"long",20);
--      cimg_save_pandore_case(0,0,3,"float",21);
--      cimg_save_pandore_case(0,0,3,"double",21);
--
--      cimg_save_pandore_case(1,1,0,"unsigned char",22);
--      cimg_save_pandore_case(1,1,0,"char",23);
--      cimg_save_pandore_case(1,1,0,"short",23);
--      cimg_save_pandore_case(1,1,0,"unsigned short",23);
--      cimg_save_pandore_case(1,1,0,"unsigned int",23);
--      cimg_save_pandore_case(1,1,0,"int",23);
--      cimg_save_pandore_case(1,1,0,"unsigned long",25);
--      cimg_save_pandore_case(1,1,0,"long",23);
--      cimg_save_pandore_case(1,1,0,"float",25);
--      cimg_save_pandore_case(1,1,0,"double",25);
--
--      cimg_save_pandore_case(0,1,0,"unsigned char",26);
--      cimg_save_pandore_case(0,1,0,"char",27);
--      cimg_save_pandore_case(0,1,0,"short",27);
--      cimg_save_pandore_case(0,1,0,"unsigned short",27);
--      cimg_save_pandore_case(0,1,0,"unsigned int",27);
--      cimg_save_pandore_case(0,1,0,"int",27);
--      cimg_save_pandore_case(0,1,0,"unsigned long",29);
--      cimg_save_pandore_case(0,1,0,"long",27);
--      cimg_save_pandore_case(0,1,0,"float",29);
--      cimg_save_pandore_case(0,1,0,"double",29);
--
--      cimg_save_pandore_case(0,0,0,"unsigned char",30);
--      cimg_save_pandore_case(0,0,0,"char",31);
--      cimg_save_pandore_case(0,0,0,"short",31);
--      cimg_save_pandore_case(0,0,0,"unsigned short",31);
--      cimg_save_pandore_case(0,0,0,"unsigned int",31);
--      cimg_save_pandore_case(0,0,0,"int",31);
--      cimg_save_pandore_case(0,0,0,"unsigned long",33);
--      cimg_save_pandore_case(0,0,0,"long",31);
--      cimg_save_pandore_case(0,0,0,"float",33);
--      cimg_save_pandore_case(0,0,0,"double",33);
--
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as a PANDORE-5 file.
--    const CImg& save_pandore(const char *const filename=0, const unsigned int colorspace=0) const {
--      return save_pandore(0,filename,colorspace);
--    }
--
--    //! Save the image as a YUV video sequence file
--    const CImg& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
--      CImgList<T>(*this).save_yuv(file,filename,rgb2yuv);
--      return *this;
--    }
--
--    //! Save the image as a YUV video sequence file
--    const CImg& save_yuv(const char *const filename, const bool rgb2yuv=true) const {
--      return save_yuv(0,filename,rgb2yuv);
--    }
--
--    //! Save the image as a BMP file
--    const CImg& save_bmp(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      cimg::warn(depth>1,
--                 "CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      cimg::warn(dim>3,
--                 "CImg<%s>::save_bmp() : Instance image (%u,%u,%u,%u,%p) is multispectral. Only the three first channels will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      unsigned char header[54]={0}, align_buf[4]={0};
--      const unsigned int
--        align     = (4-(3*width)%4)%4,
--        buf_size  = (3*width+align)*dimy(),
--        file_size = 54+buf_size;
--      header[0] = 'B'; header[1] = 'M';
--      header[0x02]=file_size&0xFF; header[0x03]=(file_size>>8)&0xFF;
--      header[0x04]=(file_size>>16)&0xFF; header[0x05]=(file_size>>24)&0xFF;
--      header[0x0A]=0x36;
--      header[0x0E]=0x28;
--      header[0x12]=width&0xFF; header[0x13]=(width>>8)&0xFF;
--      header[0x14]=(width>>16)&0xFF; header[0x15]=(width>>24)&0xFF;
--      header[0x16]=height&0xFF; header[0x17]=(height>>8)&0xFF;
--      header[0x18]=(height>>16)&0xFF; header[0x19]=(height>>24)&0xFF;
--      header[0x1A]=1;  header[0x1B]=0;
--      header[0x1C]=24; header[0x1D]=0;
--      header[0x22]=buf_size&0xFF; header[0x23]=(buf_size>>8)&0xFF;
--      header[0x24]=(buf_size>>16)&0xFF; header[0x25]=(buf_size>>24)&0xFF;
--      header[0x27]=0x1; header[0x2B]=0x1;
--      cimg::fwrite(header,54,nfile);
--
--      const T
--        *pR = ptr(0,height-1,0,0),
--        *pG = (dim>=2)?ptr(0,height-1,0,1):pR,
--        *pB = (dim>=3)?ptr(0,height-1,0,2):pR;
--
--      cimg_forY(*this,y) {
--        cimg_forX(*this,x) {
--          std::fputc((unsigned char)(*(pB++)),nfile);
--          std::fputc((unsigned char)(*(pG++)),nfile);
--          std::fputc((unsigned char)(*(pR++)),nfile);
--        }
--        cimg::fwrite(align_buf,align,nfile);
--        pR-=2*width; pG-=2*width; pB-=2*width;
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save the image as a BMP file
--    const CImg& save_bmp(const char *const filename) const {
--      return save_bmp(0,filename);
--    }
--
--    //! Save an image to a PNG file.
--    // Most of this function has been written by Eric Fausett
--    /**
--       \param filename = name of the png image file to save
--       \return *this
--       \note The png format specifies a variety of possible data formats.  Grey scale, Grey
--       scale with Alpha, RGB color, RGB color with Alpha, and Palletized color are supported.
--       Per channel bit depths of 1, 2, 4, 8, and 16 are natively supported. The
--       type of file saved depends on the number of channels in the CImg file.  If there is 4 or more
--       channels, the image will be saved as an RGB color with Alpha image using the bottom 4 channels.
--       If there are 3 channels, the saved image will be an RGB color image.  If 2 channels then the
--       image saved will be Grey scale with Alpha, and if 1 channel will be saved as a Grey scale
--       image.
--    **/
--    const CImg& save_png(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--      cimg::warn(depth>1,
--                 "CImg<%s>::save_png() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--#ifndef cimg_use_png
--      if (!file) return save_other(filename);
--      else throw CImgIOException("CImg<%s>::save_png() : Cannot save a PNG image in a *FILE output. Use libpng instead.",
--                                 pixel_type());
--#else
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--
--      // Setup PNG structures for write
--      png_voidp user_error_ptr=0;
--      png_error_ptr user_error_fn=0, user_warning_fn=0;
--      png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
--                                                    user_error_ptr, user_error_fn, user_warning_fn);
--      if(!png_ptr){
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'png_ptr' data structure.",
--                              pixel_type(),filename?filename:"(unknown)");
--      }
--      png_infop info_ptr = png_create_info_struct(png_ptr);
--      if(!info_ptr){
--        png_destroy_write_struct(&png_ptr,(png_infopp)0);
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::save_png() : File '%s', error when initializing 'info_ptr' data structure.",
--                              pixel_type(),filename?filename:"(unknown)");
--      }
--      if (setjmp(png_jmpbuf(png_ptr))){
--        png_destroy_write_struct(&png_ptr, &info_ptr);
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
--                              pixel_type(),filename?filename:"(unknown)");
--      }
--
--      png_init_io(png_ptr, nfile);
--      png_uint_32 width = dimx();
--      png_uint_32 height = dimy();
--      const CImgStats stats(*this,false);
--      const float vmin = (float)stats.min, vmax = (float)stats.max;
--      const int bit_depth = (vmin<0 || vmax>=256)?16:8;
--      int color_type;
--      switch (dimv()) {
--      case 1: color_type = PNG_COLOR_TYPE_GRAY; break;
--      case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
--      case 3: color_type = PNG_COLOR_TYPE_RGB; break;
--      default: color_type = PNG_COLOR_TYPE_RGB_ALPHA;
--      }
--      const int interlace_type = PNG_INTERLACE_NONE;
--      const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
--      const int filter_method = PNG_FILTER_TYPE_DEFAULT;
--      png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type,
--                   compression_type, filter_method);
--      png_write_info(png_ptr, info_ptr);
--      const int byte_depth = bit_depth>>3;
--      const int numChan = dimv()>4?4:dimv();
--      const int pixel_bit_depth_flag = numChan * (bit_depth-1);
--
--      // Allocate Memory for Image Save and Fill pixel data
--      png_bytep *imgData = new png_byte*[height];
--      for(unsigned int row=0; row<height; row++) imgData[row] = new png_byte[byte_depth * numChan * width];
--      const T *pC0 = ptr(0,0,0,0);
--      switch(pixel_bit_depth_flag) {
--      case 7 :  { // Gray 8-bit
--        cimg_forY(*this,y) {
--          unsigned char *ptrs = imgData[y];
--          cimg_forX(*this,x) *(ptrs++) = (unsigned char)*(pC0++);
--        }
--      } break;
--      case 14: { // Gray w/ Alpha 8-bit
--        const T *pC1 = ptr(0,0,0,1);
--        cimg_forY(*this,y) {
--          unsigned char *ptrs = imgData[y];
--          cimg_forX(*this,x) {
--            *(ptrs++) = (unsigned char)*(pC0++);
--            *(ptrs++) = (unsigned char)*(pC1++);
--          }
--        }
--      } break;
--      case 21:  { // RGB 8-bit
--        const T *pC1 = ptr(0,0,0,1);
--        const T *pC2 = ptr(0,0,0,2);
--        cimg_forY(*this,y) {
--          unsigned char *ptrs = imgData[y];
--          cimg_forX(*this,x) {
--            *(ptrs++) = (unsigned char)*(pC0++);
--            *(ptrs++) = (unsigned char)*(pC1++);
--            *(ptrs++) = (unsigned char)*(pC2++);
--          }
--        }
--      } break;
--      case 28: { // RGB x/ Alpha 8-bit
--        const T *pC1 = ptr(0,0,0,1);
--        const T *pC2 = ptr(0,0,0,2);
--        const T *pC3 = ptr(0,0,0,3);
--        cimg_forY(*this,y){
--          unsigned char *ptrs = imgData[y];
--          cimg_forX(*this,x){
--            *(ptrs++) = (unsigned char)*(pC0++);
--            *(ptrs++) = (unsigned char)*(pC1++);
--            *(ptrs++) = (unsigned char)*(pC2++);
--            *(ptrs++) = (unsigned char)*(pC3++);
--          }
--        }
--      } break;
--      case 15: { // Gray 16-bit
--        cimg_forY(*this,y){
--          unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
--          cimg_forX(*this,x) *(ptrs++) = (unsigned short)*(pC0++);
--        }
--      } break;
--      case 30: { // Gray w/ Alpha 16-bit
--        const T *pC1 = ptr(0,0,0,1);
--        cimg_forY(*this,y){
--          unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
--          cimg_forX(*this,x) {
--            *(ptrs++) = (unsigned short)*(pC0++);
--            *(ptrs++) = (unsigned short)*(pC1++);
--          }
--        }
--      } break;
--      case 45: { // RGB 16-bit
--        const T *pC1 = ptr(0,0,0,1);
--        const T *pC2 = ptr(0,0,0,2);
--        cimg_forY(*this,y) {
--          unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
--          cimg_forX(*this,x) {
--            *(ptrs++) = (unsigned short)*(pC0++);
--            *(ptrs++) = (unsigned short)*(pC1++);
--            *(ptrs++) = (unsigned short)*(pC2++);
--          }
--        }
--      } break;
--      case 60: { // RGB w/ Alpha 16-bit
--        const T *pC1 = ptr(0,0,0,1);
--        const T *pC2 = ptr(0,0,0,2);
--        const T *pC3 = ptr(0,0,0,3);
--        cimg_forY(*this,y) {
--          unsigned short *ptrs = reinterpret_cast<unsigned short*>(imgData[y]);
--          cimg_forX(*this,x) {
--            *(ptrs++) = (unsigned short)*(pC0++);
--            *(ptrs++) = (unsigned short)*(pC1++);
--            *(ptrs++) = (unsigned short)*(pC2++);
--            *(ptrs++) = (unsigned short)*(pC3++);
--          }
--        }
--      } break;
--      default:
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImg<%s>::save_png() : File '%s', unknown fatal error.",
--                              pixel_type(),filename?filename:"(unknown)");
--        break;
--      }
--      png_write_image(png_ptr, imgData);
--      png_write_end(png_ptr, info_ptr);
--      png_destroy_write_struct(&png_ptr, &info_ptr);
--
--      // Deallocate Image Write Memory
--      for (unsigned int n=0; n<height; n++) delete[] imgData[n];
--      delete[] imgData;
--      if (!file) cimg::fclose(nfile);
--      return *this;
--#endif
--    }
--
--    //! Save a file in PNG format
--    const CImg& save_png(const char *const filename) const {
--      return save_png(0,filename);
--    }
--
--    //! Save a file in TIFF format.
--    const CImg& save_tiff(const char *const filename) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_tiff() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--#ifdef cimg_use_tiff
--      uint32 rowsperstrip = (uint32) -1;
--      uint16 spp = dimv(), bpp = sizeof(T)*8;
--      uint16 photometric;
--      if (spp==3 || spp==4)
--      photometric = PHOTOMETRIC_RGB;
--        else
--          photometric =   PHOTOMETRIC_MINISBLACK;
--      uint16 compression = COMPRESSION_NONE;
--      TIFF *out;
--      out = TIFFOpen(filename,"w");
--      if (out) {
--        for (unsigned int dir=0; dir<depth; dir++) {
--          TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32)dimx());
--          TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32)dimy());
--          TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
--          TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
--          TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
--          TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
--          TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
--          TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
--          rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
--          TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
--        TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
--        TIFFSetField(out, TIFFTAG_SOFTWARE, "CImg");
--        T *buf =  (T *)_TIFFmalloc(TIFFStripSize(out));
--        if (buf){
--          for (unsigned int row = 0; row < height; row+=rowsperstrip) {
--            uint32 nrow = (row+rowsperstrip>height?height-row:rowsperstrip);
--            tstrip_t strip = TIFFComputeStrip(out, row, 0);
--            tsize_t i = 0;
--            for (unsigned int rr=0; rr<nrow; rr++)
--              for (unsigned int cc=0;cc<width;cc++)
--                for (unsigned int vv=0;vv<spp;vv++)
--                  buf[i++] = (*this)(cc,row+rr,dir,vv);
--            if(TIFFWriteEncodedStrip(out, strip, buf, i*sizeof(T))<0){
--              throw CImgException("CImg<%s>::get_save_tiff() : File '%s', an error occure while writing a strip.",
--                                  pixel_type(),filename?filename:"(FILE*)");
--            }
--          }
--          _TIFFfree(buf);
--        }
--          TIFFWriteDirectory(out);
--        }
--        TIFFClose(out);
--      }
--      else throw CImgException("CImg<%s>::save_tiff() : File '%s', error while writing tiff file.",
--                               pixel_type(),filename);
--#else
--      return save_other(filename);
--#endif
--      return *this;
--    }
--
--    //! Save a file in JPEG format.
--    const CImg<T>& save_jpeg(std::FILE *const file, const char *const filename=0, const unsigned int quality=100) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p), specified filename is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      cimg::warn(depth>1,
--                 "CImg<%s>::save_jpeg() : Instance image (%u,%u,%u,%u,%p) is volumetric. Only the first slice will be saved (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--#ifndef cimg_use_jpeg
--      if (!file) return save_other(filename,quality);
--      else throw CImgIOException("CImg<%s>::save_jpeg() : Cannot save a JPEG image in a *FILE output. Use libjpeg instead.",
--                                 pixel_type());
--#else
--
--      // Fill pixel buffer
--      unsigned char *buf;
--      unsigned int dimbuf=0;
--      J_COLOR_SPACE colortype=JCS_RGB;
--      switch (dim) {
--      case 1: { // Greyscale images
--        unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=1)];
--        colortype = JCS_GRAYSCALE;
--        const T *ptr_g = ptr();
--        cimg_forXY(*this,x,y) *(buf2++) = (unsigned char)*(ptr_g++);
--      } break;
--      case 2:
--      case 3: { // RGB images
--        unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=3)];
--        const T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,dim>2?2:0);
--        colortype = JCS_RGB;
--        cimg_forXY(*this,x,y) {
--          *(buf2++) = (unsigned char)*(ptr_r++);
--          *(buf2++) = (unsigned char)*(ptr_g++);
--          *(buf2++) = (unsigned char)*(ptr_b++);
--        }
--      } break;
--      default: { // YCMYK images
--        unsigned char *buf2 = buf = new unsigned char[width*height*(dimbuf=4)];
--        const T *ptr_r = ptr(0,0,0,0), *ptr_g = ptr(0,0,0,1), *ptr_b = ptr(0,0,0,2), *ptr_a = ptr(0,0,0,3);
--        colortype = JCS_CMYK;
--        cimg_forXY(*this,x,y) {
--          *(buf2++) = (unsigned char)*(ptr_r++);
--          *(buf2++) = (unsigned char)*(ptr_g++);
--          *(buf2++) = (unsigned char)*(ptr_b++);
--          *(buf2++) = (unsigned char)*(ptr_a++);
--        }
--      } break;
--      }
--
--      // Call libjpeg functions
--      struct jpeg_compress_struct cinfo;
--      struct jpeg_error_mgr jerr;
--      cinfo.err = jpeg_std_error(&jerr);
--      jpeg_create_compress(&cinfo);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      jpeg_stdio_dest(&cinfo,nfile);
--      cinfo.image_width = width;
--      cinfo.image_height = height;
--      cinfo.input_components = dimbuf;
--      cinfo.in_color_space = colortype;
--      jpeg_set_defaults(&cinfo);
--      jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE);
--      jpeg_start_compress(&cinfo,TRUE);
--
--      const unsigned int row_stride = width*dimbuf;
--      JSAMPROW row_pointer[1];
--      while (cinfo.next_scanline < cinfo.image_height) {
--        row_pointer[0] = &buf[cinfo.next_scanline*row_stride];
--        jpeg_write_scanlines(&cinfo,row_pointer,1);
--      }
--      jpeg_finish_compress(&cinfo);
--
--      delete[] buf;
--      if (!file) cimg::fclose(nfile);
--      jpeg_destroy_compress(&cinfo);
--      return *this;
--#endif
--    }
--
--    //! Save a file in JPEG format.
--    const CImg<T>& save_jpeg(const char *const filename, const unsigned int quality=100) const {
--      return save_jpeg(0,filename,quality);
--    }
--
--    //! Save the image using built-in ImageMagick++ library
--    const CImg& save_magick(const char *const filename) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save_magick() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                 pixel_type(),width,height,depth,dim,data);
--#ifdef cimg_use_magick
--      Magick::Image image(Magick::Geometry(width,height),"black");
--      image.type(Magick::TrueColorType);
--      const T *rdata = ptr(0,0,0,0), *gdata = dim>1?ptr(0,0,0,1):rdata, *bdata = dim>2?ptr(0,0,0,2):gdata;
--      cimg_forXY(*this,x,y) image.pixelColor(x,y,Magick::ColorRGB(*(rdata++)/255.0,*(gdata++)/255.0,*(bdata++)/255.0));
--      image.syncPixels();
--      image.write(filename);
--#else
--      throw CImgIOException("CImg<%s>::save_magick() : File '%s', Magick++ library has not been linked.",
--                            pixel_type(),filename);
--#endif
--      return *this;
--    }
--
--    //! Save the image as a RGBA file
--    const CImg& save_rgba(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      cimg::warn(dim!=4,
--                 "CImg<%s>::save_rgba() : Instance image (%u,%u,%u,%u,%p) has not exactly 4 channels (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      const unsigned int wh = width*height;
--      unsigned char *buffer = new unsigned char[4*wh], *nbuffer=buffer;
--      const T
--        *ptr1 = ptr(0,0,0,0),
--        *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
--        *ptr3 = dim>2?ptr(0,0,0,2):ptr1,
--        *ptr4 = dim>3?ptr(0,0,0,3):0;
--      for (unsigned int k=0; k<wh; k++) {
--        *(nbuffer++) = (unsigned char)(*(ptr1++));
--        *(nbuffer++) = (unsigned char)(*(ptr2++));
--        *(nbuffer++) = (unsigned char)(*(ptr3++));
--        *(nbuffer++) = (unsigned char)(ptr4?(*(ptr4++)):255);
--      }
--      cimg::fwrite(buffer,4*wh,nfile);
--      if (!file) cimg::fclose(nfile);
--      delete[] buffer;
--      return *this;
--    }
--
--    //! Save the image as a RGBA file
--    const CImg& save_rgba(const char *const filename) const {
--      return save_rgba(0,filename);
--    }
--
--    //! Save the image as a RGB file
--    const CImg& save_rgb(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p), specified file is (null).",
--                                                          pixel_type(),width,height,depth,dim,data);
--      cimg::warn(dim!=3,
--                 "CImg<%s>::save_rgb() : Instance image (%u,%u,%u,%u,%p) has not exactly 3 channels (file '%s').",
--                 pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      const unsigned int wh = width*height;
--      unsigned char *buffer = new unsigned char[3*wh], *nbuffer=buffer;
--      const T
--        *ptr1 = ptr(0,0,0,0),
--        *ptr2 = dim>1?ptr(0,0,0,1):ptr1,
--        *ptr3 = dim>2?ptr(0,0,0,2):ptr1;
--      for (unsigned int k=0; k<wh; k++) {
--        *(nbuffer++) = (unsigned char)(*(ptr1++));
--        *(nbuffer++) = (unsigned char)(*(ptr2++));
--        *(nbuffer++) = (unsigned char)(*(ptr3++));
--      }
--      cimg::fwrite(buffer,3*wh,nfile);
--      if (!file) cimg::fclose(nfile);
--      delete[] buffer;
--      return *this;
--    }
--
--    //! Save the image as a RGB file
--    const CImg& save_rgb(const char *const filename) const {
--      return save_rgb(0,filename);
--    }
--
--    //! Get a 40x38 color logo of a 'danger' item
--    static CImg get_logo40x38() {
--      static bool first_time = true;
--      static CImg<T> res(40,38,1,3);
--      if (first_time) {
--        const unsigned char *ptrs = cimg::logo40x38;
--        T *ptr1 = res.ptr(0,0,0,0), *ptr2 = res.ptr(0,0,0,1), *ptr3 = res.ptr(0,0,0,2);
--        for (unsigned int off = 0; off<res.width*res.height;) {
--          const unsigned char n = *(ptrs++), r = *(ptrs++), g = *(ptrs++), b = *(ptrs++);
--          for (unsigned int l=0; l<n; off++,l++) { *(ptr1++) = (T)r; *(ptr2++) = (T)g; *(ptr3++) = (T)b; }
--        }
--        first_time = false;
--      }
--      return res;
--    }
--
--    //! Save OFF files (GeomView 3D object files)
--    template<typename tf, typename tc>
--    const CImg& save_off(std::FILE *const file, const char *const filename,
--                         const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
--      if (is_empty()) throw CImgInstanceException("CImg<%s>::save_off() : Instance image (%u,%u,%u,%u,%p) is empty (file '%s').",
--                                                  pixel_type(),width,height,depth,dim,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_off() : Specified filename is (null).",pixel_type());
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
--      std::fprintf(nfile,"OFF\n%u %u %u\n",width,primitives.size,3*primitives.size);
--      cimg_forX(*this,i) std::fprintf(nfile,"%f %f %f\n",(float)((*this)(i,0)),(float)((*this)(i,1)),(float)((*this)(i,2)));
--      cimglist_for(primitives,l) {
--        const unsigned int prim = primitives[l].size();
--        switch (prim) {
--        case 3: {
--          if (invert_faces)
--            std::fprintf(nfile,"3 %u %u %u %f %f %f\n",
--                         (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),
--                         (float)(colors(l,0)/255.0f),(float)(colors(l,1)/255.0f),(float)(colors(l,2)/255.0f));
--          else
--            std::fprintf(nfile,"3 %u %u %u %f %f %f\n",
--                         (unsigned int)primitives(l,0),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),
--                         (float)(colors(l,0)/255.0f),(float)(colors(l,1)/255.0f),(float)(colors(l,2)/255.0f));
--        } break;
--        case 4: {
--          if (invert_faces)
--            std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
--                         (unsigned int)primitives(l,0),(unsigned int)primitives(l,1),(unsigned int)primitives(l,2),(unsigned int)primitives(l,3),
--                         (float)(colors(l,0)/255.0f),(float)(colors(l,1)/255.0f),(float)(colors(l,2)/255.0f));
--          else
--            std::fprintf(nfile,"4 %u %u %u %u %f %f %f\n",
--                         (unsigned int)primitives(l,0),(unsigned int)primitives(l,3),(unsigned int)primitives(l,2),(unsigned int)primitives(l,1),
--                         (float)(colors(l,0)/255.0f),(float)(colors(l,1)/255.0f),(float)(colors(l,2)/255.0f));
--        } break;
--        }
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save OFF files (GeomView 3D object files)
--    template<typename tf, typename tc>
--    const CImg& save_off(const char *const filename,
--                         const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
--      return save_off(filename,primitives,colors,invert_faces);
--    }
--
--  };
--
--
--  /*
--   #-----------------------------------------
--   #
--   #
--   #
--   # Definition of the CImgList<> structure
--   #
--   #
--   #
--   #------------------------------------------
--   */
--
--  //! Class representing list of images CImg<T>.
--  template<typename T> struct CImgList {
--
--    //! Size of the list (number of elements inside)
--    unsigned int size;
--
--    //! Allocation size of the list
--    unsigned int allocsize;
--
--    //! Pointer to the first list element
--    CImg<T> *data;
--
--    //! Define a CImgList<T>::iterator
--    typedef CImg<T>* iterator;
--
--    //! Define a CImgList<T>::const_iterator
--    typedef const CImg<T>* const_iterator;
--
--    //! Get value type
--    typedef T value_type;
--
--    //@}
--    //---------------------------
--    //
--    //! \name Plugins
--    //@{
--    //---------------------------
--#ifdef cimglist_plugin
--#include cimglist_plugin
--#endif
--    //@}
--
--    //------------------------------------------
--    //
--    //! \name Constructors - Destructor - Copy
--    //@{
--    //------------------------------------------
--
--    //! Default constructor
--    CImgList():
--      size(0),allocsize(0),data(0) {}
--
--    //! Destructor
--    ~CImgList() {
--      if (data) delete[] data;
--    }
--
--    //! In-place version of the default constructor and default destructor
--    CImgList& assign() {
--      if (data) delete[] data;
--      size = allocsize = 0;
--      data = 0;
--      return *this;
--    }
--
--    //! Equivalent to assign() (STL-compliant name)
--    CImgList& clear() {
--      return assign();
--    }
--
--    //! Copy constructor
--    template<typename t> CImgList(const CImgList<t>& list):
--      size(0),allocsize(0),data(0) {
--      assign(list);
--    }
--
--    CImgList(const CImgList& list):
--      size(0),allocsize(0),data(0) {
--      assign(list);
--    }
--
--    //! Copy constructor that create a shared object
--    template<typename t> CImgList(const CImgList<t>& list, const bool shared):
--      size(0),allocsize(0),data(0) {
--      assign(list,shared);
--    }
--
--    CImgList(const CImgList& list, const bool shared):
--      size(0),allocsize(0),data(0) {
--      assign(list,shared);
--    }
--
--    //! In-place version of the copy constructor
--    template<typename t> CImgList& assign(const CImgList<t>& list, const bool shared=false) {
--      assign(list.size);
--      cimglist_for(*this,l) (*this)[l].assign(list[l],shared);
--      return *this;
--    }
--
--    //! Construct an image list containing n empty images
--    explicit CImgList(const unsigned int n):
--      size(n) {
--      data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
--    }
--
--    //! In-place version of the previous constructor
--    CImgList& assign(const unsigned int n) {
--      if (n) {
--        if (allocsize<n || allocsize>(n<<2)) {
--          if (data) delete[] data;
--          data = new CImg<T>[allocsize=cimg::nearest_pow2(n)];
--        }
--        size = n;
--      } else return assign();
--      return *this;
--    }
--
--    //! Construct an image list containing n images with specified size
--    CImgList(const unsigned int n, const unsigned int width, const unsigned int height=1,
--          const unsigned int depth=1, const unsigned int dim=1):
--      size(0),allocsize(0),data(0) {
--      assign(n,width,height,depth,dim);
--    }
--
--    //! In-place version of the previous constructor
--    CImgList& assign(const unsigned int n, const unsigned int width, const unsigned int height=1,
--                  const unsigned int depth=1, const unsigned int dim=1) {
--      const unsigned int siz = width*height*depth*dim;
--      if (n && siz) { assign(n); cimglist_for(*this,l) data[l].assign(width,height,depth,dim); }
--      else return assign();
--      return *this;
--    }
--
--    //! Construct an image list containing n images with specified size, filled with val
--    CImgList(const unsigned int n, const unsigned int width, const unsigned int height,
--          const unsigned int depth, const unsigned int dim, const T& val):
--      size(0),allocsize(0),data(0) {
--      assign(n,width,height,depth,dim,val);
--    }
--
--    //! In-place version of the previous constructor
--    CImgList& assign(const unsigned int n,const unsigned int width,const unsigned int height,
--                  const unsigned int depth, const unsigned int dim,const T& val) {
--      assign(n,width,height,depth,dim);
--      cimglist_for(*this,l) data[l].fill(val);
--      return *this;
--    }
--
--    //! Construct a list containing n copies of the image img
--    template<typename t> CImgList(const unsigned int n, const CImg<t>& img, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(n,img,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t> CImgList& assign(const unsigned int n, const CImg<t>& img, const bool shared=false) {
--      assign(n);
--      cimglist_for(*this,l) data[l].assign(img,shared);
--      return *this;
--    }
--
--    //! Construct an image list from one image
--    template<typename t> explicit CImgList(const CImg<t>& img, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t> CImgList& assign(const CImg<t>& img, const bool shared=false) {
--      return assign(1,img,shared);
--    }
--
--    //! Construct an image list from two images
--    template<typename t1, typename t2> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2> CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const bool shared=false) {
--      assign(2);
--      data[0].assign(img1,shared); data[1].assign(img2,shared);
--      return *this;
--    }
--
--    //! Construct an image list from three images
--    template<typename t1, typename t2, typename t3> CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3> CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const bool shared=false) {
--      assign(3);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared);
--      return *this;
--    }
--
--    //! Construct an image list from four images
--    template<typename t1, typename t2, typename t3, typename t4>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const bool shared=false) {
--      assign(4);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      return *this;
--    }
--
--    //! Construct an image list from five images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const bool shared=false) {
--      assign(5);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared);
--      return *this;
--    }
--
--    //! Construct an image list from six images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--             const CImg<t6>& img6, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,img6,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const CImg<t6>& img6, const bool shared=false) {
--      assign(6);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared); data[5].assign(img6,shared);
--      return *this;
--    }
--
--    //! Construct an image list from seven images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--             const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,img6,img7,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const CImg<t6>& img6, const CImg<t7>& img7, const bool shared=false) {
--      assign(7);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared);
--      return *this;
--    }
--
--    //! Construct an image list from eight images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--             const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,img6,img7,img8,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const bool shared=false) {
--      assign(8);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared);
--      return *this;
--    }
--
--    //! Construct an image list from nine images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8, typename t9>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--             const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const CImg<t9>& img9, const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,img6,img7,img8,img9,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8, typename t9>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const CImg<t9>& img9, const bool shared=false) {
--      assign(9);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared);
--      data[8].assign(img9,shared);
--      return *this;
--    }
--
--    //! Construct an image list from ten images
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8, typename t9, typename t10>
--    CImgList(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--             const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const CImg<t9>& img9, const CImg<t10>& img10,
--          const bool shared=false):
--      size(0),allocsize(0),data(0) {
--      assign(img1,img2,img3,img4,img5,img6,img7,img8,img9,img10,shared);
--    }
--
--    //! In-place version of the previous constructor
--    template<typename t1, typename t2, typename t3, typename t4, typename t5, typename t6, typename t7, typename t8, typename t9, typename t10>
--    CImgList& assign(const CImg<t1>& img1, const CImg<t2>& img2, const CImg<t3>& img3, const CImg<t4>& img4, const CImg<t5>& img5,
--                     const CImg<t6>& img6, const CImg<t7>& img7, const CImg<t8>& img8, const CImg<t9>& img9, const CImg<t10>& img10,
--                     const bool shared=false) {
--      assign(10);
--      data[0].assign(img1,shared); data[1].assign(img2,shared); data[2].assign(img3,shared); data[3].assign(img4,shared);
--      data[4].assign(img5,shared); data[5].assign(img6,shared); data[6].assign(img7,shared); data[7].assign(img8,shared);
--      data[8].assign(img9,shared); data[9].assign(img10,shared);
--      return *this;
--    }
--
--    //! Construct an image list from a filename
--    CImgList(const char *const filename):
--      size(0),allocsize(0),data(0) {
--      assign(filename);
--    }
--
--    //! In-place version of the previous constructor
--    CImgList& assign(const char *const filename) {
--      return load(filename);
--    }
--
--    //! Return a string describing the type of the image pixels in the list (template parameter \p T).
--    static const char* pixel_type() {
--      return cimg::type<T>::id();
--    }
--
--    //! Return \p true if list is empty
--    bool is_empty() const {
--      return (!data || !size);
--    }
--
--    //! Return \c true if the list contains an image with indice k
--    bool contains(const int k) const {
--      return data && k<size;
--    }
--
--    //! Return \c true if the k-th image of the list contains the pixel (x,y,z,v)
--    bool contains(const int k, const int x, const int y=0, const int z=0, const int v=0) const {
--      return contains(k) && data[k].contains(x,y,z,v);
--    }
--
--
--
--    //@}
--    //------------------------------
--    //
--    //! \name Arithmetics Operators
--    //@{
--    //------------------------------
--
--    //! Assignement operator
--    template<typename t> CImgList& operator=(const CImgList<t>& list) {
--      return assign(list);
--    }
--
--    CImgList& operator=(const CImgList& list) {
--      return assign(list);
--    }
--
--    //! Assignement operator.
--    template<typename t> CImgList& operator=(const CImg<t>& img) {
--      cimglist_for(*this,l) data[l]=img;
--      return *this;
--    }
--
--    //! Assignement operator.
--    CImgList& operator=(const T& val) {
--      cimglist_for(*this,l) data[l].fill(val);
--      return *this;
--    }
--
--    //! Operator+
--    CImgList operator+() const {
--      return CImgList<T>(*this);
--    }
--
--    //! Operator+=
--#ifdef cimg_use_visualcpp6
--    CImgList& operator+=(const T& val) {
--#else
--        template<typename t> CImgList& operator+=(const t& val) {
--#endif
--      cimglist_for(*this,l) (*this)[l]+=val;
--      return *this;
--    }
--
--    //! Operator+=
--    template<typename t> CImgList& operator+=(const CImgList<t>& list) {
--      const unsigned int sizemax = min(size,list.size);
--      for (unsigned int l=0; l<sizemax; l++) (*this)[l]+=list[l];
--      return *this;
--    }
--
--    //! Operator++
--    CImgList& operator++() {
--      cimglist_for(*this,l) (*this)[l]++;
--      return *this;
--    }
--
--    //! Operator-
--    CImgList operator-() const {
--      CImgList<T> res(size);
--      cimglist_for(res,l) res[l].assign(-data[l]);
--      return res;
--    }
--
--    //! Operator-=.
--#ifdef cimg_use_visualcpp6
--    CImgList& operator-=(const T& val) {
--#else
--        template<typename t> CImgList& operator-=(const t& val) {
--#endif
--      cimglist_for(*this,l) (*this)[l]-=val;
--      return *this;
--    }
--
--    //! Operator-=.
--    template<typename t> CImgList& operator-=(const CImgList<t>& list) {
--      const unsigned int sizemax = min(size,list.size);
--      for (unsigned int l=0; l<sizemax; l++) (*this)[l]-=list[l];
--      return *this;
--    }
--
--    //! Operator--
--    CImgList& operator--() {
--      cimglist_for(*this,l) (*this)[l]--;
--      return *this;
--    }
--
--    //! Operator*=.
--#ifdef cimg_use_visualcpp6
--    CImgList& operator*=(const double val) {
--#else
--        template<typename t> CImgList& operator*=(const t& val) {
--#endif
--      cimglist_for(*this,l) (*this)[l]*=val;
--      return *this;
--    }
--
--    //! Operator*=.
--    template<typename t> CImgList& operator*=(const CImgList<t>& list) {
--      const unsigned int N = cimg::min(size,list.size);
--      for (unsigned int l=0; l<N; l++) (*this)[l]*=list[l];
--      return this;
--    }
--
--    //! Operator/=.
--#ifdef cimg_use_visualcpp6
--    CImgList& operator/=(const double val) {
--#else
--        template<typename t> CImgList& operator/=(const t& val) {
--#endif
--      cimglist_for(*this,l) (*this)[l]/=val;
--      return *this;
--    }
--
--    //! Operator/=.
--    template<typename t> CImgList& operator/=(const CImgList<t>& list) {
--      const unsigned int N = cimg::min(size,list.size);
--      for (unsigned int l=0; l<N; l++) (*this)[l]/=list[l];
--      return this;
--    }
--
--    //@}
--    //-------------------------
--    //
--    //! \name List Manipulation
--    //@{
--    //-------------------------
--
--    //! Return a reference to the i-th element of the image list.
--    CImg<T>& operator[](const unsigned int pos) {
--#if cimg_debug>=3
--      if (pos>=size) {
--        cimg::warn(true,"CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
--        return *data;
--      }
--#endif
--      return data[pos];
--    }
--
--    const CImg<T>& operator[](const unsigned int pos) const {
--#if cimg_debug>=3
--      if (pos>=size) {
--        cimg::warn(true,"CImgList<%s>::operator[] : bad list position %u, in a list of %u images",pixel_type(),pos,size);
--        return *data;
--      }
--#endif
--      return data[pos];
--    }
--
--    //! Equivalent to CImgList<T>::operator[]
--    CImg<T>& operator()(const unsigned int pos) { return (*this)[pos]; }
--    const CImg<T>& operator()(const unsigned int pos) const { return (*this)[pos]; }
--
--    //! Return a reference to (x,y,z,v) pixel of the pos-th image of the list
--    T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
--                  const unsigned int z=0, const unsigned int v=0) {
--      return (*this)[pos](x,y,z,v);
--    }
--    const T& operator()(const unsigned int pos, const unsigned int x, const unsigned int y=0,
--                        const unsigned int z=0, const unsigned int v=0) const {
--      return (*this)[pos](x,y,z,v);
--    }
--
--    //! Equivalent to CImgList<T>::operator[], with boundary checking
--    CImg<T>& at(const unsigned int pos) {
--      if (pos>=size)
--        throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
--                                    pixel_type(),pos,size);
--      return data[pos];
--    }
--
--    const CImg<T>& at(const unsigned int pos) const {
--      if (pos>=size)
--        throw CImgArgumentException("CImgList<%s>::at() : bad list position %u, in a list of %u images",
--                                    pixel_type(),pos,size);
--      return data[pos];
--    }
--
--    //! Returns a reference to last element
--    CImg<T>& back() {
--      return (*this)(size-1);
--    }
--
--    const CImg<T>& back() const {
--      return (*this)(size-1);
--    }
--
--    //! Returns a reference to the first element
--    CImg<T>& front() {
--      return *data;
--    }
--
--    const CImg<T>& front() const {
--      return *data;
--    }
--
--    //! Returns an iterator to the beginning of the vector.
--    iterator begin() {
--      return data;
--    }
--
--    const_iterator begin() const {
--      return data;
--    }
--
--    //! Returns an iterator just past the last element.
--    iterator end() {
--      return data + size;
--    }
--
--    const_iterator end() const {
--      return data + size;
--    }
--
--    //! Insert a copy of the image \p img into the current image list, at position \p pos.
--    template<typename t> CImgList& insert(const CImg<t>& img, const unsigned int pos, const bool shared) {
--      if (pos>size)
--        throw CImgArgumentException("CImgList<%s>::insert() : Cannot insert at position %u into a list with %u elements",
--                                    pixel_type(),pos,size);
--      if (shared)
--        throw CImgArgumentException("CImgList<%s>::insert(): Cannot insert a shared image CImg<%s> into a CImgList<%s>",
--                                    pixel_type(),img.pixel_type(),pixel_type());
--      CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
--      if (!size || !data) { data = new_data; *data = img; } else {
--        if (new_data) {
--          if (pos) std::memcpy(new_data,data,sizeof(CImg<T>)*pos);
--          if (pos!=size-1) std::memcpy(new_data+pos+1,data+pos,sizeof(CImg<T>)*(size-1-pos));
--          std::memset(data,0,sizeof(CImg<T>)*(size-1));
--          delete[] data;
--          data = new_data;
--        }
--        else if (pos!=size-1) memmove(data+pos+1,data+pos,sizeof(CImg<T>)*(size-1-pos));
--        data[pos].width = data[pos].height = data[pos].depth = data[pos].dim = 0; data[pos].data = 0;
--        data[pos] = img;
--      }
--      return *this;
--    }
--
--   CImgList& insert(const CImg<T>& img, const unsigned int pos, const bool shared) {
--      if (pos>size)
--        throw CImgArgumentException("CImgList<%s>::insert() : Can't insert at position %u into a list with %u elements",
--                                    pixel_type(),pos,size);
--      CImg<T> *new_data = (++size>allocsize)?new CImg<T>[allocsize?(allocsize<<=1):(allocsize=1)]:0;
--      if (!size || !data) {
--        data = new_data;
--        if (shared && !img.is_empty()) {
--          data->width = img.width; data->height = img.height; data->depth = img.depth; data->dim = img.dim;
--          data->is_shared = true; data->data = img.data;
--        } else *data = img;
--      }
--      else {
--        if (new_data) {
--          if (pos) std::memcpy(new_data,data,sizeof(CImg<T>)*pos);
--          if (pos!=size-1) std::memcpy(new_data+pos+1,data+pos,sizeof(CImg<T>)*(size-1-pos));
--          std::memset(data,0,sizeof(CImg<T>)*(size-1));
--          delete[] data;
--          data = new_data;
--        }
--        else if (pos!=size-1) memmove(data+pos+1,data+pos,sizeof(CImg<T>)*(size-1-pos));
--        if (shared && !img.is_empty()) {
--          data[pos].width = img.width; data[pos].height = img.height; data[pos].depth = img.depth; data[pos].dim = img.dim;
--          data[pos].is_shared = true; data[pos].data = img.data;
--        } else {
--          data[pos].width = data[pos].height = data[pos].depth = data[pos].dim = 0; data[pos].data = 0;
--          data[pos] = img;
--        }
--      }
--      return *this;
--    }
--
--   template<typename t> CImgList& insert(const CImg<t>& img, const unsigned int pos) {
--                return insert(img,pos,false);
--   }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const CImg<t>& img, const unsigned int pos, const bool shared=false) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(img,pos,shared);
--    }
--
--    //! Insert a copy of the image \p img at the current image list.
--    template<typename t> CImgList& insert(const CImg<t>& img) {
--      return insert(img,size);
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(img);
--    }
--
--    //! Insert a copy of the image \p img at the current image list.
--    CImgList& operator<<(const CImg<T>& img) {
--      return insert(img);
--    }
--
--    //! Insert n copies of the image \p img into the current image list, at position \p pos.
--    template<typename t> CImgList& insert(const unsigned int n, const CImg<t>& img, const unsigned int pos) {
--      for (unsigned int i=0; i<n; i++) insert(img,pos);
--      return *this;
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const unsigned int n, const CImg<t>& img, const unsigned int pos) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(n,img,pos);
--    }
--
--
--    //! Insert n copies of the image \p img at the end of the list.
--    template<typename t> CImgList& insert(const unsigned int n, const CImg<t>& img) {
--      for (unsigned int i=0; i<n; i++) insert(img);
--      return *this;
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const unsigned int n, const CImg<t>& img) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(n,img);
--    }
--
--    //! Insert a copy of the image list \p list into the current image list, starting from position \p pos.
--    template<typename t> CImgList& insert(const CImgList<t>& list, const unsigned int pos) {
--      cimglist_for(list,l) insert(list[l],pos+l);
--      return *this;
--    }
--
--    CImgList& insert(const CImgList<T>& list, const unsigned int pos) {
--      if (this!=&list) cimglist_for(list,l) insert(list[l],pos+l);
--      else insert(CImgList<T>(list),pos);
--      return *this;
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const CImgList<t>& list, const unsigned int pos) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(list,pos);
--    }
--
--    //! Append a copy of the image list \p list at the current image list.
--    template<typename t> CImgList& insert(const CImgList<t>& list) {
--      return insert(list,size);
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const CImgList<t>& list) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(list);
--    }
--
--    //! Insert a copy of the image list \p list at the current image list.
--    CImgList& operator<<(const CImgList& list) {
--      return insert(list);
--    }
--
--    //! Insert n copies of the list \p list at position \p pos of the current list.
--    template<typename t> CImgList& insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos) {
--      for (unsigned int i=0; i<n; i++) insert(list,pos);
--      return *this;
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const unsigned int n, const CImgList<t>& list, const unsigned int pos) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(n,list,pos);
--    }
--
--    //! Insert n copies of the list at the end of the current list
--    template<typename t> CImgList& insert(const unsigned int n, const CImgList<t>& list) {
--      for (unsigned int i=0; i<n; i++) insert(list);
--      return *this;
--    }
--
--    template<typename t> CImgList<typename cimg::largest<T,t>::type> get_insert(const unsigned int n, const CImgList<t>& list) const {
--      typedef typename cimg::largest<T,t>::type restype;
--      return CImgList<restype>(*this).insert(n,list);
--    }
--
--    //! Insert image \p img at the end of the list.
--    template<typename t> CImgList& push_back(const CImg<t>& img) {
--      return insert(img);
--    }
--
--    //! Insert image \p img at the front of the list.
--    template<typename t> CImgList& push_front(const CImg<t>& img) {
--      return insert(img,0);
--    }
--
--    //! Insert list \p list at the end of the current list.
--    template<typename t> CImgList& push_back(const CImgList<t>& list) {
--      return insert(list);
--    }
--
--    //! Insert list \p list at the front of the current list.
--    template<typename t> CImgList& push_front(const CImgList<t>& list) {
--      return insert(list,0);
--    }
--
--    //! Insert a shared copy of the image \p img into the current image list, at position \p pos.
--    template<typename t> CImgList& insert_shared(const CImg<t>& img, const unsigned int pos) {
--      return insert(img,pos,true);
--    }
--
--    template<typename t> CImgList get_insert_shared(const CImg<t>& img, const unsigned int pos) const {
--      return CImgList<T>(*this).insert_shared(img,pos);
--    }
--
--    //! Insert a shared copy of the image \p img at the current image list.
--    template<typename t> CImgList& insert_shared(const CImg<t>& img) {
--      return insert_shared(img,size);
--    }
--
--    template<typename t> CImgList get_insert_shared(const CImg<t>& img) const {
--      return CImgList<T>(*this).insert_shared(img);
--    }
--
--    //! Insert n shared copies of the image \p img into the current image list, at position \p pos.
--    template<typename t> CImgList& insert_shared(const unsigned int n, const CImg<t>& img, const unsigned int pos) {
--      for (unsigned int i=0; i<n; i++) insert_shared(img,pos);
--      return *this;
--    }
--
--    template<typename t> CImgList get_insert_shared(const unsigned int n, const CImg<t>& img, const unsigned int pos) const {
--      return CImgList<T>(*this).insert_shared(n,img,pos);
--    }
--
--    //! Insert n shared copies of the image \p img at the end of the list.
--    template<typename t> CImgList& insert_shared(const unsigned int n, const CImg<t>& img) {
--      for (unsigned int i=0; i<n; i++) insert_shared(img);
--      return *this;
--    }
--
--    template<typename t> CImgList get_insert_shared(const unsigned int n, const CImg<t>& img) const {
--      return CImgList<T>(*this).insert_shared(n,img);
--    }
--
--    //! Insert a shared copy of all image of the list \p list into the current image list, starting from position \p pos.
--    template<typename t> CImgList& insert_shared(const CImgList<t>& list, const unsigned int pos) {
--      if (this!=&list) cimglist_for(list,l) insert_shared(list[l],pos+l);
--      else insert_shared(CImgList<T>(list),pos);
--      return *this;
--    }
--
--    template<typename t> CImgList get_insert_shared(const CImgList<t>& list, const unsigned int pos) const {
--      return CImgList<T>(*this).insert_shared(list,pos);
--    }
--
--    //! Append a shared copy of the image list \p list at the current image list.
--    template<typename t> CImgList& insert_shared(const CImgList<t>& list) {
--      return insert_shared(list,size);
--    }
--
--    template<typename t> CImgList get_insert_shared(const CImgList<t>& list) const {
--      return CImgList<T>(*this).insert_shared(list);
--    }
--
--    //! Insert n shared copies of the list \p list at position \p pos of the current list.
--    template<typename t> CImgList& insert_shared(const unsigned int n, const CImgList<t>& list, const unsigned int pos) {
--      for (unsigned int i=0; i<n; i++) insert_shared(list,pos);
--      return *this;
--    }
--
--    template<typename t> CImgList get_insert_shared(const unsigned int n, const CImgList<t>& list, const unsigned int pos) const {
--      return CImgList<T>(*this).insert_shared(n,list,pos);
--    }
--
--    //! Insert n shared copies of the list \p list at the end of the list
--    template<typename t> CImgList& insert_shared(const unsigned int n, const CImgList<t>& list) {
--      return insert_shared(n,list,size);
--    }
--
--    template<typename t> CImgList get_insert_shared(const unsigned int n, const CImgList<t>& list) const {
--      return CImgList<T>(*this).insert_shared(n,list);
--    }
--
--    //! Remove the image at position \p pos from the image list.
--    CImgList& remove(const unsigned int pos) {
--      if (pos>=size)
--        cimg::warn(true,"CImgList<%s>::remove() : Cannot remove an image from a list (%p,%u), at position %u.",
--                   pixel_type(),data,size,pos);
--      else {
--        data[pos].assign();
--        if (!(--size)) return assign();
--        if (size<8 || size>(allocsize>>2)) { // Removing item without reallocation.
--          if (pos!=size) {
--            std::memmove(data+pos,data+pos+1,sizeof(CImg<T>)*(size-pos));
--            CImg<T> &tmp = data[size];
--            tmp.width = tmp.height = tmp.depth = tmp.dim = 0; tmp.data = 0;
--          }
--        } else { // Removing item with reallocation.
--          allocsize>>=2;
--          CImg<T> *new_data = new CImg<T>[allocsize];
--          if (pos) std::memcpy(new_data,data,sizeof(CImg<T>)*pos);
--          if (pos!=size) std::memcpy(new_data+pos,data+pos+1,sizeof(CImg<T>)*(size-pos));
--          std::memset(data,0,sizeof(CImg<T>)*(size+1));
--          delete[] data;
--          data = new_data;
--        }
--      }
--      return *this;
--    }
--
--    CImgList get_remove(const unsigned int pos) const {
--      return CImgList<T>(*this).remove(pos);
--    }
--
--    //! Remove last element of the list;
--    CImgList& pop_back() {
--      return remove(size-1);
--    }
--
--    //! Remove last element of the list;
--    CImgList& operator>>(CImg<T>& img) {
--      if (size) { img.swap((*this)[size-1]); return remove(size-1); }
--      cimg::warn(true,"CImgl<%s>::operator>>() : List is empty",pixel_type());
--      img.assign();
--      return *this;
--    }
--
--    //! Remove first element of the list;
--    CImgList& pop_front() {
--      return remove(0);
--    }
--
--    //! Remove the element pointed by iterator \p iter;
--    CImgList& erase(const iterator iter) {
--      return remove(iter-data);
--    }
--
--    //! Remove the last image from the image list.
--    CImgList& remove() {
--      if (size) return remove(size-1);
--      else cimg::warn(true,"CImgList<%s>::remove() : List is empty",pixel_type());
--      return *this;
--    }
--
--    CImgList get_remove() const {
--      return CImgList<T>(*this).remove();
--    }
--
--    //! Reverse list order
--    CImgList& reverse() {
--      for (unsigned int l=0; l<size/2; l++) (*this)[l].swap((*this)[size-1-l]);
--      return *this;
--    }
--
--    //! Get reversed list
--    CImgList get_reverse() const {
--      return CImgList<T>(*this).reverse();
--    }
--
--    //! Get a sub-list
--    const CImgList get_crop(const unsigned int i0, const unsigned int i1, const bool shared=false) const {
--      if (i0>i1 || i1>=size)
--        throw CImgArgumentException("CImgList<%s>::get_crop() : Cannot get a sub-list (%u->%u) from a list of %u images",
--                                    pixel_type(),i0,i1,size);
--      CImgList<T> res(i1-i0+1);
--      cimglist_for(res,l) res[l].assign((*this)[i0+l],shared);
--      return res;
--    }
--
--    //! Replace a list by its sublist
--    CImgList& crop(const unsigned int i0, const unsigned int i1, const bool shared=false) {
--      return get_crop(i0,i1,shared).swap(*this);
--    }
--
--    //@}
--    //----------------------------
--    //
--    //! \name Fourier Transforms
--    //@{
--    //----------------------------
--
--    //! Compute the Fast Fourier Transform (along the specified axis).
--    CImgList& FFT(const char axe, const bool inverse=false) {
--      if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
--      if (data[0].is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) is empty",
--                                                          pixel_type,data[0].width,data[0].height,data[0].depth,data[0].dim,data[0].data);
--      cimg::warn(size>2,"CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
--      if (size==1) insert(CImg<T>(data[0].width,data[0].height,data[0].depth,data[0].dim,0));
--      CImg<T> &Ir = data[0], &Ii = data[1];
--      if (Ir.width!=Ii.width || Ir.height!=Ii.height || Ir.depth!=Ii.depth || Ir.dim!=Ii.dim)
--        throw CImgInstanceException("CImgList<%s>::FFT() : Real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p)"
--                                    "have different dimensions",pixel_type(),
--                                    Ir.width,Ir.height,Ir.depth,Ir.dim,Ir.data,Ii.width,Ii.height,Ii.depth,Ii.dim,Ii.data);
--
--#ifdef cimg_use_fftw3
--      fftw_complex *data_in;
--      fftw_plan data_plan;
--
--      switch (cimg::uncase(axe)) {
--      case 'x': {
--        data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width);
--        data_plan = fftw_plan_dft_1d(Ir.width, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
--        cimg_forYZV(Ir,y,z,k) {
--          T *ptrr = Ir.ptr(0,y,z,k), *ptri = Ii.ptr(0,y,z,k);
--          double *ptrd = (double*)data_in;
--          cimg_forX(Ir,x) { *(ptrd++) = (double)*(ptrr++); *(ptrd++) = (double)*(ptri++); }
--          fftw_execute(data_plan);
--          cimg_forX(Ir,x) { *(--ptri) = (T)*(--ptrd); *(--ptrr) = (T)*(--ptrd); }
--        }
--      } break;
--
--      case 'y': {
--        data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.height);
--        data_plan = fftw_plan_dft_1d(Ir.height, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
--        const unsigned int off = Ir.width;
--        cimg_forXZV(Ir,x,z,k) {
--          T *ptrr = Ir.ptr(x,0,z,k), *ptri = Ii.ptr(x,0,z,k);
--          double *ptrd = (double*)data_in;
--          cimg_forY(Ir,y) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
--          fftw_execute(data_plan);
--          cimg_forY(Ir,y) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
--        }
--      } break;
--
--      case 'z': {
--        data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.depth);
--        data_plan = fftw_plan_dft_1d(Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
--        const unsigned int off = Ir.width*Ir.height;
--        cimg_forXYV(Ir,x,y,k) {
--          T *ptrr = Ir.ptr(x,y,0,k), *ptri = Ii.ptr(x,y,0,k);
--          double *ptrd = (double*)data_in;
--          cimg_forZ(Ir,z) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
--          fftw_execute(data_plan);
--          cimg_forZ(Ir,z) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
--        }
--      } break;
--
--      case 'v': {
--        data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.dim);
--        data_plan = fftw_plan_dft_1d(Ir.dim, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
--        const unsigned int off = Ir.width*Ir.height*Ir.depth;
--        cimg_forXYZ(Ir,x,y,z) {
--          T *ptrr = Ir.ptr(x,y,z,0), *ptri = Ii.ptr(x,y,z,0);
--          double *ptrd = (double*)data_in;
--          cimg_forV(Ir,k) { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=off; ptri+=off; }
--          fftw_execute(data_plan);
--          cimg_forV(Ir,k) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
--        }
--      } break;
--      }
--
--      fftw_destroy_plan(data_plan);
--      fftw_free(data_in);
--#else
--      switch (cimg::uncase(axe)) {
--      case 'x': { // Fourier along X
--        const unsigned int N = Ir.width, N2 = (N>>1);
--        if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image along 'x' is %d != 2^N",
--                                                           pixel_type(),N);
--        for (unsigned int i=0,j=0; i<N2; i++) {
--          if (j>i) cimg_forYZV(Ir,y,z,v) { cimg::swap(Ir(i,y,z,v),Ir(j,y,z,v)); cimg::swap(Ii(i,y,z,v),Ii(j,y,z,v));
--          if (j<N2) {
--            const unsigned int ri = N-1-i, rj = N-1-j;
--            cimg::swap(Ir(ri,y,z,v),Ir(rj,y,z,v)); cimg::swap(Ii(ri,y,z,v),Ii(rj,y,z,v));
--          }}
--          for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
--        }
--        for (unsigned int delta=2; delta<=N; delta<<=1) {
--          const unsigned int delta2 = (delta>>1);
--          for (unsigned int i=0; i<N; i+=delta) {
--            float wr = 1, wi = 0;
--            const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
--                        ca = (float)std::cos(angle),
--                        sa = (float)std::sin(angle);
--            for (unsigned int k=0; k<delta2; k++) {
--              const unsigned int j = i + k, nj = j + delta2;
--              cimg_forYZV(Ir,y,z,k) {
--                T &ir = Ir(j,y,z,k), &ii = Ii(j,y,z,k), &nir = Ir(nj,y,z,k), &nii = Ii(nj,y,z,k);
--                const T tmpr = wr*nir - wi*nii, tmpi = wr*nii + wi*nir;
--                nir = ir - tmpr; nii = ii - tmpi;
--                ir += tmpr; ii += tmpi;
--              }
--              const float nwr = wr*ca-wi*sa;
--              wi = wi*ca + wr*sa;
--              wr = nwr;
--            }
--          }
--        }
--        if (inverse) (*this)/=N;
--      } break;
--
--      case 'y': { // Fourier along Y
--        const unsigned int N = Ir.height, N2 = (N>>1);
--        if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'y' is %d != 2^N",
--                                                           pixel_type(),N);
--        for (unsigned int i=0,j=0; i<N2; i++) {
--          if (j>i) cimg_forXZV(Ir,x,z,v) { cimg::swap(Ir(x,i,z,v),Ir(x,j,z,v)); cimg::swap(Ii(x,i,z,v),Ii(x,j,z,v));
--          if (j<N2) {
--            const unsigned int ri = N-1-i, rj = N-1-j;
--            cimg::swap(Ir(x,ri,z,v),Ir(x,rj,z,v)); cimg::swap(Ii(x,ri,z,v),Ii(x,rj,z,v));
--          }}
--          for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
--        }
--        for (unsigned int delta=2; delta<=N; delta<<=1) {
--          const unsigned int delta2 = (delta>>1);
--          for (unsigned int i=0; i<N; i+=delta) {
--            float wr = 1, wi = 0;
--            const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
--                        ca = (float)std::cos(angle), sa = (float)std::sin(angle);
--            for (unsigned int k=0; k<delta2; k++) {
--              const unsigned int j = i + k, nj = j + delta2;
--              cimg_forXZV(Ir,x,z,k) {
--                T &ir = Ir(x,j,z,k), &ii = Ii(x,j,z,k), &nir = Ir(x,nj,z,k), &nii = Ii(x,nj,z,k);
--                const T tmpr = wr*nir - wi*nii, tmpi = wr*nii + wi*nir;
--                nir = ir - tmpr; nii = ii - tmpi;
--                ir += tmpr; ii += tmpi;
--              }
--              const float nwr = wr*ca-wi*sa;
--              wi = wi*ca + wr*sa;
--              wr = nwr;
--            }
--          }
--        }
--        if (inverse) (*this)/=N;
--      } break;
--
--      case 'z': { // Fourier along Z
--        const unsigned int N = Ir.depth, N2 = (N>>1);
--        if (((N-1)&N) && N!=1) throw CImgInstanceException("CImgList<%s>::FFT() : Dimension of instance image(s) along 'z' is %d != 2^N",
--                                                           pixel_type(),N);
--        for (unsigned int i=0,j=0; i<N2; i++) {
--          if (j>i) cimg_forXYV(Ir,x,y,v) { cimg::swap(Ir(x,y,i,v),Ir(x,y,j,v)); cimg::swap(Ii(x,y,i,v),Ii(x,y,j,v));
--          if (j<N2) {
--            const unsigned int ri = N-1-i, rj = N-1-j;
--            cimg::swap(Ir(x,y,ri,v),Ir(x,y,rj,v)); cimg::swap(Ii(x,y,ri,v),Ii(x,y,rj,v));
--          }}
--          for (unsigned int m=N, n=N2; (j+=n)>=m; j-=m, m=n, n>>=1);
--        }
--        for (unsigned int delta=2; delta<=N; delta<<=1) {
--          const unsigned int delta2 = (delta>>1);
--          for (unsigned int i=0; i<N; i+=delta) {
--            float wr = 1, wi = 0;
--            const float angle = (float)((inverse?+1:-1)*2*cimg::PI/delta),
--                        ca = (float)std::cos(angle), sa = (float)std::sin(angle);
--            for (unsigned int k=0; k<delta2; k++) {
--              const unsigned int j = i + k, nj = j + delta2;
--              cimg_forXYV(Ir,x,y,k) {
--                T &ir = Ir(x,y,j,k), &ii = Ii(x,y,j,k), &nir = Ir(x,y,nj,k), &nii = Ii(x,y,nj,k);
--                const T tmpr = wr*nir - wi*nii, tmpi = wr*nii + wi*nir;
--                nir = ir - tmpr; nii = ii - tmpi;
--                ir += tmpr; ii += tmpi;
--              }
--              const float nwr = wr*ca-wi*sa;
--              wi = wi*ca + wr*sa;
--              wr = nwr;
--            }
--          }
--        }
--        if (inverse) (*this)/=N;
--      } break;
--
--      default: throw CImgArgumentException("CImgList<%s>::FFT() : unknown axe '%c', must be 'x','y' or 'z'");
--      }
--#endif
--      return *this;
--    }
--
--    //! Return the Fast Fourier Transform of a complex image (along a specified axis).
--    CImgList<typename cimg::largest<T,float>::type> get_FFT(const char axe,const bool inverse=false) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImgList<restype>(*this).FFT(axe,inverse);
--    }
--
--    //! Compute the Fast Fourier Transform of a complex image.
--    CImgList& FFT(const bool inverse=false) {
--      if (is_empty()) throw CImgInstanceException("CImgList<%s>::FFT() : Instance list (%u,%p) is empty",pixel_type(),size,data);
--      cimg::warn(size>2,"CImgList<%s>::FFT() : Instance list (%u,%p) have more than 2 images",pixel_type(),size,data);
--      if (size==1) insert(CImg<T>(data[0].width,data[0].height,data[0].depth,data[0].dim,0));
--      CImg<T> &Ir = data[0];
--
--#ifdef cimg_use_fftw3
--      CImg<T> &Ii = data[1];
--      fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * Ir.width*Ir.height*Ir.depth);
--      fftw_plan data_plan;
--      const unsigned int w = Ir.width, wh = w*Ir.height, whd = wh*Ir.depth;
--      data_plan = fftw_plan_dft_3d(Ir.width, Ir.height, Ir.depth, data_in, data_in, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE);
--      cimg_forV(Ir,k) {
--        T *ptrr = Ir.ptr(0,0,0,k), *ptri = Ii.ptr(0,0,0,k);
--        double *ptrd = (double*)data_in;
--        cimg_forX(Ir,x) { cimg_forY(Ir,y) { cimg_forZ(Ir,z)
--          { *(ptrd++) = (double)*ptrr; *(ptrd++) = (double)*ptri; ptrr+=wh; ptri+=wh; }
--        ptrr-=whd-w; ptri-=whd-w; }
--        ptrr-=wh-1; ptri-=wh-1; }
--        fftw_execute(data_plan);
--        ptrd = (double*)data_in;
--        ptrr = Ir.ptr(0,0,0,k), ptri = Ii.ptr(0,0,0,k);
--        cimg_forX(Ir,x) { cimg_forY(Ir,y) { cimg_forZ(Ir,z)
--          { *ptrr = (T)*(ptrd++); *ptri = (T)*(ptrd++); ptrr+=wh; ptri+=wh; }
--        ptrr-=whd-w; ptri-=whd-w; }
--        ptrr-=wh-1; ptri-=wh-1; }
--      }
--      fftw_destroy_plan(data_plan);
--      fftw_free(data_in);
--#else
--      if (Ir.depth>1)  FFT('z',inverse);
--      if (Ir.height>1) FFT('y',inverse);
--      if (Ir.width>1)  FFT('x',inverse);
--#endif
--      return *this;
--    }
--
--    //! Return the Fast Fourier Transform of a complex image
--    CImgList<typename cimg::largest<T,float>::type> get_FFT(const bool inverse=false) const {
--      typedef typename cimg::largest<T,float>::type restype;
--      return CImgList<restype>(*this).FFT(inverse);
--    }
--
--    //@}
--    //----------------------------------
--    //
--    //! \name Input-Output and Display
--    //@{
--    //----------------------------------
--
--    //! Print informations about the list on the standard output.
--    const CImgList& print(const char* title=0, const unsigned int print_flag=1) const {
--      char tmp[1024];
--      std::fprintf(stderr,"%-8s(this=%p) : { size=%u, data=%p }\n",title?title:"CImgList",
--                   (void*)this,size,(void*)data);
--      if (print_flag>0) cimglist_for(*this,l) {
--        std::sprintf(tmp,"%s[%d]",title?title:"CImgList",l);
--        data[l].print(tmp,print_flag);
--      }
--      return *this;
--    }
--
--    //! Display informations about the list on the standart output.
--    const CImgList& print(const unsigned int print_flag) const {
--      return print(0,print_flag);
--    }
--
--    //! Load an image list from a file.
--    static CImgList get_load(const char *const filename) {
--      const char *ext = cimg::filename_split(filename);
--      if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return get_load_cimg(filename);
--      if (!cimg::strncasecmp(ext,"rec",3) ||
--          !cimg::strncasecmp(ext,"par",3)) return get_load_parrec(filename);
--      CImgList res(1);
--      res[0].load(filename);
--      return res;
--    }
--
--    //! In-place version of load().
--    CImgList& load(const char *const filename) {
--      return get_load(filename).swap(*this);
--    }
--
--#define cimg_load_cimg_case(Ts,Tss) \
--  if (!loaded && !cimg::strcasecmp(Ts,tmp2)) for (unsigned int l=0; l<n; l++) { \
--      const bool endian = cimg::endian(); \
--      j=0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j]='\0'; \
--      std::sscanf(tmp,"%u %u %u %u",&w,&h,&z,&k);\
--      if (w*h*z*k>0) { \
--        Tss *buf = new Tss[w*h*z*k]; cimg::fread(buf,w*h*z*k,nfile); \
--        if (endian) cimg::endian_swap(buf,w*h*z*k); \
--        CImg<T> idest(w,h,z,k); \
--        cimg_foroff(idest,off) idest[off] = (T)(buf[off]); idest.swap(res[l]); \
--        delete[] buf; \
--       } \
--      loaded = true; \
--    }
--
--    //! Load an image list from a file (.raw format).
--    static CImgList get_load_cimg(std::FILE *const file, const char *const filename=0) {
--      typedef unsigned char uchar;
--      typedef unsigned short ushort;
--      typedef unsigned int uint;
--      typedef unsigned long ulong;
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      char tmp[256],tmp2[256];
--      int i;
--      bool loaded = false;
--      unsigned int n,j,w,h,z,k,err;
--      j=0; while((i=std::fgetc(nfile))!='\n' && i!=EOF && j<256) tmp[j++]=i; tmp[j]='\0';
--      err=std::sscanf(tmp,"%u%*c%255[A-Za-z ]",&n,tmp2);
--      if (err!=2) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImgList<%s>::get_load_cimg() : File '%s', Unknow CImg RAW header.",
--                              pixel_type(),filename?filename:"(FILE*)");
--      }
--      CImgList<T> res(n);
--      cimg_load_cimg_case("bool",bool);
--      cimg_load_cimg_case("unsigned char",uchar);
--      cimg_load_cimg_case("uchar",uchar);
--      cimg_load_cimg_case("char",char);
--      cimg_load_cimg_case("unsigned short",ushort);
--      cimg_load_cimg_case("ushort",ushort);
--      cimg_load_cimg_case("short",short);
--      cimg_load_cimg_case("unsigned int",uint);
--      cimg_load_cimg_case("uint",uint);
--      cimg_load_cimg_case("int",int);
--      cimg_load_cimg_case("unsigned long",ulong);
--      cimg_load_cimg_case("ulong",ulong);
--      cimg_load_cimg_case("long",long);
--      cimg_load_cimg_case("float",float);
--      cimg_load_cimg_case("double",double);
--      if (!loaded) {
--        if (!file) cimg::fclose(nfile);
--        throw CImgIOException("CImgList<%s>::get_load_cimg() : File '%s', cannot read images of pixels coded as '%s'.",
--                              pixel_type(),filename?filename:"(FILE*)",tmp2);
--      }
--      if (!file) cimg::fclose(nfile);
--      return res;
--    }
--
--    //! Load an image list from a file (.raw format).
--    static CImgList get_load_cimg(const char *const filename) {
--      return get_load_cimg(0,filename);
--    }
--
--    //! In-place version of get_load_cimg().
--    CImgList& load_cimg(std::FILE *const file, const char *const filename=0) {
--      return get_load_cimg(file,filename).swap(*this);
--    }
--
--    //! In-place version of get_load_cimg().
--    CImgList& load_cimg(const char *const filename) {
--      return get_load_cimg(filename).swap(*this);
--    }
--
--    //! Load PAR-REC (Philips) image file
--    static CImgList get_load_parrec(const char *const filename) {
--      char body[1024], filenamepar[1024], filenamerec[1024];
--      const char *ext = cimg::filename_split(filename,body);
--      if (!cimg::strncmp(ext,"par",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.rec",body); }
--      if (!cimg::strncmp(ext,"PAR",3)) { std::strcpy(filenamepar,filename); std::sprintf(filenamerec,"%s.REC",body); }
--      if (!cimg::strncmp(ext,"rec",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.par",body); }
--      if (!cimg::strncmp(ext,"REC",3)) { std::strcpy(filenamerec,filename); std::sprintf(filenamepar,"%s.PAR",body); }
--      std::FILE *file = cimg::fopen(filenamepar,"r");
--
--      // Parse header file
--      CImgList<float> st_slices;
--      CImgList<unsigned int> st_global;
--      int err;
--      char line[256]={0};
--      do { err=std::fscanf(file,"%255[^\n]%*c",line); } while (err!=EOF && (line[0]=='#' || line[0]=='.'));
--      do {
--        unsigned int sn,sizex,sizey,pixsize;
--        float rs,ri,ss;
--        err=std::fscanf(file,"%u%*u%*u%*u%*u%*u%*u%u%*u%u%u%g%g%g%*[^\n]",&sn,&pixsize,&sizex,&sizey,&ri,&rs,&ss);
--        if (err==7) {
--          st_slices.insert(CImg<float>::vector((float)sn,(float)pixsize,(float)sizex,(float)sizey,ri,rs,ss,0));
--          unsigned int i; for (i=0; i<st_global.size && sn<=st_global[i][2]; i++);
--          if (i==st_global.size) st_global.insert(CImg<unsigned int>::vector(sizex,sizey,sn));
--          else {
--            CImg<unsigned int> &vec = st_global[i];
--            if (sizex>vec[0]) vec[0] = sizex;
--            if (sizey>vec[1]) vec[1] = sizey;
--            vec[2] = sn;
--          }
--          st_slices[st_slices.size-1][7] = (float)i;
--        }
--      } while (err==7);
--
--      // Read data
--      std::FILE *file2 = cimg::fopen(filenamerec,"rb");
--      CImgList<T> dest;
--      { cimglist_for(st_global,l) {
--        const CImg<unsigned int>& vec = st_global[l];
--        dest.insert(CImg<T>(vec[0],vec[1],vec[2]));
--      }}
--
--      cimglist_for(st_slices,l) {
--        const CImg<float>& vec = st_slices[l];
--        const unsigned int
--          sn = (unsigned int)vec[0]-1,
--          pixsize = (unsigned int)vec[1],
--          sizex = (unsigned int)vec[2],
--          sizey = (unsigned int)vec[3],
--          imn = (unsigned int)vec[7];
--        const float ri = vec[4], rs = vec[5], ss = vec[6];
--        switch (pixsize) {
--        case 8: {
--          CImg<unsigned char> buf(sizex,sizey);
--          cimg::fread(buf.data,sizex*sizey,file2);
--          if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
--          CImg<T>& img = dest[imn];
--          cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
--        } break;
--        case 16: {
--          CImg<unsigned short> buf(sizex,sizey);
--          cimg::fread(buf.data,sizex*sizey,file2);
--          if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
--          CImg<T>& img = dest[imn];
--          cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
--        } break;
--        case 32: {
--          CImg<unsigned int> buf(sizex,sizey);
--          cimg::fread(buf.data,sizex*sizey,file2);
--          if (cimg::endian()) cimg::endian_swap(buf.data,sizex*sizey);
--          CImg<T>& img = dest[imn];
--          cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
--        } break;
--        default:
--          cimg::fclose(file);
--          cimg::fclose(file2);
--          throw CImgIOException("CImg<%s>::get_load_parrec() : File '%s', cannot handle image with pixsize = %d bits.",
--                                pixel_type(),filename,pixsize);
--          break;
--        }
--      }
--      cimg::fclose(file);
--      cimg::fclose(file2);
--      if (!dest.size)
--        throw CImgIOException("CImg<%s>::get_load_parrec() : File '%s' does not appear to be a valid PAR-REC file.",
--                              pixel_type(),filename);
--      return dest;
--    }
--
--    //! In-place version of get_load_parrec().
--    CImgList& load_parrec(const char *const filename) {
--      return get_load_parrec(filename).swap(*this);
--    }
--
--    //! Load YUV image sequence.
--    static CImgList get_load_yuv(std::FILE *const file, const char *const filename,
--                                 const unsigned int sizex, const unsigned int sizey=1,
--                                 const unsigned int first_frame=0, const int last_frame=-1,
--                                 const bool yuv2rgb=false) {
--      if (sizex%2 || sizey%2)
--        throw CImgArgumentException("CImgList<%s>::get_load_yuv() : File '%s', image dimensions along X and Y must be even numbers (given are %ux%u)\n",
--                                    pixel_type(),filename?filename:"(unknown)",sizex,sizey);
--      if (!sizex || !sizey)
--        throw CImgArgumentException("CImgList<%s>::get_load_yuv() : File '%s', given image sequence size (%u,%u) is invalid",
--                                    pixel_type(),filename?filename:"(unknown)",sizex,sizey);
--      if (last_frame>0 && first_frame>(unsigned int)last_frame)
--        throw CImgArgumentException("CImgList<%s>::get_load_yuv() : File '%s', given first frame %u is posterior to last frame %d.",
--                                    pixel_type(),filename?filename:"(unknown)",first_frame,last_frame);
--      if (!sizex || !sizey)
--        throw CImgArgumentException("CImgList<%s>::get_load_yuv() : File '%s', given frame size (%u,%u) is invalid.",
--                                    pixel_type(),filename?filename:"(unknown)",sizex,sizey);
--      CImgList<T> res;
--      CImg<unsigned char> tmp(sizex,sizey,1,3), UV(sizex/2,sizey/2,1,2);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
--      bool stopflag = false;
--      int err;
--      if (first_frame) {
--        err = std::fseek(nfile,first_frame*(sizex*sizey + sizex*sizey/2),SEEK_CUR);
--        if (err) {
--          if (!file) cimg::fclose(nfile);
--          throw CImgIOException("CImgList<%s>::get_load_yuv() : File '%s' doesn't contain frame number %u "
--                                "(out of range error).",pixel_type(),filename?filename:"(FILE*)",first_frame);
--        }
--      }
--      unsigned int frame;
--      for (frame = first_frame; !stopflag && (last_frame<0 || frame<=(unsigned int)last_frame); frame++) {
--        tmp.fill(0);
--        // TRY to read the luminance, don't replace by cimg::fread !
--        err = (int)std::fread((void*)(tmp.ptr()),1,(size_t)(tmp.width*tmp.height),nfile);
--        if (err!=(int)(tmp.width*tmp.height)) {
--          stopflag = true;
--          cimg::warn(err>0,"CImgList<%s>::get_load_yuv() : File '%s' contains incomplete data,"
--                     " or given image dimensions (%u,%u) are incorrect.",
--                     pixel_type(),filename?filename:"(unknown)",sizex,sizey);
--        } else {
--          UV.fill(0);
--          // TRY to read the luminance, don't replace by cimg::fread !
--          err = (int)std::fread((void*)(UV.ptr()),1,(size_t)(UV.size()),nfile);
--          if (err!=(int)(UV.size())) {
--            stopflag = true;
--            cimg::warn(err>0,"CImgList<%s>::get_load_yuv() : File '%s' contains incomplete data,"
--                       " or given image dimensions (%u,%u) are incorrect.",
--                       pixel_type(),filename?filename:"(unknown)",sizex,sizey);
--          } else {
--            cimg_forXY(UV,x,y) {
--              const int x2=2*x, y2=2*y;
--              tmp(x2,y2,1) = tmp(x2+1,y2,1) = tmp(x2,y2+1,1) = tmp(x2+1,y2+1,1) = UV(x,y,0);
--              tmp(x2,y2,2) = tmp(x2+1,y2,2) = tmp(x2,y2+1,2) = tmp(x2+1,y2+1,2) = UV(x,y,1);
--            }
--            if (yuv2rgb) tmp.YCbCrtoRGB();
--            res.insert(tmp);
--          }
--        }
--      }
--      cimg::warn(stopflag && last_frame>=0 && frame!=(unsigned int)last_frame,
--                 "CImgList<%s>::get_load_yuv() : File '%s', frame %d not reached since only %u frames were found in the file.",
--                 pixel_type(),filename?filename:"(unknown)",last_frame,frame-1,filename);
--      if (!file) cimg::fclose(nfile);
--      return res;
--    }
--
--    //! Load YUV image sequence.
--    static CImgList get_load_yuv(const char *const filename,
--                                 const unsigned int sizex, const unsigned int sizey=1,
--                                 const unsigned int first_frame=0, const int last_frame=-1,
--                                 const bool yuv2rgb=false) {
--      return get_load_yuv(0,filename,sizex,sizey,first_frame,last_frame,yuv2rgb);
--    }
--
--    //! In-place version of get_load_yuv().
--    CImgList& load_yuv(std::FILE *const file, const char *const filename,
--                       const unsigned int sizex, const unsigned int sizey=1,
--                       const unsigned int first_frame=0, const int last_frame=-1,
--                       const bool yuv2rgb=false) {
--      return get_load_yuv(file,filename,sizex,sizey,first_frame,last_frame,yuv2rgb).swap(*this);
--    }
--
--    //! In-place version of get_load_yuv().
--    CImgList& load_yuv(const char *const filename,
--                       const unsigned int sizex, const unsigned int sizey,
--                       const unsigned int first_frame=0, const int last_frame=-1,
--                       const bool yuv2rgb=false) {
--      return get_load_yuv(filename,sizex,sizey,first_frame,last_frame,yuv2rgb).swap(*this);
--    }
--
--    //! Load from OFF file format
--    template<typename tf,typename tc>
--    static CImgList<T> get_load_off(std::FILE *const file, const char *const filename,
--                                    CImgList<tf>& primitives, CImgList<tc>& colors,
--                                    const bool invert_faces=false) {
--      return CImg<T>::get_load_off(file,filename,primitives,colors,invert_faces).get_split('x');
--    }
--
--    //! Load from OFF file format
--    template<typename tf,typename tc>
--      static CImgList<T> get_load_off(const char *const filename,
--                                    CImgList<tf>& primitives, CImgList<tc>& colors,
--                                      const bool invert_faces=false) {
--      return get_load_off(0,filename,primitives,colors,invert_faces);
--    }
--
--    //! In-place version of get_load_off()
--    template<typename tf,typename tc>
--    CImgList& load_off(std::FILE *const file, const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
--                       const bool invert_faces=false) {
--      return get_load_off(file,filename,primitives,colors,invert_faces).swap(*this);
--    }
--
--    //! In-place version of get_load_off()
--    template<typename tf,typename tc>
--    CImgList& load_off(const char *const filename, CImgList<tf>& primitives, CImgList<tc>& colors,
--                       const bool invert_faces=false) {
--      return get_load_off(filename,primitives,colors,invert_faces).swap(*this);
--    }
--
--    //! Save an image list into a file.
--    /**
--       Depending on the extension of the given filename, a file format is chosen for the output file.
--    **/
--    const CImgList& save(const char *const filename) const {
--      if (is_empty()) throw CImgInstanceException("CImgList<%s>::save() : Instance list (%u,%p) is empty (file '%s').",
--                                                  pixel_type(),size,data,filename);
--      if (!filename) throw CImgArgumentException("CImg<%s>::save() : Instance list (%u,%p), specified filename is (null).",
--                                                 pixel_type(),size,data);
--      const char *ext = cimg::filename_split(filename);
--      if (!cimg::strncasecmp(ext,"cimg",4) || !ext[0]) return save_cimg(filename);
--      if (!cimg::strncasecmp(ext,"yuv",3)) return save_yuv(filename,true);
--      if (size==1) data[0].save(filename,-1);
--      else cimglist_for(*this,l) data[l].save(filename,l);
--      return *this;
--    }
--
--    //! Save an image sequence into a YUV file
--    const CImgList& save_yuv(std::FILE *const file, const char *const filename=0, const bool rgb2yuv=true) const {
--      if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_yuv() : Instance list (%u,%p) is empty (file '%s').",
--                                                  pixel_type(),size,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_yuv() : Instance list (%u,%p), specified file is (null).",
--                                                          pixel_type(),size,data);
--      if ((*this)[0].dimx()%2 || (*this)[0].dimy()%2)
--        throw CImgInstanceException("CImgList<%s>::save_yuv() : Image dimensions must be even numbers (current are %ux%u, file '%s').",
--                                    pixel_type(),(*this)[0].dimx(),(*this)[0].dimy(),filename?filename:"(unknown)");
--
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      cimglist_for(*this,l) {
--        CImg<unsigned char> YCbCr((*this)[l]);
--        if (rgb2yuv) YCbCr.RGBtoYCbCr();
--        cimg::fwrite(YCbCr.ptr(),YCbCr.width*YCbCr.height,nfile);
--        cimg::fwrite(YCbCr.get_resize(YCbCr.width/2, YCbCr.height/2,1,3,3).ptr(0,0,0,1),
--                     YCbCr.width*YCbCr.height/2,nfile);
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save an image sequence into a YUV file
--    const CImgList& save_yuv(const char *const filename=0, const bool rgb2yuv=true) const {
--      return save_yuv(0,filename,rgb2yuv);
--    }
--
--    //! Save an image list into a CImg file (RAW binary file + simple header)
--    /**
--       A CImg RAW file is a simple uncompressed binary file that may be used to save list of CImg<T> images.
--       \param filename : name of the output file.
--       \return A reference to the current CImgList instance is returned.
--    **/
--    const CImgList& save_cimg(std::FILE *const file, const char *const filename=0) const {
--      if (is_empty()) throw CImgInstanceException("CImgList<%s>::save_cimg() : Instance list (%u,%p) is empty (file '%s').",
--                                                  pixel_type(),size,data,filename?filename:"(unknown)");
--      if (!file && !filename) throw CImgArgumentException("CImg<%s>::save_cimg() : Instance list (%u,%p), specified file is (null).",
--                                                          pixel_type(),size,data);
--      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
--      std::fprintf(nfile,"%u %s\n",size,pixel_type());
--      cimglist_for(*this,l) {
--        const CImg<T>& img = data[l];
--        std::fprintf(nfile,"%u %u %u %u\n",img.width,img.height,img.depth,img.dim);
--        if (img.data) {
--          if (cimg::endian()) {
--            CImg<T> tmp(img);
--            cimg::endian_swap(tmp.data,tmp.size());
--            cimg::fwrite(tmp.data,img.width*img.height*img.depth*img.dim,nfile);
--          } else cimg::fwrite(img.data,img.width*img.height*img.depth*img.dim,nfile);
--        }
--      }
--      if (!file) cimg::fclose(nfile);
--      return *this;
--    }
--
--    //! Save an image list into a CImg file (RAW binary file + simple header)
--    const CImgList& save_cimg(const char *const filename) const {
--      return save_cimg(0,filename);
--    }
--
--    //! Save an image list into a OFF file.
--    template<typename tf, typename tc>
--    const CImgList& save_off(std::FILE *const file, const char *const filename,
--                             const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
--      get_append('x').save_off(file,filename,primitives,colors,invert_faces);
--      return *this;
--    }
--
--    //! Save an image list into a OFF file.
--    template<typename tf, typename tc>
--    const CImgList& save_off(const char *const filename,
--                             const CImgList<tf>& primitives, const CImgList<tc>& colors, const bool invert_faces=false) const {
--      return save_off(filename,primitives,colors,invert_faces);
--    }
--
--    //! Return a single image which is the concatenation of all images of the current CImgList instance.
--    /**
--       \param axe : specify the axe for image concatenation. Can be 'x','y','z' or 'v'.
--       \param align : specify the alignment for image concatenation. Can be 'p' (top), 'c' (center) or 'n' (bottom).
--       \return A CImg<T> image corresponding to the concatenation is returned.
--    **/
--    CImg<T> get_append(const char axe='x',const char align='c') const {
--      if (is_empty()) return CImg<T>();
--      unsigned int dx=0,dy=0,dz=0,dv=0,pos=0;
--      CImg<T> res;
--      switch(cimg::uncase(axe)) {
--      case 'x': {
--        cimglist_for(*this,l) {
--          const CImg<T>& img = (*this)[l];
--          dx += img.width;
--          dy = cimg::max(dy,img.height);
--          dz = cimg::max(dz,img.depth);
--          dv = cimg::max(dv,img.dim);
--        }
--        res.assign(dx,dy,dz,dv,0);
--        switch (cimg::uncase(align)) {
--        case 'p' : { cimglist_for(*this,ll) { res.draw_image((*this)[ll],pos,0,0,0); pos+=(*this)[ll].width; }} break;
--        case 'n' : { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],pos,dy-(*this)[ll].height,dz-(*this)[ll].depth,dv-(*this)[ll].dim); pos+=(*this)[ll].width;
--            }} break;
--        default  : { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],pos,(dy-(*this)[ll].height)/2,(dz-(*this)[ll].depth)/2,(dv-(*this)[ll].dim)/2);
--              pos+=(*this)[ll].width;
--            }} break;
--        }
--      } break;
--      case 'y': {
--        cimglist_for(*this,l) {
--          const CImg<T>& img = (*this)[l];
--          dx = cimg::max(dx,img.width);
--          dy += img.height;
--          dz = cimg::max(dz,img.depth);
--          dv = cimg::max(dv,img.dim);
--        }
--        res.assign(dx,dy,dz,dv,0);
--        switch (cimg::uncase(align)) {
--        case 'p': { cimglist_for(*this,ll) { res.draw_image((*this)[ll],0,pos,0,0); pos+=(*this)[ll].height; }} break;
--        case 'n': { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],dx-(*this)[ll].width,pos,dz-(*this)[ll].depth,dv-(*this)[ll].dim); pos+=(*this)[ll].height;
--            }} break;
--        default : { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],(dx-(*this)[ll].width)/2,pos,(dz-(*this)[ll].depth)/2,(dv-(*this)[ll].dim)/2);
--              pos+=(*this)[ll].height;
--            }} break;
--        }
--      } break;
--      case 'z': {
--        cimglist_for(*this,l) {
--          const CImg<T>& img = (*this)[l];
--          dx = cimg::max(dx,img.width);
--          dy = cimg::max(dy,img.height);
--          dz += img.depth;
--          dv = cimg::max(dv,img.dim);
--        }
--        res.assign(dx,dy,dz,dv,0);
--        switch (cimg::uncase(align)) {
--        case 'p': { cimglist_for(*this,ll) { res.draw_image((*this)[ll],0,0,pos,0); pos+=(*this)[ll].depth; }} break;
--        case 'n': { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],dx-(*this)[ll].width,dy-(*this)[ll].height,pos,dv-(*this)[ll].dim); pos+=(*this)[ll].depth;
--            }} break;
--        case 'c': { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],(dx-(*this)[ll].width)/2,(dy-(*this)[ll].height)/2,pos,(dv-(*this)[ll].dim)/2);
--              pos+=(*this)[ll].depth;
--            }} break;
--        }
--      } break;
--      case 'v': {
--        cimglist_for(*this,l) {
--          const CImg<T>& img = (*this)[l];
--          dx = cimg::max(dx,img.width);
--          dy = cimg::max(dy,img.height);
--          dz = cimg::max(dz,img.depth);
--          dv += img.dim;
--        }
--        res.assign(dx,dy,dz,dv,0);
--        switch (cimg::uncase(align)) {
--        case 'p': { cimglist_for(*this,ll) { res.draw_image((*this)[ll],0,0,0,pos); pos+=(*this)[ll].dim; }} break;
--        case 'n': { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],dx-(*this)[ll].width,dy-(*this)[ll].height,dz-(*this)[ll].depth,pos); pos+=(*this)[ll].dim;
--            }} break;
--        case 'c': { cimglist_for(*this,ll) {
--              res.draw_image((*this)[ll],(dx-(*this)[ll].width)/2,(dy-(*this)[ll].height)/2,(dz-(*this)[ll].depth)/2,pos);
--              pos+=(*this)[ll].dim;
--            }} break;
--        }
--      } break;
--      default: throw CImgArgumentException("CImg<%s>::get_append() : unknow axe '%c', must be 'x','y','z' or 'v'",pixel_type(),axe);
--      }
--      return res;
--    }
--
--    // Create an auto-cropped font (along the X axis) from a input font \p font.
--    CImgList<T> get_crop_font() const {
--      CImgList<T> res;
--      cimglist_for(*this,l) {
--        const CImg<T>& letter = (*this)[l];
--        int xmin = letter.width, xmax = 0;
--        cimg_forXY(letter,x,y) if (letter(x,y)) { if (x<xmin) xmin=x; if (x>xmax) xmax=x; }
--        if (xmin>xmax) res.insert(CImg<T>(letter.width,letter.height,1,letter.dim,0));
--        else res.insert(letter.get_crop(xmin,0,xmax,letter.height-1));
--      }
--      res[' '].resize(res['f'].width);
--      res[' '+256].resize(res['f'].width);
--      return res;
--    }
--
--    CImgList<T>& crop_font() {
--      return get_crop_font().swap(*this);
--    }
--
--    static CImgList<T> get_font(const unsigned int *const font,const unsigned int w,const unsigned int h,
--                             const unsigned int paddingx, const unsigned int paddingy, const bool variable_size=true) {
--      CImgList<T> res = CImgList<T>(256,w,h,1,3).insert(CImgList<T>(256,w,h,1,1));
--      const unsigned int *ptr = font;
--      unsigned int m = 0, val = 0;
--      for (unsigned int y=0; y<h; y++)
--        for (unsigned int x=0; x<256*w; x++) {
--          m>>=1; if (!m) { m=0x80000000; val = *(ptr++); }
--          CImg<T>& img = res[x/w], &mask = res[x/w+256];
--          unsigned int xm = x%w;
--          img(xm,y,0) = img(xm,y,1) = img(xm,y,2) = mask(xm,y,0) = (T)((val&m)?1:0);
--        }
--      if (variable_size) res.crop_font();
--      if (paddingx || paddingy) cimglist_for(res,l) res[l].resize(res[l].dimx()+paddingx, res[l].dimy()+paddingy,1,-100,0);
--      return res;
--    }
--
--    //! Return a CImg pre-defined font with desired size
--    /**
--       \param font_height = height of the desired font (can be 11,13,24,38 or 57)
--       \param fixed_size = tell if the font has a fixed or variable width.
--    **/
--    static CImgList<T> get_font(const unsigned int font_width, const bool variable_size=true) {
--      if (font_width<=11) {
--        static CImgList<T> font7x11, nfont7x11;
--        if (!variable_size && font7x11.is_empty()) font7x11 = get_font(cimg::font7x11,7,11,1,0,false);
--        if (variable_size && nfont7x11.is_empty()) nfont7x11 = get_font(cimg::font7x11,7,11,1,0,true);
--        return variable_size?nfont7x11:font7x11;
--      }
--      if (font_width<=13) {
--        static CImgList<T> font10x13, nfont10x13;
--        if (!variable_size && font10x13.is_empty()) font10x13 = get_font(cimg::font10x13,10,13,1,0,false);
--        if (variable_size && nfont10x13.is_empty()) nfont10x13 = get_font(cimg::font10x13,10,13,1,0,true);
--        return variable_size?nfont10x13:font10x13;
--      }
--      if (font_width<=17) {
--        static CImgList<T> font8x17, nfont8x17;
--        if (!variable_size && font8x17.is_empty()) font8x17 = get_font(cimg::font8x17,8,17,1,0,false);
--        if (variable_size && nfont8x17.is_empty()) nfont8x17 = get_font(cimg::font8x17,8,17,1,0,true);
--        return variable_size?nfont8x17:font8x17;
--      }
--      if (font_width<=19) {
--        static CImgList<T> font10x19, nfont10x19;
--        if (!variable_size && font10x19.is_empty()) font10x19 = get_font(cimg::font10x19,10,19,2,0,false);
--        if (variable_size && nfont10x19.is_empty()) nfont10x19 = get_font(cimg::font10x19,10,19,2,0,true);
--        return variable_size?nfont10x19:font10x19;
--      }
--      if (font_width<=24) {
--        static CImgList<T> font12x24, nfont12x24;
--        if (!variable_size && font12x24.is_empty()) font12x24 = get_font(cimg::font12x24,12,24,2,0,false);
--        if (variable_size && nfont12x24.is_empty()) nfont12x24 = get_font(cimg::font12x24,12,24,2,0,true);
--        return variable_size?nfont12x24:font12x24;
--      }
--      if (font_width<=32) {
--        static CImgList<T> font16x32, nfont16x32;
--        if (!variable_size && font16x32.is_empty()) font16x32 = get_font(cimg::font16x32,16,32,2,0,false);
--        if (variable_size && nfont16x32.is_empty()) nfont16x32 = get_font(cimg::font16x32,16,32,2,0,true);
--        return variable_size?nfont16x32:font16x32;
--      }
--      if (font_width<=38) {
--        static CImgList<T> font19x38, nfont19x38;
--        if (!variable_size && font19x38.is_empty()) font19x38 = get_font(cimg::font19x38,19,38,3,0,false);
--        if (variable_size && nfont19x38.is_empty()) nfont19x38 = get_font(cimg::font19x38,19,38,3,0,true);
--        return variable_size?nfont19x38:font19x38;
--      }
--      static CImgList<T> font29x57, nfont29x57;
--      if (!variable_size && font29x57.is_empty()) font29x57 = get_font(cimg::font29x57,29,57,5,0,false);
--      if (variable_size && nfont29x57.is_empty()) nfont29x57 = get_font(cimg::font29x57,29,57,5,0,true);
--      return variable_size?nfont29x57:font29x57;
--    }
--
--    //! Display the current CImgList instance in an existing CImgDisplay window (by reference).
--    /**
--       This function displays the list images of the current CImgList instance into an existing CImgDisplay window.
--       Images of the list are concatenated in a single temporarly image for visualization purposes.
--       The function returns immediately.
--       \param disp : reference to an existing CImgDisplay instance, where the current image list will be displayed.
--       \param axe : specify the axe for image concatenation. Can be 'x','y','z' or 'v'.
--       \param align : specify the alignment for image concatenation. Can be 'p' (top), 'c' (center) or 'n' (bottom).
--       \return A reference to the current CImgList instance is returned.
--    **/
--    const CImgList& display(CImgDisplay& disp, const char axe='x', const char align='c') const {
--      get_append(axe,align).display(disp);
--      return *this;
--    }
--
--    //! Display the current CImgList instance in a new display window.
--    /**
--       This function opens a new window with a specific title and displays the list images of the current CImgList instance into it.
--       Images of the list are concatenated in a single temporarly image for visualization purposes.
--       The function returns when a key is pressed or the display window is closed by the user.
--       \param title : specify the title of the opening display window.
--       \param axe : specify the axe for image concatenation. Can be 'x','y','z' or 'v'.
--       \param align : specify the alignment for image concatenation. Can be 'p' (top), 'c' (center) or 'n' (bottom).
--       \param min_size : specify the minimum size of the opening display window. Images having dimensions below this
--       size will be upscaled.
--       \param max_size : specify the maximum size of the opening display window. Images having dimensions above this
--       size will be downscaled.
--       \return A reference to the current CImgList instance is returned.
--    **/
--    const CImgList& display(const char* title,const char axe='x',const char align='c',
--                         const int min_size=128,const int max_size=1024) const {
--      get_append(axe,align).display(title,min_size,max_size);
--      return *this;
--    }
--
--    //! Display the current CImgList instance in a new display window.
--    /**
--       This function opens a new window and displays the list images of the current CImgList instance into it.
--       Images of the list are concatenated in a single temporarly image for visualization purposes.
--       The function returns when a key is pressed or the display window is closed by the user.
--       \param axe : specify the axe for image concatenation. Can be 'x','y','z' or 'v'.
--       \param align : specify the alignment for image concatenation. Can be 'p' (top), 'c' (center) or 'n' (bottom).
--       \param min_size : specify the minimum size of the opening display window. Images having dimensions below this
--       size will be upscaled.
--       \param max_size : specify the maximum size of the opening display window. Images having dimensions above this
--       size will be downscaled.
--       \return A reference to the current CImgList instance is returned.
--    **/
--    const CImgList& display(const char axe='x',const char align='c',
--                         const int min_size=128,const int max_size=1024) const {
--      return display(" ",axe,align,min_size,max_size);
--    }
--
--    //! Rescale and center 3D object
--    CImgList& resize_object3d(const float siz=100, const bool centering=true) {
--      float xm = (float)((*this)(0,0)), ym = (float)((*this)(0,1)), zm = (float)((*this)(0,2)), xM = xm, yM = ym, zM = zm;
--      for (unsigned int p=1; p<size; p++) {
--         const float x = (float)((*this)(p,0)), y = (float)((*this)(p,1)), z = (float)((*this)(p,2));
--         if (x<xm) xm = x;
--         if (y<ym) ym = y;
--         if (z<zm) zm = z;
--         if (x>xM) xM = x;
--         if (y>yM) yM = y;
--         if (z>zM) zM = z;
--      }
--      const float
--        cx = 0.5f*(xm+xM),
--        cy = 0.5f*(ym+yM),
--        cz = 0.5f*(zm+zM),
--        delta = cimg::max(xM-xm,yM-ym,zM-zm),
--        ratio = (siz>=0)?siz/delta:-siz/100;
--      if (centering) cimglist_for(*this,l) {
--        T &x = (*this)(l,0), &y = (*this)(l,1), &z = (*this)(l,2);
--        x = (T)((x-cx)*ratio);
--        y = (T)((y-cy)*ratio);
--        z = (T)((z-cz)*ratio);
--      } else cimglist_for(*this,l) {
--        T &x = (*this)(l,0), &y = (*this)(l,1), &z = (*this)(l,2);
--        x = (T)(cx+(x-cx)*ratio);
--        y = (T)(cy+(y-cy)*ratio);
--        z = (T)(cz+(z-cz)*ratio);
--      }
--      return *this;
--    }
--
--    //! Get a rescaled and centered version of the 3D object
--    CImgList get_resize_object3d(const float siz=100, const bool centering=true) const {
--      return CImgList<T>(*this).resize_object3d(siz,centering);
--    }
--
--    // Swap fields of two CImgList instances.
--    CImgList& swap(CImgList& list) {
--      cimg::swap(size,list.size);
--      cimg::swap(allocsize,list.allocsize);
--      cimg::swap(data,list.data);
--      return list;
--    }
--
--  };
--
--  /*
--   #-----------------------------------------
--   #
--   #
--   #
--   # Complete previously defined functions
--   #
--   #
--   #
--   #------------------------------------------
--  */
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator+(const CImg<t>& img, const t& val) {
--        return CImg<t>(img,false)+=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator+(const CImg<t1>& img, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img,false)+=val;
-- }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator+(const t& val, const CImg<t>& img) {
--    return img+val;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator+(const t1& val, const CImg<t2>& img) {
--    return img+val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator+(const CImgList<t>& list, const t& val) {
--    return CImgList<t>(list)+=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator+(const CImgList<t1>& list, const t2& val) {
--          typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)+=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator+(const t& val, const CImgList<t>& list) {
--          return list+val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator+(const t1& val, const CImgList<t2>& list) {
--          return list+val;
--  }
--#endif
--
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator+(const CImg<t1>& img1, const CImg<t2>& img2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img1,false)+=img2;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator+(const CImg<t1>& img, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)+=img;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator+(const CImgList<t1>& list, const CImg<t2>& img) {
--    return img+list;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator+(const CImgList<t1>& list1, const CImgList<t2>& list2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list1)+=list2;
--  }
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator-(const CImg<t>& img, const t& val) {
--          return CImg<t>(img,false)-=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator-(const CImg<t1>& img, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img,false)-=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator-(const t& val, const CImg<t>& img) {
--    return CImg<t>(img.width,img.height,img.depth,img.dim,val)-=img;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator-(const t1& val, const CImg<t2>& img) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img.width,img.height,img.depth,img.dim,(restype)val)-=img;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator-(const CImgList<t>& list, const t& val) {
--          return CImgList<t>(list)-=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator-(const CImgList<t1>& list, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)-=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<double> operator-(const t& val, const CImgList<t>& list) {
--    CImgList<t> res(list.size);
--    cimglist_for(res,l) res[l] = val-list[l];
--    return res;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator-(const t1& val, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = val-list[l];
--    return res;
--  }
--#endif
--
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator-(const CImg<t1>& img1, const CImg<t2>& img2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img1,false)-=img2;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator-(const CImg<t1>& img, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = img-list[l];
--    return res;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator-(const CImgList<t1>& list, const CImg<t2>& img) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)-=img;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator-(const CImgList<t1>& list1, const CImgList<t2>& list2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list1)-=list2;
--  }
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator*(const CImg<t>& img, const double val) {
--        return CImg<t>(img,false)*=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator*(const CImg<t1>& img, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img,false)*=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator*(const double val, const CImg<t>& img) {
--        return img*val;
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator*(const t1& val, const CImg<t2>& img) {
--          return img*val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator*(const CImgList<t>& list, const double val) {
--          return CImgList<t>(list)*=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator*(const CImgList<t1>& list, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)*=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator*(const double val, const CImgList<t>& list) {
--        return list*val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator*(const t1& val, const CImgList<t2>& list) {
--          return list*val;
--  }
--#endif
--
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator*(const CImg<t1>& img1, const CImg<t2>& img2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    if (img1.width!=img2.height)
--      throw CImgArgumentException("operator*() : can't multiply a matrix (%ux%u) by a matrix (%ux%u)",
--                                  img1.width,img1.height,img2.width,img2.height);
--    CImg<restype> res(img2.width,img1.height);
--    restype val;
--    cimg_forXY(res,i,j) { val=0; cimg_forX(img1,k) val+=img1(k,j)*img2(i,k); res(i,j) = val; }
--    return res;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator*(const CImg<t1>& img, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = img*list[l];
--    return res;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator*(const CImgList<t1>& list, const CImg<t2>& img) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = list[l]*img;
--    return res;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator*(const CImgList<t1>& list1, const CImgList<t2>& list2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(cimg::min(list1.size,list2.size));
--    cimglist_for(res,l) res[l] = list1[l]*list2[l];
--    return res;
--  }
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator/(const CImg<t>& img, const double val) {
--         return CImg<t>(img,false)/=val;
--         }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator/(const CImg<t1>& img, const t2& val) {
--          typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img,false)/=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImg<t> operator/(const double val, CImg<t>& img) {
--        return val*img.get_inverse();
--  }
--#else
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator/(const t1& val, CImg<t2>& img) {
--          return val*img.get_inverse();
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator/(const CImgList<t>& list, const double val) {
--          return CImgList<t>(list)/=val;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator/(const CImgList<t1>& list, const t2& val) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)/=val;
--  }
--#endif
--
--#ifdef cimg_use_visualcpp6
--  template<typename t> inline CImgList<t> operator/(const double val, const CImgList<t>& list) {
--    CImgList<t> res(list.size);
--    cimglist_for(res,l) res[l] = val/list[l];
--    return res;
--  }
--#else
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator/(const t1& val, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = val/list[l];
--    return res;
--  }
--#endif
--
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator/(const CImg<t1>& img1, const CImg<t2>& img2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImg<restype>(img1,false)*=img2.get_inverse();
--  }
--
--  template<typename t1, typename t2> inline CImg<typename cimg::largest<t1,t2>::type> operator/(const CImg<t1>& img, const CImgList<t2>& list) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    CImgList<restype> res(list.size);
--    cimglist_for(res,l) res[l] = img/list[l];
--    return res;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator/(const CImgList<t1>& list, const CImg<t2>& img) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list)/=img;
--  }
--
--  template<typename t1, typename t2> inline CImgList<typename cimg::largest<t1,t2>::type> operator/(const CImgList<t1>& list1, const CImgList<t2>& list2) {
--    typedef typename cimg::largest<t1,t2>::type restype;
--    return CImgList<restype>(list1)/=list2;
--  }
--
--namespace cimg {
--
--  //! Display a dialog box, where a user can click standard buttons.
--  /**
--     Up to 6 buttons can be defined in the dialog window.
--     This function returns when a user clicked one of the button or closed the dialog window.
--     \param title = Title of the dialog window.
--     \param msg = Main message displayed inside the dialog window.
--     \param button1_txt = Label of the 1st button.
--     \param button2_txt = Label of the 2nd button.
--     \param button3_txt = Label of the 3rd button.
--     \param button4_txt = Label of the 4th button.
--     \param button5_txt = Label of the 5th button.
--     \param button6_txt = Label of the 6th button.
--     \param logo = Logo image displayed at the left of the main message. This parameter is optional.
--     \param centering = Tell to center the dialog window on the screen.
--     \return The button number (from 0 to 5), or -1 if the dialog window has been closed by the user.
--     \note If a button text is set to 0, then the corresponding button (and the followings) won't appear in
--     the dialog box. At least one button is necessary.
--  **/
--
--  template<typename t>
--  inline int dialog(const char *title,const char *msg,
--                    const char *button1_txt,const char *button2_txt,
--                    const char *button3_txt,const char *button4_txt,
--                    const char *button5_txt,const char *button6_txt,
--                    const CImg<t>& logo, const bool centering = false) {
--#if cimg_display_type!=0
--    const unsigned char
--      black[3]={0,0,0}, white[3]={255,255,255}, gray[3]={200,200,200}, gray2[3]={150,150,150};
--
--      // Create buttons and canvas graphics
--      CImgList<unsigned char> buttons, cbuttons, sbuttons;
--      if (button1_txt) { buttons.insert(CImg<unsigned char>().draw_text(button1_txt,0,0,black,gray,13));
--      if (button2_txt) { buttons.insert(CImg<unsigned char>().draw_text(button2_txt,0,0,black,gray,13));
--      if (button3_txt) { buttons.insert(CImg<unsigned char>().draw_text(button3_txt,0,0,black,gray,13));
--      if (button4_txt) { buttons.insert(CImg<unsigned char>().draw_text(button4_txt,0,0,black,gray,13));
--      if (button5_txt) { buttons.insert(CImg<unsigned char>().draw_text(button5_txt,0,0,black,gray,13));
--      if (button6_txt) { buttons.insert(CImg<unsigned char>().draw_text(button6_txt,0,0,black,gray,13));
--      }}}}}}
--      if (!buttons.size) throw CImgArgumentException("cimg::dialog() : No buttons have been defined. At least one is necessary");
--
--      unsigned int bw=0, bh=0;
--      cimglist_for(buttons,l) { bw = cimg::max(bw,buttons[l].width); bh = cimg::max(bh,buttons[l].height); }
--      bw+=8; bh+=8;
--      if (bw<64) bw=64;
--      if (bw>128) bw=128;
--      if (bh<24) bh=24;
--      if (bh>48) bh=48;
--
--      CImg<unsigned char> button = CImg<unsigned char>(bw,bh,1,3).
--        draw_rectangle(0,0,bw-1,bh-1,gray).
--        draw_line(0,0,bw-1,0,white).draw_line(0,bh-1,0,0,white).
--        draw_line(bw-1,0,bw-1,bh-1,black).draw_line(bw-1,bh-1,0,bh-1,black).
--        draw_line(1,bh-2,bw-2,bh-2,gray2).draw_line(bw-2,bh-2,bw-2,1,gray2);
--      CImg<unsigned char> sbutton = CImg<unsigned char>(bw,bh,1,3).
--        draw_rectangle(0,0,bw-1,bh-1,gray).
--        draw_line(0,0,bw-1,0,black).draw_line(bw-1,0,bw-1,bh-1,black).
--        draw_line(bw-1,bh-1,0,bh-1,black).draw_line(0,bh-1,0,0,black).
--        draw_line(1,1,bw-2,1,white).draw_line(1,bh-2,1,1,white).
--        draw_line(bw-2,1,bw-2,bh-2,black).draw_line(bw-2,bh-2,1,bh-2,black).
--        draw_line(2,bh-3,bw-3,bh-3,gray2).draw_line(bw-3,bh-3,bw-3,2,gray2).
--        draw_line(4,4,bw-5,4,black,0xAAAAAAAA).draw_line(bw-5,4,bw-5,bh-5,black,0xAAAAAAAA).
--        draw_line(bw-5,bh-5,4,bh-5,black,0xAAAAAAAA).draw_line(4,bh-5,4,4,black,0xAAAAAAAA);
--      CImg<unsigned char> cbutton = CImg<unsigned char>(bw,bh,1,3).
--        draw_rectangle(0,0,bw-1,bh-1,black).draw_rectangle(1,1,bw-2,bh-2,gray2).draw_rectangle(2,2,bw-3,bh-3,gray).
--        draw_line(4,4,bw-5,4,black,0xAAAAAAAA).draw_line(bw-5,4,bw-5,bh-5,black,0xAAAAAAAA).
--        draw_line(bw-5,bh-5,4,bh-5,black,0xAAAAAAAA).draw_line(4,bh-5,4,4,black,0xAAAAAAAA);
--
--        cimglist_for(buttons,ll) {
--          cbuttons.insert(CImg<unsigned char>(cbutton).draw_image(buttons[ll],1+(bw-buttons[ll].dimx())/2,1+(bh-buttons[ll].dimy())/2));
--          sbuttons.insert(CImg<unsigned char>(sbutton).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2));
--          buttons[ll] = CImg<unsigned char>(button).draw_image(buttons[ll],(bw-buttons[ll].dimx())/2,(bh-buttons[ll].dimy())/2);
--        }
--
--        CImg<unsigned char> canvas;
--        if (msg) canvas = CImg<unsigned char>().draw_text(msg,0,0,black,gray,13);
--        const unsigned int
--          bwall = (buttons.size-1)*(12+bw) + bw,
--          w = cimg::max(196U,36+logo.width+canvas.width, 24+bwall),
--          h = cimg::max(96U,36+canvas.height+bh,36+logo.height+bh),
--          lx = 12 + (canvas.data?0:((w-24-logo.width)/2)),
--          ly = (h-12-bh-logo.height)/2,
--          tx = lx+logo.width+12,
--          ty = (h-12-bh-canvas.height)/2,
--          bx = (w-bwall)/2,
--          by = h-12-bh;
--
--        if (canvas.data)
--          canvas = CImg<unsigned char>(w,h,1,3).
--            draw_rectangle(0,0,w-1,h-1,gray).
--            draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
--            draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black).
--            draw_image(canvas,tx,ty);
--        else
--          canvas = CImg<unsigned char>(w,h,1,3).
--            draw_rectangle(0,0,w-1,h-1,gray).
--            draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
--            draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black);
--        if (logo.data) canvas.draw_image(logo,lx,ly);
--
--        unsigned int xbuttons[6];
--        cimglist_for(buttons,lll) { xbuttons[lll] = bx+(bw+12)*lll; canvas.draw_image(buttons[lll],xbuttons[lll],by); }
--
--        // Open window and enter events loop
--        CImgDisplay disp(canvas,title?title:" ",0,3,false,centering?true:false);
--        if (centering) disp.move((CImgDisplay::screen_dimx()-disp.dimx())/2,
--                                 (CImgDisplay::screen_dimy()-disp.dimy())/2);
--        bool stopflag = false, refresh = false;
--        int oselected = -1, oclicked = -1, selected = -1, clicked = -1;
--        while (!disp.is_closed && !stopflag) {
--          if (refresh) {
--            if (clicked>=0) CImg<unsigned char>(canvas).draw_image(cbuttons[clicked],xbuttons[clicked],by).display(disp);
--            else {
--              if (selected>=0) CImg<unsigned char>(canvas).draw_image(sbuttons[selected],xbuttons[selected],by).display(disp);
--              else canvas.display(disp);
--            }
--            refresh = false;
--          }
--          disp.wait(15);
--          if (disp.is_resized) disp.resize(disp);
--
--          if (disp.button&1)  {
--            oclicked = clicked;
--            clicked = -1;
--            cimglist_for(buttons,l)
--              if (disp.mouse_y>=(int)by && disp.mouse_y<(int)(by+bh) &&
--                  disp.mouse_x>=(int)xbuttons[l] && disp.mouse_x<(int)(xbuttons[l]+bw)) {
--                clicked = selected = l;
--                refresh = true;
--              }
--            if (clicked!=oclicked) refresh = true;
--          } else if (clicked>=0) stopflag = true;
--
--          if (disp.key) {
--            oselected = selected;
--            switch (disp.key) {
--            case cimg::keyESC: selected=-1; stopflag=true; break;
--            case cimg::keyENTER: if (selected<0) selected=0; stopflag = true; break;
--            case cimg::keyTAB:
--            case cimg::keyARROWRIGHT:
--            case cimg::keyARROWDOWN: selected = (selected+1)%buttons.size; break;
--            case cimg::keyARROWLEFT:
--            case cimg::keyARROWUP: selected = (selected+buttons.size-1)%buttons.size; break;
--            }
--            disp.key = 0;
--            if (selected!=oselected) refresh = true;
--          }
--        }
--        if (disp.is_closed) selected = -1;
--        return selected;
--#else
--        std::fprintf(stderr,"<%s>\n\n%s\n\n",title,msg);
--        return -1+0*(int)(button1_txt-button2_txt+button3_txt-button4_txt+button5_txt-button6_txt+logo.width+(int)centering);
--#endif
--  }
--
--  inline int dialog(const char *title,const char *msg,
--                    const char *button1_txt,const char *button2_txt,const char *button3_txt,
--                    const char *button4_txt,const char *button5_txt,const char *button6_txt,
--                    const bool centering) {
--    return dialog(title,msg,button1_txt,button2_txt,button3_txt,button4_txt,button5_txt,button6_txt,
--                  CImg<unsigned char>::get_logo40x38(),centering);
--  }
--
--
--  // Inner routine used by the Marching cube algorithm
--  template<typename t> inline int _marching_cubes_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
--                                                         const unsigned int x, const unsigned int y, const unsigned int nx, const unsigned int ny) {
--    switch (edge) {
--    case 0: return indices1(x,y,0);
--    case 1: return indices1(nx,y,1);
--    case 2: return indices1(x,ny,0);
--    case 3: return indices1(x,y,1);
--    case 4: return indices2(x,y,0);
--    case 5: return indices2(nx,y,1);
--    case 6: return indices2(x,ny,0);
--    case 7: return indices2(x,y,1);
--    case 8: return indices1(x,y,2);
--    case 9: return indices1(nx,y,2);
--    case 10: return indices1(nx,ny,2);
--    case 11: return indices1(x,ny,2);
--    }
--    return 0;
--  }
--
--  //! Polygonize an implicit function
--  // This function uses the Marching Cubes Tables published on the web page :
--  // http://astronomy.swin.edu.au/~pbourke/modelling/polygonise/
--  template<typename tfunc, typename tp, typename tf>
--  inline void marching_cubes(const tfunc& func, const float isovalue,
--                             const float x0,const float y0,const float z0,
--                             const float x1,const float y1,const float z1,
--                             const float resx,const float resy,const float resz,
--                             CImgList<tp>& points, CImgList<tf>& primitives,
--                             const bool invert_faces) {
--
--    static unsigned int edges[256]={
--      0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
--      0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
--      0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
--      0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
--      0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
--      0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
--      0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
--      0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
--      0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
--      0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
--      0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
--      0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
--      0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
--      0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
--      0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
--      0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 };
--
--    static int triangles[256][16] =
--      {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
--       {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
--       {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
--       {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
--       {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
--       {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
--       {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
--       {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
--       {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
--       {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
--       {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
--       {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
--       {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
--       {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
--       {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
--       {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
--       {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
--       {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
--       {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
--       {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
--       {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
--       {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
--       {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
--       {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
--       {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
--       {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
--       {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
--       {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
--       {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
--       {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
--       {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
--       {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
--       {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
--       {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
--       {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
--       {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
--       {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
--       {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
--       {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
--       {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
--       {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
--       {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
--       {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
--       {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
--       {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
--       {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
--       {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
--       {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
--       {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
--       {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
--       {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
--       {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
--       {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
--       {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
--       {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
--       {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
--       {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
--       {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
--       {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
--       {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
--       {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
--       {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
--       {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
--       {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
--       {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
--       {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
--       {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
--       {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
--       {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
--       {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
--       {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
--       {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
--       {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
--       {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
--       {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
--       {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
--       {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
--       {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
--       {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
--       {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
--       {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
--       {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
--       {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
--       {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
--       {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
--       {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
--       {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
--       {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
--       {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
--       {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
--       {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
--       {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
--       {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
--       {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
--       {0, 3, 8, -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}};
--
--    const unsigned int
--      nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
--      ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1,
--      nz = (unsigned int)((z1-z0+1)/resz), nzm1 = nz-1;
--
--    if (!nxm1 || !nym1 || !nzm1) return;
--
--    CImg<int> indices1(nx,ny,1,3,-1), indices2(indices1);
--    CImg<float> values1(nx,ny), values2(nx,ny);
--    float X=0, Y=0, Z=0, nX=0, nY=0, nZ=0;
--
--    // Fill the first plane with function values
--    Y=y0;
--    cimg_forY(values1,y) {
--      X = x0;
--      cimg_forX(values1,x) { values1(x,y) = (float)func(X,Y,z0); X+=resx; }
--      Y+=resy;
--    }
--
--    // Run Marching Cubes algorithm
--    Z = z0; nZ = Z + resz;
--    for (unsigned int zi=0; zi<nzm1; ++zi, Z=nZ, nZ+=resz) {
--      Y = y0; nY = Y + resy;
--      indices2.fill(-1);
--      for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
--        X = x0; nX = X + resx;
--        for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
--
--          // Determine cube configuration
--          const float
--            val0 = values1(xi,yi), val1 = values1(nxi,yi), val2 = values1(nxi,nyi), val3 = values1(xi,nyi),
--            val4 = values2(xi,yi) = (float)func(X,Y,nZ),
--            val5 = values2(nxi,yi) = (float)func(nX,Y,nZ),
--            val6 = values2(nxi,nyi) = (float)func(nX,nY,nZ),
--            val7 = values2(xi,nyi) = (float)func(X,nY,nZ);
--
--          const unsigned int configuration =
--            (val0<isovalue?1:0)  | (val1<isovalue?2:0)  | (val2<isovalue?4:0)  | (val3<isovalue?8:0) |
--            (val4<isovalue?16:0) | (val5<isovalue?32:0) | (val6<isovalue?64:0) | (val7<isovalue?128:0),
--            edge = edges[configuration];
--
--          // Compute intersection points
--          if (edge) {
--            if ((edge&1) && indices1(xi,yi,0)<0) {
--              const float Xi = X + (isovalue-val0)*resx/(val1-val0);
--              indices1(xi,yi,0) = points.size;
--              points.insert(CImg<tp>::vector(Xi,Y,Z));
--            }
--            if ((edge&2) && indices1(nxi,yi,1)<0) {
--              const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
--              indices1(nxi,yi,1) = points.size;
--              points.insert(CImg<tp>::vector(nX,Yi,Z));
--            }
--            if ((edge&4) && indices1(xi,nyi,0)<0) {
--              const float Xi = X + (isovalue-val3)*resx/(val2-val3);
--              indices1(xi,nyi,0) = points.size;
--              points.insert(CImg<tp>::vector(Xi,nY,Z));
--            }
--            if ((edge&8) && indices1(xi,yi,1)<0) {
--              const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
--              indices1(xi,yi,1) = points.size;
--              points.insert(CImg<tp>::vector(X,Yi,Z));
--            }
--            if ((edge&16) && indices2(xi,yi,0)<0) {
--              const float Xi = X + (isovalue-val4)*resx/(val5-val4);
--              indices2(xi,yi,0) = points.size;
--              points.insert(CImg<tp>::vector(Xi,Y,nZ));
--            }
--            if ((edge&32) && indices2(nxi,yi,1)<0) {
--              const float Yi = Y + (isovalue-val5)*resy/(val6-val5);
--              indices2(nxi,yi,1) = points.size;
--              points.insert(CImg<tp>::vector(nX,Yi,nZ));
--            }
--            if ((edge&64) && indices2(xi,nyi,0)<0) {
--              const float Xi = X + (isovalue-val7)*resx/(val6-val7);
--              indices2(xi,nyi,0) = points.size;
--              points.insert(CImg<tp>::vector(Xi,nY,nZ));
--            }
--            if ((edge&128) && indices2(xi,yi,1)<0)  {
--              const float Yi = Y + (isovalue-val4)*resy/(val7-val4);
--              indices2(xi,yi,1) = points.size;
--              points.insert(CImg<tp>::vector(X,Yi,nZ));
--            }
--            if ((edge&256) && indices1(xi,yi,2)<0) {
--              const float Zi = Z+ (isovalue-val0)*resz/(val4-val0);
--              indices1(xi,yi,2) = points.size;
--              points.insert(CImg<tp>::vector(X,Y,Zi));
--            }
--            if ((edge&512) && indices1(nxi,yi,2)<0)  {
--              const float Zi = Z + (isovalue-val1)*resz/(val5-val1);
--              indices1(nxi,yi,2) = points.size;
--              points.insert(CImg<tp>::vector(nX,Y,Zi));
--            }
--            if ((edge&1024) && indices1(nxi,nyi,2)<0) {
--              const float Zi = Z + (isovalue-val2)*resz/(val6-val2);
--              indices1(nxi,nyi,2) = points.size;
--              points.insert(CImg<tp>::vector(nX,nY,Zi));
--            }
--            if ((edge&2048) && indices1(xi,nyi,2)<0) {
--              const float Zi = Z + (isovalue-val3)*resz/(val7-val3);
--              indices1(xi,nyi,2) = points.size;
--              points.insert(CImg<tp>::vector(X,nY,Zi));
--            }
--
--            // Create triangles
--            for (int *triangle=triangles[configuration]; *triangle!=-1; ) {
--              const unsigned int p0 = *(triangle++), p1 = *(triangle++), p2 = *(triangle++);
--              const tf
--                i0 = (tf)(_marching_cubes_indice(p0,indices1,indices2,xi,yi,nxi,nyi)),
--                i1 = (tf)(_marching_cubes_indice(p1,indices1,indices2,xi,yi,nxi,nyi)),
--                i2 = (tf)(_marching_cubes_indice(p2,indices1,indices2,xi,yi,nxi,nyi));
--              if (invert_faces) primitives.insert(CImg<tf>::vector(i0,i1,i2));
--              else primitives.insert(CImg<tf>::vector(i0,i2,i1));
--            }
--          }
--        }
--      }
--      cimg::swap(values1,values2);
--      cimg::swap(indices1,indices2);
--    }
--  }
--
--  // Inner routine used by the Marching square algorithm
--  template<typename t> inline int _marching_squares_indice(const unsigned int edge, const CImg<t>& indices1, const CImg<t>& indices2,
--                                                           const unsigned int x, const unsigned int nx) {
--    switch (edge) {
--    case 0: return (int)indices1(x,0);
--    case 1: return (int)indices1(nx,1);
--    case 2: return (int)indices2(x,0);
--    case 3: return (int)indices1(x,1);
--    }
--    return 0;
--  }
--
--  //! Polygonize an implicit 2D function by the marching squares algorithm
--  template<typename tfunc, typename tp, typename tf>
--  inline void marching_squares(const tfunc& func, const float isovalue,
--                               const float x0,const float y0,
--                               const float x1,const float y1,
--                               const float resx,const float resy,
--                               CImgList<tp>& points, CImgList<tf>& primitives) {
--
--    static unsigned int edges[16]={ 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 };
--    static int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 },
--                                   { 1,2,-1,-1 },   { 0,1,2,3 },   { 0,2,-1,-1 }, { 2,3,-1,-1 },
--                                   { 2,3,-1,-1 },   { 0,2,-1,-1},  { 0,3,1,2 },   { 1,2,-1,-1 },
--                                   { 1,3,-1,-1 },   { 0,1,-1,-1},  { 0,3,-1,-1},  { -1,-1,-1,-1 } };
--    const unsigned int
--      nx = (unsigned int)((x1-x0+1)/resx), nxm1 = nx-1,
--      ny = (unsigned int)((y1-y0+1)/resy), nym1 = ny-1;
--
--    if (!nxm1 || !nym1) return;
--
--    CImg<int> indices1(nx,1,1,2,-1), indices2(nx,1,1,2);
--    CImg<float> values1(nx), values2(nx);
--    float X = 0, Y = 0, nX = 0, nY = 0;
--
--    // Fill first line with values
--    cimg_forX(values1,x) { values1(x) = (float)func(X,Y); X+=resx; }
--
--    // Run the marching squares algorithm
--    Y = y0; nY = Y + resy;
--    for (unsigned int yi=0, nyi=1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=resy) {
--      X = x0; nX = X + resx;
--      indices2.fill(-1);
--      for (unsigned int xi=0, nxi=1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=resx) {
--
--        // Determine cube configuration
--        const float
--          val0 = values1(xi), val1 = values1(nxi),
--          val2 = values2(nxi) = (float)func(nX,nY),
--          val3 = values2(xi) = (float)func(X,nY);
--
--        const unsigned int configuration = (val0<isovalue?1:0)  | (val1<isovalue?2:0)  | (val2<isovalue?4:0)  | (val3<isovalue?8:0),
--          edge = edges[configuration];
--
--        // Compute intersection points
--        if (edge) {
--          if ((edge&1) && indices1(xi,0)<0) {
--            const float Xi = X + (isovalue-val0)*resx/(val1-val0);
--            indices1(xi,0) = points.size;
--            points.insert(CImg<tp>::vector(Xi,Y));
--          }
--          if ((edge&2) && indices1(nxi,1)<0) {
--            const float Yi = Y + (isovalue-val1)*resy/(val2-val1);
--            indices1(nxi,1) = points.size;
--            points.insert(CImg<tp>::vector(nX,Yi));
--          }
--          if ((edge&4) && indices2(xi,0)<0) {
--            const float Xi = X + (isovalue-val3)*resx/(val2-val3);
--            indices2(xi,0) = points.size;
--            points.insert(CImg<tp>::vector(Xi,nY));
--          }
--          if ((edge&8) && indices1(xi,1)<0) {
--            const float Yi = Y + (isovalue-val0)*resy/(val3-val0);
--            indices1(xi,1) = points.size;
--            points.insert(CImg<tp>::vector(X,Yi));
--          }
--
--          // Create segments
--          for (int *segment=segments[configuration]; *segment!=-1; ) {
--            const unsigned int p0 = *(segment++), p1 = *(segment++);
--            const tf
--              i0 = (tf)(_marching_squares_indice(p0,indices1,indices2,xi,nxi)),
--              i1 = (tf)(_marching_squares_indice(p1,indices1,indices2,xi,nxi));
--            primitives.insert(CImg<tf>::vector(i0,i1));
--          }
--        }
--      }
--      values1.swap(values2);
--      indices1.swap(indices2);
--    }
--  }
--
--  // End of cimg:: namespace
--}
--
--
--  // End of cimg_library:: namespace
--}
--
--#ifdef std
--#undef std
--#endif
--
--#endif
--
--// Local Variables:
--// mode: c++
--// End:
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/dummy2.cc vips-7.38.5/libvips/cimg/dummy2.cc
---- vips-7.38.5-vanilla/libvips/cimg/dummy2.cc 2014-07-17 23:48:36.231794473 -0400
-+++ vips-7.38.5/libvips/cimg/dummy2.cc 1969-12-31 19:00:00.000000000 -0500
-@@ -1,4 +0,0 @@
--/* mac os x libtool needs to link libraries containing c++ (eg. cimg) with 
-- * g++ ... force this with a dummy c++ file at the top level
-- */
--const int im__dummy_value = 42;
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/Makefile.am vips-7.38.5/libvips/cimg/Makefile.am
---- vips-7.38.5-vanilla/libvips/cimg/Makefile.am       2014-07-17 23:48:36.230794473 -0400
-+++ vips-7.38.5/libvips/cimg/Makefile.am       1969-12-31 19:00:00.000000000 -0500
-@@ -1,27 +0,0 @@
--noinst_LTLIBRARIES = libcimg.la
--
--libcimg_la_SOURCES = \
--      CImg.h \
--      cimg_dispatch.c \
--      cimg.cpp 
--
--# various cimg settings as well
--# we need to change these a bit for win32
--if OS_WIN32
--AM_CPPFLAGS = \
--      -Dcimg_strict \
--      -Dcimg_OS=0 \
--      -Dcimg_display_type=0 \
--      -DLOCALEDIR=\""$(LOCALEDIR)"\"
--else
--AM_CPPFLAGS = \
--      -Dcimg_strict \
--      -Dcimg_OS=1 \
--      -Dcimg_display_type=0 \
--      -DLOCALEDIR=\""$(LOCALEDIR)"\"
--endif
--
--# used by the final libvips link rather than us
--EXTRA_DIST = dummy2.cc
--
--AM_CPPFLAGS += -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ 
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/cimg/Makefile.in vips-7.38.5/libvips/cimg/Makefile.in
---- vips-7.38.5-vanilla/libvips/cimg/Makefile.in       2014-07-17 23:48:36.230794473 -0400
-+++ vips-7.38.5/libvips/cimg/Makefile.in       1969-12-31 19:00:00.000000000 -0500
-@@ -1,747 +0,0 @@
--# Makefile.in generated by automake 1.13.3 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994-2013 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@
--am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
--am__make_running_with_option = \
--  case $${target_option-} in \
--      ?) ;; \
--      *) echo "am__make_running_with_option: internal error: invalid" \
--              "target option '$${target_option-}' specified" >&2; \
--         exit 1;; \
--  esac; \
--  has_opt=no; \
--  sane_makeflags=$$MAKEFLAGS; \
--  if $(am__is_gnu_make); then \
--    sane_makeflags=$$MFLAGS; \
--  else \
--    case $$MAKEFLAGS in \
--      *\\[\ \ ]*) \
--        bs=\\; \
--        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
--          | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
--    esac; \
--  fi; \
--  skip_next=no; \
--  strip_trailopt () \
--  { \
--    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
--  }; \
--  for flg in $$sane_makeflags; do \
--    test $$skip_next = yes && { skip_next=no; continue; }; \
--    case $$flg in \
--      *=*|--*) continue;; \
--        -*I) strip_trailopt 'I'; skip_next=yes;; \
--      -*I?*) strip_trailopt 'I';; \
--        -*O) strip_trailopt 'O'; skip_next=yes;; \
--      -*O?*) strip_trailopt 'O';; \
--        -*l) strip_trailopt 'l'; skip_next=yes;; \
--      -*l?*) strip_trailopt 'l';; \
--      -[dEDm]) skip_next=yes;; \
--      -[JT]) skip_next=yes;; \
--    esac; \
--    case $$flg in \
--      *$$target_option*) has_opt=yes; break;; \
--    esac; \
--  done; \
--  test $$has_opt = yes
--am__make_dryrun = (target_option=n; $(am__make_running_with_option))
--am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@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@
--subdir = libvips/cimg
--DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
--      $(top_srcdir)/depcomp
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
--      $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/acinclude.m4 \
--      $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
--      $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--LTLIBRARIES = $(noinst_LTLIBRARIES)
--libcimg_la_LIBADD =
--am_libcimg_la_OBJECTS = cimg_dispatch.lo cimg.lo
--libcimg_la_OBJECTS = $(am_libcimg_la_OBJECTS)
--AM_V_lt = $(am__v_lt_@AM_V@)
--am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
--am__v_lt_0 = --silent
--am__v_lt_1 = 
--AM_V_P = $(am__v_P_@AM_V@)
--am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
--am__v_P_0 = false
--am__v_P_1 = :
--AM_V_GEN = $(am__v_GEN_@AM_V@)
--am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
--am__v_GEN_0 = @echo "  GEN     " $@;
--am__v_GEN_1 = 
--AM_V_at = $(am__v_at_@AM_V@)
--am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
--am__v_at_0 = @
--am__v_at_1 = 
--DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
--depcomp = $(SHELL) $(top_srcdir)/depcomp
--am__depfiles_maybe = depfiles
--am__mv = mv -f
--COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
--      $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
--LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
--      $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
--      $(AM_CFLAGS) $(CFLAGS)
--AM_V_CC = $(am__v_CC_@AM_V@)
--am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
--am__v_CC_0 = @echo "  CC      " $@;
--am__v_CC_1 = 
--CCLD = $(CC)
--LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
--      $(AM_LDFLAGS) $(LDFLAGS) -o $@
--AM_V_CCLD = $(am__v_CCLD_@AM_V@)
--am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
--am__v_CCLD_0 = @echo "  CCLD    " $@;
--am__v_CCLD_1 = 
--CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
--      $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
--LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
--      $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
--      $(AM_CXXFLAGS) $(CXXFLAGS)
--AM_V_CXX = $(am__v_CXX_@AM_V@)
--am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
--am__v_CXX_0 = @echo "  CXX     " $@;
--am__v_CXX_1 = 
--CXXLD = $(CXX)
--CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
--      $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
--AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
--am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
--am__v_CXXLD_0 = @echo "  CXXLD   " $@;
--am__v_CXXLD_1 = 
--SOURCES = $(libcimg_la_SOURCES)
--DIST_SOURCES = $(libcimg_la_SOURCES)
--am__can_run_installinfo = \
--  case $$AM_UPDATE_INFO_DIR in \
--    n|no|NO) false;; \
--    *) (install-info --version) >/dev/null 2>&1;; \
--  esac
--am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
--# Read a list of newline-separated strings from the standard input,
--# and print each of them once, without duplicates.  Input order is
--# *not* preserved.
--am__uniquify_input = $(AWK) '\
--  BEGIN { nonempty = 0; } \
--  { items[$$0] = 1; nonempty = 1; } \
--  END { if (nonempty) { for (i in items) print i; }; } \
--'
--# Make sure the list of sources is unique.  This is necessary because,
--# e.g., the same source file might be shared among _SOURCES variables
--# for different programs/libraries.
--am__define_uniq_tagged_files = \
--  list='$(am__tagged_files)'; \
--  unique=`for i in $$list; do \
--    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
--  done | $(am__uniquify_input)`
--ETAGS = etags
--CTAGS = ctags
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
--AR = @AR@
--AS = @AS@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CATALOGS = @CATALOGS@
--CATOBJEXT = @CATOBJEXT@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFITSIO_CFLAGS = @CFITSIO_CFLAGS@
--CFITSIO_LIBS = @CFITSIO_LIBS@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CXX = @CXX@
--CXXCPP = @CXXCPP@
--CXXDEPMODE = @CXXDEPMODE@
--CXXFLAGS = @CXXFLAGS@
--CYGPATH_W = @CYGPATH_W@
--DATADIRNAME = @DATADIRNAME@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DLLTOOL = @DLLTOOL@
--DLLWRAP = @DLLWRAP@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--EXEEXT = @EXEEXT@
--EXIF_CFLAGS = @EXIF_CFLAGS@
--EXIF_LIBS = @EXIF_LIBS@
--FFTW_CFLAGS = @FFTW_CFLAGS@
--FFTW_LIBS = @FFTW_LIBS@
--FGREP = @FGREP@
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--GMOFILES = @GMOFILES@
--GMSGFMT = @GMSGFMT@
--GREP = @GREP@
--GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
--GTHREAD_LIBS = @GTHREAD_LIBS@
--GTKDOC_CHECK = @GTKDOC_CHECK@
--GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
--GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
--GTKDOC_MKPDF = @GTKDOC_MKPDF@
--GTKDOC_REBASE = @GTKDOC_REBASE@
--HTML_DIR = @HTML_DIR@
--IMAGE_MAGICK_CFLAGS = @IMAGE_MAGICK_CFLAGS@
--IMAGE_MAGICK_LIBS = @IMAGE_MAGICK_LIBS@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--INSTOBJEXT = @INSTOBJEXT@
--INTLLIBS = @INTLLIBS@
--INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
--INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
--INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
--INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
--INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
--INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
--INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
--INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
--JPEG_INCLUDES = @JPEG_INCLUDES@
--JPEG_LIBS = @JPEG_LIBS@
--LCMS_CFLAGS = @LCMS_CFLAGS@
--LCMS_LIBS = @LCMS_LIBS@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBRARY_AGE = @LIBRARY_AGE@
--LIBRARY_CURRENT = @LIBRARY_CURRENT@
--LIBRARY_REVISION = @LIBRARY_REVISION@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
--LIBWEBP_LIBS = @LIBWEBP_LIBS@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAGICK_CFLAGS = @MAGICK_CFLAGS@
--MAGICK_LIBS = @MAGICK_LIBS@
--MAGICK_WAND_CFLAGS = @MAGICK_WAND_CFLAGS@
--MAGICK_WAND_LIBS = @MAGICK_WAND_LIBS@
--MAKEINFO = @MAKEINFO@
--MANIFEST_TOOL = @MANIFEST_TOOL@
--MATIO_CFLAGS = @MATIO_CFLAGS@
--MATIO_LIBS = @MATIO_LIBS@
--MKDIR_P = @MKDIR_P@
--MKINSTALLDIRS = @MKINSTALLDIRS@
--MONOTONIC_CFLAGS = @MONOTONIC_CFLAGS@
--MONOTONIC_LIBS = @MONOTONIC_LIBS@
--MSGFMT = @MSGFMT@
--MSGFMT_OPTS = @MSGFMT_OPTS@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
--OPENEXR_LIBS = @OPENEXR_LIBS@
--OPENSLIDE_CFLAGS = @OPENSLIDE_CFLAGS@
--OPENSLIDE_LIBS = @OPENSLIDE_LIBS@
--ORC_CFLAGS = @ORC_CFLAGS@
--ORC_LIBS = @ORC_LIBS@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGES_USED = @PACKAGES_USED@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
--PANGOFT2_LIBS = @PANGOFT2_LIBS@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--PKG_CONFIG = @PKG_CONFIG@
--PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
--PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
--PNG_CFLAGS = @PNG_CFLAGS@
--PNG_INCLUDES = @PNG_INCLUDES@
--PNG_LIBS = @PNG_LIBS@
--POFILES = @POFILES@
--POSUB = @POSUB@
--PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
--PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
--PYTHON = @PYTHON@
--PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
--PYTHON_INCLUDES = @PYTHON_INCLUDES@
--PYTHON_PLATFORM = @PYTHON_PLATFORM@
--PYTHON_PREFIX = @PYTHON_PREFIX@
--PYTHON_VERSION = @PYTHON_VERSION@
--RANLIB = @RANLIB@
--REQUIRED_CFLAGS = @REQUIRED_CFLAGS@
--REQUIRED_LIBS = @REQUIRED_LIBS@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--THREADS_CFLAGS = @THREADS_CFLAGS@
--THREADS_LIBS = @THREADS_LIBS@
--TIFF_CFLAGS = @TIFF_CFLAGS@
--TIFF_INCLUDES = @TIFF_INCLUDES@
--TIFF_LIBS = @TIFF_LIBS@
--TYPE_INIT_CFLAGS = @TYPE_INIT_CFLAGS@
--TYPE_INIT_LIBS = @TYPE_INIT_LIBS@
--USE_NLS = @USE_NLS@
--VERSION = @VERSION@
--VIPS_CFLAGS = @VIPS_CFLAGS@
--VIPS_CXX_LIBS = @VIPS_CXX_LIBS@
--VIPS_EXEEXT = @VIPS_EXEEXT@
--VIPS_INCLUDES = @VIPS_INCLUDES@
--VIPS_LIBDIR = @VIPS_LIBDIR@
--VIPS_LIBS = @VIPS_LIBS@
--VIPS_MAJOR_VERSION = @VIPS_MAJOR_VERSION@
--VIPS_MICRO_VERSION = @VIPS_MICRO_VERSION@
--VIPS_MINOR_VERSION = @VIPS_MINOR_VERSION@
--VIPS_VERSION = @VIPS_VERSION@
--VIPS_VERSION_STRING = @VIPS_VERSION_STRING@
--XGETTEXT = @XGETTEXT@
--XMKMF = @XMKMF@
--X_CFLAGS = @X_CFLAGS@
--X_EXTRA_LIBS = @X_EXTRA_LIBS@
--X_LIBS = @X_LIBS@
--X_PRE_LIBS = @X_PRE_LIBS@
--ZIP_INCLUDES = @ZIP_INCLUDES@
--ZIP_LIBS = @ZIP_LIBS@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_AR = @ac_ct_AR@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_CXX = @ac_ct_CXX@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--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@
--pdfdir = @pdfdir@
--pkgpyexecdir = @pkgpyexecdir@
--pkgpythondir = @pkgpythondir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--pyexecdir = @pyexecdir@
--pythondir = @pythondir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--vips_introspection_sources = @vips_introspection_sources@
--noinst_LTLIBRARIES = libcimg.la
--libcimg_la_SOURCES = \
--      CImg.h \
--      cimg_dispatch.c \
--      cimg.cpp 
--
--@OS_WIN32_FALSE@AM_CPPFLAGS = -Dcimg_strict -Dcimg_OS=1 \
--@OS_WIN32_FALSE@      -Dcimg_display_type=0 \
--@OS_WIN32_FALSE@      -DLOCALEDIR=\""$(LOCALEDIR)"\" \
--@OS_WIN32_FALSE@      -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ \
--@OS_WIN32_FALSE@      @VIPS_INCLUDES@ $(am__empty)
--
--# various cimg settings as well
--# we need to change these a bit for win32
--@OS_WIN32_TRUE@AM_CPPFLAGS = -Dcimg_strict -Dcimg_OS=0 \
--@OS_WIN32_TRUE@       -Dcimg_display_type=0 \
--@OS_WIN32_TRUE@       -DLOCALEDIR=\""$(LOCALEDIR)"\" \
--@OS_WIN32_TRUE@       -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ \
--@OS_WIN32_TRUE@       @VIPS_INCLUDES@ $(am__empty)
--
--# used by the final libvips link rather than us
--EXTRA_DIST = dummy2.cc
--all: all-am
--
--.SUFFIXES:
--.SUFFIXES: .c .cpp .lo .o .obj
--$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
--      @for dep in $?; do \
--        case '$(am__configure_deps)' in \
--          *$$dep*) \
--            ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
--              && { if test -f $@; then exit 0; else break; fi; }; \
--            exit 1;; \
--        esac; \
--      done; \
--      echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libvips/cimg/Makefile'; \
--      $(am__cd) $(top_srcdir) && \
--        $(AUTOMAKE) --foreign libvips/cimg/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
--      @case '$?' in \
--        *config.status*) \
--          cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
--        *) \
--          echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
--          cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
--      esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure:  $(am__configure_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--clean-noinstLTLIBRARIES:
--      -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
--      @list='$(noinst_LTLIBRARIES)'; \
--      locs=`for p in $$list; do echo $$p; done | \
--            sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
--            sort -u`; \
--      test -z "$$locs" || { \
--        echo rm -f $${locs}; \
--        rm -f $${locs}; \
--      }
--
--libcimg.la: $(libcimg_la_OBJECTS) $(libcimg_la_DEPENDENCIES) $(EXTRA_libcimg_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(CXXLINK)  $(libcimg_la_OBJECTS) $(libcimg_la_LIBADD) $(LIBS)
--
--mostlyclean-compile:
--      -rm -f *.$(OBJEXT)
--
--distclean-compile:
--      -rm -f *.tab.c
--
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cimg.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cimg_dispatch.Plo@am__quote@
--
--.c.o:
--@am__fastdepCC_TRUE@  $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCC_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
--
--.c.obj:
--@am__fastdepCC_TRUE@  $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
--@am__fastdepCC_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
--
--.c.lo:
--@am__fastdepCC_TRUE@  $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCC_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCC_FALSE@     DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
--
--.cpp.o:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
--
--.cpp.obj:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
--
--.cpp.lo:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
--
--mostlyclean-libtool:
--      -rm -f *.lo
--
--clean-libtool:
--      -rm -rf .libs _libs
--
--ID: $(am__tagged_files)
--      $(am__define_uniq_tagged_files); mkid -fID $$unique
--tags: tags-am
--TAGS: tags
--
--tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      set x; \
--      here=`pwd`; \
--      $(am__define_uniq_tagged_files); \
--      shift; \
--      if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
--        test -n "$$unique" || unique=$$empty_fix; \
--        if test $$# -gt 0; then \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            "$$@" $$unique; \
--        else \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            $$unique; \
--        fi; \
--      fi
--ctags: ctags-am
--
--CTAGS: ctags
--ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      $(am__define_uniq_tagged_files); \
--      test -z "$(CTAGS_ARGS)$$unique" \
--        || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
--           $$unique
--
--GTAGS:
--      here=`$(am__cd) $(top_builddir) && pwd` \
--        && $(am__cd) $(top_srcdir) \
--        && gtags -i $(GTAGS_ARGS) "$$here"
--cscopelist: cscopelist-am
--
--cscopelist-am: $(am__tagged_files)
--      list='$(am__tagged_files)'; \
--      case "$(srcdir)" in \
--        [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
--        *) sdir=$(subdir)/$(srcdir) ;; \
--      esac; \
--      for i in $$list; do \
--        if test -f "$$i"; then \
--          echo "$(subdir)/$$i"; \
--        else \
--          echo "$$sdir/$$i"; \
--        fi; \
--      done >> $(top_builddir)/cscope.files
--
--distclean-tags:
--      -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
--
--distdir: $(DISTFILES)
--      @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 "$(distdir)/$$file"; then \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
--            cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
--        else \
--          test -f "$(distdir)/$$file" \
--          || cp -p $$d/$$file "$(distdir)/$$file" \
--          || exit 1; \
--        fi; \
--      done
--check-am: all-am
--check: check-am
--all-am: Makefile $(LTLIBRARIES)
--installdirs:
--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:
--      if test -z '$(STRIP)'; then \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--            install; \
--      else \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--          "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
--      fi
--mostlyclean-generic:
--
--clean-generic:
--
--distclean-generic:
--      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
--      -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
--      @echo "This command is intended for maintainers to use"
--      @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
--      mostlyclean-am
--
--distclean: distclean-am
--      -rm -rf ./$(DEPDIR)
--      -rm -f Makefile
--distclean-am: clean-am distclean-compile distclean-generic \
--      distclean-tags
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am:
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
--      -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:
--
--.MAKE: install-am install-strip
--
--.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
--      clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
--      ctags-am distclean distclean-compile distclean-generic \
--      distclean-libtool distclean-tags distdir dvi dvi-am html \
--      html-am info info-am install install-am install-data \
--      install-data-am install-dvi install-dvi-am install-exec \
--      install-exec-am install-html install-html-am install-info \
--      install-info-am install-man install-pdf install-pdf-am \
--      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 tags-am uninstall uninstall-am
--
--
--# 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 -u --recursive --new-file vips-7.38.5-vanilla/libvips/Makefile.am vips-7.38.5/libvips/Makefile.am
---- vips-7.38.5-vanilla/libvips/Makefile.am    2014-07-17 23:48:36.231794473 -0400
-+++ vips-7.38.5/libvips/Makefile.am    2014-07-17 23:49:32.819792979 -0400
-@@ -1,13 +1,5 @@
--# only build in the cimg dir if C++ is enabled
--if ENABLE_CXX
--C_COMPILE_DIR = cimg
--C_DIST_DIR =
--C_LIB = cimg/libcimg.la
--else
- C_COMPILE_DIR =
--C_DIST_DIR = cimg
- C_LIB = 
--endif
- SUBDIRS = \
-       include \
-@@ -34,14 +26,6 @@
- # empty means default to C linking
- libvips_la_SOURCES = 
--# if we have C++ components enabled, make sure we link the top-level with c++
--#
--# sadly the if/endif isn't enough to stop automake detecting a c++ link even
--# when c++ is disabled ... comment out this line if you have linking problems
--if ENABLE_CXX
--nodist_EXTRA_libvips_la_SOURCES = cimg/dummy2.cc
--endif
--
- # DLLs need dependant libs there too ... put @VIPS_LIBS@ at the end
- libvips_la_LIBADD = \
-       resample/libresample.la \
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/Makefile.in vips-7.38.5/libvips/Makefile.in
---- vips-7.38.5-vanilla/libvips/Makefile.in    2014-07-17 23:48:36.231794473 -0400
-+++ vips-7.38.5/libvips/Makefile.in    2014-07-17 23:49:32.819792979 -0400
-@@ -142,7 +142,7 @@
- am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
- am__v_lt_0 = --silent
- am__v_lt_1 = 
--libvips_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-+libvips_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-       $(CXXFLAGS) $(libvips_la_LDFLAGS) $(LDFLAGS) -o $@
- AM_V_P = $(am__v_P_@AM_V@)
-@@ -163,7 +163,7 @@
- am__mv = mv -f
- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
--LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
-       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-       $(AM_CXXFLAGS) $(CXXFLAGS)
-@@ -172,7 +172,7 @@
- am__v_CXX_0 = @echo "  CXX     " $@;
- am__v_CXX_1 = 
- CXXLD = $(CXX)
--CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
-+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
-       $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
- AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
-@@ -667,11 +667,11 @@
- @am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
- dummy2.lo: cimg/dummy2.cc
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dummy2.lo -MD -MP -MF $(DEPDIR)/dummy2.Tpo -c -o dummy2.lo `test -f 'cimg/dummy2.cc' || echo '$(srcdir)/'`cimg/dummy2.cc
-+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dummy2.lo -MD -MP -MF $(DEPDIR)/dummy2.Tpo -c -o dummy2.lo `test -f 'cimg/dummy2.cc' || echo '$(srcdir)/'`cimg/dummy2.cc
- @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dummy2.Tpo $(DEPDIR)/dummy2.Plo
- @AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='cimg/dummy2.cc' object='dummy2.lo' libtool=yes @AMDEPBACKSLASH@
- @AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dummy2.lo `test -f 'cimg/dummy2.cc' || echo '$(srcdir)/'`cimg/dummy2.cc
-+@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dummy2.lo `test -f 'cimg/dummy2.cc' || echo '$(srcdir)/'`cimg/dummy2.cc
- mostlyclean-libtool:
-       -rm -f *.lo
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/bicubic.cpp vips-7.38.5/libvips/resample/bicubic.cpp
---- vips-7.38.5-vanilla/libvips/resample/bicubic.cpp   2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/bicubic.cpp   1969-12-31 19:00:00.000000000 -0500
-@@ -1,459 +0,0 @@
--/* bicubic (catmull-rom) interpolator
-- *
-- * 12/8/10
-- *    - revise window_size / window_offset stuff again
-- */
--
--/*
--
--    This file is part of VIPS.
--
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--/* Bicubic (Catmull-Rom) interpolator derived from Nicolas Robidoux's
-- * original YAFR resampler with permission and thanks.
-- */
--
--/*
--#define DEBUG
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <stdio.h>
--#include <stdlib.h>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--#include "templates.h"
--
--#ifdef WITH_DMALLOC
--#include <dmalloc.h>
--#endif /*WITH_DMALLOC*/
--
--#define VIPS_TYPE_INTERPOLATE_BICUBIC \
--      (vips_interpolate_bicubic_get_type())
--#define VIPS_INTERPOLATE_BICUBIC( obj ) \
--      (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
--      VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubic ))
--#define VIPS_INTERPOLATE_BICUBIC_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_CAST( (klass), \
--      VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass))
--#define VIPS_IS_INTERPOLATE_BICUBIC( obj ) \
--      (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_BICUBIC ))
--#define VIPS_IS_INTERPOLATE_BICUBIC_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_BICUBIC ))
--#define VIPS_INTERPOLATE_BICUBIC_GET_CLASS( obj ) \
--      (G_TYPE_INSTANCE_GET_CLASS( (obj), \
--      VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass ))
--
--typedef VipsInterpolate VipsInterpolateBicubic;
--
--typedef VipsInterpolateClass VipsInterpolateBicubicClass;
--
--/* Precalculated interpolation matrices. int (used for pel
-- * sizes up to short), and double (for all others). We go to
-- * scale + 1 so we can round-to-nearest safely.
-- */
--
--/* We could keep a large set of 2d 4x4 matricies, but this actually
-- * works out slower since for many resizes the thing will no longer
-- * fit in L1.
-- */
--static int vips_bicubic_matrixi[VIPS_TRANSFORM_SCALE + 1][4];
--static double vips_bicubic_matrixf[VIPS_TRANSFORM_SCALE + 1][4];
--
--/* We need C linkage for this.
-- */
--extern "C" {
--G_DEFINE_TYPE( VipsInterpolateBicubic, vips_interpolate_bicubic,
--      VIPS_TYPE_INTERPOLATE );
--}
--
--/* Pointers to write to / read from, number of bands,
-- * how many bytes to add to move down a line.
-- */
--
--/* T is the type of pixels we are reading and writing.
-- */
--
--/* Fixed-point version, for 8 and 16-bit types.
-- */
--template <typename T, int min_value, int max_value>
--static void inline
--bicubic_int_tab( void *pout, const VipsPel *pin,
--      const int bands, const int lskip,
--      const int *cx, const int *cy )
--{
--      T* restrict out = (T *) pout;
--      const T* restrict in = (T *) pin;
--
--      const int b1 = bands;
--      const int b2 = b1 + b1;
--      const int b3 = b1 + b2;
--
--      const int l1 = lskip / sizeof( T );
--      const int l2 = l1 + l1;
--      const int l3 = l1 + l2;
--
--        const int l1_plus_b1 = l1 + b1;
--        const int l1_plus_b2 = l1 + b2;
--        const int l1_plus_b3 = l1 + b3;
--        const int l2_plus_b1 = l2 + b1;
--        const int l2_plus_b2 = l2 + b2;
--        const int l2_plus_b3 = l2 + b3;
--        const int l3_plus_b1 = l3 + b1;
--        const int l3_plus_b2 = l3 + b2;
--        const int l3_plus_b3 = l3 + b3;
--
--      for( int z = 0; z < bands; z++ ) {
--              const T uno_one = in[0];
--              const T uno_two = in[b1];
--              const T uno_thr = in[b2];
--              const T uno_fou = in[b3];
--
--              const T dos_one = in[l1];
--              const T dos_two = in[l1_plus_b1];
--              const T dos_thr = in[l1_plus_b2];
--              const T dos_fou = in[l1_plus_b3];
--
--              const T tre_one = in[l2];
--              const T tre_two = in[l2_plus_b1];
--              const T tre_thr = in[l2_plus_b2];
--              const T tre_fou = in[l2_plus_b3];
--
--              const T qua_one = in[l3];
--              const T qua_two = in[l3_plus_b1];
--              const T qua_thr = in[l3_plus_b2];
--              const T qua_fou = in[l3_plus_b3];
--
--              int bicubic = bicubic_int<T>(
--                      uno_one, uno_two, uno_thr, uno_fou,
--                      dos_one, dos_two, dos_thr, dos_fou,
--                      tre_one, tre_two, tre_thr, tre_fou,
--                      qua_one, qua_two, qua_thr, qua_fou,
--                      cx, cy );
--
--              if( bicubic < min_value )
--                      bicubic = min_value;
--              else if( bicubic > max_value )
--                      bicubic = max_value;
--
--              out[z] = bicubic;
--
--              in += 1;
--      }
--}
--
--/* Floating-point version, for int/float types.
-- */
--template <typename T>
--static void inline
--bicubic_float_tab( void *pout, const VipsPel *pin,
--      const int bands, const int lskip,
--      const double *cx, const double *cy )
--{
--      T* restrict out = (T *) pout;
--      const T* restrict in = (T *) pin;
--
--      const int b1 = bands;
--      const int b2 = b1 + b1;
--      const int b3 = b1 + b2;
--
--      const int l1 = lskip / sizeof( T );
--      const int l2 = l1 + l1;
--      const int l3 = l1 + l2;
--
--        const int l1_plus_b1 = l1 + b1;
--        const int l1_plus_b2 = l1 + b2;
--        const int l1_plus_b3 = l1 + b3;
--        const int l2_plus_b1 = l2 + b1;
--        const int l2_plus_b2 = l2 + b2;
--        const int l2_plus_b3 = l2 + b3;
--        const int l3_plus_b1 = l3 + b1;
--        const int l3_plus_b2 = l3 + b2;
--        const int l3_plus_b3 = l3 + b3;
--
--      for( int z = 0; z < bands; z++ ) {
--              const T uno_one = in[0];
--              const T uno_two = in[b1];
--              const T uno_thr = in[b2];
--              const T uno_fou = in[b3];
--
--              const T dos_one = in[l1];
--              const T dos_two = in[l1_plus_b1];
--              const T dos_thr = in[l1_plus_b2];
--              const T dos_fou = in[l1_plus_b3];
--
--              const T tre_one = in[l2];
--              const T tre_two = in[l2_plus_b1];
--              const T tre_thr = in[l2_plus_b2];
--              const T tre_fou = in[l2_plus_b3];
--
--              const T qua_one = in[l3];
--              const T qua_two = in[l3_plus_b1];
--              const T qua_thr = in[l3_plus_b2];
--              const T qua_fou = in[l3_plus_b3];
--
--              const T bicubic = bicubic_float<T>(
--                      uno_one, uno_two, uno_thr, uno_fou,
--                      dos_one, dos_two, dos_thr, dos_fou,
--                      tre_one, tre_two, tre_thr, tre_fou,
--                      qua_one, qua_two, qua_thr, qua_fou,
--                      cx, cy );
--
--              out[z] = bicubic;
--
--              in += 1;
--      }
--}
--
--/* Ultra-high-quality version for double images.
-- */
--template <typename T>
--static void inline
--bicubic_notab( void *pout, const VipsPel *pin,
--      const int bands, const int lskip,
--      double x, double y )
--{
--      T* restrict out = (T *) pout;
--      const T* restrict in = (T *) pin;
--
--      const int b1 = bands;
--      const int b2 = b1 + b1;
--      const int b3 = b1 + b2;
--
--      const int l1 = lskip / sizeof( T );
--      const int l2 = l1 + l1;
--      const int l3 = l1 + l2;
--
--        const int l1_plus_b1 = l1 + b1;
--        const int l1_plus_b2 = l1 + b2;
--        const int l1_plus_b3 = l1 + b3;
--        const int l2_plus_b1 = l2 + b1;
--        const int l2_plus_b2 = l2 + b2;
--        const int l2_plus_b3 = l2 + b3;
--        const int l3_plus_b1 = l3 + b1;
--        const int l3_plus_b2 = l3 + b2;
--        const int l3_plus_b3 = l3 + b3;
--
--      double cx[4];
--      double cy[4];
--
--      calculate_coefficients_catmull( x, cx );
--      calculate_coefficients_catmull( y, cy );
--
--      for( int z = 0; z < bands; z++ ) {
--              const T uno_one = in[0];
--              const T uno_two = in[b1];
--              const T uno_thr = in[b2];
--              const T uno_fou = in[b3];
--
--              const T dos_one = in[l1];
--              const T dos_two = in[l1_plus_b1];
--              const T dos_thr = in[l1_plus_b2];
--              const T dos_fou = in[l1_plus_b3];
--
--              const T tre_one = in[l2];
--              const T tre_two = in[l2_plus_b1];
--              const T tre_thr = in[l2_plus_b2];
--              const T tre_fou = in[l2_plus_b3];
--
--              const T qua_one = in[l3];
--              const T qua_two = in[l3_plus_b1];
--              const T qua_thr = in[l3_plus_b2];
--              const T qua_fou = in[l3_plus_b3];
--
--              const T bicubic = bicubic_float<T>(
--                      uno_one, uno_two, uno_thr, uno_fou,
--                      dos_one, dos_two, dos_thr, dos_fou,
--                      tre_one, tre_two, tre_thr, tre_fou,
--                      qua_one, qua_two, qua_thr, qua_fou,
--                      cx, cy );
--
--              out[z] = bicubic;
--
--              in += 1;
--      }
--}
--
--static void
--vips_interpolate_bicubic_interpolate( VipsInterpolate *interpolate,
--      void *out, VipsRegion *in, double x, double y )
--{
--      /* Find the mask index. We round-to-nearest, so we need to generate 
--       * indexes in 0 to VIPS_TRANSFORM_SCALE, 2^n + 1 values. We multiply 
--       * by 2 more than we need to, add one, mask, then shift down again to 
--       * get the extra range.
--       */
--      const int sx = x * VIPS_TRANSFORM_SCALE * 2;
--      const int sy = y * VIPS_TRANSFORM_SCALE * 2;
--
--      const int six = sx & (VIPS_TRANSFORM_SCALE * 2 - 1);
--      const int siy = sy & (VIPS_TRANSFORM_SCALE * 2 - 1);
--
--      const int tx = (six + 1) >> 1;
--      const int ty = (siy + 1) >> 1;
--
--      /* We know x/y are always positive, so we can just (int) them. 
--       */
--      const int ix = (int) x;
--      const int iy = (int) y;
--
--      /* Back and up one to get the top-left of the 4x4.
--       */
--      const VipsPel *p = VIPS_REGION_ADDR( in, ix - 1, iy - 1 ); 
--
--      /* Look up the tables we need.
--       */
--      const int *cxi = vips_bicubic_matrixi[tx];
--      const int *cyi = vips_bicubic_matrixi[ty];
--      const double *cxf = vips_bicubic_matrixf[tx];
--      const double *cyf = vips_bicubic_matrixf[ty];
--
--      /* Pel size and line size.
--       */
--      const int bands = in->im->Bands;
--      const int lskip = VIPS_REGION_LSKIP( in );
--
--#ifdef DEBUG
--      printf( "vips_interpolate_bicubic_interpolate: %g %g\n", x, y );
--      printf( "\tleft=%d, top=%d, width=%d, height=%d\n",
--              ix - 1, iy - 1, 4, 4 );
--      printf( "\tmaskx=%d, masky=%d\n", tx, ty );
--#endif /*DEBUG*/
--
--      switch( in->im->BandFmt ) {
--      case VIPS_FORMAT_UCHAR:
--              bicubic_int_tab<unsigned char, 0, UCHAR_MAX>(
--                      out, p, bands, lskip,
--                      cxi, cyi );
--      /*
--
--         Handy for benchmarking
--
--              bicubic_float_tab<unsigned char>(
--                      out, p, bands, lskip,
--                      cxf, cyf );
--              bicubic_notab<unsigned char>(
--                      out, p, bands, lskip,
--                      x - ix, y - iy );
--
--       */
--              break;
--
--      case VIPS_FORMAT_CHAR:
--              bicubic_int_tab<signed char, SCHAR_MIN, SCHAR_MAX>(
--                      out, p, bands, lskip,
--                      cxi, cyi );
--              break;
--
--      case VIPS_FORMAT_USHORT:
--              bicubic_int_tab<unsigned short, 0, USHRT_MAX>(
--                      out, p, bands, lskip,
--                      cxi, cyi );
--              break;
--
--      case VIPS_FORMAT_SHORT:
--              bicubic_int_tab<signed short, SHRT_MIN, SHRT_MAX>(
--                      out, p, bands, lskip,
--                      cxi, cyi );
--              break;
--
--      case VIPS_FORMAT_UINT:
--              bicubic_float_tab<unsigned int>( out, p, bands, lskip,
--                      cxf, cyf );
--              break;
--
--      case VIPS_FORMAT_INT:
--              bicubic_float_tab<signed int>( out, p, bands, lskip,
--                      cxf, cyf );
--              break;
--
--      case VIPS_FORMAT_FLOAT:
--              bicubic_float_tab<float>( out, p, bands, lskip,
--                      cxf, cyf );
--              break;
--
--      case VIPS_FORMAT_DOUBLE:
--              bicubic_notab<double>( out, p, bands, lskip,
--                      x - ix, y - iy );
--              break;
--
--      case VIPS_FORMAT_COMPLEX:
--              bicubic_float_tab<float>( out, p, bands * 2, lskip,
--                      cxf, cyf );
--              break;
--
--      case VIPS_FORMAT_DPCOMPLEX:
--              bicubic_notab<double>( out, p, bands * 2, lskip,
--                      x - ix, y - iy );
--              break;
--
--      default:
--              break;
--      }
--}
--
--static void
--vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass )
--{
--      VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass );
--      VipsInterpolateClass *interpolate_class =
--              VIPS_INTERPOLATE_CLASS( iclass );
--
--      object_class->nickname = "bicubic";
--      object_class->description = _( "Bicubic interpolation (Catmull-Rom)" );
--
--      interpolate_class->interpolate = vips_interpolate_bicubic_interpolate;
--      interpolate_class->window_size = 4;
--
--      /* Build the tables of pre-computed coefficients.
--       */
--      for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) {
--              calculate_coefficients_catmull(
--                      (float) x / VIPS_TRANSFORM_SCALE,
--                      vips_bicubic_matrixf[x] );
--
--              for( int i = 0; i < 4; i++ )
--                      vips_bicubic_matrixi[x][i] =
--                              vips_bicubic_matrixf[x][i] * 
--                              VIPS_INTERPOLATE_SCALE;
--      }
--}
--
--static void
--vips_interpolate_bicubic_init( VipsInterpolateBicubic *bicubic )
--{
--#ifdef DEBUG
--      printf( "vips_interpolate_bicubic_init: " );
--      vips_object_print( VIPS_OBJECT( bicubic ) );
--#endif /*DEBUG*/
--
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/lbb.cpp vips-7.38.5/libvips/resample/lbb.cpp
---- vips-7.38.5-vanilla/libvips/resample/lbb.cpp       2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/lbb.cpp       1969-12-31 19:00:00.000000000 -0500
-@@ -1,868 +0,0 @@
--/* lbb (locally bounded bicubic) resampler
-- *
-- * N. Robidoux, C. Racette and J. Cupitt, 23-28/03/2010
-- *
-- * N. Robidoux, 16-19/05/2010
-- *
-- * N. Robidoux, 22/11/2011
-- */
--
--/*
--
--    This file is part of VIPS.
--
--    VIPS is free software; you can redistribute it and/or modify it
--    under the terms of the GNU Lesser 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
--    Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--/*
-- * 2010 (c) Nicolas Robidoux, Chantal Racette, John Cupitt.
-- *
-- * N. Robidoux thanks Adam Turcotte, Geert Jordaens, Ralf Meyer,
-- * Øyvind Kolås, Minglun Gong, Eric Daoust and Sven Neumann for useful
-- * comments and code.
-- *
-- * C. Racette's image resampling research and programming funded in
-- * part by an NSERC (National Science and Engineering Research Council
-- * of Canada) Alexander Graham Bell Canada Graduate Scholarship, by an
-- * NSERC Discovery Grant awarded to Julien Dompierre (grant number
-- * 20-61098) and by N. Robidoux's Laurentian University professional
-- * allowance.
-- */
--
--/*
-- * LBB has two versions:
-- *
-- *   A "soft" version, which shows a little less staircasing and a
-- *   little more haloing, and which is a little more expensive to
-- *   compute. We recommend this as the default.
-- *
-- *   A "sharp" version, which shows a little more staircasing and a
-- *   little less haloing, which is a little cheaper (it uses 6 less
-- *   comparisons and 12 less "? :").
-- *
-- * The only difference between the two is that the "soft" versions
-- * uses local minima and maxima computed over 3x3 square blocks, and
-- * the "sharp" version uses local minima and maxima computed over 3x3
-- * crosses.
-- *
-- * If you want to use the "sharp" version, comment out the following
-- * three pre-processor code lines:
-- */
--/*
--#ifndef __LBB_CHEAP_H__
--#define __LBB_CHEAP_H__
--#endif
--*/
--
--/*
-- * LBB (Locally Bounded Bicubic) is a high quality nonlinear variant
-- * of Catmull-Rom. Images resampled with LBB have much smaller halos
-- * than images resampled with windowed sincs or other interpolatory
-- * cubic spline filters. Specifically, LBB halos are narrower and the
-- * over/undershoot amplitude is smaller. This is accomplished without
-- * significantly affecting the smoothness of the result (compared to
-- * Catmull-Rom).
-- *
-- * Another important property is that the resampled values are
-- * contained within the range of nearby input values. Consequently, no
-- * final clamping is needed to stay "in range" (e.g., 0-255 for
-- * standard 8-bit images).
-- *
-- * LBB was developed by N. Robidoux and C. Racette at the Department
-- * of Mathematics and Computer Science of Laurentian University in the
-- * course of C. Racette's Masters thesis in Computational
-- * Sciences. Preliminary work directly leading to the LBB method and
-- * code was performed by C. Racette and N. Robidoux in the course of
-- * her honours thesis, and by N. Robidoux, A. Turcotte and E. Daoust
-- * during Google Summer of Code 2009 (through two awards made to GIMP
-- * to improve GEGL).
-- *
-- * LBB is a novel method with the following properties:
-- *
-- * --LBB is a Hermite bicubic method: The bicubic surface is defined,
-- *   one convex hull of four nearby input points at a time, using four
-- *   point values, four x-derivatives, four y-derivatives, and four
-- *   cross-derivatives.
-- *
-- * --The stencil for values in a square patch is the usual 4x4.
-- *
-- * --LBB is interpolatory.
-- *
-- * --It is C^1 with continuous cross derivatives.
-- *
-- * --When the limiters are inactive, LBB gives the same result as
-- *   Catmull-Rom.
-- *
-- * --When used on binary images, LBB gives results similar to bicubic
-- *   Hermite with all first derivatives---but not necessarily the
-- *   cross derivatives (this last assertion needs to be double
-- *   checked)--at input pixel locations set to zero.
-- *
-- * --The LBB reconstruction is locally bounded: Over each square
-- *   patch, the surface is contained between the minimum and the
-- *   maximum of the 16 nearest input pixel values.
-- *
-- * --Consequently, the LBB reconstruction is globally bounded between
-- *   the very smallest input pixel value and the very largest input
-- *   pixel value. It is not necessary to clamp results.
-- *
-- * The LBB method is based on the method of Ken Brodlie, Petros
-- * Mashwama and Sohail Butt for constraining Hermite interpolants
-- * between globally defined planes:
-- *
-- *   Visualization of surface data to preserve positivity and other
-- *   simple constraints. Computer & Graphics, Vol. 19, Number 4, pages
-- *   585-594, 1995. DOI: 10.1016/0097-8493(95)00036-C.
-- *
-- * Instead of forcing the reconstructed surface to lie between two
-- * GLOBALLY defined planes, LBB constrains one patch at a time to lie
-- * between LOCALLY defined planes. This is accomplished by
-- * constraining the derivatives (x, y and cross) at each input pixel
-- * location so that if the constraint was applied everywhere the
-- * surface would fit between the min and max of the values at the 9
-- * closest pixel locations. Because this is done with each of the four
-- * pixel locations which define the bicubic patch, this forces the
-- * reconstructed surface to lie between the min and max of the values
-- * at the 16 closest values pixel locations. (Each corner defines its
-- * own 3x3 subgroup of the 4x4 stencil. Consequently, the surface is
-- * necessarily above the minimum of the four minima, which happens to
-- * be the minimum over the 4x4. Similarly with the maxima.)
-- *
-- * The above paragraph described the "soft" version of LBB. The
-- * "sharp" version is similar.
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <stdio.h>
--#include <stdlib.h>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--#include "templates.h"
--
--#define VIPS_TYPE_INTERPOLATE_LBB \
--      (vips_interpolate_lbb_get_type())
--#define VIPS_INTERPOLATE_LBB( obj ) \
--      (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
--      VIPS_TYPE_INTERPOLATE_LBB, VipsInterpolateLbb ))
--#define VIPS_INTERPOLATE_LBB_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_CAST( (klass), \
--      VIPS_TYPE_INTERPOLATE_LBB, VipsInterpolateLbbClass))
--#define VIPS_IS_INTERPOLATE_LBB( obj ) \
--      (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_LBB ))
--#define VIPS_IS_INTERPOLATE_LBB_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_LBB ))
--#define VIPS_INTERPOLATE_LBB_GET_CLASS( obj ) \
--      (G_TYPE_INSTANCE_GET_CLASS( (obj), \
--      VIPS_TYPE_INTERPOLATE_LBB, VipsInterpolateLbbClass ))
--
--typedef struct _VipsInterpolateLbb {
--      VipsInterpolate parent_object;
--
--} VipsInterpolateLbb;
--
--typedef struct _VipsInterpolateLbbClass {
--      VipsInterpolateClass parent_class;
--
--} VipsInterpolateLbbClass;
--
--/*
-- * Absolute value and sign macros:
-- */
--#define LBB_ABS(x)  ( ((x)>=0.) ? (x) : -(x) )
--#define LBB_SIGN(x) ( ((x)>=0.) ? 1.0 : -1.0 )
--/*
-- * MIN and MAX macros set up so that I can put the likely winner in
-- * the first argument (forward branch likely blah blah blah):
-- */
--#define LBB_MIN(x,y) ( ((x)<=(y)) ? (x) : (y) )
--#define LBB_MAX(x,y) ( ((x)>=(y)) ? (x) : (y) )
--
--static inline double
--lbbicubic( const double c00,
--           const double c10,
--           const double c01,
--           const double c11,
--           const double c00dx,
--           const double c10dx,
--           const double c01dx,
--           const double c11dx,
--           const double c00dy,
--           const double c10dy,
--           const double c01dy,
--           const double c11dy,
--           const double c00dxdy,
--           const double c10dxdy,
--           const double c01dxdy,
--           const double c11dxdy,
--           const double uno_one,
--           const double uno_two,
--           const double uno_thr,
--           const double uno_fou,
--           const double dos_one,
--           const double dos_two,
--           const double dos_thr,
--           const double dos_fou,
--           const double tre_one,
--           const double tre_two,
--           const double tre_thr,
--           const double tre_fou,
--           const double qua_one,
--           const double qua_two,
--           const double qua_thr,
--           const double qua_fou )
--{
--  /*
--   * STENCIL (FOOTPRINT) OF INPUT VALUES:
--   *
--   * The stencil of LBB is the same as for any standard Hermite
--   * bicubic (e.g., Catmull-Rom):
--   *
--   *  (ix-1,iy-1)  (ix,iy-1)    (ix+1,iy-1)  (ix+2,iy-1)
--   *  = uno_one    = uno_two    = uno_thr    = uno_fou
--   *
--   *  (ix-1,iy)    (ix,iy)      (ix+1,iy)    (ix+2,iy)
--   *  = dos_one    = dos_two    = dos_thr    = dos_fou
--   *                        X
--   *  (ix-1,iy+1)  (ix,iy+1)    (ix+1,iy+1)  (ix+2,iy+1)
--   *  = tre_one    = tre_two    = tre_thr    = tre_fou
--   *
--   *  (ix-1,iy+2)  (ix,iy+2)    (ix+1,iy+2)  (ix+2,iy+2)
--   *  = qua_one    = qua_two    = qua_thr    = qua_fou
--   *
--   * where ix is the (pseudo-)floor of the requested left-to-right
--   * location ("X"), and iy is the floor of the requested up-to-down
--   * location.
--   */
--
--#if defined (__LBB_CHEAP_H__)
--  /*
--   * Computation of the four min and four max over 3x3 input data
--   * sub-crosses of the 4x4 input stencil, performed with only 22
--   * comparisons and 28 "? :". If you can figure out how to do this
--   * more efficiently, let us know.
--   *
--   * This is the cheaper (but arguably less desirable in terms of
--   * quality) version of the computation.
--   */
--  const double m1    = (dos_two <= dos_thr) ? dos_two : dos_thr  ;
--  const double M1    = (dos_two <= dos_thr) ? dos_thr : dos_two  ;
--  const double m2    = (tre_two <= tre_thr) ? tre_two : tre_thr  ;
--  const double M2    = (tre_two <= tre_thr) ? tre_thr : tre_two  ;
--  const double m3    = (uno_two <= dos_one) ? uno_two : dos_one  ;
--  const double M3    = (uno_two <= dos_one) ? dos_one : uno_two  ;
--  const double m4    = (uno_thr <= dos_fou) ? uno_thr : dos_fou  ;
--  const double M4    = (uno_thr <= dos_fou) ? dos_fou : uno_thr  ;
--  const double m5    = (tre_one <= qua_two) ? tre_one : qua_two  ;
--  const double M5    = (tre_one <= qua_two) ? qua_two : tre_one  ;
--  const double m6    = (tre_fou <= qua_thr) ? tre_fou : qua_thr  ;
--  const double M6    = (tre_fou <= qua_thr) ? qua_thr : tre_fou  ;
--  const double m7    = LBB_MIN(               m1,       tre_two );
--  const double M7    = LBB_MAX(               M1,       tre_two );
--  const double m8    = LBB_MIN(               m1,       tre_thr );
--  const double M8    = LBB_MAX(               M1,       tre_thr );
--  const double m9    = LBB_MIN(               m2,       dos_two );
--  const double M9    = LBB_MAX(               M2,       dos_two );
--  const double m10   = LBB_MIN(               m2,       dos_thr );
--  const double M10   = LBB_MAX(               M2,       dos_thr );
--  const double min00 = LBB_MIN(               m7,       m3      );
--  const double max00 = LBB_MAX(               M7,       M3      );
--  const double min10 = LBB_MIN(               m8,       m4      );
--  const double max10 = LBB_MAX(               M8,       M4      );
--  const double min01 = LBB_MIN(               m9,       m5      );
--  const double max01 = LBB_MAX(               M9,       M5      );
--  const double min11 = LBB_MIN(              m10,       m6      );
--  const double max11 = LBB_MAX(              M10,       M6      );
--#else
--  /*
--   * Computation of the four min and four max over 3x3 input data
--   * sub-blocks of the 4x4 input stencil, performed with only 28
--   * comparisons and 34 "? :". If you can figure how to do this more
--   * efficiently, let us know.
--   */
--  const double m1    = (dos_two <= dos_thr) ? dos_two : dos_thr  ;
--  const double M1    = (dos_two <= dos_thr) ? dos_thr : dos_two  ;
--  const double m2    = (tre_two <= tre_thr) ? tre_two : tre_thr  ;
--  const double M2    = (tre_two <= tre_thr) ? tre_thr : tre_two  ;
--  const double m6    = (dos_one <= tre_one) ? dos_one : tre_one  ;
--  const double M6    = (dos_one <= tre_one) ? tre_one : dos_one  ;
--  const double m7    = (dos_fou <= tre_fou) ? dos_fou : tre_fou  ;
--  const double M7    = (dos_fou <= tre_fou) ? tre_fou : dos_fou  ;
--  const double m3    = (uno_two <= uno_thr) ? uno_two : uno_thr  ;
--  const double M3    = (uno_two <= uno_thr) ? uno_thr : uno_two  ;
--  const double m4    = (qua_two <= qua_thr) ? qua_two : qua_thr  ;
--  const double M4    = (qua_two <= qua_thr) ? qua_thr : qua_two  ;
--  const double m5    = LBB_MIN(               m1,       m2      );
--  const double M5    = LBB_MAX(               M1,       M2      );
--  const double m10   = LBB_MIN(               m6,       uno_one );
--  const double M10   = LBB_MAX(               M6,       uno_one );
--  const double m11   = LBB_MIN(               m6,       qua_one );
--  const double M11   = LBB_MAX(               M6,       qua_one );
--  const double m12   = LBB_MIN(               m7,       uno_fou );
--  const double M12   = LBB_MAX(               M7,       uno_fou );
--  const double m13   = LBB_MIN(               m7,       qua_fou );
--  const double M13   = LBB_MAX(               M7,       qua_fou );
--  const double m8    = LBB_MIN(               m5,       m3      );
--  const double M8    = LBB_MAX(               M5,       M3      );
--  const double m9    = LBB_MIN(               m5,       m4      );
--  const double M9    = LBB_MAX(               M5,       M4      );
--  const double min00 = LBB_MIN(               m8,       m10     );
--  const double max00 = LBB_MAX(               M8,       M10     );
--  const double min10 = LBB_MIN(               m8,       m12     );
--  const double max10 = LBB_MAX(               M8,       M12     );
--  const double min01 = LBB_MIN(               m9,       m11     );
--  const double max01 = LBB_MAX(               M9,       M11     );
--  const double min11 = LBB_MIN(               m9,       m13     );
--  const double max11 = LBB_MAX(               M9,       M13     );
--#endif
--
--  /*
--   * The remainder of the "per channel" computation involves the
--   * computation of:
--   *
--   * --8 conditional moves,
--   *
--   * --8 signs (in which the sign of zero is unimportant),
--   *
--   * --12 minima of two values,
--   *
--   * --8 maxima of two values,
--   *
--   * --8 absolute values,
--   *
--   * for a grand total of 29 minima, 25 maxima, 8 conditional moves, 8
--   * signs, and 8 absolute values. If everything is done with
--   * conditional moves, "only" 28+8+8+12+8+8=72 flags are involved
--   * (because initial min and max can be computed with one flag).
--   *
--   * The "per channel" part of the computation also involves 107
--   * arithmetic operations (54 *, 21 +, 42 -).
--   */
--
--  /*
--   * Distances to the local min and max:
--   */
--  const double u00 = dos_two - min00;
--  const double v00 = max00 - dos_two;
--  const double u10 = dos_thr - min10;
--  const double v10 = max10 - dos_thr;
--  const double u01 = tre_two - min01;
--  const double v01 = max01 - tre_two;
--  const double u11 = tre_thr - min11;
--  const double v11 = max11 - tre_thr;
--
--  /*
--   * Initial values of the derivatives computed with centered
--   * differences. Factors of 1/2 are left out because they are folded
--   * in later:
--   */
--  const double dble_dzdx00i = dos_thr - dos_one;
--  const double dble_dzdy11i = qua_thr - dos_thr;
--  const double dble_dzdx10i = dos_fou - dos_two;
--  const double dble_dzdy01i = qua_two - dos_two;
--  const double dble_dzdx01i = tre_thr - tre_one;
--  const double dble_dzdy10i = tre_thr - uno_thr;
--  const double dble_dzdx11i = tre_fou - tre_two;
--  const double dble_dzdy00i = tre_two - uno_two;
--
--  /*
--   * Signs of the derivatives. The upcoming clamping does not change
--   * them (except if the clamping sends a negative derivative to 0, in
--   * which case the sign does not matter anyway).
--   */
--  const double sign_dzdx00 = LBB_SIGN( dble_dzdx00i );
--  const double sign_dzdx10 = LBB_SIGN( dble_dzdx10i );
--  const double sign_dzdx01 = LBB_SIGN( dble_dzdx01i );
--  const double sign_dzdx11 = LBB_SIGN( dble_dzdx11i );
--
--  const double sign_dzdy00 = LBB_SIGN( dble_dzdy00i );
--  const double sign_dzdy10 = LBB_SIGN( dble_dzdy10i );
--  const double sign_dzdy01 = LBB_SIGN( dble_dzdy01i );
--  const double sign_dzdy11 = LBB_SIGN( dble_dzdy11i );
--
--  /*
--   * Initial values of the cross-derivatives. Factors of 1/4 are left
--   * out because folded in later:
--   */
--  const double quad_d2zdxdy00i = uno_one - uno_thr + dble_dzdx01i;
--  const double quad_d2zdxdy10i = uno_two - uno_fou + dble_dzdx11i;
--  const double quad_d2zdxdy01i = qua_thr - qua_one - dble_dzdx00i;
--  const double quad_d2zdxdy11i = qua_fou - qua_two - dble_dzdx10i;
--
--  /*
--   * Slope limiters. The key multiplier is 3 but we fold a factor of
--   * 2, hence 6:
--   */
--  const double dble_slopelimit_00 = 6.0 * LBB_MIN( u00, v00 );
--  const double dble_slopelimit_10 = 6.0 * LBB_MIN( u10, v10 );
--  const double dble_slopelimit_01 = 6.0 * LBB_MIN( u01, v01 );
--  const double dble_slopelimit_11 = 6.0 * LBB_MIN( u11, v11 );
--
--  /*
--   * Clamped first derivatives:
--   */
--  const double dble_dzdx00 =
--    ( sign_dzdx00 * dble_dzdx00i <= dble_slopelimit_00 )
--    ? dble_dzdx00i :  sign_dzdx00 * dble_slopelimit_00;
--  const double dble_dzdy00 =
--    ( sign_dzdy00 * dble_dzdy00i <= dble_slopelimit_00 )
--    ? dble_dzdy00i :  sign_dzdy00 * dble_slopelimit_00;
--  const double dble_dzdx10 =
--    ( sign_dzdx10 * dble_dzdx10i <= dble_slopelimit_10 )
--    ? dble_dzdx10i :  sign_dzdx10 * dble_slopelimit_10;
--  const double dble_dzdy10 =
--    ( sign_dzdy10 * dble_dzdy10i <= dble_slopelimit_10 )
--    ? dble_dzdy10i :  sign_dzdy10 * dble_slopelimit_10;
--  const double dble_dzdx01 =
--    ( sign_dzdx01 * dble_dzdx01i <= dble_slopelimit_01 )
--    ? dble_dzdx01i :  sign_dzdx01 * dble_slopelimit_01;
--  const double dble_dzdy01 =
--    ( sign_dzdy01 * dble_dzdy01i <= dble_slopelimit_01 )
--    ? dble_dzdy01i :  sign_dzdy01 * dble_slopelimit_01;
--  const double dble_dzdx11 =
--    ( sign_dzdx11 * dble_dzdx11i <= dble_slopelimit_11 )
--    ? dble_dzdx11i :  sign_dzdx11 * dble_slopelimit_11;
--  const double dble_dzdy11 =
--    ( sign_dzdy11 * dble_dzdy11i <= dble_slopelimit_11 )
--    ? dble_dzdy11i :  sign_dzdy11 * dble_slopelimit_11;
--
--  /*
--   * Sums and differences of first derivatives:
--   */
--  const double twelve_sum00 = 6.0 * ( dble_dzdx00 + dble_dzdy00 );
--  const double twelve_dif00 = 6.0 * ( dble_dzdx00 - dble_dzdy00 );
--  const double twelve_sum10 = 6.0 * ( dble_dzdx10 + dble_dzdy10 );
--  const double twelve_dif10 = 6.0 * ( dble_dzdx10 - dble_dzdy10 );
--  const double twelve_sum01 = 6.0 * ( dble_dzdx01 + dble_dzdy01 );
--  const double twelve_dif01 = 6.0 * ( dble_dzdx01 - dble_dzdy01 );
--  const double twelve_sum11 = 6.0 * ( dble_dzdx11 + dble_dzdy11 );
--  const double twelve_dif11 = 6.0 * ( dble_dzdx11 - dble_dzdy11 );
--
--  /*
--   * Absolute values of the sums:
--   */
--  const double twelve_abs_sum00 = LBB_ABS( twelve_sum00 );
--  const double twelve_abs_sum10 = LBB_ABS( twelve_sum10 );
--  const double twelve_abs_sum01 = LBB_ABS( twelve_sum01 );
--  const double twelve_abs_sum11 = LBB_ABS( twelve_sum11 );
--
--  /*
--   * Scaled distances to the min:
--   */
--  const double u00_times_36 = 36.0 * u00;
--  const double u10_times_36 = 36.0 * u10;
--  const double u01_times_36 = 36.0 * u01;
--  const double u11_times_36 = 36.0 * u11;
--
--  /*
--   * First cross-derivative limiter:
--   */
--  const double first_limit00 = twelve_abs_sum00 - u00_times_36;
--  const double first_limit10 = twelve_abs_sum10 - u10_times_36;
--  const double first_limit01 = twelve_abs_sum01 - u01_times_36;
--  const double first_limit11 = twelve_abs_sum11 - u11_times_36;
--
--  const double quad_d2zdxdy00ii = LBB_MAX( quad_d2zdxdy00i, first_limit00 );
--  const double quad_d2zdxdy10ii = LBB_MAX( quad_d2zdxdy10i, first_limit10 );
--  const double quad_d2zdxdy01ii = LBB_MAX( quad_d2zdxdy01i, first_limit01 );
--  const double quad_d2zdxdy11ii = LBB_MAX( quad_d2zdxdy11i, first_limit11 );
--
--  /*
--   * Scaled distances to the max:
--   */
--  const double v00_times_36 = 36.0 * v00;
--  const double v10_times_36 = 36.0 * v10;
--  const double v01_times_36 = 36.0 * v01;
--  const double v11_times_36 = 36.0 * v11;
--
--  /*
--   * Second cross-derivative limiter:
--   */
--  const double second_limit00 = v00_times_36 - twelve_abs_sum00;
--  const double second_limit10 = v10_times_36 - twelve_abs_sum10;
--  const double second_limit01 = v01_times_36 - twelve_abs_sum01;
--  const double second_limit11 = v11_times_36 - twelve_abs_sum11;
--
--  const double quad_d2zdxdy00iii = LBB_MIN( quad_d2zdxdy00ii, second_limit00 );
--  const double quad_d2zdxdy10iii = LBB_MIN( quad_d2zdxdy10ii, second_limit10 );
--  const double quad_d2zdxdy01iii = LBB_MIN( quad_d2zdxdy01ii, second_limit01 );
--  const double quad_d2zdxdy11iii = LBB_MIN( quad_d2zdxdy11ii, second_limit11 );
--
--  /*
--   * Absolute values of the differences:
--   */
--  const double twelve_abs_dif00 = LBB_ABS( twelve_dif00 );
--  const double twelve_abs_dif10 = LBB_ABS( twelve_dif10 );
--  const double twelve_abs_dif01 = LBB_ABS( twelve_dif01 );
--  const double twelve_abs_dif11 = LBB_ABS( twelve_dif11 );
--
--  /*
--   * Third cross-derivative limiter:
--   */
--  const double third_limit00 = twelve_abs_dif00 - v00_times_36;
--  const double third_limit10 = twelve_abs_dif10 - v10_times_36;
--  const double third_limit01 = twelve_abs_dif01 - v01_times_36;
--  const double third_limit11 = twelve_abs_dif11 - v11_times_36;
--
--  const double quad_d2zdxdy00iiii = LBB_MAX( quad_d2zdxdy00iii, third_limit00);
--  const double quad_d2zdxdy10iiii = LBB_MAX( quad_d2zdxdy10iii, third_limit10);
--  const double quad_d2zdxdy01iiii = LBB_MAX( quad_d2zdxdy01iii, third_limit01);
--  const double quad_d2zdxdy11iiii = LBB_MAX( quad_d2zdxdy11iii, third_limit11);
--
--  /*
--   * Fourth cross-derivative limiter:
--   */
--  const double fourth_limit00 = u00_times_36 - twelve_abs_dif00;
--  const double fourth_limit10 = u10_times_36 - twelve_abs_dif10;
--  const double fourth_limit01 = u01_times_36 - twelve_abs_dif01;
--  const double fourth_limit11 = u11_times_36 - twelve_abs_dif11;
--
--  const double quad_d2zdxdy00 = LBB_MIN( quad_d2zdxdy00iiii, fourth_limit00);
--  const double quad_d2zdxdy10 = LBB_MIN( quad_d2zdxdy10iiii, fourth_limit10);
--  const double quad_d2zdxdy01 = LBB_MIN( quad_d2zdxdy01iiii, fourth_limit01);
--  const double quad_d2zdxdy11 = LBB_MIN( quad_d2zdxdy11iiii, fourth_limit11);
--
--  /*
--   * Part of the result which does not need derivatives:
--   */
--  const double newval1 = c00 * dos_two + c10 * dos_thr +
--                         c01 * tre_two + c11 * tre_thr;
--
--  /*
--   * Twice the part of the result which only needs first derivatives.
--   */
--  const double newval2 = c00dx * dble_dzdx00 + c10dx * dble_dzdx10 +
--                         c01dx * dble_dzdx01 + c11dx * dble_dzdx11 +
--                         c00dy * dble_dzdy00 + c10dy * dble_dzdy10 +
--                         c01dy * dble_dzdy01 + c11dy * dble_dzdy11;
--
--  /*
--   * Four times the part of the result which only uses cross
--   * derivatives:
--   */
--  const double newval3 = c00dxdy * quad_d2zdxdy00 + c10dxdy * quad_d2zdxdy10 +
--                         c01dxdy * quad_d2zdxdy01 + c11dxdy * quad_d2zdxdy11;
--
--  const double newval = newval1 + .5 * newval2 + .25 * newval3;
--
--  return newval;
--}
--
--/*
-- * Call lbb with a type conversion operator as a parameter.
-- *
-- * It would be nice to do this with templates but we can't figure out
-- * how to do it cleanly. Suggestions welcome!
-- */
--#define LBB_CONVERSION( conversion )                     \
--  template <typename T> static void inline               \
--  lbb_ ## conversion(       void*      restrict pout,    \
--                      const VipsPel*   restrict pin,     \
--                      const int             bands,       \
--                      const int             lskip,       \
--                      const double          relative_x,  \
--                      const double          relative_y ) \
--  { \
--    T* restrict out = (T *) pout; \
--    \
--    const T* restrict in = (T *) pin; \
--    \
--    const int one_shift     =  -bands; \
--    const int thr_shift     =   bands; \
--    const int fou_shift     = 2*bands; \
--    \
--    const int uno_two_shift =  -lskip; \
--    \
--    const int tre_two_shift =   lskip; \
--    const int qua_two_shift = 2*lskip; \
--    \
--    const int uno_one_shift = uno_two_shift + one_shift; \
--    const int dos_one_shift =                 one_shift; \
--    const int tre_one_shift = tre_two_shift + one_shift; \
--    const int qua_one_shift = qua_two_shift + one_shift; \
--    \
--    const int uno_thr_shift = uno_two_shift + thr_shift; \
--    const int dos_thr_shift =                 thr_shift; \
--    const int tre_thr_shift = tre_two_shift + thr_shift; \
--    const int qua_thr_shift = qua_two_shift + thr_shift; \
--    \
--    const int uno_fou_shift = uno_two_shift + fou_shift; \
--    const int dos_fou_shift =                 fou_shift; \
--    const int tre_fou_shift = tre_two_shift + fou_shift; \
--    const int qua_fou_shift = qua_two_shift + fou_shift; \
--    \
--    const double xp1over2   = relative_x; \
--    const double xm1over2   = xp1over2 - 1.0; \
--    const double onepx      = 0.5 + xp1over2; \
--    const double onemx      = 1.5 - xp1over2; \
--    const double xp1over2sq = xp1over2 * xp1over2; \
--    \
--    const double yp1over2   = relative_y; \
--    const double ym1over2   = yp1over2 - 1.0; \
--    const double onepy      = 0.5 + yp1over2; \
--    const double onemy      = 1.5 - yp1over2; \
--    const double yp1over2sq = yp1over2 * yp1over2; \
--    \
--    const double xm1over2sq = xm1over2 * xm1over2; \
--    const double ym1over2sq = ym1over2 * ym1over2; \
--    \
--    const double twice1px = onepx + onepx; \
--    const double twice1py = onepy + onepy; \
--    const double twice1mx = onemx + onemx; \
--    const double twice1my = onemy + onemy; \
--    \
--    const double xm1over2sq_times_ym1over2sq = xm1over2sq * ym1over2sq; \
--    const double xp1over2sq_times_ym1over2sq = xp1over2sq * ym1over2sq; \
--    const double xp1over2sq_times_yp1over2sq = xp1over2sq * yp1over2sq; \
--    const double xm1over2sq_times_yp1over2sq = xm1over2sq * yp1over2sq; \
--    \
--    const double four_times_1px_times_1py = twice1px * twice1py; \
--    const double four_times_1mx_times_1py = twice1mx * twice1py; \
--    const double twice_xp1over2_times_1py = xp1over2 * twice1py; \
--    const double twice_xm1over2_times_1py = xm1over2 * twice1py; \
--    \
--    const double twice_xm1over2_times_1my = xm1over2 * twice1my; \
--    const double twice_xp1over2_times_1my = xp1over2 * twice1my; \
--    const double four_times_1mx_times_1my = twice1mx * twice1my; \
--    const double four_times_1px_times_1my = twice1px * twice1my; \
--    \
--    const double twice_1px_times_ym1over2 = twice1px * ym1over2; \
--    const double twice_1mx_times_ym1over2 = twice1mx * ym1over2; \
--    const double xp1over2_times_ym1over2  = xp1over2 * ym1over2; \
--    const double xm1over2_times_ym1over2  = xm1over2 * ym1over2; \
--    \
--    const double xm1over2_times_yp1over2  = xm1over2 * yp1over2; \
--    const double xp1over2_times_yp1over2  = xp1over2 * yp1over2; \
--    const double twice_1mx_times_yp1over2 = twice1mx * yp1over2; \
--    const double twice_1px_times_yp1over2 = twice1px * yp1over2; \
--    \
--    const double c00 = \
--      four_times_1px_times_1py * xm1over2sq_times_ym1over2sq; \
--    const double c00dx = \
--      twice_xp1over2_times_1py * xm1over2sq_times_ym1over2sq; \
--    const double c00dy = \
--      twice_1px_times_yp1over2 * xm1over2sq_times_ym1over2sq; \
--    const double c00dxdy = \
--       xp1over2_times_yp1over2 * xm1over2sq_times_ym1over2sq; \
--    \
--    const double c10 = \
--      four_times_1mx_times_1py * xp1over2sq_times_ym1over2sq; \
--    const double c10dx = \
--      twice_xm1over2_times_1py * xp1over2sq_times_ym1over2sq; \
--    const double c10dy = \
--      twice_1mx_times_yp1over2 * xp1over2sq_times_ym1over2sq; \
--    const double c10dxdy = \
--       xm1over2_times_yp1over2 * xp1over2sq_times_ym1over2sq; \
--    \
--    const double c01 = \
--      four_times_1px_times_1my * xm1over2sq_times_yp1over2sq; \
--    const double c01dx = \
--      twice_xp1over2_times_1my * xm1over2sq_times_yp1over2sq; \
--    const double c01dy = \
--      twice_1px_times_ym1over2 * xm1over2sq_times_yp1over2sq; \
--    const double c01dxdy = \
--       xp1over2_times_ym1over2 * xm1over2sq_times_yp1over2sq; \
--    \
--    const double c11 = \
--      four_times_1mx_times_1my * xp1over2sq_times_yp1over2sq; \
--    const double c11dx = \
--      twice_xm1over2_times_1my * xp1over2sq_times_yp1over2sq; \
--    const double c11dy = \
--      twice_1mx_times_ym1over2 * xp1over2sq_times_yp1over2sq; \
--    const double c11dxdy = \
--       xm1over2_times_ym1over2 * xp1over2sq_times_yp1over2sq; \
--    \
--    int band = bands; \
--    \
--    do \
--      { \
--        const double double_result =        \
--          lbbicubic( c00,                   \
--                     c10,                   \
--                     c01,                   \
--                     c11,                   \
--                     c00dx,                 \
--                     c10dx,                 \
--                     c01dx,                 \
--                     c11dx,                 \
--                     c00dy,                 \
--                     c10dy,                 \
--                     c01dy,                 \
--                     c11dy,                 \
--                     c00dxdy,               \
--                     c10dxdy,               \
--                     c01dxdy,               \
--                     c11dxdy,               \
--                     in[ uno_one_shift ],   \
--                     in[ uno_two_shift ],   \
--                     in[ uno_thr_shift ],   \
--                     in[ uno_fou_shift ],   \
--                     in[ dos_one_shift ],   \
--                     in[             0 ],   \
--                     in[ dos_thr_shift ],   \
--                     in[ dos_fou_shift ],   \
--                     in[ tre_one_shift ],   \
--                     in[ tre_two_shift ],   \
--                     in[ tre_thr_shift ],   \
--                     in[ tre_fou_shift ],   \
--                     in[ qua_one_shift ],   \
--                     in[ qua_two_shift ],   \
--                     in[ qua_thr_shift ],   \
--                     in[ qua_fou_shift ] ); \
--        \
--        const T result = to_ ## conversion<T>( double_result ); \
--        in++; \
--        *out++ = result; \
--      } while (--band); \
--  }
--
--LBB_CONVERSION( fptypes )
--LBB_CONVERSION( withsign )
--LBB_CONVERSION( nosign )
--
--#define CALL( T, conversion )          \
--  lbb_ ## conversion<T>( out,          \
--                         p,            \
--                         bands,        \
--                         lskip,        \
--                         relative_x,   \
--                         relative_y );
--
--/*
-- * We need C linkage:
-- */
--extern "C" {
--G_DEFINE_TYPE( VipsInterpolateLbb, vips_interpolate_lbb,
--      VIPS_TYPE_INTERPOLATE );
--}
--
--static void
--vips_interpolate_lbb_interpolate( VipsInterpolate* restrict interpolate,
--                                  void*            restrict out,
--                                  VipsRegion*      restrict in,
--                                  double                    absolute_x,
--                                  double                    absolute_y )
--{
--  /* absolute_x and absolute_y are always >= 1.0 (see double-check assert
--   * below), so we don't need floor(). 
--   *
--   * It's 1 not 0 since have a window_offset of 1.
--   */
--  const int ix = (int) absolute_x;
--  const int iy = (int) absolute_y;
--
--  /*
--   * Move the pointer to (the first band of) the top/left pixel of the
--   * 2x2 group of pixel centers which contains the sampling location
--   * in its convex hull:
--   */
--  const VipsPel* restrict p = VIPS_REGION_ADDR( in, ix, iy );
--
--  const double relative_x = absolute_x - ix;
--  const double relative_y = absolute_y - iy;
--
--  /*
--   * VIPS versions of Nicolas's pixel addressing values.
--   */
--  const int lskip = VIPS_REGION_LSKIP( in ) / 
--        VIPS_IMAGE_SIZEOF_ELEMENT( in->im );
--  /*
--   * Double the bands for complex images to account for the real and
--   * imaginary parts being computed independently:
--   */
--  const int actual_bands = in->im->Bands;
--  const int bands =
--    vips_bandfmt_iscomplex( in->im->BandFmt ) ? 2 * actual_bands : actual_bands;
--
--  /* Confirm that absolute_x and absolute_y are >= 1, see above. 
--   */
--  g_assert( absolute_x >= 1.0 );
--  g_assert( absolute_y >= 1.0 );
--
--  switch( in->im->BandFmt ) {
--  case VIPS_FORMAT_UCHAR:
--    CALL( unsigned char, nosign );
--    break;
--
--  case VIPS_FORMAT_CHAR:
--    CALL( signed char, withsign );
--    break;
--
--  case VIPS_FORMAT_USHORT:
--    CALL( unsigned short, nosign );
--    break;
--
--  case VIPS_FORMAT_SHORT:
--    CALL( signed short, withsign );
--    break;
--
--  case VIPS_FORMAT_UINT:
--    CALL( unsigned int, nosign );
--    break;
--
--  case VIPS_FORMAT_INT:
--    CALL( signed int, withsign );
--    break;
--
--  /*
--   * Complex images are handled by doubling of bands.
--   */
--  case VIPS_FORMAT_FLOAT:
--  case VIPS_FORMAT_COMPLEX:
--    CALL( float, fptypes );
--    break;
--
--  case VIPS_FORMAT_DOUBLE:
--  case VIPS_FORMAT_DPCOMPLEX:
--    CALL( double, fptypes );
--    break;
--
--  default:
--    g_assert( 0 );
--    break;
--  }
--}
--
--static void
--vips_interpolate_lbb_class_init( VipsInterpolateLbbClass *klass )
--{
--  VipsObjectClass *object_class = VIPS_OBJECT_CLASS( klass );
--  VipsInterpolateClass *interpolate_class =
--    VIPS_INTERPOLATE_CLASS( klass );
--
--  object_class->nickname    = "lbb";
--  object_class->description = _( "Reduced halo bicubic" );
--
--  interpolate_class->interpolate   = vips_interpolate_lbb_interpolate;
--  interpolate_class->window_size   = 4;
--}
--
--static void
--vips_interpolate_lbb_init( VipsInterpolateLbb *lbb )
--{
--}
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/Makefile.am vips-7.38.5/libvips/resample/Makefile.am
---- vips-7.38.5-vanilla/libvips/resample/Makefile.am   2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/Makefile.am   2014-07-17 23:49:32.820792979 -0400
-@@ -13,10 +13,6 @@
-       shrink.c \
-       interpolate.c \
-       transform.c \
--      bicubic.cpp \
--      lbb.cpp \
--      nohalo.cpp \
--      vsqbs.cpp \
-       templates.h 
- else
-@@ -32,10 +28,6 @@
-       transform.c 
- EXTRA_DIST = \
--      bicubic.cpp \
--      lbb.cpp \
--      nohalo.cpp \
--      vsqbs.cpp \
-       templates.h 
- endif
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/Makefile.in vips-7.38.5/libvips/resample/Makefile.in
---- vips-7.38.5-vanilla/libvips/resample/Makefile.in   2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/Makefile.in   2014-07-17 23:49:32.820792979 -0400
-@@ -505,7 +505,7 @@
-       }
- libresample.la: $(libresample_la_OBJECTS) $(libresample_la_DEPENDENCIES) $(EXTRA_libresample_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(CXXLINK)  $(libresample_la_OBJECTS) $(libresample_la_LIBADD) $(LIBS)
-+      $(AM_V_CXXLD)$(LINK)  $(libresample_la_OBJECTS) $(libresample_la_LIBADD) $(LIBS)
- mostlyclean-compile:
-       -rm -f *.$(OBJEXT)
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/nohalo.cpp vips-7.38.5/libvips/resample/nohalo.cpp
---- vips-7.38.5-vanilla/libvips/resample/nohalo.cpp    2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/nohalo.cpp    1969-12-31 19:00:00.000000000 -0500
-@@ -1,1590 +0,0 @@
--/* nohalo subdivision followed by lbb (locally bounded bicubic)
-- * interpolation resampler
-- *
-- * Nohalo level 1 with bilinear finishing scheme hacked for VIPS by
-- * J. Cupitt based on code by N. Robidoux, 20/1/09
-- *
-- * N. Robidoux and J. Cupitt, 4-17/3/09
-- *
-- * N. Robidoux, 1/4-29/5/2009
-- *
-- * Nohalo level 2 with bilinear finishing scheme by N. Robidoux based
-- * on code by N. Robidoux, A. Turcotte and J. Cupitt, 27/1/2010
-- *
-- * Nohalo level 1 with LBB finishing scheme by N. Robidoux and
-- * C. Racette, 11-18/5/2010
-- */
--
--/*
--
--    This file is part of VIPS.
--
--    VIPS is free software; you can redistribute it and/or modify it
--    under the terms of the GNU Lesser 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
--    Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--/*
-- * 2009-2010 (c) Nicolas Robidoux, Chantal Racette, John Cupitt and
-- * Adam Turcotte
-- *
-- * N. Robidoux thanks Geert Jordaens, Ralf Meyer, Øyvind Kolås,
-- * Minglun Gong, Eric Daoust and Sven Neumann for useful comments and
-- * code.
-- *
-- * N. Robidoux's early research on Nohalo funded in part by an NSERC
-- * (National Science and Engineering Research Council of Canada)
-- * Discovery Grant awarded to him (298424--2004).
-- *
-- * C. Racette's image resampling research and programming funded in
-- * part by an NSERC (National Science and Engineering Research Council
-- * of Canada) Alexander Graham Bell Canada Graduate Scholarship, by an
-- * NSERC Discovery Grant awarded to Julien Dompierre (grant number
-- * 20-61098) and by N. Robidoux's Laurentian University professional
-- * allowance.
-- *
-- * A. Turcotte's image resampling research on reduced halo funded in
-- * part by an NSERC Alexander Graham Bell Canada Graduate Scholarhip
-- * awarded to him and by a Google Summer of Code 2010 award awarded to
-- * GIMP (Gnu Image Manipulation Program).
-- *
-- * Nohalo with LBB finishing scheme was developed by N. Robidoux and
-- * C. Racette at the Department of Mathematics and Computer Science of
-- * Laurentian University in the course of C. Racette's Masters thesis
-- * in Computational Sciences. Preliminary work on Nohalo and monotone
-- * interpolation was performed by C. Racette and N. Robidoux in the
-- * course of her honours thesis, by N. Robidoux, A. Turcotte and
-- * E. Daoust during Google Summer of Code 2009 (through two awards
-- * made to GIMP to improve GEGL), and, earlier, by N. Robidoux,
-- * A. Turcotte, J. Cupitt, M. Gong and K. Martinez.
-- */
--
--/*
-- * Nohalo with LBB as finishing scheme has two versions, which are
-- * only different in the way LBB is implemented:
-- *
-- *   A "soft" version, which shows a little less staircasing and a
-- *   little more haloing, and which is a little more expensive to
-- *   compute. We recommend this as the default.
-- *
-- *   A "sharp" version, which shows a little more staircasing and a
-- *   little less haloing, and which is a little cheaper (it uses 6
-- *   less comparisons and 12 less "? :").
-- *
-- * The only difference between the two is that the "soft" versions
-- * uses local minima and maxima computed over 3x3 square blocks, and
-- * the "sharp" version uses local minima and maxima computed over 3x3
-- * crosses.
-- *
-- * The "sharp" version is (a little) faster. We don't know yet for
-- * sure, but it appears that the "soft" version gives marginally
-- * better results.
-- *
-- * If you want to use the "sharp" (cheaper) version, uncomment the
-- * following three pre-processor code lines:
-- */
--
--/*
--#ifndef __NOHALO_CHEAP_H__
--#define __NOHALO_CHEAP_H__
--#endif
-- */
--
--/*
-- * ================
-- * NOHALO RESAMPLER
-- * ================
-- *
-- * "Nohalo" is a resampler with a mission: smoothly straightening
-- * oblique lines without undesirable side-effects. In particular,
-- * without much blurring and with no added haloing.
-- *
-- * In this code, one Nohalo subdivision is performed. The
-- * interpolation is finished with LBB (Locally Bounded Bicubic).
-- *
-- * Key properties:
-- *
-- * =======================
-- * Nohalo is interpolatory
-- * =======================
-- *
-- * That is, Nohalo preserves point values: If asked for the value at
-- * the center of an input pixel, the sampler returns the corresponding
-- * value, unchanged. In addition, because Nohalo is continuous, if
-- * asked for a value at a location "very close" to the center of an
-- * input pixel, then the sampler returns a value "very close" to
-- * it. (Nohalo is not smoothing like, say, B-Spline
-- * pseudo-interpolation.)
-- *
-- * ====================================================================
-- * Nohalo subdivision is co-monotone (this is why it's called "no-halo")
-- * ====================================================================
-- *
-- * One consequence of monotonicity is that additional subdivided
-- * values are in the range of the four closest input values, which is
-- * a form of local boundedness.  (Note: plain vanilla bilinear and
-- * nearest neighbour are also co-monotone.) LBB is also locally
-- * bounded. Consequently, Nohalo subdivision followed by LBB is
-- * locally bounded. When used as a finishing scheme for Nohalo, the
-- * standard LBB bounds imply that the final interpolated value is in
-- * the range of the nine closest input values. This property is why
-- * there is very little added haloing, even when a finishing scheme
-- * which is not strictly monotone. Another consequence of local
-- * boundedness is that clamping is unnecessary (provided abyss values
-- * are within the range of acceptable values, which is "always" the
-- * case).
-- *
-- * Note: If the abyss policy is an extrapolating one---for example,
-- * linear or bilinear extrapolation---clamping is still unnecessary
-- * UNLESS one attempts to resample outside of the convex hull of the
-- * input pixel positions. Consequence: the "corner" image size
-- * convention does not require clamping when using linear
-- * extrapolation abyss policy when performing image resizing, but the
-- * "center" one does, when upscaling, at locations very close to the
-- * boundary. If computing values at locations outside of the convex
-- * hull of the pixel locations of the input image, nearest neighbour
-- * abyss policy is most likely better anyway, because linear
-- * extrapolation produces "streaks" if positions far outside the
-- * original image boundary are resampled.
-- *
-- * ========================
-- * Nohalo is a local method
-- * ========================
-- *
-- * The interpolated pixel value when using Nohalo subdivision followed
-- * by LBB only depends on the 21 (5x5 minus the four corners) closest
-- * input values.
-- *
-- * ===============================
-- * Nohalo is second order accurate
-- * ===============================
-- *
-- * (Except possibly near the boundary: it is easy to make this
-- * property carry over everywhere but this requires a tuned abyss
-- * policy---linear extrapolation, say---or building the boundary
-- * conditions inside the sampler.)  Nohalo+LBB is exact on linear
-- * intensity profiles, meaning that if the input pixel values (in the
-- * stencil) are obtained from a function of the form f(x,y) = a + b*x
-- * + c*y (a, b, c constants), then the computed pixel value is exactly
-- * the value of f(x,y) at the asked-for sampling location. The
-- * boundary condition which is emulated by VIPS through the "extend"
-- * extension of the input image---this corresponds to the nearest
-- * neighbour abyss policy---does NOT make this resampler exact on
-- * linears near the boundary. It does, however, guarantee that no
-- * clamping is required even when resampled values are computed at
-- * positions outside of the extent of the input image (when
-- * extrapolation is required).
-- *
-- * ===================
-- * Nohalo is nonlinear
-- * ===================
-- *
-- * Both Nohalo and LBB are nonlinear, consequently their composition
-- * is nonlinear.  In particular, resampling a sum of images may not be
-- * the same as summing the resamples. (This occurs even without taking
-- * into account over and underflow issues: images can only take values
-- * within a banded range, and consequently no sampler is truly
-- * linear.)
-- *
-- * ====================
-- * Weaknesses of Nohalo
-- * ====================
-- *
-- * In some cases, the initial subdivision computation is wasted:
-- *
-- * If a region is bi-chromatic, the nonlinear component of Nohalo
-- * subdivision is zero in the interior of the region, and consequently
-- * Nohalo subdivision boils down to bilinear. For such images, LBB is
-- * probably a better choice.
-- *
-- * =========================
-- * Bibliographical reference
-- * =========================
-- *
-- * For more information about Nohalo (a prototype version with
-- * bilinear finish instead of LBB), see
-- *
-- * CPU, SMP and GPU implementations of Nohalo level 1, a fast
-- * co-convex antialiasing image resampler by Nicolas Robidoux, Minglun
-- * Gong, John Cupitt, Adam Turcotte, and Kirk Martinez, in C3S2E '09:
-- * Proceedings of the 2nd Canadian Conference on Computer Science and
-- * Software Engineering, p. 185--195, ACM, New York, NY, USA, 2009.
-- * http://doi.acm.org/10.1145/1557626.1557657.
-- */
--
--/* Uncomment to enable bounds checking for VIPS_REGION_ADDR().
-- */
--#define DEBUG
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <stdio.h>
--#include <stdlib.h>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--#include "templates.h"
--
--#define VIPS_TYPE_INTERPOLATE_NOHALO \
--      (vips_interpolate_nohalo_get_type())
--#define VIPS_INTERPOLATE_NOHALO( obj ) \
--      (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
--      VIPS_TYPE_INTERPOLATE_NOHALO, VipsInterpolateNohalo ))
--#define VIPS_INTERPOLATE_NOHALO_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_CAST( (klass), \
--      VIPS_TYPE_INTERPOLATE_NOHALO, VipsInterpolateNohaloClass))
--#define VIPS_IS_INTERPOLATE_NOHALO( obj ) \
--      (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_NOHALO ))
--#define VIPS_IS_INTERPOLATE_NOHALO_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_NOHALO ))
--#define VIPS_INTERPOLATE_NOHALO_GET_CLASS( obj ) \
--      (G_TYPE_INSTANCE_GET_CLASS( (obj), \
--      VIPS_TYPE_INTERPOLATE_NOHALO, VipsInterpolateNohaloClass ))
--
--typedef struct _VipsInterpolateNohalo {
--      VipsInterpolate parent_object;
--
--} VipsInterpolateNohalo;
--
--typedef struct _VipsInterpolateNohaloClass {
--      VipsInterpolateClass parent_class;
--
--} VipsInterpolateNohaloClass;
--
--/*
-- * NOHALO_MINMOD is an implementation of the minmod function which
-- * only needs two "conditional moves."
-- * NOHALO_MINMOD(a,b,a_times_a,a_times_b) "returns"
-- * minmod(a,b). The macro parameter ("input") a_times_a is assumed to
-- * contain the square of a; a_times_b, the product of a and b.
-- *
-- * For uncompressed natural images in high bit depth (images for which
-- * the slopes a and b are unlikely to be equal to zero or be equal to
-- * each other), or chips with good branch prediction, the following
-- * version of the minmod function may work well:
-- *
-- * ( (a_times_b)>=0. ? ( (a_times_b)<(a_times_a) ? (b) : (a) ) : 0. )
-- *
-- * In this version, the forward branch of the second conditional move
-- * is taken when |b|>|a| and when a*b<0. However, the "else" branch is
-- * taken when a=0 (or when a=b), which is why the above version is not
-- * as effective for images with regions with constant pixel values (or
-- * regions with pixel values which vary linearly or bilinearly) since
-- * we apply minmod to pairs of differences.
-- *
-- * The following version is more suitable for images with flat
-- * (constant) colour areas, since a, which is a pixel difference, will
-- * often be 0, in which case both forward branches are likely. This
-- * may be preferable if "branch flag look ahead" does not work so
-- * well.
-- *
-- * ( (a_times_b)>=0. ? ( (a_times_a)<=(a_times_b) ? (a) : (b) ) : 0. )
-- *
-- * This last version appears to be slightly better than the former in
-- * speed tests performed on a recent multicore Intel chip, especially
-- * when enlarging a sharp image by a large factor, hence the choice.
-- */
--#define NOHALO_MINMOD(a,b,a_times_a,a_times_b) \
--  ( ( (a_times_b)>=0. ) ? ( (a_times_a)<=(a_times_b) ? (a) : (b) ) : 0. )
--
--/*
-- * Absolute value and sign macros:
-- */
--#define NOHALO_ABS(x)  ( ((x)>=0.) ? (x) : -(x) )
--#define NOHALO_SIGN(x) ( ((x)>=0.) ? 1.  : -1.  )
--
--/*
-- * MIN and MAX macros set up so that I can put the likely winner in
-- * the first argument (forward branch likely blah blah blah):
-- */
--#define NOHALO_MIN(x,y) ( ((x)<=(y)) ? (x) : (y) )
--#define NOHALO_MAX(x,y) ( ((x)>=(y)) ? (x) : (y) )
--
--
--static void inline
--nohalo_subdivision (const double           uno_two,
--                    const double           uno_thr,
--                    const double           uno_fou,
--                    const double           dos_one,
--                    const double           dos_two,
--                    const double           dos_thr,
--                    const double           dos_fou,
--                    const double           dos_fiv,
--                    const double           tre_one,
--                    const double           tre_two,
--                    const double           tre_thr,
--                    const double           tre_fou,
--                    const double           tre_fiv,
--                    const double           qua_one,
--                    const double           qua_two,
--                    const double           qua_thr,
--                    const double           qua_fou,
--                    const double           qua_fiv,
--                    const double           cin_two,
--                    const double           cin_thr,
--                    const double           cin_fou,
--                          double* restrict uno_one_1,
--                          double* restrict uno_two_1,
--                          double* restrict uno_thr_1,
--                          double* restrict uno_fou_1,
--                          double* restrict dos_one_1,
--                          double* restrict dos_two_1,
--                          double* restrict dos_thr_1,
--                          double* restrict dos_fou_1,
--                          double* restrict tre_one_1,
--                          double* restrict tre_two_1,
--                          double* restrict tre_thr_1,
--                          double* restrict tre_fou_1,
--                          double* restrict qua_one_1,
--                          double* restrict qua_two_1,
--                          double* restrict qua_thr_1,
--                          double* restrict qua_fou_1)
--{
--  /*
--   * nohalo_subdivision calculates the missing twelve double density
--   * pixel values, and also returns the "already known" four, so that
--   * the sixteen values which make up the stencil of LBB are
--   * available.
--   */
--  /*
--   * THE STENCIL OF INPUT VALUES:
--   *
--   * Pointer arithmetic is used to implicitly reflect the input
--   * stencil about tre_thr---assumed closer to the sampling location
--   * than other pixels (ties are OK)---in such a way that after
--   * reflection the sampling point is to the bottom right of tre_thr.
--   *
--   * The following code and picture assumes that the stencil reflexion
--   * has already been performed.
--   *
--   *               (ix-1,iy-2)  (ix,iy-2)    (ix+1,iy-2)
--   *               =uno_two     = uno_thr    = uno_fou
--   *
--   *
--   *
--   *  (ix-2,iy-1)  (ix-1,iy-1)  (ix,iy-1)    (ix+1,iy-1)  (ix+2,iy-1)
--   *  = dos_one    = dos_two    = dos_thr    = dos_fou    = dos_fiv
--   *
--   *
--   *
--   *  (ix-2,iy)    (ix-1,iy)    (ix,iy)      (ix+1,iy)    (ix+2,iy)
--   *  = tre_one    = tre_two    = tre_thr    = tre_fou    = tre_fiv
--   *                                    X
--   *
--   *
--   *  (ix-2,iy+1)  (ix-1,iy+1)  (ix,iy+1)    (ix+1,iy+1)  (ix+2,iy+1)
--   *  = qua_one    = qua_two    = qua_thr    = qua_fou    = qua_fiv
--   *
--   *
--   *
--   *               (ix-1,iy+2)  (ix,iy+2)    (ix+1,iy+2)
--   *               = cin_two    = cin_thr    = cin_fou
--   *
--   *
--   * The above input pixel values are the ones needed in order to make
--   * available the following values, needed by LBB:
--   *
--   *  uno_one_1 =      uno_two_1 =  uno_thr_1 =      uno_fou_1 =
--   *  (ix-1/2,iy-1/2)  (ix,iy-1/2)  (ix+1/2,iy-1/2)  (ix+1,iy-1/2)
--   *
--   *
--   *
--   *
--   *  dos_one_1 =      dos_two_1 =  dos_thr_1 =      dos_fou_1 =
--   *  (ix-1/2,iy)      (ix,iy)      (ix+1/2,iy)      (ix+1,iy)
--   *
--   *                             X
--   *
--   *
--   *  tre_one_1 =      tre_two_1 =  tre_thr_1 =      tre_fou_1 =
--   *  (ix-1/2,iy+1/2)  (ix,iy+1/2)  (ix+1/2,iy+1/2)  (ix+1,iy+1/2)
--   *
--   *
--   *
--   *
--   *  qua_one_1 =      qua_two_1 =  qua_thr_1 =      qua_fou_1 =
--   *  (ix-1/2,iy+1)    (ix,iy+1)    (ix+1/2,iy+1)    (ix+1,iy+1)
--   *
--   */
--
--  /*
--   * Computation of the nonlinear slopes: If two consecutive pixel
--   * value differences have the same sign, the smallest one (in
--   * absolute value) is taken to be the corresponding slope; if the
--   * two consecutive pixel value differences don't have the same sign,
--   * the corresponding slope is set to 0.
--   *
--   * In other words: Apply minmod to consecutive differences.
--   */
--  /*
--   * Two vertical simple differences:
--   */
--  const double d_unodos_two = dos_two - uno_two;
--  const double d_dostre_two = tre_two - dos_two;
--  const double d_trequa_two = qua_two - tre_two;
--  const double d_quacin_two = cin_two - qua_two;
--  /*
--   * Thr(ee) vertical differences:
--   */
--  const double d_unodos_thr = dos_thr - uno_thr;
--  const double d_dostre_thr = tre_thr - dos_thr;
--  const double d_trequa_thr = qua_thr - tre_thr;
--  const double d_quacin_thr = cin_thr - qua_thr;
--  /*
--   * Fou(r) vertical differences:
--   */
--  const double d_unodos_fou = dos_fou - uno_fou;
--  const double d_dostre_fou = tre_fou - dos_fou;
--  const double d_trequa_fou = qua_fou - tre_fou;
--  const double d_quacin_fou = cin_fou - qua_fou;
--  /*
--   * Dos horizontal differences:
--   */
--  const double d_dos_onetwo = dos_two - dos_one;
--  const double d_dos_twothr = dos_thr - dos_two;
--  const double d_dos_thrfou = dos_fou - dos_thr;
--  const double d_dos_foufiv = dos_fiv - dos_fou;
--  /*
--   * Tre(s) horizontal differences:
--   */
--  const double d_tre_onetwo = tre_two - tre_one;
--  const double d_tre_twothr = tre_thr - tre_two;
--  const double d_tre_thrfou = tre_fou - tre_thr;
--  const double d_tre_foufiv = tre_fiv - tre_fou;
--  /*
--   * Qua(ttro) horizontal differences:
--   */
--  const double d_qua_onetwo = qua_two - qua_one;
--  const double d_qua_twothr = qua_thr - qua_two;
--  const double d_qua_thrfou = qua_fou - qua_thr;
--  const double d_qua_foufiv = qua_fiv - qua_fou;
--
--  /*
--   * Recyclable vertical products and squares:
--   */
--  const double d_unodos_times_dostre_two = d_unodos_two * d_dostre_two;
--  const double d_dostre_two_sq           = d_dostre_two * d_dostre_two;
--  const double d_dostre_times_trequa_two = d_dostre_two * d_trequa_two;
--  const double d_trequa_times_quacin_two = d_quacin_two * d_trequa_two;
--  const double d_quacin_two_sq           = d_quacin_two * d_quacin_two;
--
--  const double d_unodos_times_dostre_thr = d_unodos_thr * d_dostre_thr;
--  const double d_dostre_thr_sq           = d_dostre_thr * d_dostre_thr;
--  const double d_dostre_times_trequa_thr = d_trequa_thr * d_dostre_thr;
--  const double d_trequa_times_quacin_thr = d_trequa_thr * d_quacin_thr;
--  const double d_quacin_thr_sq           = d_quacin_thr * d_quacin_thr;
--
--  const double d_unodos_times_dostre_fou = d_unodos_fou * d_dostre_fou;
--  const double d_dostre_fou_sq           = d_dostre_fou * d_dostre_fou;
--  const double d_dostre_times_trequa_fou = d_trequa_fou * d_dostre_fou;
--  const double d_trequa_times_quacin_fou = d_trequa_fou * d_quacin_fou;
--  const double d_quacin_fou_sq           = d_quacin_fou * d_quacin_fou;
--  /*
--   * Recyclable horizontal products and squares:
--   */
--  const double d_dos_onetwo_times_twothr = d_dos_onetwo * d_dos_twothr;
--  const double d_dos_twothr_sq           = d_dos_twothr * d_dos_twothr;
--  const double d_dos_twothr_times_thrfou = d_dos_twothr * d_dos_thrfou;
--  const double d_dos_thrfou_times_foufiv = d_dos_thrfou * d_dos_foufiv;
--  const double d_dos_foufiv_sq           = d_dos_foufiv * d_dos_foufiv;
--
--  const double d_tre_onetwo_times_twothr = d_tre_onetwo * d_tre_twothr;
--  const double d_tre_twothr_sq           = d_tre_twothr * d_tre_twothr;
--  const double d_tre_twothr_times_thrfou = d_tre_thrfou * d_tre_twothr;
--  const double d_tre_thrfou_times_foufiv = d_tre_thrfou * d_tre_foufiv;
--  const double d_tre_foufiv_sq           = d_tre_foufiv * d_tre_foufiv;
--
--  const double d_qua_onetwo_times_twothr = d_qua_onetwo * d_qua_twothr;
--  const double d_qua_twothr_sq           = d_qua_twothr * d_qua_twothr;
--  const double d_qua_twothr_times_thrfou = d_qua_thrfou * d_qua_twothr;
--  const double d_qua_thrfou_times_foufiv = d_qua_thrfou * d_qua_foufiv;
--  const double d_qua_foufiv_sq           = d_qua_foufiv * d_qua_foufiv;
--
--  /*
--   * Minmod slopes and first level pixel values:
--   */
--  const double dos_thr_y = NOHALO_MINMOD( d_dostre_thr, d_unodos_thr,
--                                          d_dostre_thr_sq,
--                                          d_unodos_times_dostre_thr );
--  const double tre_thr_y = NOHALO_MINMOD( d_dostre_thr, d_trequa_thr,
--                                          d_dostre_thr_sq,
--                                          d_dostre_times_trequa_thr );
--
--  const double newval_uno_two =
--    .5 * ( dos_thr + tre_thr )
--    +
--    .25 * ( dos_thr_y - tre_thr_y );
--
--  const double qua_thr_y = NOHALO_MINMOD( d_quacin_thr, d_trequa_thr,
--                                          d_quacin_thr_sq,
--                                          d_trequa_times_quacin_thr );
--
--  const double newval_tre_two =
--    .5 * ( tre_thr + qua_thr )
--    +
--    .25 * ( tre_thr_y - qua_thr_y );
--
--  const double tre_fou_y = NOHALO_MINMOD( d_dostre_fou, d_trequa_fou,
--                                          d_dostre_fou_sq,
--                                          d_dostre_times_trequa_fou );
--  const double qua_fou_y = NOHALO_MINMOD( d_quacin_fou, d_trequa_fou,
--                                          d_quacin_fou_sq,
--                                          d_trequa_times_quacin_fou );
--
--  const double newval_tre_fou =
--    .5 * ( tre_fou + qua_fou )
--    +
--    .25 * ( tre_fou_y - qua_fou_y );
--
--  const double dos_fou_y = NOHALO_MINMOD( d_dostre_fou, d_unodos_fou,
--                                          d_dostre_fou_sq,
--                                          d_unodos_times_dostre_fou );
--
--  const double newval_uno_fou =
--     .5 * ( dos_fou + tre_fou )
--     +
--     .25 * (dos_fou_y - tre_fou_y );
--
--  const double tre_two_x = NOHALO_MINMOD( d_tre_twothr, d_tre_onetwo,
--                                          d_tre_twothr_sq,
--                                          d_tre_onetwo_times_twothr );
--  const double tre_thr_x = NOHALO_MINMOD( d_tre_twothr, d_tre_thrfou,
--                                          d_tre_twothr_sq,
--                                          d_tre_twothr_times_thrfou );
--
--  const double newval_dos_one =
--    .5 * ( tre_two + tre_thr )
--    +
--    .25 * ( tre_two_x - tre_thr_x );
--
--  const double tre_fou_x = NOHALO_MINMOD( d_tre_foufiv, d_tre_thrfou,
--                                          d_tre_foufiv_sq,
--                                          d_tre_thrfou_times_foufiv );
--
--  const double tre_thr_x_minus_tre_fou_x =
--    tre_thr_x - tre_fou_x;
--
--  const double newval_dos_thr =
--    .5 * ( tre_thr + tre_fou )
--    +
--    .25 * tre_thr_x_minus_tre_fou_x;
--
--  const double qua_thr_x = NOHALO_MINMOD( d_qua_twothr, d_qua_thrfou,
--                                          d_qua_twothr_sq,
--                                          d_qua_twothr_times_thrfou );
--  const double qua_fou_x = NOHALO_MINMOD( d_qua_foufiv, d_qua_thrfou,
--                                          d_qua_foufiv_sq,
--                                          d_qua_thrfou_times_foufiv );
--
--  const double qua_thr_x_minus_qua_fou_x =
--    qua_thr_x - qua_fou_x;
--
--  const double newval_qua_thr =
--    .5 * ( qua_thr + qua_fou )
--    +
--    .25 * qua_thr_x_minus_qua_fou_x;
--
--  const double qua_two_x = NOHALO_MINMOD( d_qua_twothr, d_qua_onetwo,
--                                          d_qua_twothr_sq,
--                                          d_qua_onetwo_times_twothr );
--
--  const double newval_qua_one =
--    .5 * ( qua_two + qua_thr )
--    +
--    .25 * ( qua_two_x - qua_thr_x );
--
--  const double newval_tre_thr =
--    .125 * ( tre_thr_x_minus_tre_fou_x + qua_thr_x_minus_qua_fou_x )
--    +
--    .5 * ( newval_tre_two + newval_tre_fou );
--
--  const double dos_thr_x = NOHALO_MINMOD( d_dos_twothr, d_dos_thrfou,
--                                          d_dos_twothr_sq,
--                                          d_dos_twothr_times_thrfou );
--  const double dos_fou_x = NOHALO_MINMOD( d_dos_foufiv, d_dos_thrfou,
--                                          d_dos_foufiv_sq,
--                                          d_dos_thrfou_times_foufiv );
--
--  const double newval_uno_thr =
--    .25 * ( dos_fou - tre_thr )
--    +
--    .125 * ( dos_fou_y - tre_fou_y + dos_thr_x - dos_fou_x )
--    +
--    .5 * ( newval_uno_two + newval_dos_thr );
--
--  const double tre_two_y = NOHALO_MINMOD( d_dostre_two, d_trequa_two,
--                                          d_dostre_two_sq,
--                                          d_dostre_times_trequa_two );
--  const double qua_two_y = NOHALO_MINMOD( d_quacin_two, d_trequa_two,
--                                          d_quacin_two_sq,
--                                          d_trequa_times_quacin_two );
--
--  const double newval_tre_one =
--    .25 * ( qua_two - tre_thr )
--    +
--    .125 * ( qua_two_x - qua_thr_x + tre_two_y - qua_two_y )
--    +
--    .5 * ( newval_dos_one + newval_tre_two );
--
--  const double dos_two_x = NOHALO_MINMOD( d_dos_twothr, d_dos_onetwo,
--                                          d_dos_twothr_sq,
--                                          d_dos_onetwo_times_twothr );
--
--  const double dos_two_y = NOHALO_MINMOD( d_dostre_two, d_unodos_two,
--                                          d_dostre_two_sq,
--                                          d_unodos_times_dostre_two );
--
--  const double newval_uno_one =
--    .25 * ( dos_two + dos_thr + tre_two + tre_thr )
--    +
--    .125 * ( dos_two_x - dos_thr_x + tre_two_x - tre_thr_x
--             +
--             dos_two_y + dos_thr_y - tre_two_y - tre_thr_y );
--
--  /*
--   * Return the sixteen LBB stencil values:
--   */
--  *uno_one_1 = newval_uno_one;
--  *uno_two_1 = newval_uno_two;
--  *uno_thr_1 = newval_uno_thr;
--  *uno_fou_1 = newval_uno_fou;
--  *dos_one_1 = newval_dos_one;
--  *dos_two_1 =        tre_thr;
--  *dos_thr_1 = newval_dos_thr;
--  *dos_fou_1 =        tre_fou;
--  *tre_one_1 = newval_tre_one;
--  *tre_two_1 = newval_tre_two;
--  *tre_thr_1 = newval_tre_thr;
--  *tre_fou_1 = newval_tre_fou;
--  *qua_one_1 = newval_qua_one;
--  *qua_two_1 =        qua_thr;
--  *qua_thr_1 = newval_qua_thr;
--  *qua_fou_1 =        qua_fou;
--}
--
--/*
-- * LBB (Locally Bounded Bicubic) is a high quality nonlinear variant
-- * of Catmull-Rom. Images resampled with LBB have much smaller halos
-- * than images resampled with windowed sincs or other interpolatory
-- * cubic spline filters. Specifically, LBB halos are narrower and the
-- * over/undershoot amplitude is smaller. This is accomplished without
-- * a significant reduction in the smoothness of the result (compared
-- * to Catmull-Rom).
-- *
-- * Another important property is that the resampled values are
-- * contained within the range of nearby input values. Consequently, no
-- * final clamping is needed to stay "in range" (e.g., 0-255 for
-- * standard 8-bit images).
-- *
-- * LBB was developed by N. Robidoux and C. Racette of the Department
-- * of Mathematics and Computer Science of Laurentian University in the
-- * course of C.'s Masters Thesis in Computational Sciences.
-- */
--
--/*
-- * LBB is a novel method with the following properties:
-- *
-- * --LBB is a Hermite bicubic method: The bicubic surface is defined,
-- *   one convex hull of four nearby input points at a time, using four
-- *   point values, four x-derivatives, four y-derivatives, and four
-- *   cross-derivatives.
-- *
-- * --The stencil for values in a square patch is the usual 4x4.
-- *
-- * --LBB is interpolatory.
-- *
-- * --It is C^1 with continuous cross derivatives.
-- *
-- * --When the limiters are inactive, LBB gives the same results as
-- *   Catmull-Rom.
-- *
-- * --When used on binary images, LBB gives results similar to bicubic
-- *   Hermite with all first derivatives---but not necessarily the
-- *   cross derivatives--at the input pixel locations set to zero.
-- *
-- * --The LBB reconstruction is locally bounded: Over each square
-- *   patch, the surface is contained between the minimum and the
-- *   maximum values among the 16 nearest input pixel values (those in
-- *   the stencil).
-- *
-- * --Consequently, the LBB reconstruction is globally bounded between
-- *   the very smallest input pixel value and the very largest input
-- *   pixel value. (It is not necessary to clamp results.)
-- *
-- * The LBB method is based on the method of Ken Brodlie, Petros
-- * Mashwama and Sohail Butt for constraining Hermite interpolants
-- * between globally defined planes:
-- *
-- *   Visualization of surface data to preserve positivity and other
-- *   simple constraints. Computer & Graphics, Vol. 19, Number 4, pages
-- *   585-594, 1995. DOI: 10.1016/0097-8493(95)00036-C.
-- *
-- * Instead of forcing the reconstructed surface to lie between two
-- * GLOBALLY defined planes, LBB constrains one patch at a time to lie
-- * between LOCALLY defined planes. This is accomplished by
-- * constraining the derivatives (x, y and cross) at each input pixel
-- * location so that if the constraint was applied everywhere the
-- * surface would fit between the min and max of the values at the 9
-- * closest pixel locations. Because this is done with each of the four
-- * pixel locations which define the bicubic patch, this forces the
-- * reconstructed surface to lie between the min and max of the values
-- * at the 16 closest values pixel locations. (Each corner defines its
-- * own 3x3 subgroup of the 4x4 stencil. Consequently, the surface is
-- * necessarily above the minimum of the four minima, which happens to
-- * be the minimum over the 4x4. Similarly with the maxima.)
-- *
-- * The above paragraph described the "soft" version of LBB. The
-- * "sharp" version is similar.
-- */
--
--static inline double
--lbbicubic( const double c00,
--           const double c10,
--           const double c01,
--           const double c11,
--           const double c00dx,
--           const double c10dx,
--           const double c01dx,
--           const double c11dx,
--           const double c00dy,
--           const double c10dy,
--           const double c01dy,
--           const double c11dy,
--           const double c00dxdy,
--           const double c10dxdy,
--           const double c01dxdy,
--           const double c11dxdy,
--           const double uno_one,
--           const double uno_two,
--           const double uno_thr,
--           const double uno_fou,
--           const double dos_one,
--           const double dos_two,
--           const double dos_thr,
--           const double dos_fou,
--           const double tre_one,
--           const double tre_two,
--           const double tre_thr,
--           const double tre_fou,
--           const double qua_one,
--           const double qua_two,
--           const double qua_thr,
--           const double qua_fou )
--{
--  /*
--   * STENCIL (FOOTPRINT) OF INPUT VALUES:
--   *
--   * The stencil of LBB is the same as for any standard Hermite
--   * bicubic (e.g., Catmull-Rom):
--   *
--   *  (ix-1,iy-1)  (ix,iy-1)    (ix+1,iy-1)  (ix+2,iy-1)
--   *  = uno_one    = uno_two    = uno_thr    = uno_fou
--   *
--   *  (ix-1,iy)    (ix,iy)      (ix+1,iy)    (ix+2,iy)
--   *  = dos_one    = dos_two    = dos_thr    = dos_fou
--   *                        X
--   *  (ix-1,iy+1)  (ix,iy+1)    (ix+1,iy+1)  (ix+2,iy+1)
--   *  = tre_one    = tre_two    = tre_thr    = tre_fou
--   *
--   *  (ix-1,iy+2)  (ix,iy+2)    (ix+1,iy+2)  (ix+2,iy+2)
--   *  = qua_one    = qua_two    = qua_thr    = qua_fou
--   *
--   * where ix is the (pseudo-)floor of the requested left-to-right
--   * location ("X"), and iy is the floor of the requested up-to-down
--   * location.
--   */
--
--#if defined (__NOHALO_CHEAP_H__)
--  /*
--   * Computation of the four min and four max over 3x3 input data
--   * sub-crosses of the 4x4 input stencil.
--   *
--   * We exploit the fact that the data comes from the (co-monotone)
--   * method Nohalo so that it is known ahead of time that
--   *
--   *  dos_thr is between dos_two and dos_fou
--   *
--   *  tre_two is between dos_two and qua_two
--   *
--   *  tre_fou is between dos_fou and qua_fou
--   *
--   *  qua_thr is between qua_two and qua_fou
--   *
--   *  tre_thr is in the convex hull of dos_two, dos_fou, qua_two and qua_fou
--   *
--   *  to minimize the number of flags and conditional moves.
--   *
--   * (The "between" are not strict: "a between b and c" means
--   *
--   * "min(b,c) <= a <= max(b,c)".)
--   *
--   * We have, however, succeeded in eliminating one flag computation
--   * (one comparison) and one use of an intermediate result. See the
--   * two commented out lines below.
--   *
--   * Overall, only 20 comparisons and 28 "? :" are needed (to compute
--   * 4 mins and 4 maxes). If you can figure how to do this more
--   * efficiently, let us know.
--   */
--  const double m1    = (uno_two <= tre_two) ? uno_two : tre_two  ;
--  const double M1    = (uno_two <= tre_two) ? tre_two : uno_two  ;
--  const double m2    = (dos_thr <= qua_thr) ? dos_thr : qua_thr  ;
--  const double M2    = (dos_thr <= qua_thr) ? qua_thr : dos_thr  ;
--  const double m3    = (dos_two <= dos_fou) ? dos_two : dos_fou  ;
--  const double M3    = (dos_two <= dos_fou) ? dos_fou : dos_two  ;
--  const double m4    = (uno_thr <= tre_thr) ? uno_thr : tre_thr  ;
--  const double M4    = (uno_thr <= tre_thr) ? tre_thr : uno_thr  ;
--  const double m5    = (dos_two <= qua_two) ? dos_two : qua_two  ;
--  const double M5    = (dos_two <= qua_two) ? qua_two : dos_two  ;
--  const double m6    = (tre_one <= tre_thr) ? tre_one : tre_thr  ;
--  const double M6    = (tre_one <= tre_thr) ? tre_thr : tre_one  ;
--  const double m7    = (dos_one <= dos_thr) ? dos_one : dos_thr  ;
--  const double M7    = (dos_one <= dos_thr) ? dos_thr : dos_one  ;
--  const double m8    = (tre_two <= tre_fou) ? tre_two : tre_fou  ;
--  const double M8    = (tre_two <= tre_fou) ? tre_fou : tre_two  ;
--  const double m9    = NOHALO_MIN(            m1,       dos_two );
--  const double M9    = NOHALO_MAX(            M1,       dos_two );
--  const double m10   = NOHALO_MIN(            m2,       tre_thr );
--  const double M10   = NOHALO_MAX(            M2,       tre_thr );
--  const double min10 = NOHALO_MIN(            m3,       m4      );
--  const double max10 = NOHALO_MAX(            M3,       M4      );
--  const double min01 = NOHALO_MIN(            m5,       m6      );
--  const double max01 = NOHALO_MAX(            M5,       M6      );
--  const double min00 = NOHALO_MIN(            m9,       m7      );
--  const double max00 = NOHALO_MAX(            M9,       M7      );
--  const double min11 = NOHALO_MIN(           m10,       m8      );
--  const double max11 = NOHALO_MAX(           M10,       M8      );
--#else
--  /*
--   * Computation of the four min and four max over 3x3 input data
--   * sub-blocks of the 4x4 input stencil.
--   *
--   * Surprisingly, we have not succeeded in reducing the number of "?
--   * :" needed by using the fact that the data comes from the
--   * (co-monotone) method Nohalo so that it is known ahead of time
--   * that
--   *
--   *  dos_thr is between dos_two and dos_fou
--   *
--   *  tre_two is between dos_two and qua_two
--   *
--   *  tre_fou is between dos_fou and qua_fou
--   *
--   *  qua_thr is between qua_two and qua_fou
--   *
--   *  tre_thr is in the convex hull of dos_two, dos_fou, qua_two and qua_fou
--   *
--   *  to minimize the number of flags and conditional moves.
--   *
--   * (The "between" are not strict: "a between b and c" means
--   *
--   * "min(b,c) <= a <= max(b,c)".)
--   *
--   * We have, however, succeeded in eliminating one flag computation
--   * (one comparison) and one use of an intermediate result. See the
--   * two commented out lines below.
--   *
--   * Overall, only 27 comparisons are needed (to compute 4 mins and 4
--   * maxes!). Without the simplification, 28 comparisons would be
--   * used. Either way, the number of "? :" used is 34. If you can
--   * figure how to do this more efficiently, let us know.
--   */
--  const double m1    = (dos_two <= dos_thr) ? dos_two : dos_thr  ;
--  const double M1    = (dos_two <= dos_thr) ? dos_thr : dos_two  ;
--  const double m2    = (tre_two <= tre_thr) ? tre_two : tre_thr  ;
--  const double M2    = (tre_two <= tre_thr) ? tre_thr : tre_two  ;
--  const double m4    = (qua_two <= qua_thr) ? qua_two : qua_thr  ;
--  const double M4    = (qua_two <= qua_thr) ? qua_thr : qua_two  ;
--  const double m3    = (uno_two <= uno_thr) ? uno_two : uno_thr  ;
--  const double M3    = (uno_two <= uno_thr) ? uno_thr : uno_two  ;
--  const double m5    = NOHALO_MIN(            m1,       m2      );
--  const double M5    = NOHALO_MAX(            M1,       M2      );
--  const double m6    = (dos_one <= tre_one) ? dos_one : tre_one  ;
--  const double M6    = (dos_one <= tre_one) ? tre_one : dos_one  ;
--  const double m7    = (dos_fou <= tre_fou) ? dos_fou : tre_fou  ;
--  const double M7    = (dos_fou <= tre_fou) ? tre_fou : dos_fou  ;
--  const double m13   = (dos_fou <= qua_fou) ? dos_fou : qua_fou  ;
--  const double M13   = (dos_fou <= qua_fou) ? qua_fou : dos_fou  ;
--  /*
--   * Because the data comes from Nohalo subdivision, the following two
--   * lines can be replaced by the above, simpler, two lines without
--   * changing the results.
--   *
--   * const double m13   = NOHALO_MIN(               m7,       qua_fou );
--   * const double M13   = NOHALO_MAX(               M7,       qua_fou );
--   *
--   * This also allows reodering the comparisons to put space between
--   * the computation of a result and its use.
--   */
--  const double m9    = NOHALO_MIN(            m5,       m4      );
--  const double M9    = NOHALO_MAX(            M5,       M4      );
--  const double m11   = NOHALO_MIN(            m6,       qua_one );
--  const double M11   = NOHALO_MAX(            M6,       qua_one );
--  const double m10   = NOHALO_MIN(            m6,       uno_one );
--  const double M10   = NOHALO_MAX(            M6,       uno_one );
--  const double m8    = NOHALO_MIN(            m5,       m3      );
--  const double M8    = NOHALO_MAX(            M5,       M3      );
--  const double m12   = NOHALO_MIN(            m7,       uno_fou );
--  const double M12   = NOHALO_MAX(            M7,       uno_fou );
--  const double min11 = NOHALO_MIN(            m9,       m13     );
--  const double max11 = NOHALO_MAX(            M9,       M13     );
--  const double min01 = NOHALO_MIN(            m9,       m11     );
--  const double max01 = NOHALO_MAX(            M9,       M11     );
--  const double min00 = NOHALO_MIN(            m8,       m10     );
--  const double max00 = NOHALO_MAX(            M8,       M10     );
--  const double min10 = NOHALO_MIN(            m8,       m12     );
--  const double max10 = NOHALO_MAX(            M8,       M12     );
--#endif
--
--  /*
--   * The remainder of the "per channel" computation involves the
--   * computation of:
--   *
--   * --8 conditional moves,
--   *
--   * --8 signs (in which the sign of zero is unimportant),
--   *
--   * --12 minima of two values,
--   *
--   * --8 maxima of two values,
--   *
--   * --8 absolute values,
--   *
--   * for a grand total of 29 minima, 25 maxima, 8 conditional moves, 8
--   * signs, and 8 absolute values. If everything is done with
--   * conditional moves, "only" 28+8+8+12+8+8=72 flags are involved
--   * (because initial min and max can be computed with one flag).
--   *
--   * The "per channel" part of the computation also involves 107
--   * arithmetic operations (54 *, 21 +, 42 -).
--   */
--
--  /*
--   * Distances to the local min and max:
--   */
--  const double u11 = tre_thr - min11;
--  const double v11 = max11 - tre_thr;
--  const double u01 = tre_two - min01;
--  const double v01 = max01 - tre_two;
--  const double u00 = dos_two - min00;
--  const double v00 = max00 - dos_two;
--  const double u10 = dos_thr - min10;
--  const double v10 = max10 - dos_thr;
--
--  /*
--   * Initial values of the derivatives computed with centered
--   * differences. Factors of 1/2 are left out because they are folded
--   * in later:
--   */
--  const double dble_dzdx00i = dos_thr - dos_one;
--  const double dble_dzdy11i = qua_thr - dos_thr;
--  const double dble_dzdx10i = dos_fou - dos_two;
--  const double dble_dzdy01i = qua_two - dos_two;
--  const double dble_dzdx01i = tre_thr - tre_one;
--  const double dble_dzdy10i = tre_thr - uno_thr;
--  const double dble_dzdx11i = tre_fou - tre_two;
--  const double dble_dzdy00i = tre_two - uno_two;
--
--  /*
--   * Signs of the derivatives. The upcoming clamping does not change
--   * them (except if the clamping sends a negative derivative to 0, in
--   * which case the sign does not matter anyway).
--   */
--  const double sign_dzdx00 = NOHALO_SIGN( dble_dzdx00i );
--  const double sign_dzdx10 = NOHALO_SIGN( dble_dzdx10i );
--  const double sign_dzdx01 = NOHALO_SIGN( dble_dzdx01i );
--  const double sign_dzdx11 = NOHALO_SIGN( dble_dzdx11i );
--
--  const double sign_dzdy00 = NOHALO_SIGN( dble_dzdy00i );
--  const double sign_dzdy10 = NOHALO_SIGN( dble_dzdy10i );
--  const double sign_dzdy01 = NOHALO_SIGN( dble_dzdy01i );
--  const double sign_dzdy11 = NOHALO_SIGN( dble_dzdy11i );
--
--  /*
--   * Initial values of the cross-derivatives. Factors of 1/4 are left
--   * out because folded in later:
--   */
--  const double quad_d2zdxdy00i = uno_one - uno_thr + dble_dzdx01i;
--  const double quad_d2zdxdy10i = uno_two - uno_fou + dble_dzdx11i;
--  const double quad_d2zdxdy01i = qua_thr - qua_one - dble_dzdx00i;
--  const double quad_d2zdxdy11i = qua_fou - qua_two - dble_dzdx10i;
--
--  /*
--   * Slope limiters. The key multiplier is 3 but we fold a factor of
--   * 2, hence 6:
--   */
--  const double dble_slopelimit_00 = 6.0 * NOHALO_MIN( u00, v00 );
--  const double dble_slopelimit_10 = 6.0 * NOHALO_MIN( u10, v10 );
--  const double dble_slopelimit_01 = 6.0 * NOHALO_MIN( u01, v01 );
--  const double dble_slopelimit_11 = 6.0 * NOHALO_MIN( u11, v11 );
--
--  /*
--   * Clamped first derivatives:
--   */
--  const double dble_dzdx00 =
--    ( sign_dzdx00 * dble_dzdx00i <= dble_slopelimit_00 )
--    ? dble_dzdx00i :  sign_dzdx00 * dble_slopelimit_00;
--  const double dble_dzdy00 =
--    ( sign_dzdy00 * dble_dzdy00i <= dble_slopelimit_00 )
--    ? dble_dzdy00i :  sign_dzdy00 * dble_slopelimit_00;
--  const double dble_dzdx10 =
--    ( sign_dzdx10 * dble_dzdx10i <= dble_slopelimit_10 )
--    ? dble_dzdx10i :  sign_dzdx10 * dble_slopelimit_10;
--  const double dble_dzdy10 =
--    ( sign_dzdy10 * dble_dzdy10i <= dble_slopelimit_10 )
--    ? dble_dzdy10i :  sign_dzdy10 * dble_slopelimit_10;
--  const double dble_dzdx01 =
--    ( sign_dzdx01 * dble_dzdx01i <= dble_slopelimit_01 )
--    ? dble_dzdx01i :  sign_dzdx01 * dble_slopelimit_01;
--  const double dble_dzdy01 =
--    ( sign_dzdy01 * dble_dzdy01i <= dble_slopelimit_01 )
--    ? dble_dzdy01i :  sign_dzdy01 * dble_slopelimit_01;
--  const double dble_dzdx11 =
--    ( sign_dzdx11 * dble_dzdx11i <= dble_slopelimit_11 )
--    ? dble_dzdx11i :  sign_dzdx11 * dble_slopelimit_11;
--  const double dble_dzdy11 =
--    ( sign_dzdy11 * dble_dzdy11i <= dble_slopelimit_11 )
--    ? dble_dzdy11i :  sign_dzdy11 * dble_slopelimit_11;
--
--  /*
--   * Sums and differences of first derivatives:
--   */
--  const double twelve_sum00 = 6.0 * ( dble_dzdx00 + dble_dzdy00 );
--  const double twelve_dif00 = 6.0 * ( dble_dzdx00 - dble_dzdy00 );
--  const double twelve_sum10 = 6.0 * ( dble_dzdx10 + dble_dzdy10 );
--  const double twelve_dif10 = 6.0 * ( dble_dzdx10 - dble_dzdy10 );
--  const double twelve_sum01 = 6.0 * ( dble_dzdx01 + dble_dzdy01 );
--  const double twelve_dif01 = 6.0 * ( dble_dzdx01 - dble_dzdy01 );
--  const double twelve_sum11 = 6.0 * ( dble_dzdx11 + dble_dzdy11 );
--  const double twelve_dif11 = 6.0 * ( dble_dzdx11 - dble_dzdy11 );
--
--  /*
--   * Absolute values of the sums:
--   */
--  const double twelve_abs_sum00 = NOHALO_ABS( twelve_sum00 );
--  const double twelve_abs_sum10 = NOHALO_ABS( twelve_sum10 );
--  const double twelve_abs_sum01 = NOHALO_ABS( twelve_sum01 );
--  const double twelve_abs_sum11 = NOHALO_ABS( twelve_sum11 );
--
--  /*
--   * Scaled distances to the min:
--   */
--  const double u00_times_36 = 36.0 * u00;
--  const double u10_times_36 = 36.0 * u10;
--  const double u01_times_36 = 36.0 * u01;
--  const double u11_times_36 = 36.0 * u11;
--
--  /*
--   * First cross-derivative limiter:
--   */
--  const double first_limit00 = twelve_abs_sum00 - u00_times_36;
--  const double first_limit10 = twelve_abs_sum10 - u10_times_36;
--  const double first_limit01 = twelve_abs_sum01 - u01_times_36;
--  const double first_limit11 = twelve_abs_sum11 - u11_times_36;
--
--  const double quad_d2zdxdy00ii = NOHALO_MAX( quad_d2zdxdy00i, first_limit00 );
--  const double quad_d2zdxdy10ii = NOHALO_MAX( quad_d2zdxdy10i, first_limit10 );
--  const double quad_d2zdxdy01ii = NOHALO_MAX( quad_d2zdxdy01i, first_limit01 );
--  const double quad_d2zdxdy11ii = NOHALO_MAX( quad_d2zdxdy11i, first_limit11 );
--
--  /*
--   * Scaled distances to the max:
--   */
--  const double v00_times_36 = 36.0 * v00;
--  const double v10_times_36 = 36.0 * v10;
--  const double v01_times_36 = 36.0 * v01;
--  const double v11_times_36 = 36.0 * v11;
--
--  /*
--   * Second cross-derivative limiter:
--   */
--  const double second_limit00 = v00_times_36 - twelve_abs_sum00;
--  const double second_limit10 = v10_times_36 - twelve_abs_sum10;
--  const double second_limit01 = v01_times_36 - twelve_abs_sum01;
--  const double second_limit11 = v11_times_36 - twelve_abs_sum11;
--
--  const double quad_d2zdxdy00iii =
--    NOHALO_MIN( quad_d2zdxdy00ii, second_limit00 );
--  const double quad_d2zdxdy10iii =
--    NOHALO_MIN( quad_d2zdxdy10ii, second_limit10 );
--  const double quad_d2zdxdy01iii =
--    NOHALO_MIN( quad_d2zdxdy01ii, second_limit01 );
--  const double quad_d2zdxdy11iii =
--    NOHALO_MIN( quad_d2zdxdy11ii, second_limit11 );
--
--  /*
--   * Absolute values of the differences:
--   */
--  const double twelve_abs_dif00 = NOHALO_ABS( twelve_dif00 );
--  const double twelve_abs_dif10 = NOHALO_ABS( twelve_dif10 );
--  const double twelve_abs_dif01 = NOHALO_ABS( twelve_dif01 );
--  const double twelve_abs_dif11 = NOHALO_ABS( twelve_dif11 );
--
--  /*
--   * Third cross-derivative limiter:
--   */
--  const double third_limit00 = twelve_abs_dif00 - v00_times_36;
--  const double third_limit10 = twelve_abs_dif10 - v10_times_36;
--  const double third_limit01 = twelve_abs_dif01 - v01_times_36;
--  const double third_limit11 = twelve_abs_dif11 - v11_times_36;
--
--  const double quad_d2zdxdy00iiii =
--    NOHALO_MAX( quad_d2zdxdy00iii, third_limit00);
--  const double quad_d2zdxdy10iiii =
--    NOHALO_MAX( quad_d2zdxdy10iii, third_limit10);
--  const double quad_d2zdxdy01iiii =
--    NOHALO_MAX( quad_d2zdxdy01iii, third_limit01);
--  const double quad_d2zdxdy11iiii =
--    NOHALO_MAX( quad_d2zdxdy11iii, third_limit11);
--
--  /*
--   * Fourth cross-derivative limiter:
--   */
--  const double fourth_limit00 = u00_times_36 - twelve_abs_dif00;
--  const double fourth_limit10 = u10_times_36 - twelve_abs_dif10;
--  const double fourth_limit01 = u01_times_36 - twelve_abs_dif01;
--  const double fourth_limit11 = u11_times_36 - twelve_abs_dif11;
--
--  const double quad_d2zdxdy00 = NOHALO_MIN( quad_d2zdxdy00iiii, fourth_limit00);
--  const double quad_d2zdxdy10 = NOHALO_MIN( quad_d2zdxdy10iiii, fourth_limit10);
--  const double quad_d2zdxdy01 = NOHALO_MIN( quad_d2zdxdy01iiii, fourth_limit01);
--  const double quad_d2zdxdy11 = NOHALO_MIN( quad_d2zdxdy11iiii, fourth_limit11);
--
--  /*
--   * Part of the result which does not need derivatives:
--   */
--  const double newval1 = c00 * dos_two
--                         +
--                         c10 * dos_thr
--                         +
--                         c01 * tre_two
--                         +
--                         c11 * tre_thr;
--
--  /*
--   * Twice the part of the result which only needs first derivatives.
--   */
--  const double newval2 = c00dx * dble_dzdx00
--                         +
--                         c10dx * dble_dzdx10
--                         +
--                         c01dx * dble_dzdx01
--                         +
--                         c11dx * dble_dzdx11
--                         +
--                         c00dy * dble_dzdy00
--                         +
--                         c10dy * dble_dzdy10
--                         +
--                         c01dy * dble_dzdy01
--                         +
--                         c11dy * dble_dzdy11;
--
--  /*
--   * Four times the part of the result which only uses cross
--   * derivatives:
--   */
--  const double newval3 = c00dxdy * quad_d2zdxdy00
--                         +
--                         c10dxdy * quad_d2zdxdy10
--                         +
--                         c01dxdy * quad_d2zdxdy01
--                         +
--                         c11dxdy * quad_d2zdxdy11;
--
--  const double newval = newval1 + .5 * newval2 + .25 * newval3;
--
--  return newval;
--}
--
--/*
-- * Call Nohalo+LBB with a careful type conversion as a parameter.
-- *
-- * It would be nice to do this with templates somehow---for one thing
-- * this would allow code comments!---but we can't figure a clean way
-- * to do it.
-- */
--#define NOHALO_CONVERSION( conversion )               \
--  template <typename T> static void inline            \
--  nohalo_ ## conversion(       void*  restrict pout,  \
--                         const void*  restrict pin,   \
--                         const int             bands, \
--                         const int             lskip, \
--                         const double          x_0,   \
--                         const double          y_0 )  \
--  { \
--    T* restrict out = (T *) pout; \
--    \
--    const T* restrict in = (T *) pin; \
--    \
--    \
--    const int sign_of_x_0 = 2 * ( x_0 >= 0. ) - 1; \
--    const int sign_of_y_0 = 2 * ( y_0 >= 0. ) - 1; \
--    \
--    \
--    const int shift_forw_1_pix = sign_of_x_0 * bands; \
--    const int shift_forw_1_row = sign_of_y_0 * lskip; \
--    \
--    const int shift_back_1_pix = -shift_forw_1_pix; \
--    const int shift_back_1_row = -shift_forw_1_row; \
--    \
--    const int shift_back_2_pix = 2 * shift_back_1_pix; \
--    const int shift_back_2_row = 2 * shift_back_1_row; \
--    const int shift_forw_2_pix = 2 * shift_forw_1_pix; \
--    const int shift_forw_2_row = 2 * shift_forw_1_row; \
--    \
--    \
--    const int uno_two_shift = shift_back_1_pix + shift_back_2_row; \
--    const int uno_thr_shift =                    shift_back_2_row; \
--    const int uno_fou_shift = shift_forw_1_pix + shift_back_2_row; \
--    \
--    const int dos_one_shift = shift_back_2_pix + shift_back_1_row; \
--    const int dos_two_shift = shift_back_1_pix + shift_back_1_row; \
--    const int dos_thr_shift =                    shift_back_1_row; \
--    const int dos_fou_shift = shift_forw_1_pix + shift_back_1_row; \
--    const int dos_fiv_shift = shift_forw_2_pix + shift_back_1_row; \
--    \
--    const int tre_one_shift = shift_back_2_pix; \
--    const int tre_two_shift = shift_back_1_pix; \
--    const int tre_thr_shift = 0;                \
--    const int tre_fou_shift = shift_forw_1_pix; \
--    const int tre_fiv_shift = shift_forw_2_pix; \
--    \
--    const int qua_one_shift = shift_back_2_pix + shift_forw_1_row; \
--    const int qua_two_shift = shift_back_1_pix + shift_forw_1_row; \
--    const int qua_thr_shift =                    shift_forw_1_row; \
--    const int qua_fou_shift = shift_forw_1_pix + shift_forw_1_row; \
--    const int qua_fiv_shift = shift_forw_2_pix + shift_forw_1_row; \
--    \
--    const int cin_two_shift = shift_back_1_pix + shift_forw_2_row; \
--    const int cin_thr_shift =                    shift_forw_2_row; \
--    const int cin_fou_shift = shift_forw_1_pix + shift_forw_2_row; \
--    \
--    \
--    const double xp1over2   = ( 2 * sign_of_x_0 ) * x_0; \
--    const double xm1over2   = xp1over2 - 1.0; \
--    const double onepx      = 0.5 + xp1over2; \
--    const double onemx      = 1.5 - xp1over2; \
--    const double xp1over2sq = xp1over2 * xp1over2; \
--    \
--    const double yp1over2   = ( 2 * sign_of_y_0 ) * y_0; \
--    const double ym1over2   = yp1over2 - 1.0; \
--    const double onepy      = 0.5 + yp1over2; \
--    const double onemy      = 1.5 - yp1over2; \
--    const double yp1over2sq = yp1over2 * yp1over2; \
--    \
--    const double xm1over2sq = xm1over2 * xm1over2; \
--    const double ym1over2sq = ym1over2 * ym1over2; \
--    \
--    const double twice1px = onepx + onepx; \
--    const double twice1py = onepy + onepy; \
--    const double twice1mx = onemx + onemx; \
--    const double twice1my = onemy + onemy; \
--    \
--    const double xm1over2sq_times_ym1over2sq = xm1over2sq * ym1over2sq; \
--    const double xp1over2sq_times_ym1over2sq = xp1over2sq * ym1over2sq; \
--    const double xp1over2sq_times_yp1over2sq = xp1over2sq * yp1over2sq; \
--    const double xm1over2sq_times_yp1over2sq = xm1over2sq * yp1over2sq; \
--    \
--    const double four_times_1px_times_1py = twice1px * twice1py; \
--    const double four_times_1mx_times_1py = twice1mx * twice1py; \
--    const double twice_xp1over2_times_1py = xp1over2 * twice1py; \
--    const double twice_xm1over2_times_1py = xm1over2 * twice1py; \
--    \
--    const double twice_xm1over2_times_1my = xm1over2 * twice1my; \
--    const double twice_xp1over2_times_1my = xp1over2 * twice1my; \
--    const double four_times_1mx_times_1my = twice1mx * twice1my; \
--    const double four_times_1px_times_1my = twice1px * twice1my; \
--    \
--    const double twice_1px_times_ym1over2 = twice1px * ym1over2; \
--    const double twice_1mx_times_ym1over2 = twice1mx * ym1over2; \
--    const double xp1over2_times_ym1over2  = xp1over2 * ym1over2; \
--    const double xm1over2_times_ym1over2  = xm1over2 * ym1over2; \
--    \
--    const double xm1over2_times_yp1over2  = xm1over2 * yp1over2; \
--    const double xp1over2_times_yp1over2  = xp1over2 * yp1over2; \
--    const double twice_1mx_times_yp1over2 = twice1mx * yp1over2; \
--    const double twice_1px_times_yp1over2 = twice1px * yp1over2; \
--    \
--    \
--    const double c00 = \
--      four_times_1px_times_1py * xm1over2sq_times_ym1over2sq; \
--    const double c00dx = \
--      twice_xp1over2_times_1py * xm1over2sq_times_ym1over2sq; \
--    const double c00dy = \
--      twice_1px_times_yp1over2 * xm1over2sq_times_ym1over2sq; \
--    const double c00dxdy = \
--       xp1over2_times_yp1over2 * xm1over2sq_times_ym1over2sq; \
--    \
--    const double c10 = \
--      four_times_1mx_times_1py * xp1over2sq_times_ym1over2sq; \
--    const double c10dx = \
--      twice_xm1over2_times_1py * xp1over2sq_times_ym1over2sq; \
--    const double c10dy = \
--      twice_1mx_times_yp1over2 * xp1over2sq_times_ym1over2sq; \
--    const double c10dxdy = \
--       xm1over2_times_yp1over2 * xp1over2sq_times_ym1over2sq; \
--    \
--    const double c01 = \
--      four_times_1px_times_1my * xm1over2sq_times_yp1over2sq; \
--    const double c01dx = \
--      twice_xp1over2_times_1my * xm1over2sq_times_yp1over2sq; \
--    const double c01dy = \
--      twice_1px_times_ym1over2 * xm1over2sq_times_yp1over2sq; \
--    const double c01dxdy = \
--       xp1over2_times_ym1over2 * xm1over2sq_times_yp1over2sq; \
--    \
--    const double c11 = \
--      four_times_1mx_times_1my * xp1over2sq_times_yp1over2sq; \
--    const double c11dx = \
--      twice_xm1over2_times_1my * xp1over2sq_times_yp1over2sq; \
--    const double c11dy = \
--      twice_1mx_times_ym1over2 * xp1over2sq_times_yp1over2sq; \
--    const double c11dxdy = \
--       xm1over2_times_ym1over2 * xp1over2sq_times_yp1over2sq; \
--    \
--    \
--    int band = bands; \
--    \
--    \
--    do \
--      { \
--        double uno_one, uno_two, uno_thr, uno_fou;  \
--        double dos_one, dos_two, dos_thr, dos_fou;  \
--        double tre_one, tre_two, tre_thr, tre_fou;  \
--        double qua_one, qua_two, qua_thr, qua_fou;  \
--        \
--        nohalo_subdivision( in[ uno_two_shift ], \
--                            in[ uno_thr_shift ], \
--                            in[ uno_fou_shift ], \
--                            in[ dos_one_shift ], \
--                            in[ dos_two_shift ], \
--                            in[ dos_thr_shift ], \
--                            in[ dos_fou_shift ], \
--                            in[ dos_fiv_shift ], \
--                            in[ tre_one_shift ], \
--                            in[ tre_two_shift ], \
--                            in[ tre_thr_shift ], \
--                            in[ tre_fou_shift ], \
--                            in[ tre_fiv_shift ], \
--                            in[ qua_one_shift ], \
--                            in[ qua_two_shift ], \
--                            in[ qua_thr_shift ], \
--                            in[ qua_fou_shift ], \
--                            in[ qua_fiv_shift ], \
--                            in[ cin_two_shift ], \
--                            in[ cin_thr_shift ], \
--                            in[ cin_fou_shift ], \
--                            &uno_one,            \
--                            &uno_two,            \
--                            &uno_thr,            \
--                            &uno_fou,            \
--                            &dos_one,            \
--                            &dos_two,            \
--                            &dos_thr,            \
--                            &dos_fou,            \
--                            &tre_one,            \
--                            &tre_two,            \
--                            &tre_thr,            \
--                            &tre_fou,            \
--                            &qua_one,            \
--                            &qua_two,            \
--                            &qua_thr,            \
--                            &qua_fou );          \
--        \
--        const double double_result =        \
--          lbbicubic( c00,                   \
--                     c10,                   \
--                     c01,                   \
--                     c11,                   \
--                     c00dx,                 \
--                     c10dx,                 \
--                     c01dx,                 \
--                     c11dx,                 \
--                     c00dy,                 \
--                     c10dy,                 \
--                     c01dy,                 \
--                     c11dy,                 \
--                     c00dxdy,               \
--                     c10dxdy,               \
--                     c01dxdy,               \
--                     c11dxdy,               \
--                     uno_one,               \
--                     uno_two,               \
--                     uno_thr,               \
--                     uno_fou,               \
--                     dos_one,               \
--                     dos_two,               \
--                     dos_thr,               \
--                     dos_fou,               \
--                     tre_one,               \
--                     tre_two,               \
--                     tre_thr,               \
--                     tre_fou,               \
--                     qua_one,               \
--                     qua_two,               \
--                     qua_thr,               \
--                     qua_fou );             \
--        \
--        {                                                         \
--          const T result = to_ ## conversion<T>( double_result ); \
--          in++;                                                   \
--          *out++ = result;                                        \
--        }                                                         \
--        \
--      } while (--band); \
--  }
--
--
--NOHALO_CONVERSION( fptypes )
--NOHALO_CONVERSION( withsign )
--NOHALO_CONVERSION( nosign )
--
--
--#define CALL( T, conversion )             \
--  nohalo_ ## conversion<T>( out,          \
--                            p,            \
--                            bands,        \
--                            lskip,        \
--                            relative_x,   \
--                            relative_y );
--
--
--/*
-- * We need C linkage:
-- */
--extern "C" {
--G_DEFINE_TYPE( VipsInterpolateNohalo, vips_interpolate_nohalo,
--      VIPS_TYPE_INTERPOLATE );
--}
--
--
--static void
--vips_interpolate_nohalo_interpolate( VipsInterpolate* restrict interpolate,
--                                     void*            restrict out,
--                                     VipsRegion*      restrict in,
--                                     double                    absolute_x,
--                                     double                    absolute_y )
--{
--  /* absolute_x and absolute_y are always >= 2.0 (see double-check assert
--   * below), so we don't need floor(). 
--   *
--   * It's 2 not 0 since we ask for a window_offset of 2 at the bottom.
--   */
--  const int ix = (int) (absolute_x + 0.5);
--  const int iy = (int) (absolute_y + 0.5);
--
--  /*
--   * Move the pointer to (the first band of) the top/left pixel of the
--   * 2x2 group of pixel centers which contains the sampling location
--   * in its convex hull:
--   */
--  const VipsPel* restrict p = VIPS_REGION_ADDR( in, ix, iy );
--
--  const double relative_x = absolute_x - ix;
--  const double relative_y = absolute_y - iy;
--
--  /*
--   * VIPS versions of Nicolas's pixel addressing values.
--   */
--  const int lskip = VIPS_REGION_LSKIP( in ) / 
--        VIPS_IMAGE_SIZEOF_ELEMENT( in->im );
--
--  /*
--   * Double the bands for complex images to account for the real and
--   * imaginary parts being computed independently:
--   */
--  const int actual_bands = in->im->Bands;
--  const int bands =
--    vips_bandfmt_iscomplex( in->im->BandFmt ) ? 2 * actual_bands : actual_bands;
--
--  /* Confirm that absolute_x and absolute_y are >= 2, see above. 
--   */
--  g_assert( absolute_x >= 2.0 );
--  g_assert( absolute_y >= 2.0 );
--
--  switch( in->im->BandFmt ) {
--  case VIPS_FORMAT_UCHAR:
--    CALL( unsigned char, nosign );
--    break;
--
--  case VIPS_FORMAT_CHAR:
--    CALL( signed char, withsign );
--    break;
--
--  case VIPS_FORMAT_USHORT:
--    CALL( unsigned short, nosign );
--    break;
--
--  case VIPS_FORMAT_SHORT:
--    CALL( signed short, withsign );
--    break;
--
--  case VIPS_FORMAT_UINT:
--    CALL( unsigned int, nosign );
--    break;
--
--  case VIPS_FORMAT_INT:
--    CALL( signed int, withsign );
--    break;
--
--  /*
--   * Complex images are handled by doubling of bands.
--   */
--  case VIPS_FORMAT_FLOAT:
--  case VIPS_FORMAT_COMPLEX:
--    CALL( float, fptypes );
--    break;
--
--  case VIPS_FORMAT_DOUBLE:
--  case VIPS_FORMAT_DPCOMPLEX:
--    CALL( double, fptypes );
--    break;
--
--  default:
--    g_assert( 0 );
--    break;
--  }
--}
--
--static void
--vips_interpolate_nohalo_class_init( VipsInterpolateNohaloClass *klass )
--{
--  VipsObjectClass *object_class = VIPS_OBJECT_CLASS( klass );
--  VipsInterpolateClass *interpolate_class = VIPS_INTERPOLATE_CLASS( klass );
--
--  object_class->nickname    = "nohalo";
--  object_class->description =
--    _( "Edge sharpening resampler with halo reduction" );
--
--  interpolate_class->interpolate   = vips_interpolate_nohalo_interpolate;
--  interpolate_class->window_size   = 5;
--  interpolate_class->window_offset = 2;
--}
--
--static void
--vips_interpolate_nohalo_init( VipsInterpolateNohalo *nohalo )
--{
--}
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvips/resample/vsqbs.cpp vips-7.38.5/libvips/resample/vsqbs.cpp
---- vips-7.38.5-vanilla/libvips/resample/vsqbs.cpp     2014-07-17 23:48:36.232794473 -0400
-+++ vips-7.38.5/libvips/resample/vsqbs.cpp     1969-12-31 19:00:00.000000000 -0500
-@@ -1,409 +0,0 @@
--/* vertex-split subdivision followed by quadratic b-spline smoothing
-- *
-- * C. Racette 23-28/05/2010 based on code by N. Robidoux and J. Cupitt
-- *
-- * N. Robidoux 29-30/05/2010
-- */
--
--/*
--
--    This file is part of VIPS.
--
--    VIPS is free software; you can redistribute it and/or modify it
--    under the terms of the GNU Lesser 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
--    Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--/*
-- * 2010 (c) Chantal Racette, Nicolas Robidoux, John Cupitt.
-- *
-- * Nicolas Robidoux thanks Adam Turcotte, Geert Jordaens, Ralf Meyer,
-- * Øyvind Kolås, Minglun Gong and Eric Daoust for useful comments and
-- * code.
-- *
-- * Chantal Racette's image resampling research and programming funded
-- * in part by a NSERC Discovery Grant awarded to Julien Dompierre
-- * (20-61098).
-- */
--
--/*
-- * Vertex-Split Quadratic B-Splines (VSQBS) is a brand new method
-- * which consists of vertex-split subdivision, a subdivision method
-- * with the (as yet unknown?) property that data which is (locally)
-- * constant on diagonals is subdivided into data which is (locally)
-- * constant on diagonals, followed by quadratic B-Spline smoothing.
-- * Because both methods are linear, their combination can be
-- * implemented as if there is no subdivision.
-- *
-- * At high enlargement ratios, VSQBS is very effective at "masking"
-- * that the original has pixels uniformly distributed on a grid. In
-- * particular, VSQBS produces resamples with only very mild
-- * staircasing. Like cubic B-Spline smoothing, however, VSQBS is not
-- * an interpolatory method. For example, using VSQBS to perform the
-- * identity geometric transformation (enlargement by a scaling factor
-- * equal to 1) on an image does not return the original: VSQBS
-- * effectively smooths out the image with the convolution mask
-- *
-- *     1/8
-- * 1/8 1/2 1/8
-- *     1/8
-- *
-- * which is a fairly moderate blur (although the checkerboard mode is
-- * in its nullspace).
-- *
-- * By blending VSQBS with an interpolatory method (bilinear, say) in a
-- * transformation adaptive environment (current GEGL, for example), it
-- * is quite easy to restore that resampling for identity geometric
-- * transformation is equivalent to the identity, and rotations are not
-- * affected by the above, implicit, blur. Contact N. Robidoux for
-- * details.
-- *
-- * An article on VSQBS is forthcoming.
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <stdio.h>
--#include <stdlib.h>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--#include "templates.h"
--
--#define VIPS_TYPE_INTERPOLATE_VSQBS \
--      (vips_interpolate_vsqbs_get_type())
--#define VIPS_INTERPOLATE_VSQBS( obj ) \
--      (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
--      VIPS_TYPE_INTERPOLATE_VSQBS, VipsInterpolateVsqbs ))
--#define VIPS_INTERPOLATE_VSQBS_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_CAST( (klass), \
--      VIPS_TYPE_INTERPOLATE_VSQBS, VipsInterpolateVsqbsClass))
--#define VIPS_IS_INTERPOLATE_VSQBS( obj ) \
--      (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_VSQBS ))
--#define VIPS_IS_INTERPOLATE_VSQBS_CLASS( klass ) \
--      (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_VSQBS ))
--#define VIPS_INTERPOLATE_VSQBS_GET_CLASS( obj ) \
--      (G_TYPE_INSTANCE_GET_CLASS( (obj), \
--      VIPS_TYPE_INTERPOLATE_VSQBS, VipsInterpolateVsqbsClass ))
--
--typedef struct _VipsInterpolateVsqbs {
--      VipsInterpolate parent_object;
--
--} VipsInterpolateVsqbs;
--
--typedef struct _VipsInterpolateVsqbsClass {
--      VipsInterpolateClass parent_class;
--
--} VipsInterpolateVsqbsClass;
--
--/*
-- * THE STENCIL OF INPUT VALUES:
-- *
-- * Pointer arithmetic is used to implicitly reflect the input stencil
-- * about dos_two---assumed closer to the sampling location than other
-- * pixels (ties are OK)---in such a way that after reflection the
-- * sampling point is to the bottom right of dos_two.
-- *
-- * The following code and picture assumes that the stencil reflexion
-- * has already been performed. (X is the sampling location.)
-- *
-- *
-- *               (ix,iy-1)    (ix+1,iy-1)
-- *               = uno_two    = uno_thr
-- *
-- *
-- *
-- *  (ix-1,iy)    (ix,iy)      (ix+1,iy)
-- *  = dos_one    = dos_two    = dos_thr
-- *                       X
-- *
-- *
-- *  (ix-1,iy+1)  (ix,iy+1)    (ix+1,iy+1)
-- *  = tre_one    = tre_two    = tre_thr
-- *
-- *
-- * The above input pixel values are the ones needed in order to
-- * IMPLICITLY make available the following values, needed by quadratic
-- * B-Splines, which is performed on (shifted) double density data:
-- *
-- *
-- *  uno_one_1 =      uno_two_1 =      uno_thr_1 =
-- *  (ix-1/4,iy-1/4)  (ix+1/4,iy-1/4)  (ix+3/4,iy-1/4)
-- *
-- *
-- *
-- *                 X            or X
-- *  dos_one_1 =      dos_two_1 =      dos_thr_1 =
-- *  (ix-1/4,iy+1/4)  (ix+1/4,iy+1/4)  (ix+3/4,iy+1/4)
-- *              or X            or X
-- *
-- *
-- *
-- *  tre_one_1 =      tre_two_1 =      tre_thr_1 =
-- *  (ix-1/4,iy+3/4)  (ix+1/4,iy+3/4)  (ix+3/4,iy+3/4)
-- *
-- *
-- * In the coefficient computations, we fix things so that coordinates
-- * are relative to dos_two_1, and so that distances are rescaled so
-- * that double density pixel locations are at a distance of 1.
-- */
--
--/*
-- * Call vertex-split + quadratic B-splines with a careful type
-- * conversion as a parameter. (It would be nice to do this with
-- * templates somehow---for one thing this would allow code
-- * comments---but we can't figure a clean way to do it.)
-- */
--#define VSQBS_CONVERSION( conversion )               \
--  template <typename T> static void inline           \
--  vsqbs_ ## conversion(       void*    restrict pout, \
--                        const VipsPel* restrict pin,  \
--                        const int             bands, \
--                        const int             lskip, \
--                        const double          x_0,   \
--                        const double          y_0 )  \
--  { \
--    T* restrict out = (T *) pout; \
--    \
--    const T* restrict in = (T *) pin; \
--    \
--    const int sign_of_x_0 = 2 * ( x_0 >= 0. ) - 1; \
--    const int sign_of_y_0 = 2 * ( y_0 >= 0. ) - 1; \
--    \
--    const int shift_forw_1_pix = sign_of_x_0 * bands; \
--    const int shift_forw_1_row = sign_of_y_0 * lskip; \
--    \
--    const int shift_back_1_pix = -shift_forw_1_pix; \
--    const int shift_back_1_row = -shift_forw_1_row; \
--    \
--    const int uno_two_shift =                    shift_back_1_row; \
--    const int uno_thr_shift = shift_forw_1_pix + shift_back_1_row; \
--    \
--    const int dos_one_shift = shift_back_1_pix; \
--    const int dos_two_shift = 0;                \
--    const int dos_thr_shift = shift_forw_1_pix; \
--    \
--    const int tre_one_shift = shift_back_1_pix + shift_forw_1_row; \
--    const int tre_two_shift =                    shift_forw_1_row; \
--    const int tre_thr_shift = shift_forw_1_pix + shift_forw_1_row; \
--    \
--    \
--    const double twice_abs_x_0 = ( 2 * sign_of_x_0 ) * x_0; \
--    const double twice_abs_y_0 = ( 2 * sign_of_y_0 ) * y_0; \
--    const double x             = twice_abs_x_0 + -0.5;      \
--    const double y             = twice_abs_y_0 + -0.5;      \
--    const double cent          = 0.75 - x * x;              \
--    const double mid           = 0.75 - y * y;              \
--    const double left          = -0.5 * ( x + cent ) + 0.5; \
--    const double top           = -0.5 * ( y + mid  ) + 0.5; \
--    const double left_p_cent   = left + cent;               \
--    const double top_p_mid     = top  + mid;                \
--    const double cent_p_rite   = 1.0 - left;                \
--    const double mid_p_bot     = 1.0 - top;                 \
--    const double rite          = 1.0 - left_p_cent;         \
--    const double bot           = 1.0 - top_p_mid;           \
--    \
--    const double four_c_uno_two = left_p_cent * top;                    \
--    const double four_c_dos_one = left        * top_p_mid;              \
--    const double four_c_dos_two = left_p_cent + top_p_mid;              \
--    const double four_c_dos_thr = cent_p_rite * top_p_mid + rite;       \
--    const double four_c_tre_two = mid_p_bot * left_p_cent + bot;        \
--    const double four_c_tre_thr = mid_p_bot * rite + cent_p_rite * bot; \
--    const double four_c_uno_thr = top  - four_c_uno_two;                \
--    const double four_c_tre_one = left - four_c_dos_one;                \
--    \
--    \
--    int band = bands; \
--    \
--    do \
--      { \
--        const double double_result =               \
--          (                                        \
--            (                                      \
--              (                                    \
--                four_c_uno_two * in[uno_two_shift] \
--                +                                  \
--                four_c_dos_one * in[dos_one_shift] \
--              )                                    \
--              +                                    \
--              (                                    \
--                four_c_dos_two * in[dos_two_shift] \
--                +                                  \
--                four_c_dos_thr * in[dos_thr_shift] \
--              )                                    \
--            )                                      \
--            +                                      \
--            (                                      \
--              (                                    \
--                four_c_tre_two * in[tre_two_shift] \
--                +                                  \
--                four_c_tre_thr * in[tre_thr_shift] \
--              )                                    \
--              +                                    \
--              (                                    \
--                four_c_uno_thr * in[uno_thr_shift] \
--                +                                  \
--                four_c_tre_one * in[tre_one_shift] \
--              )                                    \
--            )                                      \
--          ) * 0.25;                                \
--        \
--        const T result = to_ ## conversion<T>( double_result ); \
--        in++;                                                   \
--        *out++ = result;                                        \
--        \
--      } while (--band); \
--  }
--
--
--VSQBS_CONVERSION( fptypes )
--VSQBS_CONVERSION( withsign )
--VSQBS_CONVERSION( nosign )
--
--
--#define CALL( T, conversion )               \
--  vsqbs_ ## conversion<T>( out,             \
--                              p,            \
--                              bands,        \
--                              lskip,        \
--                              relative_x,   \
--                              relative_y );
--
--
--/*
-- * We need C linkage:
-- */
--extern "C" {
--  G_DEFINE_TYPE( VipsInterpolateVsqbs, vips_interpolate_vsqbs,
--                 VIPS_TYPE_INTERPOLATE );
--}
--
--
--static void
--vips_interpolate_vsqbs_interpolate( VipsInterpolate* restrict interpolate,
--                                    void*            restrict out,
--                                    REGION*          restrict in,
--                                    double                    absolute_x,
--                                    double                    absolute_y )
--{
--  /* absolute_x and absolute_y are always >= 1.0 (see double-check assert
--   * below), so we don't need floor(). 
--   *
--   * It's 1 not 0 since we ask for a window_offset of 1 at the bottom.
--   */
--  const int ix = (int) (absolute_x + 0.5);
--  const int iy = (int) (absolute_y + 0.5);
--
--  /*
--   * Move the pointer to (the first band of) the top/left pixel of the
--   * 2x2 group of pixel centers which contains the sampling location
--   * in its convex hull:
--   */
--  const VipsPel* restrict p = VIPS_REGION_ADDR( in, ix, iy );
--
--  const double relative_x = absolute_x - ix;
--  const double relative_y = absolute_y - iy;
--
--  /*
--   * VIPS versions of Nicolas's pixel addressing values.
--   */
--  const int lskip = VIPS_REGION_LSKIP( in ) / 
--        VIPS_IMAGE_SIZEOF_ELEMENT( in->im );
--
--  /*
--   * Double the bands for complex images to account for the real and
--   * imaginary parts being computed independently:
--   */
--  const int actual_bands = in->im->Bands;
--  const int bands =
--    vips_bandfmt_iscomplex( in->im->BandFmt ) ? 2 * actual_bands : actual_bands;
--
--  /* Confirm that absolute_x and absolute_y are >= 1, see above. 
--   */
--  g_assert( absolute_x >= 1.0 );
--  g_assert( absolute_y >= 1.0 );
--
--  switch( in->im->BandFmt ) {
--  case VIPS_FORMAT_UCHAR:
--    CALL( unsigned char, nosign );
--    break;
--
--  case VIPS_FORMAT_CHAR:
--    CALL( signed char, withsign );
--    break;
--
--  case VIPS_FORMAT_USHORT:
--    CALL( unsigned short, nosign );
--    break;
--
--  case VIPS_FORMAT_SHORT:
--    CALL( signed short, withsign );
--    break;
--
--  case VIPS_FORMAT_UINT:
--    CALL( unsigned int, nosign );
--    break;
--
--  case VIPS_FORMAT_INT:
--    CALL( signed int, withsign );
--    break;
--
--  /*
--   * Complex images are handled by doubling bands:
--   */
--  case VIPS_FORMAT_FLOAT:
--  case VIPS_FORMAT_COMPLEX:
--    CALL( float, fptypes );
--    break;
--
--  case VIPS_FORMAT_DOUBLE:
--  case VIPS_FORMAT_DPCOMPLEX:
--    CALL( double, fptypes );
--    break;
--
--  default:
--    g_assert( 0 );
--    break;
--  }
--}
--
--static void
--vips_interpolate_vsqbs_class_init( VipsInterpolateVsqbsClass *klass )
--{
--  VipsObjectClass           *object_class =      VIPS_OBJECT_CLASS( klass );
--  VipsInterpolateClass *interpolate_class = VIPS_INTERPOLATE_CLASS( klass );
--
--  object_class->nickname    = "vsqbs";
--  object_class->description = _( "B-Splines with antialiasing smoothing" );
--
--  interpolate_class->interpolate   = vips_interpolate_vsqbs_interpolate;
--  interpolate_class->window_size   = 3;
--  interpolate_class->window_offset = 1;
--}
--
--static void
--vips_interpolate_vsqbs_init( VipsInterpolateVsqbs *vsqbs )
--{
--}
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/Makefile.am vips-7.38.5/libvipsCC/include/Makefile.am
---- vips-7.38.5-vanilla/libvipsCC/include/Makefile.am  2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/Makefile.am  1969-12-31 19:00:00.000000000 -0500
-@@ -1,2 +0,0 @@
--
--SUBDIRS = vips
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/Makefile.in vips-7.38.5/libvipsCC/include/Makefile.in
---- vips-7.38.5-vanilla/libvipsCC/include/Makefile.in  2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/Makefile.in  1969-12-31 19:00:00.000000000 -0500
-@@ -1,719 +0,0 @@
--# Makefile.in generated by automake 1.13.3 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994-2013 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@
--am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
--am__make_running_with_option = \
--  case $${target_option-} in \
--      ?) ;; \
--      *) echo "am__make_running_with_option: internal error: invalid" \
--              "target option '$${target_option-}' specified" >&2; \
--         exit 1;; \
--  esac; \
--  has_opt=no; \
--  sane_makeflags=$$MAKEFLAGS; \
--  if $(am__is_gnu_make); then \
--    sane_makeflags=$$MFLAGS; \
--  else \
--    case $$MAKEFLAGS in \
--      *\\[\ \ ]*) \
--        bs=\\; \
--        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
--          | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
--    esac; \
--  fi; \
--  skip_next=no; \
--  strip_trailopt () \
--  { \
--    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
--  }; \
--  for flg in $$sane_makeflags; do \
--    test $$skip_next = yes && { skip_next=no; continue; }; \
--    case $$flg in \
--      *=*|--*) continue;; \
--        -*I) strip_trailopt 'I'; skip_next=yes;; \
--      -*I?*) strip_trailopt 'I';; \
--        -*O) strip_trailopt 'O'; skip_next=yes;; \
--      -*O?*) strip_trailopt 'O';; \
--        -*l) strip_trailopt 'l'; skip_next=yes;; \
--      -*l?*) strip_trailopt 'l';; \
--      -[dEDm]) skip_next=yes;; \
--      -[JT]) skip_next=yes;; \
--    esac; \
--    case $$flg in \
--      *$$target_option*) has_opt=yes; break;; \
--    esac; \
--  done; \
--  test $$has_opt = yes
--am__make_dryrun = (target_option=n; $(am__make_running_with_option))
--am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@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@
--subdir = libvipsCC/include
--DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
--      $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/acinclude.m4 \
--      $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
--      $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--AM_V_P = $(am__v_P_@AM_V@)
--am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
--am__v_P_0 = false
--am__v_P_1 = :
--AM_V_GEN = $(am__v_GEN_@AM_V@)
--am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
--am__v_GEN_0 = @echo "  GEN     " $@;
--am__v_GEN_1 = 
--AM_V_at = $(am__v_at_@AM_V@)
--am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
--am__v_at_0 = @
--am__v_at_1 = 
--SOURCES =
--DIST_SOURCES =
--RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
--      ctags-recursive dvi-recursive html-recursive info-recursive \
--      install-data-recursive install-dvi-recursive \
--      install-exec-recursive install-html-recursive \
--      install-info-recursive install-pdf-recursive \
--      install-ps-recursive install-recursive installcheck-recursive \
--      installdirs-recursive pdf-recursive ps-recursive \
--      tags-recursive uninstall-recursive
--am__can_run_installinfo = \
--  case $$AM_UPDATE_INFO_DIR in \
--    n|no|NO) false;; \
--    *) (install-info --version) >/dev/null 2>&1;; \
--  esac
--RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive       \
--  distclean-recursive maintainer-clean-recursive
--am__recursive_targets = \
--  $(RECURSIVE_TARGETS) \
--  $(RECURSIVE_CLEAN_TARGETS) \
--  $(am__extra_recursive_targets)
--AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
--      distdir
--am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
--# Read a list of newline-separated strings from the standard input,
--# and print each of them once, without duplicates.  Input order is
--# *not* preserved.
--am__uniquify_input = $(AWK) '\
--  BEGIN { nonempty = 0; } \
--  { items[$$0] = 1; nonempty = 1; } \
--  END { if (nonempty) { for (i in items) print i; }; } \
--'
--# Make sure the list of sources is unique.  This is necessary because,
--# e.g., the same source file might be shared among _SOURCES variables
--# for different programs/libraries.
--am__define_uniq_tagged_files = \
--  list='$(am__tagged_files)'; \
--  unique=`for i in $$list; do \
--    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
--  done | $(am__uniquify_input)`
--ETAGS = etags
--CTAGS = ctags
--DIST_SUBDIRS = $(SUBDIRS)
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--am__relativize = \
--  dir0=`pwd`; \
--  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
--  sed_rest='s,^[^/]*/*,,'; \
--  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
--  sed_butlast='s,/*[^/]*$$,,'; \
--  while test -n "$$dir1"; do \
--    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
--    if test "$$first" != "."; then \
--      if test "$$first" = ".."; then \
--        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
--        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
--      else \
--        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
--        if test "$$first2" = "$$first"; then \
--          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
--        else \
--          dir2="../$$dir2"; \
--        fi; \
--        dir0="$$dir0"/"$$first"; \
--      fi; \
--    fi; \
--    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
--  done; \
--  reldir="$$dir2"
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
--AR = @AR@
--AS = @AS@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CATALOGS = @CATALOGS@
--CATOBJEXT = @CATOBJEXT@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFITSIO_CFLAGS = @CFITSIO_CFLAGS@
--CFITSIO_LIBS = @CFITSIO_LIBS@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CXX = @CXX@
--CXXCPP = @CXXCPP@
--CXXDEPMODE = @CXXDEPMODE@
--CXXFLAGS = @CXXFLAGS@
--CYGPATH_W = @CYGPATH_W@
--DATADIRNAME = @DATADIRNAME@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DLLTOOL = @DLLTOOL@
--DLLWRAP = @DLLWRAP@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--EXEEXT = @EXEEXT@
--EXIF_CFLAGS = @EXIF_CFLAGS@
--EXIF_LIBS = @EXIF_LIBS@
--FFTW_CFLAGS = @FFTW_CFLAGS@
--FFTW_LIBS = @FFTW_LIBS@
--FGREP = @FGREP@
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--GMOFILES = @GMOFILES@
--GMSGFMT = @GMSGFMT@
--GREP = @GREP@
--GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
--GTHREAD_LIBS = @GTHREAD_LIBS@
--GTKDOC_CHECK = @GTKDOC_CHECK@
--GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
--GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
--GTKDOC_MKPDF = @GTKDOC_MKPDF@
--GTKDOC_REBASE = @GTKDOC_REBASE@
--HTML_DIR = @HTML_DIR@
--IMAGE_MAGICK_CFLAGS = @IMAGE_MAGICK_CFLAGS@
--IMAGE_MAGICK_LIBS = @IMAGE_MAGICK_LIBS@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--INSTOBJEXT = @INSTOBJEXT@
--INTLLIBS = @INTLLIBS@
--INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
--INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
--INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
--INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
--INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
--INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
--INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
--INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
--JPEG_INCLUDES = @JPEG_INCLUDES@
--JPEG_LIBS = @JPEG_LIBS@
--LCMS_CFLAGS = @LCMS_CFLAGS@
--LCMS_LIBS = @LCMS_LIBS@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBRARY_AGE = @LIBRARY_AGE@
--LIBRARY_CURRENT = @LIBRARY_CURRENT@
--LIBRARY_REVISION = @LIBRARY_REVISION@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
--LIBWEBP_LIBS = @LIBWEBP_LIBS@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAGICK_CFLAGS = @MAGICK_CFLAGS@
--MAGICK_LIBS = @MAGICK_LIBS@
--MAGICK_WAND_CFLAGS = @MAGICK_WAND_CFLAGS@
--MAGICK_WAND_LIBS = @MAGICK_WAND_LIBS@
--MAKEINFO = @MAKEINFO@
--MANIFEST_TOOL = @MANIFEST_TOOL@
--MATIO_CFLAGS = @MATIO_CFLAGS@
--MATIO_LIBS = @MATIO_LIBS@
--MKDIR_P = @MKDIR_P@
--MKINSTALLDIRS = @MKINSTALLDIRS@
--MONOTONIC_CFLAGS = @MONOTONIC_CFLAGS@
--MONOTONIC_LIBS = @MONOTONIC_LIBS@
--MSGFMT = @MSGFMT@
--MSGFMT_OPTS = @MSGFMT_OPTS@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
--OPENEXR_LIBS = @OPENEXR_LIBS@
--OPENSLIDE_CFLAGS = @OPENSLIDE_CFLAGS@
--OPENSLIDE_LIBS = @OPENSLIDE_LIBS@
--ORC_CFLAGS = @ORC_CFLAGS@
--ORC_LIBS = @ORC_LIBS@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGES_USED = @PACKAGES_USED@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
--PANGOFT2_LIBS = @PANGOFT2_LIBS@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--PKG_CONFIG = @PKG_CONFIG@
--PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
--PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
--PNG_CFLAGS = @PNG_CFLAGS@
--PNG_INCLUDES = @PNG_INCLUDES@
--PNG_LIBS = @PNG_LIBS@
--POFILES = @POFILES@
--POSUB = @POSUB@
--PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
--PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
--PYTHON = @PYTHON@
--PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
--PYTHON_INCLUDES = @PYTHON_INCLUDES@
--PYTHON_PLATFORM = @PYTHON_PLATFORM@
--PYTHON_PREFIX = @PYTHON_PREFIX@
--PYTHON_VERSION = @PYTHON_VERSION@
--RANLIB = @RANLIB@
--REQUIRED_CFLAGS = @REQUIRED_CFLAGS@
--REQUIRED_LIBS = @REQUIRED_LIBS@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--THREADS_CFLAGS = @THREADS_CFLAGS@
--THREADS_LIBS = @THREADS_LIBS@
--TIFF_CFLAGS = @TIFF_CFLAGS@
--TIFF_INCLUDES = @TIFF_INCLUDES@
--TIFF_LIBS = @TIFF_LIBS@
--TYPE_INIT_CFLAGS = @TYPE_INIT_CFLAGS@
--TYPE_INIT_LIBS = @TYPE_INIT_LIBS@
--USE_NLS = @USE_NLS@
--VERSION = @VERSION@
--VIPS_CFLAGS = @VIPS_CFLAGS@
--VIPS_CXX_LIBS = @VIPS_CXX_LIBS@
--VIPS_EXEEXT = @VIPS_EXEEXT@
--VIPS_INCLUDES = @VIPS_INCLUDES@
--VIPS_LIBDIR = @VIPS_LIBDIR@
--VIPS_LIBS = @VIPS_LIBS@
--VIPS_MAJOR_VERSION = @VIPS_MAJOR_VERSION@
--VIPS_MICRO_VERSION = @VIPS_MICRO_VERSION@
--VIPS_MINOR_VERSION = @VIPS_MINOR_VERSION@
--VIPS_VERSION = @VIPS_VERSION@
--VIPS_VERSION_STRING = @VIPS_VERSION_STRING@
--XGETTEXT = @XGETTEXT@
--XMKMF = @XMKMF@
--X_CFLAGS = @X_CFLAGS@
--X_EXTRA_LIBS = @X_EXTRA_LIBS@
--X_LIBS = @X_LIBS@
--X_PRE_LIBS = @X_PRE_LIBS@
--ZIP_INCLUDES = @ZIP_INCLUDES@
--ZIP_LIBS = @ZIP_LIBS@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_AR = @ac_ct_AR@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_CXX = @ac_ct_CXX@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--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@
--pdfdir = @pdfdir@
--pkgpyexecdir = @pkgpyexecdir@
--pkgpythondir = @pkgpythondir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--pyexecdir = @pyexecdir@
--pythondir = @pythondir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--vips_introspection_sources = @vips_introspection_sources@
--SUBDIRS = vips
--all: all-recursive
--
--.SUFFIXES:
--$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
--      @for dep in $?; do \
--        case '$(am__configure_deps)' in \
--          *$$dep*) \
--            ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
--              && { if test -f $@; then exit 0; else break; fi; }; \
--            exit 1;; \
--        esac; \
--      done; \
--      echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libvipsCC/include/Makefile'; \
--      $(am__cd) $(top_srcdir) && \
--        $(AUTOMAKE) --foreign libvipsCC/include/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
--      @case '$?' in \
--        *config.status*) \
--          cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
--        *) \
--          echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
--          cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
--      esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure:  $(am__configure_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--mostlyclean-libtool:
--      -rm -f *.lo
--
--clean-libtool:
--      -rm -rf .libs _libs
--
--# This directory's subdirectories are mostly independent; you can cd
--# into them and run 'make' without going through this Makefile.
--# To change the values of 'make' variables: instead of editing Makefiles,
--# (1) if the variable is set in 'config.status', edit 'config.status'
--#     (which will cause the Makefiles to be regenerated when you run 'make');
--# (2) otherwise, pass the desired values on the 'make' command line.
--$(am__recursive_targets):
--      @fail=; \
--      if $(am__make_keepgoing); then \
--        failcom='fail=yes'; \
--      else \
--        failcom='exit 1'; \
--      fi; \
--      dot_seen=no; \
--      target=`echo $@ | sed s/-recursive//`; \
--      case "$@" in \
--        distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
--        *) list='$(SUBDIRS)' ;; \
--      esac; \
--      for subdir in $$list; do \
--        echo "Making $$target in $$subdir"; \
--        if test "$$subdir" = "."; then \
--          dot_seen=yes; \
--          local_target="$$target-am"; \
--        else \
--          local_target="$$target"; \
--        fi; \
--        ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
--        || eval $$failcom; \
--      done; \
--      if test "$$dot_seen" = "no"; then \
--        $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
--      fi; test -z "$$fail"
--
--ID: $(am__tagged_files)
--      $(am__define_uniq_tagged_files); mkid -fID $$unique
--tags: tags-recursive
--TAGS: tags
--
--tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      set x; \
--      here=`pwd`; \
--      if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
--        include_option=--etags-include; \
--        empty_fix=.; \
--      else \
--        include_option=--include; \
--        empty_fix=; \
--      fi; \
--      list='$(SUBDIRS)'; for subdir in $$list; do \
--        if test "$$subdir" = .; then :; else \
--          test ! -f $$subdir/TAGS || \
--            set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
--        fi; \
--      done; \
--      $(am__define_uniq_tagged_files); \
--      shift; \
--      if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
--        test -n "$$unique" || unique=$$empty_fix; \
--        if test $$# -gt 0; then \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            "$$@" $$unique; \
--        else \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            $$unique; \
--        fi; \
--      fi
--ctags: ctags-recursive
--
--CTAGS: ctags
--ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      $(am__define_uniq_tagged_files); \
--      test -z "$(CTAGS_ARGS)$$unique" \
--        || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
--           $$unique
--
--GTAGS:
--      here=`$(am__cd) $(top_builddir) && pwd` \
--        && $(am__cd) $(top_srcdir) \
--        && gtags -i $(GTAGS_ARGS) "$$here"
--cscopelist: cscopelist-recursive
--
--cscopelist-am: $(am__tagged_files)
--      list='$(am__tagged_files)'; \
--      case "$(srcdir)" in \
--        [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
--        *) sdir=$(subdir)/$(srcdir) ;; \
--      esac; \
--      for i in $$list; do \
--        if test -f "$$i"; then \
--          echo "$(subdir)/$$i"; \
--        else \
--          echo "$$sdir/$$i"; \
--        fi; \
--      done >> $(top_builddir)/cscope.files
--
--distclean-tags:
--      -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
--
--distdir: $(DISTFILES)
--      @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 "$(distdir)/$$file"; then \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
--            cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
--        else \
--          test -f "$(distdir)/$$file" \
--          || cp -p $$d/$$file "$(distdir)/$$file" \
--          || exit 1; \
--        fi; \
--      done
--      @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
--        if test "$$subdir" = .; then :; else \
--          $(am__make_dryrun) \
--            || test -d "$(distdir)/$$subdir" \
--            || $(MKDIR_P) "$(distdir)/$$subdir" \
--            || exit 1; \
--          dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
--          $(am__relativize); \
--          new_distdir=$$reldir; \
--          dir1=$$subdir; dir2="$(top_distdir)"; \
--          $(am__relativize); \
--          new_top_distdir=$$reldir; \
--          echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
--          echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
--          ($(am__cd) $$subdir && \
--            $(MAKE) $(AM_MAKEFLAGS) \
--              top_distdir="$$new_top_distdir" \
--              distdir="$$new_distdir" \
--              am__remove_distdir=: \
--              am__skip_length_check=: \
--              am__skip_mode_fix=: \
--              distdir) \
--            || exit 1; \
--        fi; \
--      done
--check-am: all-am
--check: check-recursive
--all-am: Makefile
--installdirs: installdirs-recursive
--installdirs-am:
--install: install-recursive
--install-exec: install-exec-recursive
--install-data: install-data-recursive
--uninstall: uninstall-recursive
--
--install-am: all-am
--      @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--
--installcheck: installcheck-recursive
--install-strip:
--      if test -z '$(STRIP)'; then \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--            install; \
--      else \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--          "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
--      fi
--mostlyclean-generic:
--
--clean-generic:
--
--distclean-generic:
--      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
--      -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
--      @echo "This command is intended for maintainers to use"
--      @echo "it deletes files that may require special tools to rebuild."
--clean: clean-recursive
--
--clean-am: clean-generic clean-libtool mostlyclean-am
--
--distclean: distclean-recursive
--      -rm -f Makefile
--distclean-am: clean-am distclean-generic distclean-tags
--
--dvi: dvi-recursive
--
--dvi-am:
--
--html: html-recursive
--
--html-am:
--
--info: info-recursive
--
--info-am:
--
--install-data-am:
--
--install-dvi: install-dvi-recursive
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-recursive
--
--install-html-am:
--
--install-info: install-info-recursive
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-recursive
--
--install-pdf-am:
--
--install-ps: install-ps-recursive
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-recursive
--      -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-recursive
--
--mostlyclean-am: mostlyclean-generic mostlyclean-libtool
--
--pdf: pdf-recursive
--
--pdf-am:
--
--ps: ps-recursive
--
--ps-am:
--
--uninstall-am:
--
--.MAKE: $(am__recursive_targets) install-am install-strip
--
--.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
--      check-am clean clean-generic clean-libtool cscopelist-am ctags \
--      ctags-am distclean distclean-generic distclean-libtool \
--      distclean-tags distdir dvi dvi-am html html-am info info-am \
--      install install-am install-data install-data-am install-dvi \
--      install-dvi-am install-exec install-exec-am install-html \
--      install-html-am install-info install-info-am install-man \
--      install-pdf install-pdf-am install-ps install-ps-am \
--      install-strip installcheck installcheck-am installdirs \
--      installdirs-am maintainer-clean maintainer-clean-generic \
--      mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
--      ps ps-am tags tags-am uninstall uninstall-am
--
--
--# 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 -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/Makefile.am vips-7.38.5/libvipsCC/include/vips/Makefile.am
---- vips-7.38.5-vanilla/libvipsCC/include/vips/Makefile.am     2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/Makefile.am     1969-12-31 19:00:00.000000000 -0500
-@@ -1,21 +0,0 @@
--pkginclude_HEADERS = \
--      VDisplay.h \
--      VError.h \
--      VImage.h \
--      VMask.h \
--      vipscpp.h \
--      vips \
--      vipsc++.h 
--
--# swap the 'awk' line for this:
--# awk '{if($$1!="deprecated") print $$1}'` ; \
--# to not generate the wrappers for deprecated functions
--vipsc++.h:
--      packages=`vips list packages | \
--        awk '{print $$1}'` ; \
--        echo > vipsc++.h ; \
--        for name in $$packages; do \
--          echo "// headers for package $$name" >> vipsc++.h ; \
--          vips cpph $$name >> vipsc++.h ; \
--          echo >> vipsc++.h ; \
--        done 
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/Makefile.in vips-7.38.5/libvipsCC/include/vips/Makefile.in
---- vips-7.38.5-vanilla/libvipsCC/include/vips/Makefile.in     2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/Makefile.in     1969-12-31 19:00:00.000000000 -0500
-@@ -1,681 +0,0 @@
--# Makefile.in generated by automake 1.13.3 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994-2013 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@
--am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
--am__make_running_with_option = \
--  case $${target_option-} in \
--      ?) ;; \
--      *) echo "am__make_running_with_option: internal error: invalid" \
--              "target option '$${target_option-}' specified" >&2; \
--         exit 1;; \
--  esac; \
--  has_opt=no; \
--  sane_makeflags=$$MAKEFLAGS; \
--  if $(am__is_gnu_make); then \
--    sane_makeflags=$$MFLAGS; \
--  else \
--    case $$MAKEFLAGS in \
--      *\\[\ \ ]*) \
--        bs=\\; \
--        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
--          | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
--    esac; \
--  fi; \
--  skip_next=no; \
--  strip_trailopt () \
--  { \
--    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
--  }; \
--  for flg in $$sane_makeflags; do \
--    test $$skip_next = yes && { skip_next=no; continue; }; \
--    case $$flg in \
--      *=*|--*) continue;; \
--        -*I) strip_trailopt 'I'; skip_next=yes;; \
--      -*I?*) strip_trailopt 'I';; \
--        -*O) strip_trailopt 'O'; skip_next=yes;; \
--      -*O?*) strip_trailopt 'O';; \
--        -*l) strip_trailopt 'l'; skip_next=yes;; \
--      -*l?*) strip_trailopt 'l';; \
--      -[dEDm]) skip_next=yes;; \
--      -[JT]) skip_next=yes;; \
--    esac; \
--    case $$flg in \
--      *$$target_option*) has_opt=yes; break;; \
--    esac; \
--  done; \
--  test $$has_opt = yes
--am__make_dryrun = (target_option=n; $(am__make_running_with_option))
--am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@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@
--subdir = libvipsCC/include/vips
--DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
--      $(pkginclude_HEADERS)
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
--      $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/acinclude.m4 \
--      $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
--      $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--AM_V_P = $(am__v_P_@AM_V@)
--am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
--am__v_P_0 = false
--am__v_P_1 = :
--AM_V_GEN = $(am__v_GEN_@AM_V@)
--am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
--am__v_GEN_0 = @echo "  GEN     " $@;
--am__v_GEN_1 = 
--AM_V_at = $(am__v_at_@AM_V@)
--am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
--am__v_at_0 = @
--am__v_at_1 = 
--SOURCES =
--DIST_SOURCES =
--am__can_run_installinfo = \
--  case $$AM_UPDATE_INFO_DIR in \
--    n|no|NO) false;; \
--    *) (install-info --version) >/dev/null 2>&1;; \
--  esac
--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 = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
--  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
--  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
--  for p in $$list; do echo "$$p $$p"; done | \
--  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
--  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
--    if (++n[$$2] == $(am__install_max)) \
--      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
--    END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
--  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
--  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__uninstall_files_from_dir = { \
--  test -z "$$files" \
--    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
--    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
--         $(am__cd) "$$dir" && rm -f $$files; }; \
--  }
--am__installdirs = "$(DESTDIR)$(pkgincludedir)"
--HEADERS = $(pkginclude_HEADERS)
--am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
--# Read a list of newline-separated strings from the standard input,
--# and print each of them once, without duplicates.  Input order is
--# *not* preserved.
--am__uniquify_input = $(AWK) '\
--  BEGIN { nonempty = 0; } \
--  { items[$$0] = 1; nonempty = 1; } \
--  END { if (nonempty) { for (i in items) print i; }; } \
--'
--# Make sure the list of sources is unique.  This is necessary because,
--# e.g., the same source file might be shared among _SOURCES variables
--# for different programs/libraries.
--am__define_uniq_tagged_files = \
--  list='$(am__tagged_files)'; \
--  unique=`for i in $$list; do \
--    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
--  done | $(am__uniquify_input)`
--ETAGS = etags
--CTAGS = ctags
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
--AR = @AR@
--AS = @AS@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CATALOGS = @CATALOGS@
--CATOBJEXT = @CATOBJEXT@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFITSIO_CFLAGS = @CFITSIO_CFLAGS@
--CFITSIO_LIBS = @CFITSIO_LIBS@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CXX = @CXX@
--CXXCPP = @CXXCPP@
--CXXDEPMODE = @CXXDEPMODE@
--CXXFLAGS = @CXXFLAGS@
--CYGPATH_W = @CYGPATH_W@
--DATADIRNAME = @DATADIRNAME@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DLLTOOL = @DLLTOOL@
--DLLWRAP = @DLLWRAP@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--EXEEXT = @EXEEXT@
--EXIF_CFLAGS = @EXIF_CFLAGS@
--EXIF_LIBS = @EXIF_LIBS@
--FFTW_CFLAGS = @FFTW_CFLAGS@
--FFTW_LIBS = @FFTW_LIBS@
--FGREP = @FGREP@
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--GMOFILES = @GMOFILES@
--GMSGFMT = @GMSGFMT@
--GREP = @GREP@
--GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
--GTHREAD_LIBS = @GTHREAD_LIBS@
--GTKDOC_CHECK = @GTKDOC_CHECK@
--GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
--GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
--GTKDOC_MKPDF = @GTKDOC_MKPDF@
--GTKDOC_REBASE = @GTKDOC_REBASE@
--HTML_DIR = @HTML_DIR@
--IMAGE_MAGICK_CFLAGS = @IMAGE_MAGICK_CFLAGS@
--IMAGE_MAGICK_LIBS = @IMAGE_MAGICK_LIBS@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--INSTOBJEXT = @INSTOBJEXT@
--INTLLIBS = @INTLLIBS@
--INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
--INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
--INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
--INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
--INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
--INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
--INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
--INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
--JPEG_INCLUDES = @JPEG_INCLUDES@
--JPEG_LIBS = @JPEG_LIBS@
--LCMS_CFLAGS = @LCMS_CFLAGS@
--LCMS_LIBS = @LCMS_LIBS@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBRARY_AGE = @LIBRARY_AGE@
--LIBRARY_CURRENT = @LIBRARY_CURRENT@
--LIBRARY_REVISION = @LIBRARY_REVISION@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
--LIBWEBP_LIBS = @LIBWEBP_LIBS@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAGICK_CFLAGS = @MAGICK_CFLAGS@
--MAGICK_LIBS = @MAGICK_LIBS@
--MAGICK_WAND_CFLAGS = @MAGICK_WAND_CFLAGS@
--MAGICK_WAND_LIBS = @MAGICK_WAND_LIBS@
--MAKEINFO = @MAKEINFO@
--MANIFEST_TOOL = @MANIFEST_TOOL@
--MATIO_CFLAGS = @MATIO_CFLAGS@
--MATIO_LIBS = @MATIO_LIBS@
--MKDIR_P = @MKDIR_P@
--MKINSTALLDIRS = @MKINSTALLDIRS@
--MONOTONIC_CFLAGS = @MONOTONIC_CFLAGS@
--MONOTONIC_LIBS = @MONOTONIC_LIBS@
--MSGFMT = @MSGFMT@
--MSGFMT_OPTS = @MSGFMT_OPTS@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
--OPENEXR_LIBS = @OPENEXR_LIBS@
--OPENSLIDE_CFLAGS = @OPENSLIDE_CFLAGS@
--OPENSLIDE_LIBS = @OPENSLIDE_LIBS@
--ORC_CFLAGS = @ORC_CFLAGS@
--ORC_LIBS = @ORC_LIBS@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGES_USED = @PACKAGES_USED@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
--PANGOFT2_LIBS = @PANGOFT2_LIBS@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--PKG_CONFIG = @PKG_CONFIG@
--PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
--PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
--PNG_CFLAGS = @PNG_CFLAGS@
--PNG_INCLUDES = @PNG_INCLUDES@
--PNG_LIBS = @PNG_LIBS@
--POFILES = @POFILES@
--POSUB = @POSUB@
--PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
--PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
--PYTHON = @PYTHON@
--PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
--PYTHON_INCLUDES = @PYTHON_INCLUDES@
--PYTHON_PLATFORM = @PYTHON_PLATFORM@
--PYTHON_PREFIX = @PYTHON_PREFIX@
--PYTHON_VERSION = @PYTHON_VERSION@
--RANLIB = @RANLIB@
--REQUIRED_CFLAGS = @REQUIRED_CFLAGS@
--REQUIRED_LIBS = @REQUIRED_LIBS@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--THREADS_CFLAGS = @THREADS_CFLAGS@
--THREADS_LIBS = @THREADS_LIBS@
--TIFF_CFLAGS = @TIFF_CFLAGS@
--TIFF_INCLUDES = @TIFF_INCLUDES@
--TIFF_LIBS = @TIFF_LIBS@
--TYPE_INIT_CFLAGS = @TYPE_INIT_CFLAGS@
--TYPE_INIT_LIBS = @TYPE_INIT_LIBS@
--USE_NLS = @USE_NLS@
--VERSION = @VERSION@
--VIPS_CFLAGS = @VIPS_CFLAGS@
--VIPS_CXX_LIBS = @VIPS_CXX_LIBS@
--VIPS_EXEEXT = @VIPS_EXEEXT@
--VIPS_INCLUDES = @VIPS_INCLUDES@
--VIPS_LIBDIR = @VIPS_LIBDIR@
--VIPS_LIBS = @VIPS_LIBS@
--VIPS_MAJOR_VERSION = @VIPS_MAJOR_VERSION@
--VIPS_MICRO_VERSION = @VIPS_MICRO_VERSION@
--VIPS_MINOR_VERSION = @VIPS_MINOR_VERSION@
--VIPS_VERSION = @VIPS_VERSION@
--VIPS_VERSION_STRING = @VIPS_VERSION_STRING@
--XGETTEXT = @XGETTEXT@
--XMKMF = @XMKMF@
--X_CFLAGS = @X_CFLAGS@
--X_EXTRA_LIBS = @X_EXTRA_LIBS@
--X_LIBS = @X_LIBS@
--X_PRE_LIBS = @X_PRE_LIBS@
--ZIP_INCLUDES = @ZIP_INCLUDES@
--ZIP_LIBS = @ZIP_LIBS@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_AR = @ac_ct_AR@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_CXX = @ac_ct_CXX@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--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@
--pdfdir = @pdfdir@
--pkgpyexecdir = @pkgpyexecdir@
--pkgpythondir = @pkgpythondir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--pyexecdir = @pyexecdir@
--pythondir = @pythondir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--vips_introspection_sources = @vips_introspection_sources@
--pkginclude_HEADERS = \
--      VDisplay.h \
--      VError.h \
--      VImage.h \
--      VMask.h \
--      vipscpp.h \
--      vips \
--      vipsc++.h 
--
--all: all-am
--
--.SUFFIXES:
--$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
--      @for dep in $?; do \
--        case '$(am__configure_deps)' in \
--          *$$dep*) \
--            ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
--              && { if test -f $@; then exit 0; else break; fi; }; \
--            exit 1;; \
--        esac; \
--      done; \
--      echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libvipsCC/include/vips/Makefile'; \
--      $(am__cd) $(top_srcdir) && \
--        $(AUTOMAKE) --foreign libvipsCC/include/vips/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
--      @case '$?' in \
--        *config.status*) \
--          cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
--        *) \
--          echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
--          cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
--      esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure:  $(am__configure_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--mostlyclean-libtool:
--      -rm -f *.lo
--
--clean-libtool:
--      -rm -rf .libs _libs
--install-pkgincludeHEADERS: $(pkginclude_HEADERS)
--      @$(NORMAL_INSTALL)
--      @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
--      if test -n "$$list"; then \
--        echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
--        $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
--      fi; \
--      for p in $$list; do \
--        if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
--        echo "$$d$$p"; \
--      done | $(am__base_list) | \
--      while read files; do \
--        echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
--        $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
--      done
--
--uninstall-pkgincludeHEADERS:
--      @$(NORMAL_UNINSTALL)
--      @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
--      files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
--      dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
--
--ID: $(am__tagged_files)
--      $(am__define_uniq_tagged_files); mkid -fID $$unique
--tags: tags-am
--TAGS: tags
--
--tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      set x; \
--      here=`pwd`; \
--      $(am__define_uniq_tagged_files); \
--      shift; \
--      if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
--        test -n "$$unique" || unique=$$empty_fix; \
--        if test $$# -gt 0; then \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            "$$@" $$unique; \
--        else \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            $$unique; \
--        fi; \
--      fi
--ctags: ctags-am
--
--CTAGS: ctags
--ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      $(am__define_uniq_tagged_files); \
--      test -z "$(CTAGS_ARGS)$$unique" \
--        || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
--           $$unique
--
--GTAGS:
--      here=`$(am__cd) $(top_builddir) && pwd` \
--        && $(am__cd) $(top_srcdir) \
--        && gtags -i $(GTAGS_ARGS) "$$here"
--cscopelist: cscopelist-am
--
--cscopelist-am: $(am__tagged_files)
--      list='$(am__tagged_files)'; \
--      case "$(srcdir)" in \
--        [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
--        *) sdir=$(subdir)/$(srcdir) ;; \
--      esac; \
--      for i in $$list; do \
--        if test -f "$$i"; then \
--          echo "$(subdir)/$$i"; \
--        else \
--          echo "$$sdir/$$i"; \
--        fi; \
--      done >> $(top_builddir)/cscope.files
--
--distclean-tags:
--      -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
--
--distdir: $(DISTFILES)
--      @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 "$(distdir)/$$file"; then \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
--            cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
--        else \
--          test -f "$(distdir)/$$file" \
--          || cp -p $$d/$$file "$(distdir)/$$file" \
--          || exit 1; \
--        fi; \
--      done
--check-am: all-am
--check: check-am
--all-am: Makefile $(HEADERS)
--installdirs:
--      for dir in "$(DESTDIR)$(pkgincludedir)"; 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:
--      if test -z '$(STRIP)'; then \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--            install; \
--      else \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--          "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
--      fi
--mostlyclean-generic:
--
--clean-generic:
--
--distclean-generic:
--      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
--      -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
--      @echo "This command is intended for maintainers to use"
--      @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool mostlyclean-am
--
--distclean: distclean-am
--      -rm -f Makefile
--distclean-am: clean-am distclean-generic distclean-tags
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am: install-pkgincludeHEADERS
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
--      -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-am
--
--mostlyclean-am: mostlyclean-generic mostlyclean-libtool
--
--pdf: pdf-am
--
--pdf-am:
--
--ps: ps-am
--
--ps-am:
--
--uninstall-am: uninstall-pkgincludeHEADERS
--
--.MAKE: install-am install-strip
--
--.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
--      clean-libtool cscopelist-am ctags ctags-am distclean \
--      distclean-generic distclean-libtool distclean-tags distdir dvi \
--      dvi-am html html-am info info-am install install-am \
--      install-data install-data-am install-dvi install-dvi-am \
--      install-exec install-exec-am install-html install-html-am \
--      install-info install-info-am install-man install-pdf \
--      install-pdf-am install-pkgincludeHEADERS install-ps \
--      install-ps-am install-strip installcheck installcheck-am \
--      installdirs maintainer-clean maintainer-clean-generic \
--      mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
--      ps ps-am tags tags-am uninstall uninstall-am \
--      uninstall-pkgincludeHEADERS
--
--
--# swap the 'awk' line for this:
--# awk '{if($$1!="deprecated") print $$1}'` ; \
--# to not generate the wrappers for deprecated functions
--vipsc++.h:
--      packages=`vips list packages | \
--        awk '{print $$1}'` ; \
--        echo > vipsc++.h ; \
--        for name in $$packages; do \
--          echo "// headers for package $$name" >> vipsc++.h ; \
--          vips cpph $$name >> vipsc++.h ; \
--          echo >> vipsc++.h ; \
--        done 
--
--# 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 -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/VDisplay.h vips-7.38.5/libvipsCC/include/vips/VDisplay.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/VDisplay.h      2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/VDisplay.h      1969-12-31 19:00:00.000000000 -0500
-@@ -1,114 +0,0 @@
--/* VIPS display class.
-- *
-- * Hide details of im_col_display API.
-- */
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifndef IM_VDISPLAY_H
--#define IM_VDISPLAY_H
--
--/* SWIG includes this file directly rather than going through vipscpp.h ... so
-- * we have to define these macros here as well.
-- */
--#ifdef SWIG
--#define VIPS_NAMESPACE_START namespace vips {
--#define VIPS_NAMESPACE_END }
--#endif /*SWIG*/
--
--/* Wrap pointers to these, but we don't want to import all the old C API. Just 
-- * declare them.
-- */
--extern "C" {
--      struct im_col_display;
--      struct im_col_tab_disp;
--}
--
--VIPS_NAMESPACE_START
--
--// Wrapper over im_col_display with ref counting
--class VDisplay {
--      struct refblock {
--              im_col_display *disp;   // im_col_display struct
--              im_col_tab_disp *luts;  // luts built from this display
--              int priv;               // disp is ours, or system
--              int nrefs;              // Refs to us
--
--              // Invalidate lut
--              void cleanlut();
--
--              // Break attached stuff
--              void cleanref();
--
--              // Get ready to write
--              void wready() throw( VError );
--
--              // Check that luts are up-to-date
--              void cluts() throw( VError );
--
--              refblock() : disp(0), luts(0), priv(0), nrefs(1) {}
--              ~refblock() { cleanref(); }
--      };
--
--      refblock *ref;
--
--public:
--      enum VDisplayType {
--              BARCO,                  // Does many corrections for us
--              DUMB                    // Needs many corrections
--      };
--
--      // Get named display
--      VDisplay( const char *name ) throw( VError );
--
--      // Get default display
--      VDisplay();
--
--      // Copy constructor 
--      VDisplay( const VDisplay &a ) { ref = a.ref; ref->nrefs++; }
--
--      // Assignment
--      VDisplay &operator=( const VDisplay &a );
--
--      // Destructor
--      virtual ~VDisplay();
--
--      // The matrix type we use
--      typedef float matrix[3][3];
--
--      // Extract display pointer
--      void *disp() const { return( ref->disp ); }
--
--      // Extract luts pointer, rebuilding luts if necessary
--      im_col_tab_disp *luts() const throw( VError ) 
--              { ref->cluts(); return( ref->luts ); }
--};
--
--VIPS_NAMESPACE_END
--
--#endif /*IM_VDISPLAY_H*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/VError.h vips-7.38.5/libvipsCC/include/vips/VError.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/VError.h        2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/VError.h        1969-12-31 19:00:00.000000000 -0500
-@@ -1,83 +0,0 @@
--// Header for error type
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifndef IM_VERROR_H
--#define IM_VERROR_H
--
--/* SWIG includes this file directly rather than going through vipscpp.h ... so
-- * we have to define these macros here as well.
-- */
--#ifdef SWIG
--#define VIPS_NAMESPACE_START namespace vips {
--#define VIPS_NAMESPACE_END }
--#endif /*SWIG*/
--
--/* Don't include these when parsing for SWIG.
-- */
--#ifndef SWIG
--# include <string>
--# include <iosfwd>
--# include <exception>
--#endif /*!SWIG*/
--
--VIPS_NAMESPACE_START
--
--// Error type
--class VError : public std::exception {
--      std::string _what;
--
--public:
--      VError( std::string what ) : _what( what ) {}
--      VError() {}
--      virtual ~VError() throw() {}
--
--      // Print message and exit
--      void perror( const char * );
--      void perror();
--
--      // Append some more text to the message
--      VError &app( std::string txt );
--      VError &app( const int i );
--
--      // Extract string
--      virtual const char *what() const throw() { return _what.c_str(); }
--      void ostream_print( std::ostream & ) const;
--};
--
--inline std::ostream &operator<<( std::ostream &file, const VError &err )
--{
--      err.ostream_print( file );
--      return( file );
--}
--
--void verror( std::string str = "" ) throw( VError );
--
--VIPS_NAMESPACE_END
--
--#endif /*IM_VERROR_H*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/VImage.h vips-7.38.5/libvipsCC/include/vips/VImage.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/VImage.h        2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/VImage.h        1969-12-31 19:00:00.000000000 -0500
-@@ -1,457 +0,0 @@
--// VIPS image wrapper
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifndef IM_VIMAGE_H
--#define IM_VIMAGE_H
--
--/* SWIG includes this file directly rather than going through vipscpp.h ... so
-- * we have to define these macros here as well.
-- */
--#ifdef SWIG
--# define VIPS_NAMESPACE_START namespace vips {
--# define VIPS_NAMESPACE_END }
--#endif /*SWIG*/
--
--/* Don't include these when parsing for SWIG.
-- */
--#ifndef SWIG
--# include <list>
--# include <complex>
--# include <vector>
--#endif /*!SWIG*/
--
--/* Wrap pointers to these, but we don't want to import all the old C API. Just 
-- * declare them.
-- */
--extern "C" {
--      struct _VipsImage;
--
--      /* Needed by Vargv, see below.
--       */
--      struct im__function;
--      typedef void *im__object;
--}
--
--VIPS_NAMESPACE_START
--
--/* vips_init() and vips_shutdown as namespaced C++ functions.
-- */
--bool init( const char *argv0 = "nothing" );
--void shutdown( void ); 
--
--/* A VIPS callback, our name for im_callback_fn.
-- */
--typedef int (*VCallback)( void *, void * );
--
--/* VIPS image class.
-- *
-- * Slightly tricky: we have two sorts of sharing. Several VImage can share one
-- * refblock (while results are being returned from functions, for example),
-- * and several other refblocks can have IMAGEs which depend upon this IMAGE
-- * for their result.
-- */
--class VImage {
--      /* We'd like this to be protected so that user subclasses can define
--       * their own member wrappers. But sadly C++ doesn't work like that:
--       * subclasses of VImage can only refer to protected members via
--       * this->, which isn't what we need. Just make it public and hope no
--       * one touches it.
--       */
--public:
--/* Doesn't need to be wrapped.
-- */
--#ifndef SWIG
--      // Count ref etc. in one of these. One for each open VIPS image.
--      struct refblock {
--              _VipsImage *im;                 // IMAGE pointer
--              int close_on_delete;            // Set if we must im_close()
--              int nrefs;                      // Number of refs to us
--              std::list<refblock*> orefs;     // Refs im makes 
--
--              // Construct/destruct
--              refblock();
--              virtual ~refblock() throw( VError );
--
--              // Add a ref - this (output image) depends upon IMAGE in
--              void addref( refblock *in ) throw( VError );
--
--              // Remove a ref
--              void removeref() throw( VError );
--
--              // Debugging
--              void debug_print();
--
--              // Linked list needs "==" -- use address equivalence
--              friend int operator==( const refblock &left, 
--                      const refblock &right ) { return( &left == &right ); }
--      };
--
--      refblock *_ref;
--#endif /*!SWIG*/
--
--public:
--#ifdef DEBUG
--      /* All the refblocks in the world.
--       */
--      static std::list<refblock*> all_refblock;
--#endif /*DEBUG*/
--
--      /* Print all refblocks ... debugging. Compile with DEBUG to enable
--       * this.
--       */
--      static void print_all();
--
--      /* Typedefs and enums we need.
--       */
--
--      // Type type
--      enum TType {
--              MULTIBAND      = 0,
--              B_W            = 1,
--              LUMINACE       = 2,
--              XRAY           = 3,
--              IR             = 4,
--              YUV            = 5,
--              RED_ONLY       = 6,
--              GREEN_ONLY     = 7,
--              BLUE_ONLY      = 8,
--              POWER_SPECTRUM = 9,
--              HISTOGRAM      = 10,
--              LUT            = 11,
--              XYZ            = 12,
--              LAB            = 13,
--              CMC            = 14,
--              CMYK           = 15,
--              LABQ           = 16,
--              RGB            = 17,
--              UCS            = 18,
--              LCH            = 19,
--              LABS           = 21,
--              sRGB           = 22,
--              YXY            = 23,
--              FOURIER        = 24,
--              RGB16          = 25,
--              GREY16         = 26
--      };
--
--      // Format type
--      enum TBandFmt {
--              FMTNOTSET      = -1,
--              FMTUCHAR       = 0,
--              FMTCHAR        = 1,
--              FMTUSHORT      = 2,
--              FMTSHORT       = 3,
--              FMTUINT        = 4,
--              FMTINT         = 5,
--              FMTFLOAT       = 6,
--              FMTCOMPLEX     = 7,
--              FMTDOUBLE      = 8,
--              FMTDPCOMPLEX   = 9
--      };
--
--      // Coding type
--      enum TCoding {
--              NOCODING              = 0,
--              COLQUANT              = 1,
--              LABPACK               = 2,
--              LABPACK_COMPRESSED    = 3,
--              RGB_COMPRESSED        = 4,
--              LUM_COMPRESSED        = 5,
--              RAD                   = 6
--      };
--
--      // Compression type
--      enum TCompression {
--              NO_COMPRESSION        = 0,
--              TCSF_COMPRESSION      = 1,
--              JPEG_COMPRESSION      = 2
--      };
--
--      /* Start of wrappers for iofuncs.
--       */
--
--      // Plain constructors
--      VImage( const char *name, const char *mode = "rd" ) throw( VError );
--      VImage( void *data, int width, int height, 
--              int bands, TBandFmt format ) throw( VError );
--      VImage( _VipsImage *image );
--      VImage() throw( VError );
--
--      // Convert to a disc file, eg:
--      //      VImage fred = VImage::convert2disc( "im_jpeg2vips", 
--      //              "file.jpg", "temp.v" );
--      // Runs im_jpeg2vips to the temp file, then opens that and returns
--      // it. Useful for opening very large files without using a lot of RAM.
--      // Now superseded by the format API, though that's not yet wrapped in
--      // C++
--      // Also replaced by the new default "rd" mode
--      static VImage convert2disc( const char* convert, 
--              const char* in, const char* disc ) throw( VError );
--
--      // Copy constructor 
--      VImage( const VImage &a );
--
--      // Assignment - delete old ref
--      VImage &operator=( const VImage &a ) throw( VError );
--
--      // Destructor
--      virtual ~VImage() throw( VError ) { _ref->removeref(); }
--
--      // Extract underlying IMAGE* pointer
--      _VipsImage *image() const { return( _ref->im ); }
--
--      // Extract underlying data pointer
--      void *data() const throw( VError );
--
--      // Write this to another VImage, to a file, or to a mem buffer
--      VImage write( VImage out ) throw( VError );
--      VImage write( const char *name ) throw( VError );
--      VImage write() throw( VError );
--
--      // Debugging ... print header fields
--      void debug_print();
--
--      // Projection functions to get header fields
--      int Xsize();
--      int Ysize();
--      int Bands();
--      TBandFmt BandFmt();
--      TCoding Coding();
--      TType Type();
--      float Xres();
--      float Yres();
--      int Length();
--      TCompression Compression();
--      short Level();
--      int Xoffset();
--      int Yoffset();
--
--      // Derived fields
--      const char *filename();
--      const char *Hist();
--
--      // metadata
--#ifndef SWIG
--      // base functionality
--      // we don't wrap GValue, so we can't wrap these for now
--      void meta_set( const char *field, GValue *value ) throw( VError );
--      void meta_get( const char *field, GValue *value_copy ) throw( VError );
--#endif /*SWIG*/
--
--      // We can wrap these, fwiw
--      gboolean meta_remove( const char *field );
--      GType meta_get_typeof( const char *field );
--
--      // convenience functions
--      int meta_get_int( const char *field ) throw( VError );
--      double meta_get_double( const char *field ) throw( VError );
--      const char *meta_get_string( const char *field ) throw( VError );
--      void *meta_get_area( const char *field ) throw( VError );
--      void *meta_get_blob( const char *field, size_t *length ) 
--              throw( VError );
--
--      void meta_set( const char *field, int value ) throw( VError );
--      void meta_set( const char *field, double value ) throw( VError );
--      void meta_set( const char *field, const char *value ) throw( VError );
--
--#ifndef SWIG
--      // we don't wrap callbacks yet, so we can't wrap these for now
--      void meta_set( const char *field, 
--              VCallback free_fn, void *value ) 
--              throw( VError );
--      void meta_set( const char *field, 
--              VCallback free_fn, void *value, size_t length ) 
--              throw( VError );
--#endif /*SWIG*/
--
--      // Set header fields
--      void initdesc( int, int, int, TBandFmt, TCoding, TType, 
--              float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError );
--
--      /* Insert automatically generated headers.
--       */
--#include "vipsc++.h"
--
--/* No point getting SWIG to wrap these ... we do this by hand later so we can
-- * handle things like "a + 12" correctly.
-- */
--#ifndef SWIG
--      // And some in-line operator equivalences done by hand
--      friend VImage operator+( VImage a, VImage b ) throw( VError ) 
--              { return( a.add( b ) ); }
--      friend VImage operator+( double a, VImage b ) throw( VError )
--              { return( b.lin( 1.0, a ) ); }
--      friend VImage operator+( VImage a, double b ) throw( VError )
--              { return( a.lin( 1.0, b ) ); }
--
--      friend VImage operator-( VImage a, VImage b ) throw( VError )
--              { return( a.subtract( b ) ); }
--      friend VImage operator-( double a, VImage b ) throw( VError )
--              { return( b.lin( -1.0, a ) ); }
--      friend VImage operator-( VImage a, double b ) throw( VError )
--              { return( a.lin( 1.0, -b ) ); }
--
--      friend VImage operator*( VImage a, VImage b ) throw( VError )
--              { return( a.multiply( b ) ); }
--      friend VImage operator*( double a, VImage b ) throw( VError )
--              { return( b.lin( a, 0.0 ) ); }
--      friend VImage operator*( VImage a, double b ) throw( VError )
--              { return( a.lin( b, 0.0 ) ); }
--
--      friend VImage operator/( VImage a, VImage b ) throw( VError )
--              { return( a.divide( b ) ); }
--      friend VImage operator/( double a, VImage b ) throw( VError )
--              { return( b.pow( -1.0 ).lin( a, 0.0 ) ); }
--      friend VImage operator/( VImage a, double b ) throw( VError )
--              { return( a.lin( 1.0/b, 0.0 ) ); }
--
--      friend VImage operator%( VImage a, VImage b ) throw( VError )
--              { return( a.remainder( b ) ); }
--      friend VImage operator%( VImage a, double b ) throw( VError )
--              { return( a.remainder( b ) ); }
--
--      friend VImage operator<( VImage a, VImage b ) throw( VError )
--              { return( a.less( b ) ); }
--      friend VImage operator<( double a, VImage b ) throw( VError )
--              { return( b.more( a ) ); }
--      friend VImage operator<( VImage a, double b ) throw( VError )
--              { return( a.less( b ) ); }
--
--      friend VImage operator<=( VImage a, VImage b ) throw( VError )
--              { return( a.lesseq( b ) ); }
--      friend VImage operator<=( double a, VImage b ) throw( VError )
--              { return( b.moreeq( a ) ); }
--      friend VImage operator<=( VImage a, double b ) throw( VError )
--              { return( a.lesseq( b ) ); }
--
--      friend VImage operator>( VImage a, VImage b ) throw( VError )
--              { return( a.more( b ) ); }
--      friend VImage operator>( double a, VImage b ) throw( VError )
--              { return( b.less( a ) ); }
--      friend VImage operator>( VImage a, double b ) throw( VError )
--              { return( a.more( b ) ); }
--
--      friend VImage operator>=( VImage a, VImage b ) throw( VError )
--              { return( a.moreeq( b ) ); }
--      friend VImage operator>=( double a, VImage b ) throw( VError )
--              { return( b.lesseq( a ) ); }
--      friend VImage operator>=( VImage a, double b ) throw( VError )
--              { return( a.moreeq( b ) ); }
--
--      friend VImage operator==( VImage a, VImage b ) throw( VError )
--              { return( a.equal( b ) ); }
--      friend VImage operator==( double a, VImage b ) throw( VError )
--              { return( b.equal( a ) ); }
--      friend VImage operator==( VImage a, double b ) throw( VError )
--              { return( a.equal( b ) ); }
--
--      friend VImage operator!=( VImage a, VImage b ) throw( VError )
--              { return( a.notequal( b ) ); }
--      friend VImage operator!=( double a, VImage b ) throw( VError )
--              { return( b.notequal( a ) ); }
--      friend VImage operator!=( VImage a, double b ) throw( VError )
--              { return( a.notequal( b ) ); }
--
--      friend VImage operator&( VImage a, VImage b ) throw( VError )
--              { return( a.andimage( b ) ); }
--      friend VImage operator&( int a, VImage b ) throw( VError )
--              { return( b.andimage( a ) ); }
--      friend VImage operator&( VImage a, int b ) throw( VError )
--              { return( a.andimage( b ) ); }
--
--      friend VImage operator|( VImage a, VImage b ) throw( VError )
--              { return( a.orimage( b ) ); }
--      friend VImage operator|( int a, VImage b ) throw( VError )
--              { return( b.orimage( a ) ); }
--      friend VImage operator|( VImage a, int b ) throw( VError )
--              { return( a.orimage( b ) ); }
--
--      friend VImage operator^( VImage a, VImage b ) throw( VError )
--              { return( a.eorimage( b ) ); }
--      friend VImage operator^( int a, VImage b ) throw( VError )
--              { return( b.eorimage( a ) ); }
--      friend VImage operator^( VImage a, int b ) throw( VError )
--              { return( a.eorimage( b ) ); }
--
--      friend VImage operator<<( VImage a, int b ) throw( VError )
--              { return( a.shiftleft( b ) ); }
--      friend VImage operator>>( VImage a, int b ) throw( VError )
--              { return( a.shiftright( b ) ); }
--
--      friend VImage operator-( VImage a ) throw( VError )
--              { return( a * -1 ); }
--
--      // Type conversion: VImage to VDMask and VIMask
--      operator VDMask() throw( VError ) 
--              { return( this->vips2mask() ); }
--      operator VIMask() throw( VError ) 
--              { return( VIMask( VDMask( *this ) ) ); }
--#endif /*!SWIG*/
--};
--
--/* Don't include these when parsing for SWIG.
-- */
--#ifndef SWIG
--
--/* Class wrapping up a vargv. Member function wrappers need this. It needs to
-- * be part of the public API in case people subclass VImage and add their own
-- * members.
-- */
--class Vargv {
--      // Function we are args to
--      im__function *fn;
--
--      // Base of object vector
--      im__object *base;
--
--public:
--      Vargv( const char *name );
--      ~Vargv();
--
--      // Reference to element of base
--      im__object &data( int i = 0 ) { return( base[i] ); };
--
--      // Invoke function
--      void call();
--};
--
--#endif /*!SWIG*/
--
--VIPS_NAMESPACE_END
--
--// Other VIPS protos we need 
--extern "C" {
--extern int im_init_world( const char *argv0 ); 
--extern void im__print_all(); 
--extern void im_col_Lab2XYZ( 
--      float, float, float,
--      float *, float *, float * );
--}
--
--#endif /*IM_VIMAGE_H*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/vips vips-7.38.5/libvipsCC/include/vips/vips
---- vips-7.38.5-vanilla/libvipsCC/include/vips/vips    2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/vips    1969-12-31 19:00:00.000000000 -0500
-@@ -1,110 +0,0 @@
--// Include file to get all VIPS C++ bindings
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifndef IM_VIPS
--#define IM_VIPS
--
--#include <vips/version.h>
--
--// VImage.h uses GValue for metadata
--#include <glib-object.h>
--
--// If we have already #included the C vips headers, we have to undef a load of
--// stuff to stop vips's stupid macros messing up our enums
--#ifdef IM_VIPS_H
--#ifdef IM_ENABLE_DEPRECATED
--
--#undef MULTIBAND
--#undef B_W
--#undef LUMINACE
--#undef XRAY
--#undef IR
--#undef YUV
--#undef RED_ONLY
--#undef GREEN_ONLY
--#undef BLUE_ONLY
--#undef POWER_SPECTRUM
--#undef HISTOGRAM
--
--#undef LUT
--#undef XYZ
--#undef LAB
--#undef CMC
--#undef CMYK
--#undef LABQ
--#undef RGB
--#undef UCS
--#undef LCH
--#undef LABS
--#undef sRGB
--
--#undef FMTNOTSET
--#undef FMTUCHAR
--#undef FMTCHAR
--#undef FMTUSHORT
--#undef FMTSHORT
--#undef FMTUINT
--#undef FMTINT
--#undef FMTFLOAT
--#undef FMTCOMPLEX
--#undef FMTDOUBLE
--#undef FMTDPCOMPLEX
--
--#undef NOCODING
--#undef COLQUANT
--#undef LABPACK
--#undef LABPACK_COMPRESSED
--#undef RGB_COMPRESSED
--#undef LUM_COMPRESSED
--
--#undef NO_COMPRESSION
--#undef TCSF_COMPRESSION
--#undef JPEG_COMPRESSION
--
--#endif /*IM_ENABLE_DEPRECATED*/
--#endif /*IM_VIPS_H*/
--
--#ifdef IM_RECT_H
--#ifdef IM_ENABLE_DEPRECATED
--
--#undef right
--#undef bottom
--
--#endif /*IM_ENABLE_DEPRECATED*/
--#endif /*IM_RECT_H*/
--
--#define VIPS_NAMESPACE_START namespace vips {
--#define VIPS_NAMESPACE_END }
--
--#include <vips/VError.h>
--#include <vips/VDisplay.h>
--#include <vips/VMask.h>
--#include <vips/VImage.h>
--
--#endif /*IM_VIPS*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/vipsc++.h vips-7.38.5/libvipsCC/include/vips/vipsc++.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/vipsc++.h       2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/vipsc++.h       1969-12-31 19:00:00.000000000 -0500
-@@ -1,418 +0,0 @@
--
--// headers for package arithmetic
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage abs() throw( VError );
--VImage acos() throw( VError );
--VImage add( VImage add_in2 ) throw( VError );
--VImage asin() throw( VError );
--VImage atan() throw( VError );
--double avg() throw( VError );
--double point( char* point_interpolate, double point_x, double point_y, int point_band ) throw( VError );
--double point_bilinear( double point_bilinear_x, double point_bilinear_y, int point_bilinear_band ) throw( VError );
--VImage bandmean() throw( VError );
--VImage ceil() throw( VError );
--VImage cos() throw( VError );
--VImage cross_phase( VImage cross_phase_in2 ) throw( VError );
--double deviate() throw( VError );
--VImage divide( VImage divide_in2 ) throw( VError );
--VImage exp10() throw( VError );
--VImage expn( double expn_x ) throw( VError );
--VImage expn( std::vector<double> expn_v ) throw( VError );
--VImage exp() throw( VError );
--VImage floor() throw( VError );
--VImage invert() throw( VError );
--VImage lin( double lin_a, double lin_b ) throw( VError );
--static VImage linreg( std::vector<VImage> linreg_ins, std::vector<double> linreg_xs ) throw( VError );
--VImage lin( std::vector<double> lin_a, std::vector<double> lin_b ) throw( VError );
--VImage log10() throw( VError );
--VImage log() throw( VError );
--double max() throw( VError );
--std::complex<double> maxpos() throw( VError );
--double maxpos_avg( double& maxpos_avg_y, double& maxpos_avg_out ) throw( VError );
--VDMask measure( int measure_x, int measure_y, int measure_w, int measure_h, int measure_h_patches, int measure_v_patches ) throw( VError );
--double min() throw( VError );
--std::complex<double> minpos() throw( VError );
--VImage multiply( VImage multiply_in2 ) throw( VError );
--VImage pow( double pow_x ) throw( VError );
--VImage pow( std::vector<double> pow_v ) throw( VError );
--VImage recomb( VDMask recomb_matrix ) throw( VError );
--VImage remainder( VImage remainder_in2 ) throw( VError );
--VImage remainder( double remainder_x ) throw( VError );
--VImage remainder( std::vector<double> remainder_x ) throw( VError );
--VImage rint() throw( VError );
--VImage sign() throw( VError );
--VImage sin() throw( VError );
--VDMask stats() throw( VError );
--VImage subtract( VImage subtract_in2 ) throw( VError );
--VImage tan() throw( VError );
--
--// headers for package cimg
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage greyc( int greyc_iterations, double greyc_amplitude, double greyc_sharpness, double greyc_anisotropy, double greyc_alpha, double greyc_sigma, double greyc_dl, double greyc_da, double greyc_gauss_prec, int greyc_interpolation, int greyc_fast_approx ) throw( VError );
--VImage greyc_mask( VImage greyc_mask_mask, int greyc_mask_iterations, double greyc_mask_amplitude, double greyc_mask_sharpness, double greyc_mask_anisotropy, double greyc_mask_alpha, double greyc_mask_sigma, double greyc_mask_dl, double greyc_mask_da, double greyc_mask_gauss_prec, int greyc_mask_interpolation, int greyc_mask_fast_approx ) throw( VError );
--
--// headers for package colour
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage LCh2Lab() throw( VError );
--VImage LCh2UCS() throw( VError );
--VImage Lab2LCh() throw( VError );
--VImage Lab2LabQ() throw( VError );
--VImage Lab2LabS() throw( VError );
--VImage Lab2UCS() throw( VError );
--VImage Lab2XYZ() throw( VError );
--VImage Lab2XYZ_temp( double Lab2XYZ_temp_X0, double Lab2XYZ_temp_Y0, double Lab2XYZ_temp_Z0 ) throw( VError );
--VImage Lab2disp( VDisplay Lab2disp_disp ) throw( VError );
--VImage LabQ2LabS() throw( VError );
--VImage LabQ2Lab() throw( VError );
--VImage LabQ2XYZ() throw( VError );
--VImage LabQ2disp( VDisplay LabQ2disp_disp ) throw( VError );
--VImage LabS2LabQ() throw( VError );
--VImage LabS2Lab() throw( VError );
--VImage UCS2LCh() throw( VError );
--VImage UCS2Lab() throw( VError );
--VImage UCS2XYZ() throw( VError );
--VImage XYZ2Lab() throw( VError );
--VImage XYZ2Lab_temp( double XYZ2Lab_temp_X0, double XYZ2Lab_temp_Y0, double XYZ2Lab_temp_Z0 ) throw( VError );
--VImage XYZ2UCS() throw( VError );
--VImage XYZ2Yxy() throw( VError );
--VImage XYZ2disp( VDisplay XYZ2disp_disp ) throw( VError );
--VImage XYZ2sRGB() throw( VError );
--VImage Yxy2XYZ() throw( VError );
--VImage dE00_fromLab( VImage dE00_fromLab_in2 ) throw( VError );
--VImage dECMC_fromLab( VImage dECMC_fromLab_in2 ) throw( VError );
--VImage dECMC_fromdisp( VImage dECMC_fromdisp_in2, VDisplay dECMC_fromdisp_disp ) throw( VError );
--VImage dE_fromLab( VImage dE_fromLab_in2 ) throw( VError );
--VImage dE_fromXYZ( VImage dE_fromXYZ_in2 ) throw( VError );
--VImage dE_fromdisp( VImage dE_fromdisp_in2, VDisplay dE_fromdisp_disp ) throw( VError );
--VImage disp2Lab( VDisplay disp2Lab_disp ) throw( VError );
--VImage disp2XYZ( VDisplay disp2XYZ_disp ) throw( VError );
--VImage float2rad() throw( VError );
--VImage icc_ac2rc( char* icc_ac2rc_profile ) throw( VError );
--VImage icc_export_depth( int icc_export_depth_depth, char* icc_export_depth_output_profile, int icc_export_depth_intent ) throw( VError );
--VImage icc_import( char* icc_import_input_profile, int icc_import_intent ) throw( VError );
--VImage icc_import_embedded( int icc_import_embedded_intent ) throw( VError );
--VImage icc_transform( char* icc_transform_input_profile, char* icc_transform_output_profile, int icc_transform_intent ) throw( VError );
--VImage lab_morph( VDMask lab_morph_greyscale, double lab_morph_L_offset, double lab_morph_L_scale, double lab_morph_a_scale, double lab_morph_b_scale ) throw( VError );
--VImage rad2float() throw( VError );
--VImage sRGB2XYZ() throw( VError );
--
--// headers for package conversion
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--static VImage gaussnoise( int gaussnoise_xsize, int gaussnoise_ysize, double gaussnoise_mean, double gaussnoise_sigma ) throw( VError );
--VImage bandjoin( VImage bandjoin_in2 ) throw( VError );
--static VImage black( int black_x_size, int black_y_size, int black_bands ) throw( VError );
--VImage c2amph() throw( VError );
--VImage c2imag() throw( VError );
--VImage c2real() throw( VError );
--VImage c2rect() throw( VError );
--VImage clip2fmt( int clip2fmt_ofmt ) throw( VError );
--VImage copy() throw( VError );
--VImage copy_file() throw( VError );
--VImage copy_morph( int copy_morph_Bands, int copy_morph_BandFmt, int copy_morph_Coding ) throw( VError );
--VImage copy_swap() throw( VError );
--VImage copy_set( int copy_set_Type, double copy_set_Xres, double copy_set_Yres, int copy_set_Xoffset, int copy_set_Yoffset ) throw( VError );
--VImage extract_area( int extract_area_left, int extract_area_top, int extract_area_width, int extract_area_height ) throw( VError );
--VImage extract_areabands( int extract_areabands_left, int extract_areabands_top, int extract_areabands_width, int extract_areabands_height, int extract_areabands_band, int extract_areabands_nbands ) throw( VError );
--VImage extract_band( int extract_band_band ) throw( VError );
--VImage extract_bands( int extract_bands_band, int extract_bands_nbands ) throw( VError );
--VImage extract( int extract_left, int extract_top, int extract_width, int extract_height, int extract_band ) throw( VError );
--VImage falsecolour() throw( VError );
--VImage fliphor() throw( VError );
--VImage flipver() throw( VError );
--static VImage gbandjoin( std::vector<VImage> gbandjoin_in ) throw( VError );
--VImage grid( int grid_tile_height, int grid_across, int grid_down ) throw( VError );
--VImage insert( VImage insert_sub, int insert_x, int insert_y ) throw( VError );
--VImage insert( VImage insert_sub, std::vector<int> insert_x, std::vector<int> insert_y ) throw( VError );
--VImage insert_noexpand( VImage insert_noexpand_sub, int insert_noexpand_x, int insert_noexpand_y ) throw( VError );
--VImage embed( int embed_type, int embed_x, int embed_y, int embed_width, int embed_height ) throw( VError );
--VImage lrjoin( VImage lrjoin_in2 ) throw( VError );
--VImage msb() throw( VError );
--VImage msb_band( int msb_band_band ) throw( VError );
--VImage replicate( int replicate_across, int replicate_down ) throw( VError );
--VImage ri2c( VImage ri2c_in2 ) throw( VError );
--VImage rot180() throw( VError );
--VImage rot270() throw( VError );
--VImage rot90() throw( VError );
--VImage scale() throw( VError );
--VImage scaleps() throw( VError );
--VImage subsample( int subsample_xshrink, int subsample_yshrink ) throw( VError );
--char* system( char* system_command ) throw( VError );
--VImage system_image( char* system_image_in_format, char* system_image_out_format, char* system_image_command, char*& system_image_log ) throw( VError );
--VImage tbjoin( VImage tbjoin_in2 ) throw( VError );
--static VImage text( char* text_text, char* text_font, int text_width, int text_alignment, int text_dpi ) throw( VError );
--VImage wrap( int wrap_x, int wrap_y ) throw( VError );
--VImage zoom( int zoom_xfac, int zoom_yfac ) throw( VError );
--
--// headers for package convolution
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage aconvsep( VDMask aconvsep_matrix, int aconvsep_n_layers ) throw( VError );
--VImage aconv( VDMask aconv_matrix, int aconv_n_layers, int aconv_cluster ) throw( VError );
--VImage addgnoise( double addgnoise_sigma ) throw( VError );
--VImage compass( VIMask compass_matrix ) throw( VError );
--VImage contrast_surface( int contrast_surface_half_win_size, int contrast_surface_spacing ) throw( VError );
--VImage conv( VIMask conv_matrix ) throw( VError );
--VImage conv( VDMask conv_matrix ) throw( VError );
--VImage convsep( VIMask convsep_matrix ) throw( VError );
--VImage convsep( VDMask convsep_matrix ) throw( VError );
--VImage fastcor( VImage fastcor_in2 ) throw( VError );
--VImage gradcor( VImage gradcor_in2 ) throw( VError );
--VImage gradient( VIMask gradient_matrix ) throw( VError );
--VImage grad_x() throw( VError );
--VImage grad_y() throw( VError );
--VImage lindetect( VIMask lindetect_matrix ) throw( VError );
--VImage sharpen( int sharpen_mask_size, double sharpen_x1, double sharpen_y2, double sharpen_y3, double sharpen_m1, double sharpen_m2 ) throw( VError );
--VImage spcor( VImage spcor_in2 ) throw( VError );
--
--// headers for package deprecated
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage argb2rgba() throw( VError );
--VImage flood_copy( int flood_copy_start_x, int flood_copy_start_y, std::vector<double> flood_copy_ink ) throw( VError );
--VImage flood_blob_copy( int flood_blob_copy_start_x, int flood_blob_copy_start_y, std::vector<double> flood_blob_copy_ink ) throw( VError );
--VImage flood_other_copy( VImage flood_other_copy_mark, int flood_other_copy_start_x, int flood_other_copy_start_y, int flood_other_copy_serial ) throw( VError );
--VImage clip() throw( VError );
--VImage c2ps() throw( VError );
--VImage resize_linear( int resize_linear_X, int resize_linear_Y ) throw( VError );
--VImage cmulnorm( VImage cmulnorm_in2 ) throw( VError );
--VImage fav4( VImage fav4_in2, VImage fav4_in3, VImage fav4_in4 ) throw( VError );
--VImage gadd( double gadd_a, double gadd_b, VImage gadd_in2, double gadd_c ) throw( VError );
--VImage icc_export( char* icc_export_output_profile, int icc_export_intent ) throw( VError );
--VImage litecor( VImage litecor_white, int litecor_clip, double litecor_factor ) throw( VError );
--VImage affine( double affine_a, double affine_b, double affine_c, double affine_d, double affine_dx, double affine_dy, int affine_x, int affine_y, int affine_w, int affine_h ) throw( VError );
--VImage clip2c() throw( VError );
--VImage clip2cm() throw( VError );
--VImage clip2d() throw( VError );
--VImage clip2dcm() throw( VError );
--VImage clip2f() throw( VError );
--VImage clip2i() throw( VError );
--VImage convsub( VIMask convsub_matrix, int convsub_xskip, int convsub_yskip ) throw( VError );
--VImage convf( VDMask convf_matrix ) throw( VError );
--VImage convsepf( VDMask convsepf_matrix ) throw( VError );
--VImage clip2s() throw( VError );
--VImage clip2ui() throw( VError );
--VImage insertplace( VImage insertplace_sub, std::vector<int> insertplace_x, std::vector<int> insertplace_y ) throw( VError );
--VImage clip2us() throw( VError );
--VImage slice( double slice_thresh1, double slice_thresh2 ) throw( VError );
--VImage segment( int& segment_segments ) throw( VError );
--void line( int line_x1, int line_y1, int line_x2, int line_y2, int line_pelval ) throw( VError );
--VImage thresh( double thresh_threshold ) throw( VError );
--VImage convf_raw( VDMask convf_raw_matrix ) throw( VError );
--VImage conv_raw( VIMask conv_raw_matrix ) throw( VError );
--VImage contrast_surface_raw( int contrast_surface_raw_half_win_size, int contrast_surface_raw_spacing ) throw( VError );
--VImage convsepf_raw( VDMask convsepf_raw_matrix ) throw( VError );
--VImage convsep_raw( VIMask convsep_raw_matrix ) throw( VError );
--VImage fastcor_raw( VImage fastcor_raw_in2 ) throw( VError );
--VImage gradcor_raw( VImage gradcor_raw_in2 ) throw( VError );
--VImage spcor_raw( VImage spcor_raw_in2 ) throw( VError );
--VImage lhisteq_raw( int lhisteq_raw_width, int lhisteq_raw_height ) throw( VError );
--VImage stdif_raw( double stdif_raw_a, double stdif_raw_m0, double stdif_raw_b, double stdif_raw_s0, int stdif_raw_xw, int stdif_raw_yw ) throw( VError );
--VImage rank_raw( int rank_raw_xsize, int rank_raw_ysize, int rank_raw_n ) throw( VError );
--VImage dilate_raw( VIMask dilate_raw_mask ) throw( VError );
--VImage erode_raw( VIMask erode_raw_mask ) throw( VError );
--VImage similarity_area( double similarity_area_a, double similarity_area_b, double similarity_area_dx, double similarity_area_dy, int similarity_area_x, int similarity_area_y, int similarity_area_w, int similarity_area_h ) throw( VError );
--VImage similarity( double similarity_a, double similarity_b, double similarity_dx, double similarity_dy ) throw( VError );
--static VImage mask2vips( VDMask mask2vips_input ) throw( VError );
--VDMask vips2mask() throw( VError );
--void insertplace( VImage insertplace_sub, int insertplace_x, int insertplace_y ) throw( VError );
--void circle( int circle_cx, int circle_cy, int circle_radius, int circle_intensity ) throw( VError );
--VImage andimage( VImage andimage_in2 ) throw( VError );
--VImage andimage( int andimage_c ) throw( VError );
--VImage andimage( std::vector<double> andimage_vec ) throw( VError );
--VImage orimage( VImage orimage_in2 ) throw( VError );
--VImage orimage( int orimage_c ) throw( VError );
--VImage orimage( std::vector<double> orimage_vec ) throw( VError );
--VImage eorimage( VImage eorimage_in2 ) throw( VError );
--VImage eorimage( int eorimage_c ) throw( VError );
--VImage eorimage( std::vector<double> eorimage_vec ) throw( VError );
--VImage shiftleft( std::vector<double> shiftleft_vec ) throw( VError );
--VImage shiftleft( int shiftleft_c ) throw( VError );
--VImage shiftright( std::vector<double> shiftright_vec ) throw( VError );
--VImage shiftright( int shiftright_c ) throw( VError );
--VImage blend( VImage blend_in1, VImage blend_in2 ) throw( VError );
--VImage equal( VImage equal_in2 ) throw( VError );
--VImage equal( std::vector<double> equal_vec ) throw( VError );
--VImage equal( double equal_c ) throw( VError );
--VImage ifthenelse( VImage ifthenelse_in1, VImage ifthenelse_in2 ) throw( VError );
--VImage less( VImage less_in2 ) throw( VError );
--VImage less( std::vector<double> less_vec ) throw( VError );
--VImage less( double less_c ) throw( VError );
--VImage lesseq( VImage lesseq_in2 ) throw( VError );
--VImage lesseq( std::vector<double> lesseq_vec ) throw( VError );
--VImage lesseq( double lesseq_c ) throw( VError );
--VImage more( VImage more_in2 ) throw( VError );
--VImage more( std::vector<double> more_vec ) throw( VError );
--VImage more( double more_c ) throw( VError );
--VImage moreeq( VImage moreeq_in2 ) throw( VError );
--VImage moreeq( std::vector<double> moreeq_vec ) throw( VError );
--VImage moreeq( double moreeq_c ) throw( VError );
--VImage notequal( VImage notequal_in2 ) throw( VError );
--VImage notequal( std::vector<double> notequal_vec ) throw( VError );
--VImage notequal( double notequal_c ) throw( VError );
--VImage quadratic( VImage quadratic_coeff ) throw( VError );
--
--// headers for package format
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--static VImage csv2vips( char* csv2vips_filename ) throw( VError );
--static VImage fits2vips( char* fits2vips_in ) throw( VError );
--static VImage jpeg2vips( char* jpeg2vips_in ) throw( VError );
--static VImage magick2vips( char* magick2vips_in ) throw( VError );
--static VImage png2vips( char* png2vips_in ) throw( VError );
--static VImage exr2vips( char* exr2vips_in ) throw( VError );
--static VImage ppm2vips( char* ppm2vips_filename ) throw( VError );
--static VImage analyze2vips( char* analyze2vips_filename ) throw( VError );
--static VImage tiff2vips( char* tiff2vips_in ) throw( VError );
--void vips2csv( char* vips2csv_filename ) throw( VError );
--void vips2dz( char* vips2dz_out ) throw( VError );
--void vips2jpeg( char* vips2jpeg_out ) throw( VError );
--void vips2mimejpeg( int vips2mimejpeg_qfac ) throw( VError );
--void vips2png( char* vips2png_out ) throw( VError );
--void vips2ppm( char* vips2ppm_filename ) throw( VError );
--void vips2tiff( char* vips2tiff_out ) throw( VError );
--
--// headers for package freq_filt
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--static VImage create_fmask( int create_fmask_width, int create_fmask_height, int create_fmask_type, double create_fmask_p1, double create_fmask_p2, double create_fmask_p3, double create_fmask_p4, double create_fmask_p5 ) throw( VError );
--VImage disp_ps() throw( VError );
--VImage flt_image_freq( int flt_image_freq_type, double flt_image_freq_p1, double flt_image_freq_p2, double flt_image_freq_p3, double flt_image_freq_p4, double flt_image_freq_p5 ) throw( VError );
--static VImage fractsurf( int fractsurf_size, double fractsurf_dimension ) throw( VError );
--VImage freqflt( VImage freqflt_mask ) throw( VError );
--VImage fwfft() throw( VError );
--VImage rotquad() throw( VError );
--VImage invfft() throw( VError );
--VImage phasecor_fft( VImage phasecor_fft_in2 ) throw( VError );
--VImage invfftr() throw( VError );
--
--// headers for package histograms_lut
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage gammacorrect( double gammacorrect_exponent ) throw( VError );
--VImage heq( int heq_band_number ) throw( VError );
--VImage hist( int hist_band_number ) throw( VError );
--VImage histcum() throw( VError );
--VImage histeq() throw( VError );
--VImage hist_indexed( VImage hist_indexed_value ) throw( VError );
--VImage histgr( int histgr_band_number ) throw( VError );
--VImage histnD( int histnD_bins ) throw( VError );
--VImage histnorm() throw( VError );
--VImage histplot() throw( VError );
--VImage histspec( VImage histspec_ref ) throw( VError );
--VImage hsp( VImage hsp_ref ) throw( VError );
--static VImage identity( int identity_nbands ) throw( VError );
--static VImage identity_ushort( int identity_ushort_nbands, int identity_ushort_size ) throw( VError );
--int ismonotonic() throw( VError );
--VImage lhisteq( int lhisteq_width, int lhisteq_height ) throw( VError );
--int mpercent( double mpercent_percent ) throw( VError );
--static VImage invertlut( VDMask invertlut_measures, int invertlut_lut_size ) throw( VError );
--static VImage buildlut( VDMask buildlut_xyes ) throw( VError );
--VImage maplut( VImage maplut_lut ) throw( VError );
--VImage project( VImage& project_vout ) throw( VError );
--VImage stdif( double stdif_a, double stdif_m0, double stdif_b, double stdif_s0, int stdif_xw, int stdif_yw ) throw( VError );
--VImage tone_analyse( double tone_analyse_Ps, double tone_analyse_Pm, double tone_analyse_Ph, double tone_analyse_S, double tone_analyse_M, double tone_analyse_H ) throw( VError );
--static VImage tone_build( double tone_build_Lb, double tone_build_Lw, double tone_build_Ps, double tone_build_Pm, double tone_build_Ph, double tone_build_S, double tone_build_M, double tone_build_H ) throw( VError );
--static VImage tone_build_range( int tone_build_range_in_max, int tone_build_range_out_max, double tone_build_range_Lb, double tone_build_range_Lw, double tone_build_range_Ps, double tone_build_range_Pm, double tone_build_range_Ph, double tone_build_range_S, double tone_build_range_M, double tone_build_range_H ) throw( VError );
--VImage tone_map( VImage tone_map_lut ) throw( VError );
--
--// headers for package inplace
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--void draw_circle( int draw_circle_cx, int draw_circle_cy, int draw_circle_radius, int draw_circle_fill, std::vector<double> draw_circle_ink ) throw( VError );
--void draw_rect( int draw_rect_left, int draw_rect_top, int draw_rect_width, int draw_rect_height, int draw_rect_fill, std::vector<double> draw_rect_ink ) throw( VError );
--void draw_line( int draw_line_x1, int draw_line_y1, int draw_line_x2, int draw_line_y2, std::vector<double> draw_line_ink ) throw( VError );
--void draw_point( int draw_point_x, int draw_point_y, std::vector<double> draw_point_ink ) throw( VError );
--void draw_smudge( int draw_smudge_left, int draw_smudge_top, int draw_smudge_width, int draw_smudge_height ) throw( VError );
--void draw_flood( int draw_flood_x, int draw_flood_y, std::vector<double> draw_flood_ink ) throw( VError );
--void draw_flood_blob( int draw_flood_blob_x, int draw_flood_blob_y, std::vector<double> draw_flood_blob_ink ) throw( VError );
--void draw_flood_other( VImage draw_flood_other_test, int draw_flood_other_x, int draw_flood_other_y, int draw_flood_other_serial ) throw( VError );
--void draw_image( VImage draw_image_sub, int draw_image_x, int draw_image_y ) throw( VError );
--void draw_mask( VImage draw_mask_mask, int draw_mask_x, int draw_mask_y, std::vector<double> draw_mask_ink ) throw( VError );
--VImage line( VImage line_mask, VImage line_ink, std::vector<int> line_x1, std::vector<int> line_y1, std::vector<int> line_x2, std::vector<int> line_y2 ) throw( VError );
--
--// headers for package iofuncs
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--static VImage binfile( char* binfile_filename, int binfile_width, int binfile_height, int binfile_bands, int binfile_offset ) throw( VError );
--VImage cache( int cache_tile_width, int cache_tile_height, int cache_max_tiles ) throw( VError );
--char* getext() throw( VError );
--int header_get_typeof( char* header_get_typeof_field ) throw( VError );
--int header_int( char* header_int_field ) throw( VError );
--double header_double( char* header_double_field ) throw( VError );
--char* header_string( char* header_string_field ) throw( VError );
--char* history_get() throw( VError );
--void printdesc() throw( VError );
--
--// headers for package mask
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--
--// headers for package morphology
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--double cntlines( int cntlines_direction ) throw( VError );
--VImage dilate( VIMask dilate_mask ) throw( VError );
--VImage rank( int rank_xsize, int rank_ysize, int rank_n ) throw( VError );
--static VImage rank_image( std::vector<VImage> rank_image_in, int rank_image_index ) throw( VError );
--static VImage maxvalue( std::vector<VImage> maxvalue_in ) throw( VError );
--VImage label_regions( int& label_regions_segments ) throw( VError );
--VImage zerox( int zerox_flag ) throw( VError );
--VImage erode( VIMask erode_mask ) throw( VError );
--VImage profile( int profile_direction ) throw( VError );
--
--// headers for package mosaicing
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage align_bands() throw( VError );
--double correl( VImage correl_sec, int correl_xref, int correl_yref, int correl_xsec, int correl_ysec, int correl_hwindowsize, int correl_hsearchsize, int& correl_x, int& correl_y ) throw( VError );
--int _find_lroverlap( VImage _find_lroverlap_sec, int _find_lroverlap_bandno, int _find_lroverlap_xr, int _find_lroverlap_yr, int _find_lroverlap_xs, int _find_lroverlap_ys, int _find_lroverlap_halfcorrelation, int _find_lroverlap_halfarea, int& _find_lroverlap_dy0, double& _find_lroverlap_scale1, double& _find_lroverlap_angle1, double& _find_lroverlap_dx1, double& _find_lroverlap_dy1 ) throw( VError );
--int _find_tboverlap( VImage _find_tboverlap_sec, int _find_tboverlap_bandno, int _find_tboverlap_xr, int _find_tboverlap_yr, int _find_tboverlap_xs, int _find_tboverlap_ys, int _find_tboverlap_halfcorrelation, int _find_tboverlap_halfarea, int& _find_tboverlap_dy0, double& _find_tboverlap_scale1, double& _find_tboverlap_angle1, double& _find_tboverlap_dx1, double& _find_tboverlap_dy1 ) throw( VError );
--VImage global_balance( double global_balance_gamma ) throw( VError );
--VImage global_balancef( double global_balancef_gamma ) throw( VError );
--VImage lrmerge( VImage lrmerge_sec, int lrmerge_dx, int lrmerge_dy, int lrmerge_mwidth ) throw( VError );
--VImage lrmerge1( VImage lrmerge1_sec, int lrmerge1_xr1, int lrmerge1_yr1, int lrmerge1_xs1, int lrmerge1_ys1, int lrmerge1_xr2, int lrmerge1_yr2, int lrmerge1_xs2, int lrmerge1_ys2, int lrmerge1_mwidth ) throw( VError );
--VImage lrmosaic( VImage lrmosaic_sec, int lrmosaic_bandno, int lrmosaic_xr, int lrmosaic_yr, int lrmosaic_xs, int lrmosaic_ys, int lrmosaic_halfcorrelation, int lrmosaic_halfarea, int lrmosaic_balancetype, int lrmosaic_mwidth ) throw( VError );
--VImage lrmosaic1( VImage lrmosaic1_sec, int lrmosaic1_bandno, int lrmosaic1_xr1, int lrmosaic1_yr1, int lrmosaic1_xs1, int lrmosaic1_ys1, int lrmosaic1_xr2, int lrmosaic1_yr2, int lrmosaic1_xs2, int lrmosaic1_ys2, int lrmosaic1_halfcorrelation, int lrmosaic1_halfarea, int lrmosaic1_balancetype, int lrmosaic1_mwidth ) throw( VError );
--VImage match_linear( VImage match_linear_sec, int match_linear_xref1, int match_linear_yref1, int match_linear_xsec1, int match_linear_ysec1, int match_linear_xref2, int match_linear_yref2, int match_linear_xsec2, int match_linear_ysec2 ) throw( VError );
--VImage match_linear_search( VImage match_linear_search_sec, int match_linear_search_xref1, int match_linear_search_yref1, int match_linear_search_xsec1, int match_linear_search_ysec1, int match_linear_search_xref2, int match_linear_search_yref2, int match_linear_search_xsec2, int match_linear_search_ysec2, int match_linear_search_hwindowsize, int match_linear_search_hsearchsize ) throw( VError );
--double maxpos_subpel( double& maxpos_subpel_y ) throw( VError );
--VImage remosaic( char* remosaic_old_str, char* remosaic_new_str ) throw( VError );
--VImage tbmerge( VImage tbmerge_sec, int tbmerge_dx, int tbmerge_dy, int tbmerge_mwidth ) throw( VError );
--VImage tbmerge1( VImage tbmerge1_sec, int tbmerge1_xr1, int tbmerge1_yr1, int tbmerge1_xs1, int tbmerge1_ys1, int tbmerge1_xr2, int tbmerge1_yr2, int tbmerge1_xs2, int tbmerge1_ys2, int tbmerge1_mwidth ) throw( VError );
--VImage tbmosaic( VImage tbmosaic_sec, int tbmosaic_bandno, int tbmosaic_xr, int tbmosaic_yr, int tbmosaic_xs, int tbmosaic_ys, int tbmosaic_halfcorrelation, int tbmosaic_halfarea, int tbmosaic_balancetype, int tbmosaic_mwidth ) throw( VError );
--VImage tbmosaic1( VImage tbmosaic1_sec, int tbmosaic1_bandno, int tbmosaic1_xr1, int tbmosaic1_yr1, int tbmosaic1_xs1, int tbmosaic1_ys1, int tbmosaic1_xr2, int tbmosaic1_yr2, int tbmosaic1_xs2, int tbmosaic1_ys2, int tbmosaic1_halfcorrelation, int tbmosaic1_halfarea, int tbmosaic1_balancetype, int tbmosaic1_mwidth ) throw( VError );
--
--// headers for package other
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage benchmark() throw( VError );
--double benchmark2() throw( VError );
--VImage benchmarkn( int benchmarkn_n ) throw( VError );
--static VImage eye( int eye_xsize, int eye_ysize, double eye_factor ) throw( VError );
--static VImage grey( int grey_xsize, int grey_ysize ) throw( VError );
--static VImage feye( int feye_xsize, int feye_ysize, double feye_factor ) throw( VError );
--static VImage fgrey( int fgrey_xsize, int fgrey_ysize ) throw( VError );
--static VImage fzone( int fzone_size ) throw( VError );
--static VImage make_xy( int make_xy_xsize, int make_xy_ysize ) throw( VError );
--static VImage sines( int sines_xsize, int sines_ysize, double sines_horfreq, double sines_verfreq ) throw( VError );
--static VImage zone( int zone_size ) throw( VError );
--
--// headers for package resample
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--VImage rightshift_size( int rightshift_size_xshift, int rightshift_size_yshift, int rightshift_size_band_fmt ) throw( VError );
--VImage shrink( double shrink_xfac, double shrink_yfac ) throw( VError );
--VImage stretch3( double stretch3_xdisp, double stretch3_ydisp ) throw( VError );
--VImage affinei( char* affinei_interpolate, double affinei_a, double affinei_b, double affinei_c, double affinei_d, double affinei_dx, double affinei_dy, int affinei_x, int affinei_y, int affinei_w, int affinei_h ) throw( VError );
--VImage affinei_all( char* affinei_all_interpolate, double affinei_all_a, double affinei_all_b, double affinei_all_c, double affinei_all_d, double affinei_all_dx, double affinei_all_dy ) throw( VError );
--
--// headers for package video
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--static VImage video_test( int video_test_brightness, int video_test_error ) throw( VError );
--static VImage video_v4l1( char* video_v4l1_device, int video_v4l1_channel, int video_v4l1_brightness, int video_v4l1_colour, int video_v4l1_contrast, int video_v4l1_hue, int video_v4l1_ngrabs ) throw( VError );
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/vipscpp.h vips-7.38.5/libvipsCC/include/vips/vipscpp.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/vipscpp.h       2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/vipscpp.h       1969-12-31 19:00:00.000000000 -0500
-@@ -1,40 +0,0 @@
--// Include file to get all VIPS C++ bindings
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--/* This header is just for compatibility with the pre-namespace C++ bindings.
-- */
--
--#ifndef IM_VIPSCPP_H
--#define IM_VIPSCPP_H
--
--#include <vips/vips>
--
--using namespace vips;
--
--#endif /*IM_VIPSCPP_H*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/include/vips/VMask.h vips-7.38.5/libvipsCC/include/vips/VMask.h
---- vips-7.38.5-vanilla/libvipsCC/include/vips/VMask.h 2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/include/vips/VMask.h 1969-12-31 19:00:00.000000000 -0500
-@@ -1,411 +0,0 @@
--/* VIPS mask class.
-- *
-- * Just like VImage, but we don't need dependency stuff. Instead, have a base
-- * wrapper over *MASK, derive VMaskD and VMaskI from that, and then put
-- * refcounting over all of them.
-- */
--
--/*
--
--    This file is part of VIPS.
--    
--    VIPS is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifndef IM_VMASK_H
--#define IM_VMASK_H
--
--/* SWIG includes this file directly rather than going through vipscpp.h ... so
-- * we have to define these macros here as well.
-- */
--#ifdef SWIG
--# define VIPS_NAMESPACE_START namespace vips {
--# define VIPS_NAMESPACE_END }
--#endif /*SWIG*/
--
--/* Don't include these when parsing for SWIG.
-- */
--#ifndef SWIG
--# include <cstdarg>
--# include <iosfwd>
--# include <vector>
--#endif /*!SWIG*/
--
--/* Wrap pointers to these, but we don't want to import all the old C API. Just 
-- * declare them.
-- */
--extern "C" {
--      struct im__INTMASK;
--      struct im__DOUBLEMASK;
--}
--
--VIPS_NAMESPACE_START
--
--/* This first section is private. Only expose the non-P versions of these
-- * classes later on. Don't need to wrap then in SWIG either.
-- */
--#ifndef SWIG
--namespace _private_detail { 
--
--union MASKUNION {
--       im__INTMASK *iptr;
--       im__DOUBLEMASK *dptr;
--}; 
--
--// Private wrapper over *MASK - user does not see this
--class VPMask {
--      friend class VMask;
--
--public:
--      // Track type of mask with this
--      enum VMaskType {
--              UNASSIGNED,             // Not yet set
--              INT,                    // mask points to INTMASK
--              DOUBLE                  // mask points to DOUBLEMASK
--      };
--
--      MASKUNION data;                 // Mask pointer - INT or DOUBLE
--      VMaskType type;                 // Track type too, for safety
--
--      virtual ~VPMask() {};
--
--      // Duplicate
--      virtual VPMask *dup() const = 0;
--
--      // Projection functions to get MASK fields
--      virtual int xsize() const = 0;
--      virtual int ysize() const = 0;
--      virtual const char *filename() const = 0;
--
--      // Output
--      virtual void ostream_print( std::ostream & ) const = 0;
--};
--
--// Specialise for INTMASK
--class VPIMask : public VPMask {
--public:
--      VPIMask( int xsize, int ysize ) throw( VError );
--      VPIMask( int xsize, int ysize, int scale, int offset, 
--              std::vector<int> coeff ) throw( VError );
--      VPIMask( const char * )
--              throw( VError );
--      VPIMask( im__INTMASK * );
--      VPIMask();
--      virtual ~VPIMask();
--
--      VPMask *dup() const throw( VError );
--      void embed( im__INTMASK * ) throw( VError );
--
--      int xsize() const throw( VError );
--      int ysize() const throw( VError );
--      int scale() const throw( VError );
--      int offset() const throw( VError );
--      const char *filename() const throw( VError );
--
--      // Output
--      virtual void ostream_print( std::ostream & ) const throw( VError );
--
--      // Extract start of array of ints
--      int *array() const;
--};
--
--// Specialise for DOUBLEMASK
--class VPDMask : public VPMask {
--public:
--      VPDMask( int xsize, int ysize ) throw( VError );
--      VPDMask( int xsize, int ysize, 
--              double scale, double offset, std::vector<double> coeff ) 
--              throw( VError );
--      VPDMask( const char * ) throw( VError );
--      VPDMask( im__DOUBLEMASK * );
--      VPDMask();
--      virtual ~VPDMask();
--
--      VPMask *dup() const throw( VError );
--      void embed( im__DOUBLEMASK * ) throw( VError );
--
--      int xsize() const throw( VError );
--      int ysize() const throw( VError );
--      double scale() const throw( VError );
--      double offset() const throw( VError );
--      const char *filename() const throw( VError );
--
--      // Output
--      virtual void ostream_print( std::ostream & ) const throw( VError );
--
--      // Extract start of array of doubles
--      double *array() const;
--};
--
--} // end of namespace _private_detail
--
--inline std::ostream &operator<<( std::ostream &file, 
--      const _private_detail::VPMask &msk )
--{ 
--      msk.ostream_print( file ); 
--      return( file ); 
--}
--
--#endif /*!SWIG*/
--
--// Wrapper over VP?Mask with ref counting
--class VMask {
--protected:
--      struct refblock {
--              _private_detail::VPMask *pmask; // Mask: double or int
--              int nrefs;              // Refs to us
--
--              refblock() : pmask(0), nrefs(1) {}
--              virtual ~refblock() { delete pmask; }
--      };
--
--      refblock *ref;
--
--      // Make sure this is a private copy of pmask --- dup if nrefs != 1
--      void make_private();
--
--public:
--      // Constructor leaves msk uninitialised
--      VMask() { ref = new refblock; }
--
--      // Copy constructor 
--      VMask( const VMask &a ) { ref = a.ref; ref->nrefs++; }
--
--      // Assignment
--      VMask &operator=( const VMask &a );
--
--      // Destructor
--      virtual ~VMask();
--
--      int xsize() const throw( VError ) 
--              { return( ref->pmask->xsize() ); }
--      int ysize() const throw( VError ) 
--              { return( ref->pmask->ysize() ); }
--      int size() const throw( VError ) 
--              { return( xsize() * ysize() ); }
--      const char *filename() const throw( VError ) 
--              { return( ref->pmask->filename() ); }
--
--      // Extract underlying type
--      _private_detail::VPMask::VMaskType type() const 
--              { return( ref->pmask->type ); }
--
--      // Extract underlying VIPS pointer
--      _private_detail::MASKUNION mask() const { return( ref->pmask->data ); }
--
--      void ostream_print( std::ostream & ) const;
--};
--
--inline std::ostream &operator<<( std::ostream &file, const VMask &msk )
--{
--      msk.ostream_print( file );
--      return( file );
--}
--
--// Need to forward ref these
--class VDMask;
--class VImage;
--
--// Wrapper over _private_detail::VPIMask with ref counting
--class VIMask : public VMask {
--public:
--      VIMask( int xsize, int ysize )
--      {
--              ref->pmask = new _private_detail::VPIMask( xsize, ysize );
--      }
--
--/* Don't wrap the varargs constructor. We want Python to use the vector one.
-- */
--#ifndef SWIG
--      VIMask( int xsize, int ysize, int scale, int offset, ... )
--      {
--              va_list ap;
--              int i;
--              std::vector<int> coeff( xsize * ysize );
--
--              va_start( ap, offset );
--              for( i = 0; i < xsize * ysize; i++ )
--                      coeff[i] = va_arg( ap, int );
--              va_end( ap );
--
--              ref->pmask = new _private_detail::VPIMask( xsize, ysize, 
--                      scale, offset, coeff );
--      }
--#endif /*!SWIG*/
--
--      VIMask( int xsize, int ysize, int scale, int offset, 
--              std::vector<int> coeff )
--      {
--              ref->pmask = new _private_detail::VPIMask( xsize, ysize, 
--                      scale, offset, coeff );
--      }
--
--      VIMask( const char *name )
--      {
--              ref->pmask = new _private_detail::VPIMask( name );
--      }
--
--      // No mask there yet
--      VIMask() {}
--
--      int scale() 
--      { 
--              return( ((_private_detail::VPIMask *)ref->pmask)->scale() ); 
--      }
--      
--      int offset() 
--      { 
--              return( ((_private_detail::VPIMask *)ref->pmask)->offset() ); 
--      }
--
--      // Embed INTMASK in VIMask
--      void embed( im__INTMASK * ) throw( VError );
--
--      // Overload [] to get linear array subscript.
--      int &operator[]( int ) throw( VError );
--
--      // Overload () to get matrix subscript.
--      int &operator()( int x, int y ) throw( VError ) 
--              { return( (*this)[x + y*xsize()] ); }
--
--      // and as a function call that SWIG can wrap
--      int get( int i ) throw( VError ) 
--              { return( (*this)[i] ); }
--
--      // Type conversion: INTMASK->DOUBLEMASK
--      operator VDMask();
--
--      // Type conversion: INTMASK->image
--      operator VImage();
--
--      // VIMask build functions
--      static VIMask gauss( double, double ) throw( VError );
--      static VIMask gauss_sep( double, double ) throw( VError );
--      static VIMask log( double, double ) throw( VError );
--
--      // VIMask manipulation
--      VIMask rotate45() throw( VError );
--      VIMask rotate90() throw( VError );
--
--      // Arithmetic ... cast to double, and use VDMask funcs. For some
--      // reason, the compiler won't let us do casts to VDImage yet, so no
--      // inlines.
--      VDMask trn() throw( VError );
--      VDMask inv() throw( VError );
--      VDMask cat( VDMask ) throw( VError );
--      VDMask mul( VDMask ) throw( VError );
--};
--
--// Wrapper over _private_detail::VPDMask with ref counting
--class VDMask : public VMask {
--public:
--      VDMask( int xsize, int ysize )
--      {
--              ref->pmask = new _private_detail::VPDMask( xsize, ysize );
--      }
--
--/* Don't wrap the varargs constructor. We want Python to use the vector one.
-- */
--#ifndef SWIG
--      VDMask( int xsize, int ysize, double scale, double offset, ... )
--      {
--              va_list ap;
--              int i;
--              std::vector<double> coeff( xsize * ysize );
--
--              va_start( ap, offset );
--              for( i = 0; i < xsize * ysize; i++ )
--                      coeff[i] = va_arg( ap, double );
--              va_end( ap );
--
--              ref->pmask = new _private_detail::VPDMask( xsize, ysize, 
--                      scale, offset, coeff );
--      }
--#endif /*!SWIG*/
--
--      VDMask( int xsize, int ysize, double scale, double offset, 
--              std::vector<double> coeff )
--      {
--              ref->pmask = new _private_detail::VPDMask( xsize, ysize, 
--                      scale, offset, coeff );
--      }
--
--      VDMask( const char *name )
--      {
--              ref->pmask = new _private_detail::VPDMask( name );
--      }
--
--      // No mask yet
--      VDMask() { }
--
--      // Embed DOUBLEMASK in VDMask
--      void embed( im__DOUBLEMASK * ) throw( VError );
--
--      double scale() throw( VError )
--      { 
--              return( ((_private_detail::VPDMask *)ref->pmask)->scale() ); 
--      }
--
--      double offset() throw( VError )
--      { 
--              return( ((_private_detail::VPDMask *)ref->pmask)->offset() ); 
--      }
--
--      // Overload [] to get linear array subscript.
--      double &operator[]( int ) throw( VError );
--
--      // Overload () to get matrix subscript.
--      double &operator()( int x, int y ) throw( VError )
--              { return( (*this)[x + y*xsize()] ); }
--
--      // and as a function call that SWIG can wrap
--      double get( int i ) throw( VError ) 
--              { return( (*this)[i] ); }
--
--      // Type conversion: double->int
--      operator VIMask();
--
--      // Type conversion: DOUBLEMASK->image
--      operator VImage() throw( VError );
--
--      // VDMask build functions
--      static VDMask gauss( double, double ) throw( VError );
--      static VDMask log( double, double ) throw( VError );
--
--      // VDMask manipulation
--      VDMask rotate45() throw( VError );
--      VDMask rotate90() throw( VError ); 
--
--      // Scale to intmask
--      VIMask scalei() throw( VError );
--
--      // Simple arithmetic
--      VDMask trn() throw( VError );
--      VDMask inv() throw( VError );
--      VDMask cat( VDMask ) throw( VError );
--      VDMask mul( VDMask ) throw( VError );
--};
--
--VIPS_NAMESPACE_END
--
--#endif /*IM_VMASK_H*/
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/Makefile.am vips-7.38.5/libvipsCC/Makefile.am
---- vips-7.38.5-vanilla/libvipsCC/Makefile.am  2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/Makefile.am  1969-12-31 19:00:00.000000000 -0500
-@@ -1,37 +0,0 @@
--SUBDIRS = \
--      include 
--
--AM_CPPFLAGS = \
--      -I$(top_srcdir)/libvips/include \
--      -I$(top_srcdir)/libvipsCC/include \
--      @VIPS_CFLAGS@ 
--
--lib_LTLIBRARIES = libvipsCC.la
--
--libvipsCC_la_SOURCES = \
--      VImage.cc \
--      VError.cc \
--      VDisplay.cc \
--      VMask.cc
--
--libvipsCC_la_LDFLAGS = \
--      -no-undefined \
--      -version-info @LIBRARY_CURRENT@:@LIBRARY_REVISION@:@LIBRARY_AGE@
--
--libvipsCC_la_LIBADD = \
--      $(top_builddir)/libvips/libvips.la @VIPS_LIBS@
--
--# swap the 'awk' line for this:
--# awk '{if($$1!="deprecated") print $$1}'` ; \
--# to not generate the wrappers for deprecated functions
--vipsc++.cc:
--      packages=`vips list packages | \
--        awk '{print $$1}'` ; \
--        echo > vipsc++.cc ; \
--        for name in $$packages; do \
--          echo "// bodies for package $$name" >> vipsc++.cc ; \
--          vips cppc $$name >> vipsc++.cc ; \
--          echo >> vipsc++.cc ; \
--        done 
--
--EXTRA_DIST = vipsc++.cc
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/Makefile.in vips-7.38.5/libvipsCC/Makefile.in
---- vips-7.38.5-vanilla/libvipsCC/Makefile.in  2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/Makefile.in  1969-12-31 19:00:00.000000000 -0500
-@@ -1,898 +0,0 @@
--# Makefile.in generated by automake 1.13.3 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994-2013 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@
--am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
--am__make_running_with_option = \
--  case $${target_option-} in \
--      ?) ;; \
--      *) echo "am__make_running_with_option: internal error: invalid" \
--              "target option '$${target_option-}' specified" >&2; \
--         exit 1;; \
--  esac; \
--  has_opt=no; \
--  sane_makeflags=$$MAKEFLAGS; \
--  if $(am__is_gnu_make); then \
--    sane_makeflags=$$MFLAGS; \
--  else \
--    case $$MAKEFLAGS in \
--      *\\[\ \ ]*) \
--        bs=\\; \
--        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
--          | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
--    esac; \
--  fi; \
--  skip_next=no; \
--  strip_trailopt () \
--  { \
--    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
--  }; \
--  for flg in $$sane_makeflags; do \
--    test $$skip_next = yes && { skip_next=no; continue; }; \
--    case $$flg in \
--      *=*|--*) continue;; \
--        -*I) strip_trailopt 'I'; skip_next=yes;; \
--      -*I?*) strip_trailopt 'I';; \
--        -*O) strip_trailopt 'O'; skip_next=yes;; \
--      -*O?*) strip_trailopt 'O';; \
--        -*l) strip_trailopt 'l'; skip_next=yes;; \
--      -*l?*) strip_trailopt 'l';; \
--      -[dEDm]) skip_next=yes;; \
--      -[JT]) skip_next=yes;; \
--    esac; \
--    case $$flg in \
--      *$$target_option*) has_opt=yes; break;; \
--    esac; \
--  done; \
--  test $$has_opt = yes
--am__make_dryrun = (target_option=n; $(am__make_running_with_option))
--am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@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@
--subdir = libvipsCC
--DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
--      $(top_srcdir)/depcomp
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
--      $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/acinclude.m4 \
--      $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
--      $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--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 = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
--  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
--  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
--  for p in $$list; do echo "$$p $$p"; done | \
--  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
--  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
--    if (++n[$$2] == $(am__install_max)) \
--      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
--    END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
--  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
--  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__uninstall_files_from_dir = { \
--  test -z "$$files" \
--    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
--    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
--         $(am__cd) "$$dir" && rm -f $$files; }; \
--  }
--am__installdirs = "$(DESTDIR)$(libdir)"
--LTLIBRARIES = $(lib_LTLIBRARIES)
--libvipsCC_la_DEPENDENCIES = $(top_builddir)/libvips/libvips.la
--am_libvipsCC_la_OBJECTS = VImage.lo VError.lo VDisplay.lo VMask.lo
--libvipsCC_la_OBJECTS = $(am_libvipsCC_la_OBJECTS)
--AM_V_lt = $(am__v_lt_@AM_V@)
--am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
--am__v_lt_0 = --silent
--am__v_lt_1 = 
--libvipsCC_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
--      $(CXXFLAGS) $(libvipsCC_la_LDFLAGS) $(LDFLAGS) -o $@
--AM_V_P = $(am__v_P_@AM_V@)
--am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
--am__v_P_0 = false
--am__v_P_1 = :
--AM_V_GEN = $(am__v_GEN_@AM_V@)
--am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
--am__v_GEN_0 = @echo "  GEN     " $@;
--am__v_GEN_1 = 
--AM_V_at = $(am__v_at_@AM_V@)
--am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
--am__v_at_0 = @
--am__v_at_1 = 
--DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
--depcomp = $(SHELL) $(top_srcdir)/depcomp
--am__depfiles_maybe = depfiles
--am__mv = mv -f
--CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
--      $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
--LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
--      $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
--      $(AM_CXXFLAGS) $(CXXFLAGS)
--AM_V_CXX = $(am__v_CXX_@AM_V@)
--am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
--am__v_CXX_0 = @echo "  CXX     " $@;
--am__v_CXX_1 = 
--CXXLD = $(CXX)
--CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
--      $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
--AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
--am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
--am__v_CXXLD_0 = @echo "  CXXLD   " $@;
--am__v_CXXLD_1 = 
--SOURCES = $(libvipsCC_la_SOURCES)
--DIST_SOURCES = $(libvipsCC_la_SOURCES)
--RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
--      ctags-recursive dvi-recursive html-recursive info-recursive \
--      install-data-recursive install-dvi-recursive \
--      install-exec-recursive install-html-recursive \
--      install-info-recursive install-pdf-recursive \
--      install-ps-recursive install-recursive installcheck-recursive \
--      installdirs-recursive pdf-recursive ps-recursive \
--      tags-recursive uninstall-recursive
--am__can_run_installinfo = \
--  case $$AM_UPDATE_INFO_DIR in \
--    n|no|NO) false;; \
--    *) (install-info --version) >/dev/null 2>&1;; \
--  esac
--RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive       \
--  distclean-recursive maintainer-clean-recursive
--am__recursive_targets = \
--  $(RECURSIVE_TARGETS) \
--  $(RECURSIVE_CLEAN_TARGETS) \
--  $(am__extra_recursive_targets)
--AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
--      distdir
--am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
--# Read a list of newline-separated strings from the standard input,
--# and print each of them once, without duplicates.  Input order is
--# *not* preserved.
--am__uniquify_input = $(AWK) '\
--  BEGIN { nonempty = 0; } \
--  { items[$$0] = 1; nonempty = 1; } \
--  END { if (nonempty) { for (i in items) print i; }; } \
--'
--# Make sure the list of sources is unique.  This is necessary because,
--# e.g., the same source file might be shared among _SOURCES variables
--# for different programs/libraries.
--am__define_uniq_tagged_files = \
--  list='$(am__tagged_files)'; \
--  unique=`for i in $$list; do \
--    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
--  done | $(am__uniquify_input)`
--ETAGS = etags
--CTAGS = ctags
--DIST_SUBDIRS = $(SUBDIRS)
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--am__relativize = \
--  dir0=`pwd`; \
--  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
--  sed_rest='s,^[^/]*/*,,'; \
--  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
--  sed_butlast='s,/*[^/]*$$,,'; \
--  while test -n "$$dir1"; do \
--    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
--    if test "$$first" != "."; then \
--      if test "$$first" = ".."; then \
--        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
--        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
--      else \
--        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
--        if test "$$first2" = "$$first"; then \
--          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
--        else \
--          dir2="../$$dir2"; \
--        fi; \
--        dir0="$$dir0"/"$$first"; \
--      fi; \
--    fi; \
--    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
--  done; \
--  reldir="$$dir2"
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
--AR = @AR@
--AS = @AS@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CATALOGS = @CATALOGS@
--CATOBJEXT = @CATOBJEXT@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFITSIO_CFLAGS = @CFITSIO_CFLAGS@
--CFITSIO_LIBS = @CFITSIO_LIBS@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CXX = @CXX@
--CXXCPP = @CXXCPP@
--CXXDEPMODE = @CXXDEPMODE@
--CXXFLAGS = @CXXFLAGS@
--CYGPATH_W = @CYGPATH_W@
--DATADIRNAME = @DATADIRNAME@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DLLTOOL = @DLLTOOL@
--DLLWRAP = @DLLWRAP@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--EXEEXT = @EXEEXT@
--EXIF_CFLAGS = @EXIF_CFLAGS@
--EXIF_LIBS = @EXIF_LIBS@
--FFTW_CFLAGS = @FFTW_CFLAGS@
--FFTW_LIBS = @FFTW_LIBS@
--FGREP = @FGREP@
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--GMOFILES = @GMOFILES@
--GMSGFMT = @GMSGFMT@
--GREP = @GREP@
--GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
--GTHREAD_LIBS = @GTHREAD_LIBS@
--GTKDOC_CHECK = @GTKDOC_CHECK@
--GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
--GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
--GTKDOC_MKPDF = @GTKDOC_MKPDF@
--GTKDOC_REBASE = @GTKDOC_REBASE@
--HTML_DIR = @HTML_DIR@
--IMAGE_MAGICK_CFLAGS = @IMAGE_MAGICK_CFLAGS@
--IMAGE_MAGICK_LIBS = @IMAGE_MAGICK_LIBS@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--INSTOBJEXT = @INSTOBJEXT@
--INTLLIBS = @INTLLIBS@
--INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
--INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
--INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
--INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
--INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
--INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
--INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
--INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
--JPEG_INCLUDES = @JPEG_INCLUDES@
--JPEG_LIBS = @JPEG_LIBS@
--LCMS_CFLAGS = @LCMS_CFLAGS@
--LCMS_LIBS = @LCMS_LIBS@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBRARY_AGE = @LIBRARY_AGE@
--LIBRARY_CURRENT = @LIBRARY_CURRENT@
--LIBRARY_REVISION = @LIBRARY_REVISION@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
--LIBWEBP_LIBS = @LIBWEBP_LIBS@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAGICK_CFLAGS = @MAGICK_CFLAGS@
--MAGICK_LIBS = @MAGICK_LIBS@
--MAGICK_WAND_CFLAGS = @MAGICK_WAND_CFLAGS@
--MAGICK_WAND_LIBS = @MAGICK_WAND_LIBS@
--MAKEINFO = @MAKEINFO@
--MANIFEST_TOOL = @MANIFEST_TOOL@
--MATIO_CFLAGS = @MATIO_CFLAGS@
--MATIO_LIBS = @MATIO_LIBS@
--MKDIR_P = @MKDIR_P@
--MKINSTALLDIRS = @MKINSTALLDIRS@
--MONOTONIC_CFLAGS = @MONOTONIC_CFLAGS@
--MONOTONIC_LIBS = @MONOTONIC_LIBS@
--MSGFMT = @MSGFMT@
--MSGFMT_OPTS = @MSGFMT_OPTS@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
--OPENEXR_LIBS = @OPENEXR_LIBS@
--OPENSLIDE_CFLAGS = @OPENSLIDE_CFLAGS@
--OPENSLIDE_LIBS = @OPENSLIDE_LIBS@
--ORC_CFLAGS = @ORC_CFLAGS@
--ORC_LIBS = @ORC_LIBS@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGES_USED = @PACKAGES_USED@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
--PANGOFT2_LIBS = @PANGOFT2_LIBS@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--PKG_CONFIG = @PKG_CONFIG@
--PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
--PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
--PNG_CFLAGS = @PNG_CFLAGS@
--PNG_INCLUDES = @PNG_INCLUDES@
--PNG_LIBS = @PNG_LIBS@
--POFILES = @POFILES@
--POSUB = @POSUB@
--PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
--PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
--PYTHON = @PYTHON@
--PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
--PYTHON_INCLUDES = @PYTHON_INCLUDES@
--PYTHON_PLATFORM = @PYTHON_PLATFORM@
--PYTHON_PREFIX = @PYTHON_PREFIX@
--PYTHON_VERSION = @PYTHON_VERSION@
--RANLIB = @RANLIB@
--REQUIRED_CFLAGS = @REQUIRED_CFLAGS@
--REQUIRED_LIBS = @REQUIRED_LIBS@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--THREADS_CFLAGS = @THREADS_CFLAGS@
--THREADS_LIBS = @THREADS_LIBS@
--TIFF_CFLAGS = @TIFF_CFLAGS@
--TIFF_INCLUDES = @TIFF_INCLUDES@
--TIFF_LIBS = @TIFF_LIBS@
--TYPE_INIT_CFLAGS = @TYPE_INIT_CFLAGS@
--TYPE_INIT_LIBS = @TYPE_INIT_LIBS@
--USE_NLS = @USE_NLS@
--VERSION = @VERSION@
--VIPS_CFLAGS = @VIPS_CFLAGS@
--VIPS_CXX_LIBS = @VIPS_CXX_LIBS@
--VIPS_EXEEXT = @VIPS_EXEEXT@
--VIPS_INCLUDES = @VIPS_INCLUDES@
--VIPS_LIBDIR = @VIPS_LIBDIR@
--VIPS_LIBS = @VIPS_LIBS@
--VIPS_MAJOR_VERSION = @VIPS_MAJOR_VERSION@
--VIPS_MICRO_VERSION = @VIPS_MICRO_VERSION@
--VIPS_MINOR_VERSION = @VIPS_MINOR_VERSION@
--VIPS_VERSION = @VIPS_VERSION@
--VIPS_VERSION_STRING = @VIPS_VERSION_STRING@
--XGETTEXT = @XGETTEXT@
--XMKMF = @XMKMF@
--X_CFLAGS = @X_CFLAGS@
--X_EXTRA_LIBS = @X_EXTRA_LIBS@
--X_LIBS = @X_LIBS@
--X_PRE_LIBS = @X_PRE_LIBS@
--ZIP_INCLUDES = @ZIP_INCLUDES@
--ZIP_LIBS = @ZIP_LIBS@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_AR = @ac_ct_AR@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_CXX = @ac_ct_CXX@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--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@
--pdfdir = @pdfdir@
--pkgpyexecdir = @pkgpyexecdir@
--pkgpythondir = @pkgpythondir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--pyexecdir = @pyexecdir@
--pythondir = @pythondir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--vips_introspection_sources = @vips_introspection_sources@
--SUBDIRS = \
--      include 
--
--AM_CPPFLAGS = \
--      -I$(top_srcdir)/libvips/include \
--      -I$(top_srcdir)/libvipsCC/include \
--      @VIPS_CFLAGS@ 
--
--lib_LTLIBRARIES = libvipsCC.la
--libvipsCC_la_SOURCES = \
--      VImage.cc \
--      VError.cc \
--      VDisplay.cc \
--      VMask.cc
--
--libvipsCC_la_LDFLAGS = \
--      -no-undefined \
--      -version-info @LIBRARY_CURRENT@:@LIBRARY_REVISION@:@LIBRARY_AGE@
--
--libvipsCC_la_LIBADD = \
--      $(top_builddir)/libvips/libvips.la @VIPS_LIBS@
--
--EXTRA_DIST = vipsc++.cc
--all: all-recursive
--
--.SUFFIXES:
--.SUFFIXES: .cc .lo .o .obj
--$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
--      @for dep in $?; do \
--        case '$(am__configure_deps)' in \
--          *$$dep*) \
--            ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
--              && { if test -f $@; then exit 0; else break; fi; }; \
--            exit 1;; \
--        esac; \
--      done; \
--      echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libvipsCC/Makefile'; \
--      $(am__cd) $(top_srcdir) && \
--        $(AUTOMAKE) --foreign libvipsCC/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
--      @case '$?' in \
--        *config.status*) \
--          cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
--        *) \
--          echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
--          cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
--      esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure:  $(am__configure_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--install-libLTLIBRARIES: $(lib_LTLIBRARIES)
--      @$(NORMAL_INSTALL)
--      @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
--      list2=; for p in $$list; do \
--        if test -f $$p; then \
--          list2="$$list2 $$p"; \
--        else :; fi; \
--      done; \
--      test -z "$$list2" || { \
--        echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
--        $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
--        echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
--        $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
--      }
--
--uninstall-libLTLIBRARIES:
--      @$(NORMAL_UNINSTALL)
--      @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
--      for p in $$list; do \
--        $(am__strip_dir) \
--        echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
--        $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
--      done
--
--clean-libLTLIBRARIES:
--      -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
--      @list='$(lib_LTLIBRARIES)'; \
--      locs=`for p in $$list; do echo $$p; done | \
--            sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
--            sort -u`; \
--      test -z "$$locs" || { \
--        echo rm -f $${locs}; \
--        rm -f $${locs}; \
--      }
--
--libvipsCC.la: $(libvipsCC_la_OBJECTS) $(libvipsCC_la_DEPENDENCIES) $(EXTRA_libvipsCC_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(libvipsCC_la_LINK) -rpath $(libdir) $(libvipsCC_la_OBJECTS) $(libvipsCC_la_LIBADD) $(LIBS)
--
--mostlyclean-compile:
--      -rm -f *.$(OBJEXT)
--
--distclean-compile:
--      -rm -f *.tab.c
--
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VDisplay.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VError.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VImage.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VMask.Plo@am__quote@
--
--.cc.o:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
--
--.cc.obj:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
--
--.cc.lo:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
--
--mostlyclean-libtool:
--      -rm -f *.lo
--
--clean-libtool:
--      -rm -rf .libs _libs
--
--# This directory's subdirectories are mostly independent; you can cd
--# into them and run 'make' without going through this Makefile.
--# To change the values of 'make' variables: instead of editing Makefiles,
--# (1) if the variable is set in 'config.status', edit 'config.status'
--#     (which will cause the Makefiles to be regenerated when you run 'make');
--# (2) otherwise, pass the desired values on the 'make' command line.
--$(am__recursive_targets):
--      @fail=; \
--      if $(am__make_keepgoing); then \
--        failcom='fail=yes'; \
--      else \
--        failcom='exit 1'; \
--      fi; \
--      dot_seen=no; \
--      target=`echo $@ | sed s/-recursive//`; \
--      case "$@" in \
--        distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
--        *) list='$(SUBDIRS)' ;; \
--      esac; \
--      for subdir in $$list; do \
--        echo "Making $$target in $$subdir"; \
--        if test "$$subdir" = "."; then \
--          dot_seen=yes; \
--          local_target="$$target-am"; \
--        else \
--          local_target="$$target"; \
--        fi; \
--        ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
--        || eval $$failcom; \
--      done; \
--      if test "$$dot_seen" = "no"; then \
--        $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
--      fi; test -z "$$fail"
--
--ID: $(am__tagged_files)
--      $(am__define_uniq_tagged_files); mkid -fID $$unique
--tags: tags-recursive
--TAGS: tags
--
--tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      set x; \
--      here=`pwd`; \
--      if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
--        include_option=--etags-include; \
--        empty_fix=.; \
--      else \
--        include_option=--include; \
--        empty_fix=; \
--      fi; \
--      list='$(SUBDIRS)'; for subdir in $$list; do \
--        if test "$$subdir" = .; then :; else \
--          test ! -f $$subdir/TAGS || \
--            set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
--        fi; \
--      done; \
--      $(am__define_uniq_tagged_files); \
--      shift; \
--      if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
--        test -n "$$unique" || unique=$$empty_fix; \
--        if test $$# -gt 0; then \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            "$$@" $$unique; \
--        else \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            $$unique; \
--        fi; \
--      fi
--ctags: ctags-recursive
--
--CTAGS: ctags
--ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      $(am__define_uniq_tagged_files); \
--      test -z "$(CTAGS_ARGS)$$unique" \
--        || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
--           $$unique
--
--GTAGS:
--      here=`$(am__cd) $(top_builddir) && pwd` \
--        && $(am__cd) $(top_srcdir) \
--        && gtags -i $(GTAGS_ARGS) "$$here"
--cscopelist: cscopelist-recursive
--
--cscopelist-am: $(am__tagged_files)
--      list='$(am__tagged_files)'; \
--      case "$(srcdir)" in \
--        [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
--        *) sdir=$(subdir)/$(srcdir) ;; \
--      esac; \
--      for i in $$list; do \
--        if test -f "$$i"; then \
--          echo "$(subdir)/$$i"; \
--        else \
--          echo "$$sdir/$$i"; \
--        fi; \
--      done >> $(top_builddir)/cscope.files
--
--distclean-tags:
--      -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
--
--distdir: $(DISTFILES)
--      @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 "$(distdir)/$$file"; then \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
--            cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
--        else \
--          test -f "$(distdir)/$$file" \
--          || cp -p $$d/$$file "$(distdir)/$$file" \
--          || exit 1; \
--        fi; \
--      done
--      @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
--        if test "$$subdir" = .; then :; else \
--          $(am__make_dryrun) \
--            || test -d "$(distdir)/$$subdir" \
--            || $(MKDIR_P) "$(distdir)/$$subdir" \
--            || exit 1; \
--          dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
--          $(am__relativize); \
--          new_distdir=$$reldir; \
--          dir1=$$subdir; dir2="$(top_distdir)"; \
--          $(am__relativize); \
--          new_top_distdir=$$reldir; \
--          echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
--          echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
--          ($(am__cd) $$subdir && \
--            $(MAKE) $(AM_MAKEFLAGS) \
--              top_distdir="$$new_top_distdir" \
--              distdir="$$new_distdir" \
--              am__remove_distdir=: \
--              am__skip_length_check=: \
--              am__skip_mode_fix=: \
--              distdir) \
--            || exit 1; \
--        fi; \
--      done
--check-am: all-am
--check: check-recursive
--all-am: Makefile $(LTLIBRARIES)
--installdirs: installdirs-recursive
--installdirs-am:
--      for dir in "$(DESTDIR)$(libdir)"; do \
--        test -z "$$dir" || $(MKDIR_P) "$$dir"; \
--      done
--install: install-recursive
--install-exec: install-exec-recursive
--install-data: install-data-recursive
--uninstall: uninstall-recursive
--
--install-am: all-am
--      @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
--
--installcheck: installcheck-recursive
--install-strip:
--      if test -z '$(STRIP)'; then \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--            install; \
--      else \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--          "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
--      fi
--mostlyclean-generic:
--
--clean-generic:
--
--distclean-generic:
--      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
--      -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
--      @echo "This command is intended for maintainers to use"
--      @echo "it deletes files that may require special tools to rebuild."
--clean: clean-recursive
--
--clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
--      mostlyclean-am
--
--distclean: distclean-recursive
--      -rm -rf ./$(DEPDIR)
--      -rm -f Makefile
--distclean-am: clean-am distclean-compile distclean-generic \
--      distclean-tags
--
--dvi: dvi-recursive
--
--dvi-am:
--
--html: html-recursive
--
--html-am:
--
--info: info-recursive
--
--info-am:
--
--install-data-am:
--
--install-dvi: install-dvi-recursive
--
--install-dvi-am:
--
--install-exec-am: install-libLTLIBRARIES
--
--install-html: install-html-recursive
--
--install-html-am:
--
--install-info: install-info-recursive
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-recursive
--
--install-pdf-am:
--
--install-ps: install-ps-recursive
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-recursive
--      -rm -rf ./$(DEPDIR)
--      -rm -f Makefile
--maintainer-clean-am: distclean-am maintainer-clean-generic
--
--mostlyclean: mostlyclean-recursive
--
--mostlyclean-am: mostlyclean-compile mostlyclean-generic \
--      mostlyclean-libtool
--
--pdf: pdf-recursive
--
--pdf-am:
--
--ps: ps-recursive
--
--ps-am:
--
--uninstall-am: uninstall-libLTLIBRARIES
--
--.MAKE: $(am__recursive_targets) install-am install-strip
--
--.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
--      check-am clean clean-generic clean-libLTLIBRARIES \
--      clean-libtool cscopelist-am ctags ctags-am distclean \
--      distclean-compile distclean-generic distclean-libtool \
--      distclean-tags distdir dvi dvi-am html html-am info info-am \
--      install install-am install-data install-data-am install-dvi \
--      install-dvi-am install-exec install-exec-am install-html \
--      install-html-am install-info install-info-am \
--      install-libLTLIBRARIES install-man install-pdf install-pdf-am \
--      install-ps install-ps-am install-strip installcheck \
--      installcheck-am installdirs installdirs-am maintainer-clean \
--      maintainer-clean-generic mostlyclean mostlyclean-compile \
--      mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
--      tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
--
--
--# swap the 'awk' line for this:
--# awk '{if($$1!="deprecated") print $$1}'` ; \
--# to not generate the wrappers for deprecated functions
--vipsc++.cc:
--      packages=`vips list packages | \
--        awk '{print $$1}'` ; \
--        echo > vipsc++.cc ; \
--        for name in $$packages; do \
--          echo "// bodies for package $$name" >> vipsc++.cc ; \
--          vips cppc $$name >> vipsc++.cc ; \
--          echo >> vipsc++.cc ; \
--        done 
--
--# 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 -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/VDisplay.cc vips-7.38.5/libvipsCC/VDisplay.cc
---- vips-7.38.5-vanilla/libvipsCC/VDisplay.cc  2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/VDisplay.cc  1969-12-31 19:00:00.000000000 -0500
-@@ -1,152 +0,0 @@
--// Object part of VDisplay class
--
--/*
--
--    Copyright (C) 1991-2001 The National Gallery
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <cstdlib>
--#include <cstring>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--
--#include <vips/vipscpp.h>
--
--#ifdef WITH_DMALLOC
--#include <dmalloc.h>
--#endif /*WITH_DMALLOC*/
--
--VIPS_NAMESPACE_START
--
--/* Refcounting stuff first.
-- */
--
--// Free an im_col_display
--static void
--free_display( im_col_display *d )
--{
--}
--
--// Dupe an im_col_display
--static im_col_display *
--dup_display( im_col_display *in ) throw( VError )
--{
--      return( in );
--}
--
--// Remove lut
--void VDisplay::refblock::cleanlut()
--{
--      if( luts ) {
--              im_free( luts );
--              luts = 0;
--      }
--}
--
--// Remove attached things
--void VDisplay::refblock::cleanref()
--{
--      if( disp && priv ) {
--              free_display( disp );
--              disp = 0;
--              priv = 0;
--      }
--      cleanlut();
--}
--
--// Get ready to write to disp
--void VDisplay::refblock::wready() throw( VError )
--{
--      cleanlut();
--      if( !priv ) {
--              disp = dup_display( disp );
--              priv = 1;
--      }
--}
--
--// Check that luts are up-to-date
--void VDisplay::refblock::cluts() throw( VError )
--{
--}
--
--VDisplay::~VDisplay()
--{
--      ref->nrefs--;
--      if( !ref->nrefs ) 
--              delete ref;
--}
--
--VDisplay &VDisplay::operator=( const VDisplay &a )
--{ 
--      ref->nrefs--;
--
--      if( ref->nrefs > 0 ) 
--              // Need fresh
--              ref = new refblock;
--      else 
--              // Recycle old
--              ref->cleanref();
--
--      ref = a.ref; 
--      ref->nrefs++; 
--      
--      return( *this ); 
--}
--
--VDisplay::VDisplay( const char *name ) throw( VError )
--{
--      // Install display
--      ref = new refblock;
--      ref->disp = NULL;
--}
--
--VDisplay::VDisplay()
--{
--      // Just use sRGB
--      ref = new refblock;
--      ref->disp = im_col_displays( 7 );
--}
--
--/*
--
--Setters and getters. We used to have a lot of code of the form:
-- 
--float &VDisplay::YCW()
--      { ref->wready(); return( ((im_col_display*)ref->disp)->d_YCW ); }
--
--This should be split to separate setters/getters so we can exploit const. Too 
--annoying to do this on such a useless class (I'm certain no one used these 
--functions anyway), fix in vips8.
--
-- */
--
--VIPS_NAMESPACE_END
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/VError.cc vips-7.38.5/libvipsCC/VError.cc
---- vips-7.38.5-vanilla/libvipsCC/VError.cc    2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/VError.cc    1969-12-31 19:00:00.000000000 -0500
-@@ -1,100 +0,0 @@
--// Code for error type
--
--/*
--
--    Copyright (C) 1991-2001 The National Gallery
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <cstdio>
--#include <cstdlib>
--
--#include <iostream>
--
--#include <vips/vips.h>
--
--#include <vips/vipscpp.h>
--
--#ifdef WITH_DMALLOC
--#include <dmalloc.h>
--#endif /*WITH_DMALLOC*/
--
--VIPS_NAMESPACE_START
--
--void VError::perror() 
--{ 
--      std::cerr << _what; 
--      exit( 1 );
--}
--
--void VError::perror( const char *name ) 
--{ 
--      std::cerr << name << ": " << _what; 
--      exit( 1 );
--}
--
--// Add a new bit to the end of the error buffer
--VError &VError::app( const int i )
--{ 
--      char buf[ 256 ];
--
--      sprintf( buf, "%d", i );
--      _what += buf;
--
--      return( *this );
--}
--
--VError &VError::app( std::string txt ) 
--{ 
--      _what += txt; 
--
--      return( *this );
--}; 
--
--void VError::ostream_print( std::ostream &file ) const
--{
--      file << _what;
--}
--
--void verror( std::string str ) throw( VError )
--{
--      VError err;
--
--      err.app( "VIPS error: " );
--      if( str == "" ) {
--              err.app( im_error_buffer() );
--              im_error_clear();
--      }
--      else 
--              err.app( str ).app( "\n" );
--
--      throw( err );
--}
--
--VIPS_NAMESPACE_END
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/VImage.cc vips-7.38.5/libvipsCC/VImage.cc
---- vips-7.38.5-vanilla/libvipsCC/VImage.cc    2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/VImage.cc    1969-12-31 19:00:00.000000000 -0500
-@@ -1,524 +0,0 @@
--// Object part of VImage class
--
--/*
--
--    Copyright (C) 1991-2001 The National Gallery
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <cstdlib>
--#include <cstring>
--#include <cstdio>
--
--#include <vips/vips.h>
--#include <vips/internal.h>
--#include <vips/debug.h>
--
--#include <vips/vipscpp.h>
--
--#ifdef WITH_DMALLOC
--#include <dmalloc.h>
--#endif /*WITH_DMALLOC*/
--
--/*
--#define DEBUG
-- */
--
--VIPS_NAMESPACE_START
--
--/* Useful to have these as C++ functions.
-- */
--bool init( const char *argv0 )
--{
--      return( vips_init( argv0 ) == 0 ); 
--}
--
--void shutdown()
--{
--      vips_shutdown(); 
--}
--
--void VImage::refblock::debug_print()
--{
--      std::list<refblock *>::iterator i;
--
--      printf( "refblock %p:\n", this );
--      printf( "  im = %p", im );
--      if( im && im->filename ) 
--              printf( " (im->filename = \"%s\")", im->filename );
--      printf( "\n" );
--      printf( "  close_on_delete = %d\n", close_on_delete );
--      printf( "  nrefs (refs to us) = %d\n", nrefs );
--      printf( "  orefs (refs we make) = refblocks " );
--      for( i = orefs.begin(); i != orefs.end(); i++ )
--              printf( "%p ", *i );
--      printf( "\n" );
--}
--
--// dump all refblocks for debugging
--void VImage::print_all()
--{
--#ifdef DEBUG
--      std::list<VImage::refblock *>::iterator i;
--
--      printf( "*** VImage::refblock::print_all() start\n" );
--      for( i = all_refblock.begin(); i != all_refblock.end(); i++ )
--              (*i)->debug_print();
--      printf( "*** VImage::refblock::print_all() end\n" );
--#endif /*DEBUG*/
--}
--
--// easy call from C version
--void im__ccp_print_all()
--{
--      VImage::print_all();
--}
--
--// constructor
--VImage::refblock::refblock() 
--{
--      im = 0; 
--      close_on_delete = 1; 
--      nrefs = 1; 
--
--#ifdef DEBUG
--      all_refblock.push_front( this );
--#endif /*DEBUG*/
--}
--
--// Add a ref - this (output image) depends upon VipsImage in
--void VImage::refblock::addref( refblock *in ) throw( VError )
--{
--      if( this == in )
--              verror( "sanity failure" );
--
--      in->nrefs++;
--      orefs.push_front( in );
--}
--
--VImage::refblock::~refblock() throw( VError )
--{
--#ifdef DEBUG
--      printf( "VImage::refblock::removeref(): death!\n" );
--      debug_print();
--#endif /*DEBUG*/
--
--      std::list<refblock *>::iterator i;
--
--      if( close_on_delete && im ) {
--              if( im_close( im ) )
--                      verror();
--              im = 0;
--      }
--
--      // remove any refs we have ... may trigger other destructs in turn
--      for( i = orefs.begin(); i != orefs.end(); i++ )
--              (*i)->removeref();
--
--#ifdef DEBUG
--      all_refblock.remove( this );
--#endif /*DEBUG*/
--}
--
--// Remove a ref
--void VImage::refblock::removeref() throw( VError )
--{
--      nrefs--;
--      if( nrefs < 0 )
--              verror( "too many closes!" );           
--      if( nrefs == 0 ) 
--              delete this;
--}
--
--// Init with name ... mode defaults to "rd"
--VImage::VImage( const char *name, const char *mode ) throw( VError )
--{
--      _ref = new refblock;
--
--      if( !(_ref->im = im_open( name, mode )) )
--              verror();
--      _ref->close_on_delete = 1;
--
--#ifdef DEBUG
--      printf( "VImage::VImage( \"%s\", \"%s\" )\n", name, mode );
--      _ref->debug_print();
--#endif /*DEBUG*/
--}
--
--// Build a VImage from an VipsImage structure
--VImage::VImage( _VipsImage *in )
--{
--      _ref = new refblock;
--      
--      _ref->im = in;
--      _ref->close_on_delete = 0;
--
--#ifdef DEBUG
--      printf( "VImage::VImage( VipsImage* %p )\n", in );
--      _ref->debug_print();
--#endif /*DEBUG*/
--}
--
--// Build from memory buffer
--VImage::VImage( void *buffer, int width, int height, 
--      int bands, TBandFmt format ) throw( VError )
--{
--      _ref = new refblock;
--
--      if( !(_ref->im = im_image( buffer, width, height, 
--              bands, VipsBandFmt( format ) )) )
--              verror();
--      _ref->close_on_delete = 1;
--
--#ifdef DEBUG
--      printf( "VImage::VImage( void* %p, %d, %d )\n", 
--              buffer, width, height );
--      _ref->debug_print();
--#endif /*DEBUG*/
--}
--
--// Empty init ... means open intermediate
--VImage::VImage() throw( VError )
--{
--      static int id = 0;
--      char filename[256];
--
--      _ref = new refblock;
--
--      /* This is not 100% safe if VIPS threading is not implemented on this
--       * platform ... but it doesn't really matter.
--       */
--      g_mutex_lock( im__global_lock );
--      im_snprintf( filename, 256, "intermediate image #%d", id++ );
--      g_mutex_unlock( im__global_lock );
--
--      if( !(_ref->im = im_open( filename, "p" )) )
--              verror();
--      _ref->close_on_delete = 1;
--
--#ifdef DEBUG
--      printf( "VImage::VImage()\n" ); 
--      _ref->debug_print();
--#endif /*DEBUG*/
--}
--
--// Copy constructor
--VImage::VImage( const VImage &a ) 
--{ 
--      _ref = a._ref; 
--      _ref->nrefs++; 
--}
--
--// Assignment
--VImage &VImage::operator=( const VImage &a ) throw( VError )
--{ 
--      _ref->removeref(); 
--      _ref = a._ref; 
--      _ref->nrefs++; 
--      
--      return( *this ); 
--}
--
--// Extract underlying data pointer
--void *VImage::data() const throw( VError )
--{
--      if( im_incheck( _ref->im ) )
--              verror();
--      
--      return( (void *) _ref->im->data );
--}
--
--void VImage::debug_print()
--{
--      im_printdesc( image() );
--}
--
--// Like jpeg2vips, but convert to a disc file rather than to memory
--// We can handle huge files without running out of RAM
--VImage VImage::convert2disc( const char* convert, 
--      const char* in, const char* disc ) throw( VError )
--{
--      VImage out( disc, "w" );
--
--      Vargv _vec( convert );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// Write this to a VImage
--VImage VImage::write( VImage out ) throw( VError )
--{
--      if( im_copy( _ref->im, out._ref->im ) )
--              verror();
--      out._ref->addref( _ref );
--
--      return( out );
--}
--
--VImage VImage::write( const char *name ) throw( VError )
--{
--      VImage out( name, "w" );
--
--      if( im_copy( _ref->im, out._ref->im ) )
--              verror();
--      out._ref->addref( _ref );
--
--      return( out );
--}
--
--VImage VImage::write() throw( VError )
--{
--      VImage out( "VImage:w1", "t" );
--
--      if( im_copy( _ref->im, out._ref->im ) )
--              verror();
--      out._ref->addref( _ref );
--
--      return( out );
--}
--
--// Projection functions to get header fields
--int VImage::Xsize() { return( _ref->im->Xsize ); }
--int VImage::Ysize() { return( _ref->im->Ysize ); }
--int VImage::Bands() { return( _ref->im->Bands ); }
--VImage::TBandFmt VImage::BandFmt() 
--      { return( (TBandFmt) _ref->im->BandFmt ); }
--VImage::TCoding VImage::Coding() 
--      { return( (TCoding) _ref->im->Coding ); }
--VImage::TType VImage::Type() { return( (TType) _ref->im->Type ); }
--float VImage::Xres() { return( _ref->im->Xres ); }
--float VImage::Yres() { return( _ref->im->Yres ); }
--int VImage::Length() { return( _ref->im->Length ); }
--VImage::TCompression VImage::Compression() 
--      { return( (TCompression) _ref->im->Compression ); }
--short VImage::Level() { return( _ref->im->Level ); }
--int VImage::Xoffset() { return( _ref->im->Xoffset ); }
--int VImage::Yoffset() { return( _ref->im->Yoffset ); }
--
--// Derived fields
--const char *VImage::filename() { return( _ref->im->filename ); }
--const char *VImage::Hist() { return( im_history_get( _ref->im ) ); }
--
--// metadata
--
--// base functionality
--void VImage::meta_set( const char *field, GValue *value ) throw( VError )
--{
--      if( im_meta_set( _ref->im, field, value ) )
--              verror();
--}
--
--gboolean VImage::meta_remove( const char *field ) 
--{
--      return( im_meta_remove( _ref->im, field ) );
--}
--
--void VImage::meta_get( const char *field, GValue *value_copy ) throw( VError )
--{
--      if( im_meta_get( _ref->im, field, value_copy ) )
--              verror();
--}
--
--GType VImage::meta_get_typeof( const char *field ) 
--{
--      return( im_meta_get_typeof( _ref->im, field ) );
--}
--
--// convenience functions
--int VImage::meta_get_int( const char *field ) 
--      throw( VError )
--{
--      int result;
--
--      if( im_meta_get_int( _ref->im, field, &result ) )
--              verror();
--
--      return( result );
--}
--
--double VImage::meta_get_double( const char *field ) 
--      throw( VError )
--{
--      double result;
--
--      if( im_meta_get_double( _ref->im, field, &result ) )
--              verror();
--
--      return( result );
--}
--
--const char *VImage::meta_get_string( const char *field ) 
--      throw( VError )
--{
--      const char *result;
--
--      if( im_meta_get_string( _ref->im, field, &result ) )
--              verror();
--
--      return( result );
--}
--
--void *VImage::meta_get_area( const char *field ) throw( VError )
--{
--      void *result;
--
--      if( im_meta_get_area( _ref->im, field, &result ) )
--              verror();
--
--      return( result );
--}
--
--void *VImage::meta_get_blob( const char *field, size_t *length ) throw( VError )
--{
--      void *result;
--
--      if( im_meta_get_blob( _ref->im, field, &result, length ) )
--              verror();
--
--      return( result );
--}
--
--void VImage::meta_set( const char *field, int value ) 
--      throw( VError )
--{
--      if( im_meta_set_int( _ref->im, field, value ) )
--              verror();
--}
--
--void VImage::meta_set( const char *field, double value ) 
--      throw( VError )
--{
--      if( im_meta_set_double( _ref->im, field, value ) )
--              verror();
--}
--
--void VImage::meta_set( const char *field, const char *value ) 
--      throw( VError )
--{
--      if( im_meta_set_string( _ref->im, field, value ) )
--              verror();
--}
--
--void VImage::meta_set( const char *field, 
--      VCallback free_fn, void *value ) 
--      throw( VError )
--{
--      if( im_meta_set_area( _ref->im, field, free_fn, value ) )
--              verror();
--}
--
--void VImage::meta_set( const char *field, 
--      VCallback free_fn, void *value, size_t length ) 
--      throw( VError )
--{
--      if( im_meta_set_blob( _ref->im, field, free_fn, value, length ) )
--              verror();
--}
--
--// Set header fields and setbuf() in one go.
--void VImage::initdesc( int x, int y, int b,
--      TBandFmt f, TCoding c, TType t, float xr, float yr, int xo, int yo )
--      throw( VError )
--{
--      im_initdesc( _ref->im, x, y, b, 0, 
--              VipsBandFmt( f ), VipsCoding( c ), VipsType( t ), 
--              xr, yr, xo, yo );
--      if( im_setupout( _ref->im ) )
--              verror();
--}
--
--// Create a Vargv from a name
--Vargv::Vargv( const char *name )
--{
--      im_function *f = im_find_function( (char *) name );
--      
--      if( !f )
--              verror();
--
--      fn = (im__function *) f;
--      base = new im_object[f->argc]; 
--      if( im_allocate_vargv( f, base ) ) {
--              delete[] base;
--              verror();
--      }
--}
--
--// Destroy a Vargv
--Vargv::~Vargv()
--{
--      im_function *f = (im_function *) fn;
--
--      // free any memory allocated for input vectors
--      // this is the stuff allocated in each function during _object* build,
--      // see vipsc++.cc
--      for( int i = 0; i < f->argc; i++ ) {
--              im_type_desc *ty = f->argv[i].desc;
--
--              if( !(ty->flags & IM_TYPE_OUTPUT) ) {
--                      if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 ||
--                              strcmp( ty->type, IM_TYPE_DOUBLEVEC ) == 0 ||
--                              strcmp( ty->type, IM_TYPE_INTVEC ) == 0 ) {
--                              // will work for doublevec and intvec too
--                              im_imagevec_object *io = 
--                                      (im_imagevec_object *) base[i];
--
--                              if( io->vec ) {
--                                      delete[] io->vec;
--                                      io->vec = NULL;
--                              }
--                      }
--                      else if( strcmp( ty->type, IM_TYPE_INTERPOLATE ) == 0 )
--                              g_object_unref( base[i] );
--              }
--      }
--
--      im_free_vargv( f, base );
--      delete[] base;
--}
--
--// Call the function
--void
--Vargv::call()
--{
--      im_function *f = (im_function *) fn;
--
--      if( f->disp( base ) ) 
--              verror();
--}
--
--/* Insert automatically generated wrappers for VIPS image processing 
-- * functions.
-- */
--#include "vipsc++.cc"
--
--VIPS_NAMESPACE_END
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/vipsc++.cc vips-7.38.5/libvipsCC/vipsc++.cc
---- vips-7.38.5-vanilla/libvipsCC/vipsc++.cc   2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/vipsc++.cc   1969-12-31 19:00:00.000000000 -0500
-@@ -1,6202 +0,0 @@
--
--// bodies for package arithmetic
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_abs: absolute value
--VImage VImage::abs() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_abs" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_acostra: acos of image (result in degrees)
--VImage VImage::acos() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_acostra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_add: add two images
--VImage VImage::add( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_add" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_asintra: asin of image (result in degrees)
--VImage VImage::asin() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_asintra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_atantra: atan of image (result in degrees)
--VImage VImage::atan() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_atantra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_avg: average value of image
--double VImage::avg() throw( VError )
--{
--      VImage in = *this;
--      double value;
--
--      Vargv _vec( "im_avg" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      value = *((double*)_vec.data(1));
--
--      return( value );
--}
--
--// im_point: interpolate value at single point
--double VImage::point( char* interpolate, double x, double y, int band ) throw( VError )
--{
--      VImage in = *this;
--      double out;
--
--      Vargv _vec( "im_point" );
--
--      _vec.data(0) = in.image();
--      if( vips__input_interpolate_init( &_vec.data(1), interpolate ) )
--              verror();
--      *((double*) _vec.data(2)) = x;
--      *((double*) _vec.data(3)) = y;
--      *((int*) _vec.data(4)) = band;
--      _vec.call();
--      out = *((double*)_vec.data(5));
--
--      return( out );
--}
--
--// im_point_bilinear: interpolate value at single point, linearly
--double VImage::point_bilinear( double x, double y, int band ) throw( VError )
--{
--      VImage in = *this;
--      double val;
--
--      Vargv _vec( "im_point_bilinear" );
--
--      _vec.data(0) = in.image();
--      *((double*) _vec.data(1)) = x;
--      *((double*) _vec.data(2)) = y;
--      *((int*) _vec.data(3)) = band;
--      _vec.call();
--      val = *((double*)_vec.data(4));
--
--      return( val );
--}
--
--// im_bandmean: average image bands
--VImage VImage::bandmean() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_bandmean" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_ceil: round to smallest integer value not less than
--VImage VImage::ceil() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_ceil" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_costra: cos of image (angles in degrees)
--VImage VImage::cos() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_costra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_cross_phase: phase of cross power spectrum of two complex images
--VImage VImage::cross_phase( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_cross_phase" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_deviate: standard deviation of image
--double VImage::deviate() throw( VError )
--{
--      VImage in = *this;
--      double value;
--
--      Vargv _vec( "im_deviate" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      value = *((double*)_vec.data(1));
--
--      return( value );
--}
--
--// im_divide: divide two images
--VImage VImage::divide( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_divide" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_exp10tra: 10^pel of image
--VImage VImage::exp10() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_exp10tra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_expntra: x^pel of image
--VImage VImage::expn( double x ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_expntra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = x;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_expntra_vec: [x,y,z]^pel of image
--VImage VImage::expn( std::vector<double> v ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_expntra_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = v.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[v.size()];
--      for( unsigned int i = 0; i < v.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = v[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_exptra: e^pel of image
--VImage VImage::exp() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_exptra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_floor: round to largest integer value not greater than
--VImage VImage::floor() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_floor" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_invert: photographic negative
--VImage VImage::invert() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_invert" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lintra: calculate a*in + b = outfile
--VImage VImage::lin( double a, double b ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lintra" );
--
--      *((double*) _vec.data(0)) = a;
--      _vec.data(1) = in.image();
--      *((double*) _vec.data(2)) = b;
--      _vec.data(3) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_linreg: pixelwise linear regression
--VImage VImage::linreg( std::vector<VImage> ins, std::vector<double> xs ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_linreg" );
--
--      ((im_imagevec_object*) _vec.data(0))->n = ins.size();
--      ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[ins.size()];
--      for( unsigned int i = 0; i < ins.size(); i++ )
--              ((im_imagevec_object*) _vec.data(0))->vec[i] = ins[i].image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = xs.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[xs.size()];
--      for( unsigned int i = 0; i < xs.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = xs[i];
--      _vec.call();
--      for( unsigned int i = 0; i < ins.size(); i++ )
--              out._ref->addref( ins[i]._ref );
--
--      return( out );
--}
--
--// im_lintra_vec: calculate a*in + b -> out, a and b vectors
--VImage VImage::lin( std::vector<double> a, std::vector<double> b ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lintra_vec" );
--
--      ((im_doublevec_object*) _vec.data(0))->n = a.size();
--      ((im_doublevec_object*) _vec.data(0))->vec = new double[a.size()];
--      for( unsigned int i = 0; i < a.size(); i++ )
--              ((im_doublevec_object*) _vec.data(0))->vec[i] = a[i];
--      _vec.data(1) = in.image();
--      ((im_doublevec_object*) _vec.data(2))->n = b.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[b.size()];
--      for( unsigned int i = 0; i < b.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = b[i];
--      _vec.data(3) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_log10tra: log10 of image
--VImage VImage::log10() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_log10tra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_logtra: ln of image
--VImage VImage::log() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_logtra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_max: maximum value of image
--double VImage::max() throw( VError )
--{
--      VImage in = *this;
--      double value;
--
--      Vargv _vec( "im_max" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      value = *((double*)_vec.data(1));
--
--      return( value );
--}
--
--// im_maxpos: position of maximum value of image
--std::complex<double> VImage::maxpos() throw( VError )
--{
--      VImage in = *this;
--      std::complex<double> position;
--
--      Vargv _vec( "im_maxpos" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      position = *((std::complex<double>*)_vec.data(1));
--
--      return( position );
--}
--
--// im_maxpos_avg: position of maximum value of image, averaging in case of draw
--double VImage::maxpos_avg( double& y, double& out ) throw( VError )
--{
--      VImage in = *this;
--      double x;
--
--      Vargv _vec( "im_maxpos_avg" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      x = *((double*)_vec.data(1));
--      y = *((double*)_vec.data(2));
--      out = *((double*)_vec.data(3));
--
--      return( x );
--}
--
--// im_measure: measure averages of a grid of patches
--VDMask VImage::measure( int x, int y, int w, int h, int h_patches, int v_patches ) throw( VError )
--{
--      VImage in = *this;
--      VDMask mask;
--
--      Vargv _vec( "im_measure" );
--
--      _vec.data(0) = in.image();
--      ((im_mask_object*) _vec.data(1))->name = (char*)"noname";
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      *((int*) _vec.data(4)) = w;
--      *((int*) _vec.data(5)) = h;
--      *((int*) _vec.data(6)) = h_patches;
--      *((int*) _vec.data(7)) = v_patches;
--      _vec.call();
--      mask.embed( (DOUBLEMASK *)((im_mask_object*)_vec.data(1))->mask );
--
--      return( mask );
--}
--
--// im_min: minimum value of image
--double VImage::min() throw( VError )
--{
--      VImage in = *this;
--      double value;
--
--      Vargv _vec( "im_min" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      value = *((double*)_vec.data(1));
--
--      return( value );
--}
--
--// im_minpos: position of minimum value of image
--std::complex<double> VImage::minpos() throw( VError )
--{
--      VImage in = *this;
--      std::complex<double> position;
--
--      Vargv _vec( "im_minpos" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      position = *((std::complex<double>*)_vec.data(1));
--
--      return( position );
--}
--
--// im_multiply: multiply two images
--VImage VImage::multiply( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_multiply" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_powtra: pel^x of image
--VImage VImage::pow( double x ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_powtra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = x;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_powtra_vec: pel^[x,y,z] of image
--VImage VImage::pow( std::vector<double> v ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_powtra_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = v.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[v.size()];
--      for( unsigned int i = 0; i < v.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = v[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_recomb: linear recombination with mask
--VImage VImage::recomb( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_recomb" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_remainder: remainder after integer division
--VImage VImage::remainder( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_remainder" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_remainderconst: remainder after integer division by a constant
--VImage VImage::remainder( double x ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_remainderconst" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = x;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_remainder_vec: remainder after integer division by a vector of constants
--VImage VImage::remainder( std::vector<double> x ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_remainder_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = x.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[x.size()];
--      for( unsigned int i = 0; i < x.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = x[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rint: round to nearest integer value
--VImage VImage::rint() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rint" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_sign: unit vector in direction of value
--VImage VImage::sign() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_sign" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_sintra: sin of image (angles in degrees)
--VImage VImage::sin() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_sintra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_stats: many image statistics in one pass
--VDMask VImage::stats() throw( VError )
--{
--      VImage in = *this;
--      VDMask statistics;
--
--      Vargv _vec( "im_stats" );
--
--      _vec.data(0) = in.image();
--      ((im_mask_object*) _vec.data(1))->name = (char*)"noname";
--      _vec.call();
--      statistics.embed( (DOUBLEMASK *)((im_mask_object*)_vec.data(1))->mask );
--
--      return( statistics );
--}
--
--// im_subtract: subtract two images
--VImage VImage::subtract( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_subtract" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_tantra: tan of image (angles in degrees)
--VImage VImage::tan() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_tantra" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--
--// bodies for package cimg
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_greyc: noise-removing filter
--VImage VImage::greyc( int iterations, double amplitude, double sharpness, double anisotropy, double alpha, double sigma, double dl, double da, double gauss_prec, int interpolation, int fast_approx ) throw( VError )
--{
--      VImage src = *this;
--      VImage dst;
--
--      Vargv _vec( "im_greyc" );
--
--      _vec.data(0) = src.image();
--      _vec.data(1) = dst.image();
--      *((int*) _vec.data(2)) = iterations;
--      *((double*) _vec.data(3)) = amplitude;
--      *((double*) _vec.data(4)) = sharpness;
--      *((double*) _vec.data(5)) = anisotropy;
--      *((double*) _vec.data(6)) = alpha;
--      *((double*) _vec.data(7)) = sigma;
--      *((double*) _vec.data(8)) = dl;
--      *((double*) _vec.data(9)) = da;
--      *((double*) _vec.data(10)) = gauss_prec;
--      *((int*) _vec.data(11)) = interpolation;
--      *((int*) _vec.data(12)) = fast_approx;
--      _vec.call();
--      dst._ref->addref( src._ref );
--
--      return( dst );
--}
--
--// im_greyc_mask: noise-removing filter, with a mask
--VImage VImage::greyc_mask( VImage mask, int iterations, double amplitude, double sharpness, double anisotropy, double alpha, double sigma, double dl, double da, double gauss_prec, int interpolation, int fast_approx ) throw( VError )
--{
--      VImage src = *this;
--      VImage dst;
--
--      Vargv _vec( "im_greyc_mask" );
--
--      _vec.data(0) = src.image();
--      _vec.data(1) = dst.image();
--      _vec.data(2) = mask.image();
--      *((int*) _vec.data(3)) = iterations;
--      *((double*) _vec.data(4)) = amplitude;
--      *((double*) _vec.data(5)) = sharpness;
--      *((double*) _vec.data(6)) = anisotropy;
--      *((double*) _vec.data(7)) = alpha;
--      *((double*) _vec.data(8)) = sigma;
--      *((double*) _vec.data(9)) = dl;
--      *((double*) _vec.data(10)) = da;
--      *((double*) _vec.data(11)) = gauss_prec;
--      *((int*) _vec.data(12)) = interpolation;
--      *((int*) _vec.data(13)) = fast_approx;
--      _vec.call();
--      dst._ref->addref( src._ref );
--      dst._ref->addref( mask._ref );
--
--      return( dst );
--}
--
--
--// bodies for package colour
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_LCh2Lab: convert LCh to Lab
--VImage VImage::LCh2Lab() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LCh2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LCh2UCS: convert LCh to UCS
--VImage VImage::LCh2UCS() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LCh2UCS" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2LCh: convert Lab to LCh
--VImage VImage::Lab2LCh() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2LCh" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2LabQ: convert Lab to LabQ
--VImage VImage::Lab2LabQ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2LabQ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2LabS: convert Lab to LabS
--VImage VImage::Lab2LabS() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2LabS" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2UCS: convert Lab to UCS
--VImage VImage::Lab2UCS() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2UCS" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2XYZ: convert D65 Lab to XYZ
--VImage VImage::Lab2XYZ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2XYZ_temp: convert Lab to XYZ, with a specified colour temperature
--VImage VImage::Lab2XYZ_temp( double X0, double Y0, double Z0 ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2XYZ_temp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = X0;
--      *((double*) _vec.data(3)) = Y0;
--      *((double*) _vec.data(4)) = Z0;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Lab2disp: convert Lab to displayable
--VImage VImage::Lab2disp( VDisplay disp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Lab2disp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = disp.disp();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabQ2LabS: convert LabQ to LabS
--VImage VImage::LabQ2LabS() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabQ2LabS" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabQ2Lab: convert LabQ to Lab
--VImage VImage::LabQ2Lab() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabQ2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabQ2XYZ: convert LabQ to XYZ
--VImage VImage::LabQ2XYZ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabQ2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabQ2disp: convert LabQ to displayable
--VImage VImage::LabQ2disp( VDisplay disp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabQ2disp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = disp.disp();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabS2LabQ: convert LabS to LabQ
--VImage VImage::LabS2LabQ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabS2LabQ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_LabS2Lab: convert LabS to Lab
--VImage VImage::LabS2Lab() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_LabS2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_UCS2LCh: convert UCS to LCh
--VImage VImage::UCS2LCh() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_UCS2LCh" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_UCS2Lab: convert UCS to Lab
--VImage VImage::UCS2Lab() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_UCS2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_UCS2XYZ: convert UCS to XYZ
--VImage VImage::UCS2XYZ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_UCS2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2Lab: convert D65 XYZ to Lab
--VImage VImage::XYZ2Lab() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2Lab_temp: convert XYZ to Lab, with a specified colour temperature
--VImage VImage::XYZ2Lab_temp( double X0, double Y0, double Z0 ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2Lab_temp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = X0;
--      *((double*) _vec.data(3)) = Y0;
--      *((double*) _vec.data(4)) = Z0;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2UCS: convert XYZ to UCS
--VImage VImage::XYZ2UCS() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2UCS" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2Yxy: convert XYZ to Yxy
--VImage VImage::XYZ2Yxy() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2Yxy" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2disp: convert XYZ to displayble
--VImage VImage::XYZ2disp( VDisplay disp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2disp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = disp.disp();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_XYZ2sRGB: convert XYZ to sRGB
--VImage VImage::XYZ2sRGB() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_XYZ2sRGB" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_Yxy2XYZ: convert Yxy to XYZ
--VImage VImage::Yxy2XYZ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_Yxy2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_dE00_fromLab: calculate delta-E CIE2000 for two Lab images
--VImage VImage::dE00_fromLab( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dE00_fromLab" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_dECMC_fromLab: calculate delta-E CMC(1:1) for two Lab images
--VImage VImage::dECMC_fromLab( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dECMC_fromLab" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_dECMC_fromdisp: calculate delta-E CMC(1:1) for two displayable images
--VImage VImage::dECMC_fromdisp( VImage in2, VDisplay disp ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dECMC_fromdisp" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.data(3) = disp.disp();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_dE_fromLab: calculate delta-E for two Lab images
--VImage VImage::dE_fromLab( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dE_fromLab" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_dE_fromXYZ: calculate delta-E for two XYZ images
--VImage VImage::dE_fromXYZ( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dE_fromXYZ" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_dE_fromdisp: calculate delta-E for two displayable images
--VImage VImage::dE_fromdisp( VImage in2, VDisplay disp ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_dE_fromdisp" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.data(3) = disp.disp();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_disp2Lab: convert displayable to Lab
--VImage VImage::disp2Lab( VDisplay disp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_disp2Lab" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = disp.disp();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_disp2XYZ: convert displayable to XYZ
--VImage VImage::disp2XYZ( VDisplay disp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_disp2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = disp.disp();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_float2rad: convert float to Radiance packed
--VImage VImage::float2rad() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_float2rad" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_icc_ac2rc: convert LAB from AC to RC using an ICC profile
--VImage VImage::icc_ac2rc( char* profile ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_ac2rc" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) profile;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_icc_export_depth: convert a float LAB to device space with an ICC profile
--VImage VImage::icc_export_depth( int depth, char* output_profile, int intent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_export_depth" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = depth;
--      _vec.data(3) = (im_object) output_profile;
--      *((int*) _vec.data(4)) = intent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_icc_import: convert a device image to float LAB with an ICC profile
--VImage VImage::icc_import( char* input_profile, int intent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_import" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) input_profile;
--      *((int*) _vec.data(3)) = intent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_icc_import_embedded: convert a device image to float LAB using the embedded profile
--VImage VImage::icc_import_embedded( int intent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_import_embedded" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = intent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_icc_transform: convert between two device images with a pair of ICC profiles
--VImage VImage::icc_transform( char* input_profile, char* output_profile, int intent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_transform" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) input_profile;
--      _vec.data(3) = (im_object) output_profile;
--      *((int*) _vec.data(4)) = intent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lab_morph: morph colourspace of a LAB image
--VImage VImage::lab_morph( VDMask greyscale, double L_offset, double L_scale, double a_scale, double b_scale ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lab_morph" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = greyscale.mask().dptr;
--      *((double*) _vec.data(3)) = L_offset;
--      *((double*) _vec.data(4)) = L_scale;
--      *((double*) _vec.data(5)) = a_scale;
--      *((double*) _vec.data(6)) = b_scale;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rad2float: convert Radiance packed to float
--VImage VImage::rad2float() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rad2float" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_sRGB2XYZ: convert sRGB to XYZ
--VImage VImage::sRGB2XYZ() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_sRGB2XYZ" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--
--// bodies for package conversion
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_gaussnoise: generate image of gaussian noise with specified statistics
--VImage VImage::gaussnoise( int xsize, int ysize, double mean, double sigma ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_gaussnoise" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      *((double*) _vec.data(3)) = mean;
--      *((double*) _vec.data(4)) = sigma;
--      _vec.call();
--
--      return( out );
--}
--
--// im_bandjoin: bandwise join of two images
--VImage VImage::bandjoin( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_bandjoin" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_black: generate black image
--VImage VImage::black( int x_size, int y_size, int bands ) throw( VError )
--{
--      VImage output;
--
--      Vargv _vec( "im_black" );
--
--      _vec.data(0) = output.image();
--      *((int*) _vec.data(1)) = x_size;
--      *((int*) _vec.data(2)) = y_size;
--      *((int*) _vec.data(3)) = bands;
--      _vec.call();
--
--      return( output );
--}
--
--// im_c2amph: convert real and imaginary to phase and amplitude
--VImage VImage::c2amph() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_c2amph" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_c2imag: extract imaginary part of complex image
--VImage VImage::c2imag() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_c2imag" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_c2real: extract real part of complex image
--VImage VImage::c2real() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_c2real" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_c2rect: convert phase and amplitude to real and imaginary
--VImage VImage::c2rect() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_c2rect" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2fmt: convert image format to ofmt
--VImage VImage::clip2fmt( int ofmt ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2fmt" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = ofmt;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_copy: copy image
--VImage VImage::copy() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_copy" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_copy_file: copy image to a file and return that
--VImage VImage::copy_file() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_copy_file" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_copy_morph: copy image, setting pixel layout
--VImage VImage::copy_morph( int Bands, int BandFmt, int Coding ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_copy_morph" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = Bands;
--      *((int*) _vec.data(3)) = BandFmt;
--      *((int*) _vec.data(4)) = Coding;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_copy_swap: copy image, swapping byte order
--VImage VImage::copy_swap() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_copy_swap" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_copy_set: copy image, setting informational fields
--VImage VImage::copy_set( int Type, double Xres, double Yres, int Xoffset, int Yoffset ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_copy_set" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = Type;
--      *((double*) _vec.data(3)) = Xres;
--      *((double*) _vec.data(4)) = Yres;
--      *((int*) _vec.data(5)) = Xoffset;
--      *((int*) _vec.data(6)) = Yoffset;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_extract_area: extract area
--VImage VImage::extract_area( int left, int top, int width, int height ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_extract_area" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = left;
--      *((int*) _vec.data(3)) = top;
--      *((int*) _vec.data(4)) = width;
--      *((int*) _vec.data(5)) = height;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_extract_areabands: extract area and bands
--VImage VImage::extract_areabands( int left, int top, int width, int height, int band, int nbands ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_extract_areabands" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = left;
--      *((int*) _vec.data(3)) = top;
--      *((int*) _vec.data(4)) = width;
--      *((int*) _vec.data(5)) = height;
--      *((int*) _vec.data(6)) = band;
--      *((int*) _vec.data(7)) = nbands;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_extract_band: extract band
--VImage VImage::extract_band( int band ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_extract_band" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = band;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_extract_bands: extract several bands
--VImage VImage::extract_bands( int band, int nbands ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_extract_bands" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = band;
--      *((int*) _vec.data(3)) = nbands;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_extract: extract area/band
--VImage VImage::extract( int left, int top, int width, int height, int band ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_extract" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = left;
--      *((int*) _vec.data(3)) = top;
--      *((int*) _vec.data(4)) = width;
--      *((int*) _vec.data(5)) = height;
--      *((int*) _vec.data(6)) = band;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_falsecolour: turn luminance changes into chrominance changes
--VImage VImage::falsecolour() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_falsecolour" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_fliphor: flip image left-right
--VImage VImage::fliphor() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_fliphor" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_flipver: flip image top-bottom
--VImage VImage::flipver() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_flipver" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_gbandjoin: bandwise join of many images
--VImage VImage::gbandjoin( std::vector<VImage> in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_gbandjoin" );
--
--      ((im_imagevec_object*) _vec.data(0))->n = in.size();
--      ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[in.size()];
--      for( unsigned int i = 0; i < in.size(); i++ )
--              ((im_imagevec_object*) _vec.data(0))->vec[i] = in[i].image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      for( unsigned int i = 0; i < in.size(); i++ )
--              out._ref->addref( in[i]._ref );
--
--      return( out );
--}
--
--// im_grid: chop a tall thin image into a grid of images
--VImage VImage::grid( int tile_height, int across, int down ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_grid" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = tile_height;
--      *((int*) _vec.data(3)) = across;
--      *((int*) _vec.data(4)) = down;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_insert: insert sub-image into main image at position
--VImage VImage::insert( VImage sub, int x, int y ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_insert" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = sub.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = x;
--      *((int*) _vec.data(4)) = y;
--      _vec.call();
--      out._ref->addref( in._ref );
--      out._ref->addref( sub._ref );
--
--      return( out );
--}
--
--// im_insertset: insert sub into main at every position in x, y
--VImage VImage::insert( VImage sub, std::vector<int> x, std::vector<int> y ) throw( VError )
--{
--      VImage main = *this;
--      VImage out;
--
--      Vargv _vec( "im_insertset" );
--
--      _vec.data(0) = main.image();
--      _vec.data(1) = sub.image();
--      _vec.data(2) = out.image();
--      ((im_intvec_object*) _vec.data(3))->n = x.size();
--      ((im_intvec_object*) _vec.data(3))->vec = new int[x.size()];
--      for( unsigned int i = 0; i < x.size(); i++ )
--              ((im_intvec_object*) _vec.data(3))->vec[i] = x[i];
--      ((im_intvec_object*) _vec.data(4))->n = y.size();
--      ((im_intvec_object*) _vec.data(4))->vec = new int[y.size()];
--      for( unsigned int i = 0; i < y.size(); i++ )
--              ((im_intvec_object*) _vec.data(4))->vec[i] = y[i];
--      _vec.call();
--
--      return( out );
--}
--
--// im_insert_noexpand: insert sub-image into main image at position, no expansion
--VImage VImage::insert_noexpand( VImage sub, int x, int y ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_insert_noexpand" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = sub.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = x;
--      *((int*) _vec.data(4)) = y;
--      _vec.call();
--      out._ref->addref( in._ref );
--      out._ref->addref( sub._ref );
--
--      return( out );
--}
--
--// im_embed: embed in within a set of borders
--VImage VImage::embed( int type, int x, int y, int width, int height ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_embed" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = type;
--      *((int*) _vec.data(3)) = x;
--      *((int*) _vec.data(4)) = y;
--      *((int*) _vec.data(5)) = width;
--      *((int*) _vec.data(6)) = height;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lrjoin: join two images left-right
--VImage VImage::lrjoin( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_lrjoin" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_msb: convert to uchar by discarding bits
--VImage VImage::msb() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_msb" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_msb_band: convert to single band uchar by discarding bits
--VImage VImage::msb_band( int band ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_msb_band" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = band;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_replicate: replicate an image horizontally and vertically
--VImage VImage::replicate( int across, int down ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_replicate" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = across;
--      *((int*) _vec.data(3)) = down;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--// im_ri2c: join two non-complex images to form complex
--VImage VImage::ri2c( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_ri2c" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_rot180: rotate image 180 degrees
--VImage VImage::rot180() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rot180" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rot270: rotate image 270 degrees clockwise
--VImage VImage::rot270() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rot270" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rot90: rotate image 90 degrees clockwise
--VImage VImage::rot90() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rot90" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_scale: scale image linearly to fit range 0-255
--VImage VImage::scale() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_scale" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_scaleps: logarithmic scale of image to fit range 0-255
--VImage VImage::scaleps() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_scaleps" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_subsample: subsample image by integer factors
--VImage VImage::subsample( int xshrink, int yshrink ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_subsample" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = xshrink;
--      *((int*) _vec.data(3)) = yshrink;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_system: run command on image
--char* VImage::system( char* command ) throw( VError )
--{
--      VImage im = *this;
--      char* output;
--
--      Vargv _vec( "im_system" );
--
--      _vec.data(0) = im.image();
--      _vec.data(1) = (im_object) command;
--      _vec.call();
--      output = (char*) _vec.data(2);
--
--      return( output );
--}
--
--// im_system_image: run command on image, with image output
--VImage VImage::system_image( char* in_format, char* out_format, char* command, char*& log ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_system_image" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) in_format;
--      _vec.data(3) = (im_object) out_format;
--      _vec.data(4) = (im_object) command;
--      _vec.call();
--      log = (char*) _vec.data(5);
--
--      return( out );
--}
--
--// im_tbjoin: join two images top-bottom
--VImage VImage::tbjoin( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_tbjoin" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_text: generate text image
--VImage VImage::text( char* text, char* font, int width, int alignment, int dpi ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_text" );
--
--      _vec.data(0) = out.image();
--      _vec.data(1) = (im_object) text;
--      _vec.data(2) = (im_object) font;
--      *((int*) _vec.data(3)) = width;
--      *((int*) _vec.data(4)) = alignment;
--      *((int*) _vec.data(5)) = dpi;
--      _vec.call();
--
--      return( out );
--}
--
--// im_wrap: shift image origin, wrapping at sides
--VImage VImage::wrap( int x, int y ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_wrap" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_zoom: simple zoom of an image by integer factors
--VImage VImage::zoom( int xfac, int yfac ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_zoom" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((int*) _vec.data(2)) = xfac;
--      *((int*) _vec.data(3)) = yfac;
--      _vec.call();
--      output._ref->addref( input._ref );
--
--      return( output );
--}
--
--
--// bodies for package convolution
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_aconvsep: approximate separable convolution
--VImage VImage::aconvsep( VDMask matrix, int n_layers ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_aconvsep" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      *((int*) _vec.data(3)) = n_layers;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_aconv: approximate convolution
--VImage VImage::aconv( VDMask matrix, int n_layers, int cluster ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_aconv" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      *((int*) _vec.data(3)) = n_layers;
--      *((int*) _vec.data(4)) = cluster;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_addgnoise: add gaussian noise with mean 0 and std. dev. sigma
--VImage VImage::addgnoise( double sigma ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_addgnoise" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = sigma;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_compass: convolve with 8-way rotating integer mask
--VImage VImage::compass( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_compass" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_contrast_surface: find high-contrast points in an image
--VImage VImage::contrast_surface( int half_win_size, int spacing ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_contrast_surface" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = half_win_size;
--      *((int*) _vec.data(3)) = spacing;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_conv: convolve
--VImage VImage::conv( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_conv" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_conv_f: convolve, with DOUBLEMASK
--VImage VImage::conv( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_conv_f" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsep: seperable convolution
--VImage VImage::convsep( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsep" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsep_f: seperable convolution, with DOUBLEMASK
--VImage VImage::convsep( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsep_f" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_fastcor: fast correlate in2 within in1
--VImage VImage::fastcor( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_fastcor" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_gradcor: non-normalised correlation of gradient of in2 within in1
--VImage VImage::gradcor( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_gradcor" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_gradient: convolve with 2-way rotating mask
--VImage VImage::gradient( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_gradient" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_grad_x: horizontal difference image
--VImage VImage::grad_x() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_grad_x" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_grad_y: vertical difference image
--VImage VImage::grad_y() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_grad_y" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lindetect: convolve with 4-way rotating mask
--VImage VImage::lindetect( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lindetect" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_sharpen: sharpen high frequencies of L channel of LabQ
--VImage VImage::sharpen( int mask_size, double x1, double y2, double y3, double m1, double m2 ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_sharpen" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = mask_size;
--      *((double*) _vec.data(3)) = x1;
--      *((double*) _vec.data(4)) = y2;
--      *((double*) _vec.data(5)) = y3;
--      *((double*) _vec.data(6)) = m1;
--      *((double*) _vec.data(7)) = m2;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_spcor: normalised correlation of in2 within in1
--VImage VImage::spcor( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_spcor" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--
--// bodies for package deprecated
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_argb2rgba: convert pre-multipled argb to png-style rgba
--VImage VImage::argb2rgba() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_argb2rgba" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_flood_copy: flood with ink from start_x, start_y while pixel == start pixel
--VImage VImage::flood_copy( int start_x, int start_y, std::vector<double> ink ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_flood_copy" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = start_x;
--      *((int*) _vec.data(3)) = start_y;
--      ((im_doublevec_object*) _vec.data(4))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(4))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(4))->vec[i] = ink[i];
--      _vec.call();
--
--      return( out );
--}
--
--// im_flood_blob_copy: flood with ink from start_x, start_y while pixel == start pixel
--VImage VImage::flood_blob_copy( int start_x, int start_y, std::vector<double> ink ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_flood_blob_copy" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = start_x;
--      *((int*) _vec.data(3)) = start_y;
--      ((im_doublevec_object*) _vec.data(4))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(4))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(4))->vec[i] = ink[i];
--      _vec.call();
--
--      return( out );
--}
--
--// im_flood_other_copy: flood mark with serial from start_x, start_y while pixel == start pixel
--VImage VImage::flood_other_copy( VImage mark, int start_x, int start_y, int serial ) throw( VError )
--{
--      VImage test = *this;
--      VImage out;
--
--      Vargv _vec( "im_flood_other_copy" );
--
--      _vec.data(0) = test.image();
--      _vec.data(1) = mark.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = start_x;
--      *((int*) _vec.data(4)) = start_y;
--      *((int*) _vec.data(5)) = serial;
--      _vec.call();
--
--      return( out );
--}
--
--// im_clip: convert to unsigned 8-bit integer
--VImage VImage::clip() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_c2ps: find power spectrum of complex image
--VImage VImage::c2ps() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_c2ps" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_resize_linear: resize to X by Y pixels with linear interpolation
--VImage VImage::resize_linear( int X, int Y ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_resize_linear" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = X;
--      *((int*) _vec.data(3)) = Y;
--      _vec.call();
--
--      return( out );
--}
--
--// im_cmulnorm: multiply two complex images, normalising output
--VImage VImage::cmulnorm( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_cmulnorm" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_fav4: average of 4 images
--VImage VImage::fav4( VImage in2, VImage in3, VImage in4 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_fav4" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = in3.image();
--      _vec.data(3) = in4.image();
--      _vec.data(4) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_gadd: calculate a*in1 + b*in2 + c = outfile
--VImage VImage::gadd( double a, double b, VImage in2, double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_gadd" );
--
--      *((double*) _vec.data(0)) = a;
--      _vec.data(1) = in1.image();
--      *((double*) _vec.data(2)) = b;
--      _vec.data(3) = in2.image();
--      *((double*) _vec.data(4)) = c;
--      _vec.data(5) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_icc_export: convert a float LAB to an 8-bit device image with an ICC profile
--VImage VImage::icc_export( char* output_profile, int intent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_icc_export" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) output_profile;
--      *((int*) _vec.data(3)) = intent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_litecor: calculate max(white)*factor*(in/white), if clip == 1
--VImage VImage::litecor( VImage white, int clip, double factor ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_litecor" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = white.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = clip;
--      *((double*) _vec.data(4)) = factor;
--      _vec.call();
--
--      return( out );
--}
--
--// im_affine: affine transform
--VImage VImage::affine( double a, double b, double c, double d, double dx, double dy, int x, int y, int w, int h ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_affine" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = a;
--      *((double*) _vec.data(3)) = b;
--      *((double*) _vec.data(4)) = c;
--      *((double*) _vec.data(5)) = d;
--      *((double*) _vec.data(6)) = dx;
--      *((double*) _vec.data(7)) = dy;
--      *((int*) _vec.data(8)) = x;
--      *((int*) _vec.data(9)) = y;
--      *((int*) _vec.data(10)) = w;
--      *((int*) _vec.data(11)) = h;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2c: convert to signed 8-bit integer
--VImage VImage::clip2c() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2c" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2cm: convert to complex
--VImage VImage::clip2cm() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2cm" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2d: convert to double-precision float
--VImage VImage::clip2d() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2d" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2dcm: convert to double complex
--VImage VImage::clip2dcm() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2dcm" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2f: convert to single-precision float
--VImage VImage::clip2f() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2f" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2i: convert to signed 32-bit integer
--VImage VImage::clip2i() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2i" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsub: convolve uchar to uchar, sub-sampling by xskip, yskip
--VImage VImage::convsub( VIMask matrix, int xskip, int yskip ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsub" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      *((int*) _vec.data(3)) = xskip;
--      *((int*) _vec.data(4)) = yskip;
--      _vec.call();
--
--      return( out );
--}
--
--// im_convf: convolve, with DOUBLEMASK
--VImage VImage::convf( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convf" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsepf: seperable convolution, with DOUBLEMASK
--VImage VImage::convsepf( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsepf" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2s: convert to signed 16-bit integer
--VImage VImage::clip2s() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2s" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_clip2ui: convert to unsigned 32-bit integer
--VImage VImage::clip2ui() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2ui" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_insertplaceset: insert sub into main at every position in x, y
--VImage VImage::insertplace( VImage sub, std::vector<int> x, std::vector<int> y ) throw( VError )
--{
--      VImage main = *this;
--      VImage out;
--
--      Vargv _vec( "im_insertplaceset" );
--
--      _vec.data(0) = main.image();
--      _vec.data(1) = sub.image();
--      _vec.data(2) = out.image();
--      ((im_intvec_object*) _vec.data(3))->n = x.size();
--      ((im_intvec_object*) _vec.data(3))->vec = new int[x.size()];
--      for( unsigned int i = 0; i < x.size(); i++ )
--              ((im_intvec_object*) _vec.data(3))->vec[i] = x[i];
--      ((im_intvec_object*) _vec.data(4))->n = y.size();
--      ((im_intvec_object*) _vec.data(4))->vec = new int[y.size()];
--      for( unsigned int i = 0; i < y.size(); i++ )
--              ((im_intvec_object*) _vec.data(4))->vec[i] = y[i];
--      _vec.call();
--
--      return( out );
--}
--
--// im_clip2us: convert to unsigned 16-bit integer
--VImage VImage::clip2us() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_clip2us" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_slice: slice an image using two thresholds
--VImage VImage::slice( double thresh1, double thresh2 ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_slice" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((double*) _vec.data(2)) = thresh1;
--      *((double*) _vec.data(3)) = thresh2;
--      _vec.call();
--
--      return( output );
--}
--
--// im_segment: number continuous regions in an image
--VImage VImage::segment( int& segments ) throw( VError )
--{
--      VImage test = *this;
--      VImage mask;
--
--      Vargv _vec( "im_segment" );
--
--      _vec.data(0) = test.image();
--      _vec.data(1) = mask.image();
--      _vec.call();
--      segments = *((int*)_vec.data(2));
--
--      return( mask );
--}
--
--// im_line: draw line between points (x1,y1) and (x2,y2)
--void VImage::line( int x1, int y1, int x2, int y2, int pelval ) throw( VError )
--{
--      VImage im = *this;
--      Vargv _vec( "im_line" );
--
--      _vec.data(0) = im.image();
--      *((int*) _vec.data(1)) = x1;
--      *((int*) _vec.data(2)) = y1;
--      *((int*) _vec.data(3)) = x2;
--      *((int*) _vec.data(4)) = y2;
--      *((int*) _vec.data(5)) = pelval;
--      _vec.call();
--}
--
--// im_thresh: slice an image at a threshold
--VImage VImage::thresh( double threshold ) throw( VError )
--{
--      VImage input = *this;
--      VImage output;
--
--      Vargv _vec( "im_thresh" );
--
--      _vec.data(0) = input.image();
--      _vec.data(1) = output.image();
--      *((double*) _vec.data(2)) = threshold;
--      _vec.call();
--
--      return( output );
--}
--
--// im_convf_raw: convolve, with DOUBLEMASK, no border
--VImage VImage::convf_raw( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convf_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_conv_raw: convolve, no border
--VImage VImage::conv_raw( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_conv_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_contrast_surface_raw: find high-contrast points in an image
--VImage VImage::contrast_surface_raw( int half_win_size, int spacing ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_contrast_surface_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = half_win_size;
--      *((int*) _vec.data(3)) = spacing;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsepf_raw: seperable convolution, with DOUBLEMASK, no border
--VImage VImage::convsepf_raw( VDMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsepf_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().dptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_convsep_raw: seperable convolution, no border
--VImage VImage::convsep_raw( VIMask matrix ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_convsep_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = matrix.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_fastcor_raw: fast correlate in2 within in1, no border
--VImage VImage::fastcor_raw( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_fastcor_raw" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_gradcor_raw: non-normalised correlation of gradient of in2 within in1, no padding
--VImage VImage::gradcor_raw( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_gradcor_raw" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_spcor_raw: normalised correlation of in2 within in1, no black padding
--VImage VImage::spcor_raw( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_spcor_raw" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_lhisteq_raw: local histogram equalisation, no border
--VImage VImage::lhisteq_raw( int width, int height ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lhisteq_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = width;
--      *((int*) _vec.data(3)) = height;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_stdif_raw: statistical differencing, no border
--VImage VImage::stdif_raw( double a, double m0, double b, double s0, int xw, int yw ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_stdif_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = a;
--      *((double*) _vec.data(3)) = m0;
--      *((double*) _vec.data(4)) = b;
--      *((double*) _vec.data(5)) = s0;
--      *((int*) _vec.data(6)) = xw;
--      *((int*) _vec.data(7)) = yw;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rank_raw: rank filter nth element of xsize/ysize window, no border
--VImage VImage::rank_raw( int xsize, int ysize, int n ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rank_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = xsize;
--      *((int*) _vec.data(3)) = ysize;
--      *((int*) _vec.data(4)) = n;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_dilate_raw: dilate image with mask
--VImage VImage::dilate_raw( VIMask mask ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_dilate_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = mask.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_erode_raw: erode image with mask
--VImage VImage::erode_raw( VIMask mask ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_erode_raw" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = mask.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_similarity_area: output area xywh of similarity transformation
--VImage VImage::similarity_area( double a, double b, double dx, double dy, int x, int y, int w, int h ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_similarity_area" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = a;
--      *((double*) _vec.data(3)) = b;
--      *((double*) _vec.data(4)) = dx;
--      *((double*) _vec.data(5)) = dy;
--      *((int*) _vec.data(6)) = x;
--      *((int*) _vec.data(7)) = y;
--      *((int*) _vec.data(8)) = w;
--      *((int*) _vec.data(9)) = h;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_similarity: similarity transformation
--VImage VImage::similarity( double a, double b, double dx, double dy ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_similarity" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = a;
--      *((double*) _vec.data(3)) = b;
--      *((double*) _vec.data(4)) = dx;
--      *((double*) _vec.data(5)) = dy;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_mask2vips: convert DOUBLEMASK to VIPS image
--VImage VImage::mask2vips( VDMask input ) throw( VError )
--{
--      VImage output;
--
--      Vargv _vec( "im_mask2vips" );
--
--      ((im_mask_object*) _vec.data(0))->mask = input.mask().dptr;
--      _vec.data(1) = output.image();
--      _vec.call();
--
--      return( output );
--}
--
--// im_vips2mask: convert VIPS image to DOUBLEMASK
--VDMask VImage::vips2mask() throw( VError )
--{
--      VImage input = *this;
--      VDMask output;
--
--      Vargv _vec( "im_vips2mask" );
--
--      _vec.data(0) = input.image();
--      ((im_mask_object*) _vec.data(1))->name = (char*)"noname";
--      _vec.call();
--      output.embed( (DOUBLEMASK *)((im_mask_object*)_vec.data(1))->mask );
--
--      return( output );
--}
--
--// im_insertplace: draw image sub inside image main at position (x,y)
--void VImage::insertplace( VImage sub, int x, int y ) throw( VError )
--{
--      VImage main = *this;
--      Vargv _vec( "im_insertplace" );
--
--      _vec.data(0) = main.image();
--      _vec.data(1) = sub.image();
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      _vec.call();
--}
--
--// im_circle: plot circle on image
--void VImage::circle( int cx, int cy, int radius, int intensity ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_circle" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = cx;
--      *((int*) _vec.data(2)) = cy;
--      *((int*) _vec.data(3)) = radius;
--      *((int*) _vec.data(4)) = intensity;
--      _vec.call();
--}
--
--// im_andimage: bitwise and of two images
--VImage VImage::andimage( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_andimage" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_andimageconst: bitwise and of an image with a constant
--VImage VImage::andimage( int c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_andimageconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_andimage_vec: bitwise and of an image with a vector constant
--VImage VImage::andimage( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_andimage_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_orimage: bitwise or of two images
--VImage VImage::orimage( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_orimage" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_orimageconst: bitwise or of an image with a constant
--VImage VImage::orimage( int c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_orimageconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_orimage_vec: bitwise or of an image with a vector constant
--VImage VImage::orimage( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_orimage_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_eorimage: bitwise eor of two images
--VImage VImage::eorimage( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_eorimage" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_eorimageconst: bitwise eor of an image with a constant
--VImage VImage::eorimage( int c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_eorimageconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_eorimage_vec: bitwise eor of an image with a vector constant
--VImage VImage::eorimage( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_eorimage_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_shiftleft_vec: shift image array bits to left
--VImage VImage::shiftleft( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_shiftleft_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_shiftleft: shift image n bits to left
--VImage VImage::shiftleft( int c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_shiftleft" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_shiftright_vec: shift image array bits to right
--VImage VImage::shiftright( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_shiftright_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_shiftright: shift integer image n bits to right
--VImage VImage::shiftright( int c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_shiftright" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_blend: use cond image to blend between images in1 and in2
--VImage VImage::blend( VImage in1, VImage in2 ) throw( VError )
--{
--      VImage cond = *this;
--      VImage out;
--
--      Vargv _vec( "im_blend" );
--
--      _vec.data(0) = cond.image();
--      _vec.data(1) = in1.image();
--      _vec.data(2) = in2.image();
--      _vec.data(3) = out.image();
--      _vec.call();
--      out._ref->addref( cond._ref );
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_equal: two images equal in value
--VImage VImage::equal( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_equal" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_equal_vec: image equals doublevec
--VImage VImage::equal( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_equal_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_equalconst: image equals const
--VImage VImage::equal( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_equalconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_ifthenelse: use cond image to choose pels from image in1 or in2
--VImage VImage::ifthenelse( VImage in1, VImage in2 ) throw( VError )
--{
--      VImage cond = *this;
--      VImage out;
--
--      Vargv _vec( "im_ifthenelse" );
--
--      _vec.data(0) = cond.image();
--      _vec.data(1) = in1.image();
--      _vec.data(2) = in2.image();
--      _vec.data(3) = out.image();
--      _vec.call();
--      out._ref->addref( cond._ref );
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_less: in1 less than in2 in value
--VImage VImage::less( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_less" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_less_vec: in less than doublevec
--VImage VImage::less( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_less_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lessconst: in less than const
--VImage VImage::less( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_lessconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_lesseq: in1 less than or equal to in2 in value
--VImage VImage::lesseq( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_lesseq" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_lesseq_vec: in less than or equal to doublevec
--VImage VImage::lesseq( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lesseq_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lesseqconst: in less than or equal to const
--VImage VImage::lesseq( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_lesseqconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_more: in1 more than in2 in value
--VImage VImage::more( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_more" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_more_vec: in more than doublevec
--VImage VImage::more( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_more_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_moreconst: in more than const
--VImage VImage::more( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_moreconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_moreeq: in1 more than or equal to in2 in value
--VImage VImage::moreeq( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_moreeq" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_moreeq_vec: in more than or equal to doublevec
--VImage VImage::moreeq( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_moreeq_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_moreeqconst: in more than or equal to const
--VImage VImage::moreeq( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_moreeqconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_notequal: two images not equal in value
--VImage VImage::notequal( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_notequal" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( in1._ref );
--      out._ref->addref( in2._ref );
--
--      return( out );
--}
--
--// im_notequal_vec: image does not equal doublevec
--VImage VImage::notequal( std::vector<double> vec ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_notequal_vec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_doublevec_object*) _vec.data(2))->n = vec.size();
--      ((im_doublevec_object*) _vec.data(2))->vec = new double[vec.size()];
--      for( unsigned int i = 0; i < vec.size(); i++ )
--              ((im_doublevec_object*) _vec.data(2))->vec[i] = vec[i];
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_notequalconst: image does not equal const
--VImage VImage::notequal( double c ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_notequalconst" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = c;
--      _vec.call();
--      out._ref->addref( in1._ref );
--
--      return( out );
--}
--
--// im_quadratic: transform via quadratic
--VImage VImage::quadratic( VImage coeff ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_quadratic" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = coeff.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--      out._ref->addref( coeff._ref );
--
--      return( out );
--}
--
--
--// bodies for package format
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_csv2vips: read a file in csv format
--VImage VImage::csv2vips( char* filename ) throw( VError )
--{
--      VImage im;
--
--      Vargv _vec( "im_csv2vips" );
--
--      _vec.data(0) = (im_object) filename;
--      _vec.data(1) = im.image();
--      _vec.call();
--
--      return( im );
--}
--
--// im_fits2vips: convert from fits
--VImage VImage::fits2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_fits2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_jpeg2vips: convert from jpeg
--VImage VImage::jpeg2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_jpeg2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_magick2vips: load file with libMagick
--VImage VImage::magick2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_magick2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_png2vips: convert PNG file to VIPS image
--VImage VImage::png2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_png2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_exr2vips: convert an OpenEXR file to VIPS
--VImage VImage::exr2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_exr2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_ppm2vips: read a file in pbm/pgm/ppm format
--VImage VImage::ppm2vips( char* filename ) throw( VError )
--{
--      VImage im;
--
--      Vargv _vec( "im_ppm2vips" );
--
--      _vec.data(0) = (im_object) filename;
--      _vec.data(1) = im.image();
--      _vec.call();
--
--      return( im );
--}
--
--// im_analyze2vips: read a file in analyze format
--VImage VImage::analyze2vips( char* filename ) throw( VError )
--{
--      VImage im;
--
--      Vargv _vec( "im_analyze2vips" );
--
--      _vec.data(0) = (im_object) filename;
--      _vec.data(1) = im.image();
--      _vec.call();
--
--      return( im );
--}
--
--// im_tiff2vips: convert TIFF file to VIPS image
--VImage VImage::tiff2vips( char* in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_tiff2vips" );
--
--      _vec.data(0) = (im_object) in;
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_vips2csv: write an image in csv format
--void VImage::vips2csv( char* filename ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2csv" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = (im_object) filename;
--      _vec.call();
--}
--
--// im_vips2dz: save as deepzoom
--void VImage::vips2dz( char* out ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2dz" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = (im_object) out;
--      _vec.call();
--}
--
--// im_vips2jpeg: convert to jpeg
--void VImage::vips2jpeg( char* out ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2jpeg" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = (im_object) out;
--      _vec.call();
--}
--
--// im_vips2mimejpeg: convert to jpeg as mime type on stdout
--void VImage::vips2mimejpeg( int qfac ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2mimejpeg" );
--
--      _vec.data(0) = in.image();
--      *((int*) _vec.data(1)) = qfac;
--      _vec.call();
--}
--
--// im_vips2png: convert VIPS image to PNG file
--void VImage::vips2png( char* out ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2png" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = (im_object) out;
--      _vec.call();
--}
--
--// im_vips2ppm: write a file in pbm/pgm/ppm format
--void VImage::vips2ppm( char* filename ) throw( VError )
--{
--      VImage im = *this;
--      Vargv _vec( "im_vips2ppm" );
--
--      _vec.data(0) = im.image();
--      _vec.data(1) = (im_object) filename;
--      _vec.call();
--}
--
--// im_vips2tiff: convert VIPS image to TIFF file
--void VImage::vips2tiff( char* out ) throw( VError )
--{
--      VImage in = *this;
--      Vargv _vec( "im_vips2tiff" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = (im_object) out;
--      _vec.call();
--}
--
--
--// bodies for package freq_filt
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_create_fmask: create frequency domain filter mask
--VImage VImage::create_fmask( int width, int height, int type, double p1, double p2, double p3, double p4, double p5 ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_create_fmask" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = width;
--      *((int*) _vec.data(2)) = height;
--      *((int*) _vec.data(3)) = type;
--      *((double*) _vec.data(4)) = p1;
--      *((double*) _vec.data(5)) = p2;
--      *((double*) _vec.data(6)) = p3;
--      *((double*) _vec.data(7)) = p4;
--      *((double*) _vec.data(8)) = p5;
--      _vec.call();
--
--      return( out );
--}
--
--// im_disp_ps: make displayable power spectrum
--VImage VImage::disp_ps() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_disp_ps" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_flt_image_freq: frequency domain filter image
--VImage VImage::flt_image_freq( int type, double p1, double p2, double p3, double p4, double p5 ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_flt_image_freq" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = type;
--      *((double*) _vec.data(3)) = p1;
--      *((double*) _vec.data(4)) = p2;
--      *((double*) _vec.data(5)) = p3;
--      *((double*) _vec.data(6)) = p4;
--      *((double*) _vec.data(7)) = p5;
--      _vec.call();
--
--      return( out );
--}
--
--// im_fractsurf: generate a fractal surface of given dimension
--VImage VImage::fractsurf( int size, double dimension ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_fractsurf" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = size;
--      *((double*) _vec.data(2)) = dimension;
--      _vec.call();
--
--      return( out );
--}
--
--// im_freqflt: frequency-domain filter of in with mask
--VImage VImage::freqflt( VImage mask ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_freqflt" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = mask.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_fwfft: forward fast-fourier transform
--VImage VImage::fwfft() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_fwfft" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_rotquad: rotate image quadrants to move origin to centre
--VImage VImage::rotquad() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rotquad" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_invfft: inverse fast-fourier transform
--VImage VImage::invfft() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_invfft" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_phasecor_fft: non-normalised correlation of gradient of in2 within in1
--VImage VImage::phasecor_fft( VImage in2 ) throw( VError )
--{
--      VImage in1 = *this;
--      VImage out;
--
--      Vargv _vec( "im_phasecor_fft" );
--
--      _vec.data(0) = in1.image();
--      _vec.data(1) = in2.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_invfftr: real part of inverse fast-fourier transform
--VImage VImage::invfftr() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_invfftr" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--
--// bodies for package histograms_lut
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_gammacorrect: gamma-correct image
--VImage VImage::gammacorrect( double exponent ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_gammacorrect" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = exponent;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_heq: histogram-equalise image
--VImage VImage::heq( int band_number ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_heq" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = band_number;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_hist: find and graph histogram of image
--VImage VImage::hist( int band_number ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_hist" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = band_number;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_histcum: turn histogram to cumulative histogram
--VImage VImage::histcum() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histcum" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_histeq: form histogram equalistion LUT
--VImage VImage::histeq() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histeq" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_hist_indexed: make a histogram with an index image
--VImage VImage::hist_indexed( VImage value ) throw( VError )
--{
--      VImage index = *this;
--      VImage out;
--
--      Vargv _vec( "im_hist_indexed" );
--
--      _vec.data(0) = index.image();
--      _vec.data(1) = value.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--      out._ref->addref( index._ref );
--      out._ref->addref( value._ref );
--
--      return( out );
--}
--
--// im_histgr: find histogram of image
--VImage VImage::histgr( int band_number ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histgr" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = band_number;
--      _vec.call();
--
--      return( out );
--}
--
--// im_histnD: find 1D, 2D or 3D histogram of image
--VImage VImage::histnD( int bins ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histnD" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = bins;
--      _vec.call();
--
--      return( out );
--}
--
--// im_histnorm: form normalised histogram
--VImage VImage::histnorm() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histnorm" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_histplot: plot graph of histogram
--VImage VImage::histplot() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histplot" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_histspec: find histogram which will make pdf of in match ref
--VImage VImage::histspec( VImage ref ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_histspec" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = ref.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_hsp: match stats of in to stats of ref
--VImage VImage::hsp( VImage ref ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_hsp" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = ref.image();
--      _vec.data(2) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_identity: generate identity histogram
--VImage VImage::identity( int nbands ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_identity" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = nbands;
--      _vec.call();
--
--      return( out );
--}
--
--// im_identity_ushort: generate ushort identity histogram
--VImage VImage::identity_ushort( int nbands, int size ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_identity_ushort" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = nbands;
--      *((int*) _vec.data(2)) = size;
--      _vec.call();
--
--      return( out );
--}
--
--// im_ismonotonic: test LUT for monotonicity
--int VImage::ismonotonic() throw( VError )
--{
--      VImage lut = *this;
--      int mono;
--
--      Vargv _vec( "im_ismonotonic" );
--
--      _vec.data(0) = lut.image();
--      _vec.call();
--      mono = *((int*)_vec.data(1));
--
--      return( mono );
--}
--
--// im_lhisteq: local histogram equalisation
--VImage VImage::lhisteq( int width, int height ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lhisteq" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = width;
--      *((int*) _vec.data(3)) = height;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_mpercent: find threshold above which there are percent values
--int VImage::mpercent( double percent ) throw( VError )
--{
--      VImage in = *this;
--      int thresh;
--
--      Vargv _vec( "im_mpercent" );
--
--      _vec.data(0) = in.image();
--      *((double*) _vec.data(1)) = percent;
--      _vec.call();
--      thresh = *((int*)_vec.data(2));
--
--      return( thresh );
--}
--
--// im_invertlut: generate correction table from set of measures
--VImage VImage::invertlut( VDMask measures, int lut_size ) throw( VError )
--{
--      VImage lut;
--
--      Vargv _vec( "im_invertlut" );
--
--      ((im_mask_object*) _vec.data(0))->mask = measures.mask().dptr;
--      _vec.data(1) = lut.image();
--      *((int*) _vec.data(2)) = lut_size;
--      _vec.call();
--
--      return( lut );
--}
--
--// im_buildlut: generate LUT table from set of x/y positions
--VImage VImage::buildlut( VDMask xyes ) throw( VError )
--{
--      VImage lut;
--
--      Vargv _vec( "im_buildlut" );
--
--      ((im_mask_object*) _vec.data(0))->mask = xyes.mask().dptr;
--      _vec.data(1) = lut.image();
--      _vec.call();
--
--      return( lut );
--}
--
--// im_maplut: map image through LUT
--VImage VImage::maplut( VImage lut ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_maplut" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = lut.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--      out._ref->addref( lut._ref );
--
--      return( out );
--}
--
--// im_project: find horizontal and vertical projections of an image
--VImage VImage::project( VImage& vout ) throw( VError )
--{
--      VImage in = *this;
--      VImage hout;
--
--      Vargv _vec( "im_project" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = hout.image();
--      _vec.data(2) = vout.image();
--      _vec.call();
--
--      return( hout );
--}
--
--// im_stdif: statistical differencing
--VImage VImage::stdif( double a, double m0, double b, double s0, int xw, int yw ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_stdif" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = a;
--      *((double*) _vec.data(3)) = m0;
--      *((double*) _vec.data(4)) = b;
--      *((double*) _vec.data(5)) = s0;
--      *((int*) _vec.data(6)) = xw;
--      *((int*) _vec.data(7)) = yw;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_tone_analyse: analyse in and create LUT for tone adjustment
--VImage VImage::tone_analyse( double Ps, double Pm, double Ph, double S, double M, double H ) throw( VError )
--{
--      VImage in = *this;
--      VImage hist;
--
--      Vargv _vec( "im_tone_analyse" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = hist.image();
--      *((double*) _vec.data(2)) = Ps;
--      *((double*) _vec.data(3)) = Pm;
--      *((double*) _vec.data(4)) = Ph;
--      *((double*) _vec.data(5)) = S;
--      *((double*) _vec.data(6)) = M;
--      *((double*) _vec.data(7)) = H;
--      _vec.call();
--
--      return( hist );
--}
--
--// im_tone_build: create LUT for tone adjustment of LabS images
--VImage VImage::tone_build( double Lb, double Lw, double Ps, double Pm, double Ph, double S, double M, double H ) throw( VError )
--{
--      VImage hist;
--
--      Vargv _vec( "im_tone_build" );
--
--      _vec.data(0) = hist.image();
--      *((double*) _vec.data(1)) = Lb;
--      *((double*) _vec.data(2)) = Lw;
--      *((double*) _vec.data(3)) = Ps;
--      *((double*) _vec.data(4)) = Pm;
--      *((double*) _vec.data(5)) = Ph;
--      *((double*) _vec.data(6)) = S;
--      *((double*) _vec.data(7)) = M;
--      *((double*) _vec.data(8)) = H;
--      _vec.call();
--
--      return( hist );
--}
--
--// im_tone_build_range: create LUT for tone adjustment
--VImage VImage::tone_build_range( int in_max, int out_max, double Lb, double Lw, double Ps, double Pm, double Ph, double S, double M, double H ) throw( VError )
--{
--      VImage hist;
--
--      Vargv _vec( "im_tone_build_range" );
--
--      _vec.data(0) = hist.image();
--      *((int*) _vec.data(1)) = in_max;
--      *((int*) _vec.data(2)) = out_max;
--      *((double*) _vec.data(3)) = Lb;
--      *((double*) _vec.data(4)) = Lw;
--      *((double*) _vec.data(5)) = Ps;
--      *((double*) _vec.data(6)) = Pm;
--      *((double*) _vec.data(7)) = Ph;
--      *((double*) _vec.data(8)) = S;
--      *((double*) _vec.data(9)) = M;
--      *((double*) _vec.data(10)) = H;
--      _vec.call();
--
--      return( hist );
--}
--
--// im_tone_map: map L channel of LabS or LabQ image through LUT
--VImage VImage::tone_map( VImage lut ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_tone_map" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = lut.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--      out._ref->addref( lut._ref );
--
--      return( out );
--}
--
--
--// bodies for package inplace
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_draw_circle: draw circle on image
--void VImage::draw_circle( int cx, int cy, int radius, int fill, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_circle" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = cx;
--      *((int*) _vec.data(2)) = cy;
--      *((int*) _vec.data(3)) = radius;
--      *((int*) _vec.data(4)) = fill;
--      ((im_doublevec_object*) _vec.data(5))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(5))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(5))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_rect: draw rect on image
--void VImage::draw_rect( int left, int top, int width, int height, int fill, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_rect" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = left;
--      *((int*) _vec.data(2)) = top;
--      *((int*) _vec.data(3)) = width;
--      *((int*) _vec.data(4)) = height;
--      *((int*) _vec.data(5)) = fill;
--      ((im_doublevec_object*) _vec.data(6))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(6))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(6))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_line: draw line on image
--void VImage::draw_line( int x1, int y1, int x2, int y2, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_line" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = x1;
--      *((int*) _vec.data(2)) = y1;
--      *((int*) _vec.data(3)) = x2;
--      *((int*) _vec.data(4)) = y2;
--      ((im_doublevec_object*) _vec.data(5))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(5))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(5))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_point: draw point on image
--void VImage::draw_point( int x, int y, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_point" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = x;
--      *((int*) _vec.data(2)) = y;
--      ((im_doublevec_object*) _vec.data(3))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(3))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(3))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_smudge: smudge part of an image
--void VImage::draw_smudge( int left, int top, int width, int height ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_smudge" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = left;
--      *((int*) _vec.data(2)) = top;
--      *((int*) _vec.data(3)) = width;
--      *((int*) _vec.data(4)) = height;
--      _vec.call();
--}
--
--// im_draw_flood: flood with ink from x, y while pixel != ink
--void VImage::draw_flood( int x, int y, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_flood" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = x;
--      *((int*) _vec.data(2)) = y;
--      ((im_doublevec_object*) _vec.data(3))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(3))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(3))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_flood_blob: flood with ink from x, y while pixel == start
--void VImage::draw_flood_blob( int x, int y, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_flood_blob" );
--
--      _vec.data(0) = image.image();
--      *((int*) _vec.data(1)) = x;
--      *((int*) _vec.data(2)) = y;
--      ((im_doublevec_object*) _vec.data(3))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(3))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(3))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_draw_flood_other: flood image with serial from x, y while pixel == start
--void VImage::draw_flood_other( VImage test, int x, int y, int serial ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_flood_other" );
--
--      _vec.data(0) = image.image();
--      _vec.data(1) = test.image();
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      *((int*) _vec.data(4)) = serial;
--      _vec.call();
--}
--
--// im_draw_image: draw image sub inside image main at position (x,y)
--void VImage::draw_image( VImage sub, int x, int y ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_image" );
--
--      _vec.data(0) = image.image();
--      _vec.data(1) = sub.image();
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      _vec.call();
--}
--
--// im_draw_mask: draw mask sub inside image main at position (x,y)
--void VImage::draw_mask( VImage mask, int x, int y, std::vector<double> ink ) throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_draw_mask" );
--
--      _vec.data(0) = image.image();
--      _vec.data(1) = mask.image();
--      *((int*) _vec.data(2)) = x;
--      *((int*) _vec.data(3)) = y;
--      ((im_doublevec_object*) _vec.data(4))->n = ink.size();
--      ((im_doublevec_object*) _vec.data(4))->vec = new double[ink.size()];
--      for( unsigned int i = 0; i < ink.size(); i++ )
--              ((im_doublevec_object*) _vec.data(4))->vec[i] = ink[i];
--      _vec.call();
--}
--
--// im_lineset: draw line between points (x1,y1) and (x2,y2)
--VImage VImage::line( VImage mask, VImage ink, std::vector<int> x1, std::vector<int> y1, std::vector<int> x2, std::vector<int> y2 ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_lineset" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = mask.image();
--      _vec.data(3) = ink.image();
--      ((im_intvec_object*) _vec.data(4))->n = x1.size();
--      ((im_intvec_object*) _vec.data(4))->vec = new int[x1.size()];
--      for( unsigned int i = 0; i < x1.size(); i++ )
--              ((im_intvec_object*) _vec.data(4))->vec[i] = x1[i];
--      ((im_intvec_object*) _vec.data(5))->n = y1.size();
--      ((im_intvec_object*) _vec.data(5))->vec = new int[y1.size()];
--      for( unsigned int i = 0; i < y1.size(); i++ )
--              ((im_intvec_object*) _vec.data(5))->vec[i] = y1[i];
--      ((im_intvec_object*) _vec.data(6))->n = x2.size();
--      ((im_intvec_object*) _vec.data(6))->vec = new int[x2.size()];
--      for( unsigned int i = 0; i < x2.size(); i++ )
--              ((im_intvec_object*) _vec.data(6))->vec[i] = x2[i];
--      ((im_intvec_object*) _vec.data(7))->n = y2.size();
--      ((im_intvec_object*) _vec.data(7))->vec = new int[y2.size()];
--      for( unsigned int i = 0; i < y2.size(); i++ )
--              ((im_intvec_object*) _vec.data(7))->vec[i] = y2[i];
--      _vec.call();
--
--      return( out );
--}
--
--
--// bodies for package iofuncs
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_binfile: open a headerless binary file
--VImage VImage::binfile( char* filename, int width, int height, int bands, int offset ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_binfile" );
--
--      _vec.data(0) = (im_object) filename;
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = width;
--      *((int*) _vec.data(3)) = height;
--      *((int*) _vec.data(4)) = bands;
--      *((int*) _vec.data(5)) = offset;
--      _vec.call();
--
--      return( out );
--}
--
--// im_cache: cache results of an operation
--VImage VImage::cache( int tile_width, int tile_height, int max_tiles ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_cache" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = tile_width;
--      *((int*) _vec.data(3)) = tile_height;
--      *((int*) _vec.data(4)) = max_tiles;
--      _vec.call();
--
--      return( out );
--}
--
--// im_getext: return the image metadata XML as a string
--char* VImage::getext() throw( VError )
--{
--      VImage image = *this;
--      char* history;
--
--      Vargv _vec( "im_getext" );
--
--      _vec.data(0) = image.image();
--      _vec.call();
--      history = (char*) _vec.data(1);
--
--      return( history );
--}
--
--// im_header_get_typeof: return field type
--int VImage::header_get_typeof( char* field ) throw( VError )
--{
--      VImage image = *this;
--      int gtype;
--
--      Vargv _vec( "im_header_get_typeof" );
--
--      _vec.data(0) = (im_object) field;
--      _vec.data(1) = image.image();
--      _vec.call();
--      gtype = *((int*)_vec.data(2));
--
--      return( gtype );
--}
--
--// im_header_int: extract int fields from header
--int VImage::header_int( char* field ) throw( VError )
--{
--      VImage image = *this;
--      int value;
--
--      Vargv _vec( "im_header_int" );
--
--      _vec.data(0) = (im_object) field;
--      _vec.data(1) = image.image();
--      _vec.call();
--      value = *((int*)_vec.data(2));
--
--      return( value );
--}
--
--// im_header_double: extract double fields from header
--double VImage::header_double( char* field ) throw( VError )
--{
--      VImage image = *this;
--      double value;
--
--      Vargv _vec( "im_header_double" );
--
--      _vec.data(0) = (im_object) field;
--      _vec.data(1) = image.image();
--      _vec.call();
--      value = *((double*)_vec.data(2));
--
--      return( value );
--}
--
--// im_header_string: extract fields from headers as strings
--char* VImage::header_string( char* field ) throw( VError )
--{
--      VImage image = *this;
--      char* value;
--
--      Vargv _vec( "im_header_string" );
--
--      _vec.data(0) = (im_object) field;
--      _vec.data(1) = image.image();
--      _vec.call();
--      value = (char*) _vec.data(2);
--
--      return( value );
--}
--
--// im_history_get: return the image history as a string
--char* VImage::history_get() throw( VError )
--{
--      VImage image = *this;
--      char* history;
--
--      Vargv _vec( "im_history_get" );
--
--      _vec.data(0) = image.image();
--      _vec.call();
--      history = (char*) _vec.data(1);
--
--      return( history );
--}
--
--// im_printdesc: print an image header to stdout
--void VImage::printdesc() throw( VError )
--{
--      VImage image = *this;
--      Vargv _vec( "im_printdesc" );
--
--      _vec.data(0) = image.image();
--      _vec.call();
--}
--
--
--// bodies for package mask
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--
--// bodies for package morphology
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_cntlines: count horizontal or vertical lines
--double VImage::cntlines( int direction ) throw( VError )
--{
--      VImage in = *this;
--      double nlines;
--
--      Vargv _vec( "im_cntlines" );
--
--      _vec.data(0) = in.image();
--      *((int*) _vec.data(2)) = direction;
--      _vec.call();
--      nlines = *((double*)_vec.data(1));
--
--      return( nlines );
--}
--
--// im_dilate: dilate image with mask, adding a black border
--VImage VImage::dilate( VIMask mask ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_dilate" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = mask.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rank: rank filter nth element of xsize/ysize window
--VImage VImage::rank( int xsize, int ysize, int n ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rank" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = xsize;
--      *((int*) _vec.data(3)) = ysize;
--      *((int*) _vec.data(4)) = n;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_rank_image: point-wise pixel rank
--VImage VImage::rank_image( std::vector<VImage> in, int index ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_rank_image" );
--
--      ((im_imagevec_object*) _vec.data(0))->n = in.size();
--      ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[in.size()];
--      for( unsigned int i = 0; i < in.size(); i++ )
--              ((im_imagevec_object*) _vec.data(0))->vec[i] = in[i].image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = index;
--      _vec.call();
--      for( unsigned int i = 0; i < in.size(); i++ )
--              out._ref->addref( in[i]._ref );
--
--      return( out );
--}
--
--// im_maxvalue: point-wise maximum value
--VImage VImage::maxvalue( std::vector<VImage> in ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_maxvalue" );
--
--      ((im_imagevec_object*) _vec.data(0))->n = in.size();
--      ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[in.size()];
--      for( unsigned int i = 0; i < in.size(); i++ )
--              ((im_imagevec_object*) _vec.data(0))->vec[i] = in[i].image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      for( unsigned int i = 0; i < in.size(); i++ )
--              out._ref->addref( in[i]._ref );
--
--      return( out );
--}
--
--// im_label_regions: number continuous regions in an image
--VImage VImage::label_regions( int& segments ) throw( VError )
--{
--      VImage test = *this;
--      VImage mask;
--
--      Vargv _vec( "im_label_regions" );
--
--      _vec.data(0) = test.image();
--      _vec.data(1) = mask.image();
--      _vec.call();
--      segments = *((int*)_vec.data(2));
--
--      return( mask );
--}
--
--// im_zerox: find +ve or -ve zero crossings in image
--VImage VImage::zerox( int flag ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_zerox" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = flag;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_erode: erode image with mask, adding a black border
--VImage VImage::erode( VIMask mask ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_erode" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      ((im_mask_object*) _vec.data(2))->mask = mask.mask().iptr;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_profile: find first horizontal/vertical edge
--VImage VImage::profile( int direction ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_profile" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = direction;
--      _vec.call();
--
--      return( out );
--}
--
--
--// bodies for package mosaicing
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_align_bands: align the bands of an image
--VImage VImage::align_bands() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_align_bands" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--
--      return( out );
--}
--
--// im_correl: search area around sec for match for area around ref
--double VImage::correl( VImage sec, int xref, int yref, int xsec, int ysec, int hwindowsize, int hsearchsize, int& x, int& y ) throw( VError )
--{
--      VImage ref = *this;
--      double correlation;
--
--      Vargv _vec( "im_correl" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      *((int*) _vec.data(2)) = xref;
--      *((int*) _vec.data(3)) = yref;
--      *((int*) _vec.data(4)) = xsec;
--      *((int*) _vec.data(5)) = ysec;
--      *((int*) _vec.data(6)) = hwindowsize;
--      *((int*) _vec.data(7)) = hsearchsize;
--      _vec.call();
--      correlation = *((double*)_vec.data(8));
--      x = *((int*)_vec.data(9));
--      y = *((int*)_vec.data(10));
--
--      return( correlation );
--}
--
--// im__find_lroverlap: search for left-right overlap of ref and sec
--int VImage::_find_lroverlap( VImage sec, int bandno, int xr, int yr, int xs, int ys, int halfcorrelation, int halfarea, int& dy0, double& scale1, double& angle1, double& dx1, double& dy1 ) throw( VError )
--{
--      VImage ref = *this;
--      int dx0;
--
--      Vargv _vec( "im__find_lroverlap" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      *((int*) _vec.data(2)) = bandno;
--      *((int*) _vec.data(3)) = xr;
--      *((int*) _vec.data(4)) = yr;
--      *((int*) _vec.data(5)) = xs;
--      *((int*) _vec.data(6)) = ys;
--      *((int*) _vec.data(7)) = halfcorrelation;
--      *((int*) _vec.data(8)) = halfarea;
--      _vec.call();
--      dx0 = *((int*)_vec.data(9));
--      dy0 = *((int*)_vec.data(10));
--      scale1 = *((double*)_vec.data(11));
--      angle1 = *((double*)_vec.data(12));
--      dx1 = *((double*)_vec.data(13));
--      dy1 = *((double*)_vec.data(14));
--
--      return( dx0 );
--}
--
--// im__find_tboverlap: search for top-bottom overlap of ref and sec
--int VImage::_find_tboverlap( VImage sec, int bandno, int xr, int yr, int xs, int ys, int halfcorrelation, int halfarea, int& dy0, double& scale1, double& angle1, double& dx1, double& dy1 ) throw( VError )
--{
--      VImage ref = *this;
--      int dx0;
--
--      Vargv _vec( "im__find_tboverlap" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      *((int*) _vec.data(2)) = bandno;
--      *((int*) _vec.data(3)) = xr;
--      *((int*) _vec.data(4)) = yr;
--      *((int*) _vec.data(5)) = xs;
--      *((int*) _vec.data(6)) = ys;
--      *((int*) _vec.data(7)) = halfcorrelation;
--      *((int*) _vec.data(8)) = halfarea;
--      _vec.call();
--      dx0 = *((int*)_vec.data(9));
--      dy0 = *((int*)_vec.data(10));
--      scale1 = *((double*)_vec.data(11));
--      angle1 = *((double*)_vec.data(12));
--      dx1 = *((double*)_vec.data(13));
--      dy1 = *((double*)_vec.data(14));
--
--      return( dx0 );
--}
--
--// im_global_balance: automatically rebuild mosaic with balancing
--VImage VImage::global_balance( double gamma ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_global_balance" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = gamma;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_global_balancef: automatically rebuild mosaic with balancing, float output
--VImage VImage::global_balancef( double gamma ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_global_balancef" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = gamma;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_lrmerge: left-right merge of in1 and in2
--VImage VImage::lrmerge( VImage sec, int dx, int dy, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_lrmerge" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = dx;
--      *((int*) _vec.data(4)) = dy;
--      *((int*) _vec.data(5)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_lrmerge1: first-order left-right merge of ref and sec
--VImage VImage::lrmerge1( VImage sec, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_lrmerge1" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = xr1;
--      *((int*) _vec.data(4)) = yr1;
--      *((int*) _vec.data(5)) = xs1;
--      *((int*) _vec.data(6)) = ys1;
--      *((int*) _vec.data(7)) = xr2;
--      *((int*) _vec.data(8)) = yr2;
--      *((int*) _vec.data(9)) = xs2;
--      *((int*) _vec.data(10)) = ys2;
--      *((int*) _vec.data(11)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_lrmosaic: left-right mosaic of ref and sec
--VImage VImage::lrmosaic( VImage sec, int bandno, int xr, int yr, int xs, int ys, int halfcorrelation, int halfarea, int balancetype, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_lrmosaic" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = bandno;
--      *((int*) _vec.data(4)) = xr;
--      *((int*) _vec.data(5)) = yr;
--      *((int*) _vec.data(6)) = xs;
--      *((int*) _vec.data(7)) = ys;
--      *((int*) _vec.data(8)) = halfcorrelation;
--      *((int*) _vec.data(9)) = halfarea;
--      *((int*) _vec.data(10)) = balancetype;
--      *((int*) _vec.data(11)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_lrmosaic1: first-order left-right mosaic of ref and sec
--VImage VImage::lrmosaic1( VImage sec, int bandno, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int halfcorrelation, int halfarea, int balancetype, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_lrmosaic1" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = bandno;
--      *((int*) _vec.data(4)) = xr1;
--      *((int*) _vec.data(5)) = yr1;
--      *((int*) _vec.data(6)) = xs1;
--      *((int*) _vec.data(7)) = ys1;
--      *((int*) _vec.data(8)) = xr2;
--      *((int*) _vec.data(9)) = yr2;
--      *((int*) _vec.data(10)) = xs2;
--      *((int*) _vec.data(11)) = ys2;
--      *((int*) _vec.data(12)) = halfcorrelation;
--      *((int*) _vec.data(13)) = halfarea;
--      *((int*) _vec.data(14)) = balancetype;
--      *((int*) _vec.data(15)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_match_linear: resample ref so that tie-points match
--VImage VImage::match_linear( VImage sec, int xref1, int yref1, int xsec1, int ysec1, int xref2, int yref2, int xsec2, int ysec2 ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_match_linear" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = xref1;
--      *((int*) _vec.data(4)) = yref1;
--      *((int*) _vec.data(5)) = xsec1;
--      *((int*) _vec.data(6)) = ysec1;
--      *((int*) _vec.data(7)) = xref2;
--      *((int*) _vec.data(8)) = yref2;
--      *((int*) _vec.data(9)) = xsec2;
--      *((int*) _vec.data(10)) = ysec2;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_match_linear_search: search sec, then resample so that tie-points match
--VImage VImage::match_linear_search( VImage sec, int xref1, int yref1, int xsec1, int ysec1, int xref2, int yref2, int xsec2, int ysec2, int hwindowsize, int hsearchsize ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_match_linear_search" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = xref1;
--      *((int*) _vec.data(4)) = yref1;
--      *((int*) _vec.data(5)) = xsec1;
--      *((int*) _vec.data(6)) = ysec1;
--      *((int*) _vec.data(7)) = xref2;
--      *((int*) _vec.data(8)) = yref2;
--      *((int*) _vec.data(9)) = xsec2;
--      *((int*) _vec.data(10)) = ysec2;
--      *((int*) _vec.data(11)) = hwindowsize;
--      *((int*) _vec.data(12)) = hsearchsize;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_maxpos_subpel: subpixel position of maximum of (phase correlation) image
--double VImage::maxpos_subpel( double& y ) throw( VError )
--{
--      VImage im = *this;
--      double x;
--
--      Vargv _vec( "im_maxpos_subpel" );
--
--      _vec.data(0) = im.image();
--      _vec.call();
--      x = *((double*)_vec.data(1));
--      y = *((double*)_vec.data(2));
--
--      return( x );
--}
--
--// im_remosaic: automatically rebuild mosaic with new files
--VImage VImage::remosaic( char* old_str, char* new_str ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_remosaic" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.data(2) = (im_object) old_str;
--      _vec.data(3) = (im_object) new_str;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_tbmerge: top-bottom merge of in1 and in2
--VImage VImage::tbmerge( VImage sec, int dx, int dy, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_tbmerge" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = dx;
--      *((int*) _vec.data(4)) = dy;
--      *((int*) _vec.data(5)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_tbmerge1: first-order top-bottom merge of in1 and in2
--VImage VImage::tbmerge1( VImage sec, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_tbmerge1" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = xr1;
--      *((int*) _vec.data(4)) = yr1;
--      *((int*) _vec.data(5)) = xs1;
--      *((int*) _vec.data(6)) = ys1;
--      *((int*) _vec.data(7)) = xr2;
--      *((int*) _vec.data(8)) = yr2;
--      *((int*) _vec.data(9)) = xs2;
--      *((int*) _vec.data(10)) = ys2;
--      *((int*) _vec.data(11)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_tbmosaic: top-bottom mosaic of in1 and in2
--VImage VImage::tbmosaic( VImage sec, int bandno, int xr, int yr, int xs, int ys, int halfcorrelation, int halfarea, int balancetype, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_tbmosaic" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = bandno;
--      *((int*) _vec.data(4)) = xr;
--      *((int*) _vec.data(5)) = yr;
--      *((int*) _vec.data(6)) = xs;
--      *((int*) _vec.data(7)) = ys;
--      *((int*) _vec.data(8)) = halfcorrelation;
--      *((int*) _vec.data(9)) = halfarea;
--      *((int*) _vec.data(10)) = balancetype;
--      *((int*) _vec.data(11)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--// im_tbmosaic1: first-order top-bottom mosaic of ref and sec
--VImage VImage::tbmosaic1( VImage sec, int bandno, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int halfcorrelation, int halfarea, int balancetype, int mwidth ) throw( VError )
--{
--      VImage ref = *this;
--      VImage out;
--
--      Vargv _vec( "im_tbmosaic1" );
--
--      _vec.data(0) = ref.image();
--      _vec.data(1) = sec.image();
--      _vec.data(2) = out.image();
--      *((int*) _vec.data(3)) = bandno;
--      *((int*) _vec.data(4)) = xr1;
--      *((int*) _vec.data(5)) = yr1;
--      *((int*) _vec.data(6)) = xs1;
--      *((int*) _vec.data(7)) = ys1;
--      *((int*) _vec.data(8)) = xr2;
--      *((int*) _vec.data(9)) = yr2;
--      *((int*) _vec.data(10)) = xs2;
--      *((int*) _vec.data(11)) = ys2;
--      *((int*) _vec.data(12)) = halfcorrelation;
--      *((int*) _vec.data(13)) = halfarea;
--      *((int*) _vec.data(14)) = balancetype;
--      *((int*) _vec.data(15)) = mwidth;
--      _vec.call();
--      out._ref->addref( ref._ref );
--      out._ref->addref( sec._ref );
--
--      return( out );
--}
--
--
--// bodies for package other
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_benchmark: do something complicated for testing
--VImage VImage::benchmark() throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_benchmark" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_benchmark2: do something complicated for testing
--double VImage::benchmark2() throw( VError )
--{
--      VImage in = *this;
--      double value;
--
--      Vargv _vec( "im_benchmark2" );
--
--      _vec.data(0) = in.image();
--      _vec.call();
--      value = *((double*)_vec.data(1));
--
--      return( value );
--}
--
--// im_benchmarkn: do something complicated for testing
--VImage VImage::benchmarkn( int n ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_benchmarkn" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = n;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_eye: generate IM_BANDFMT_UCHAR [0,255] frequency/amplitude image
--VImage VImage::eye( int xsize, int ysize, double factor ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_eye" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      *((double*) _vec.data(3)) = factor;
--      _vec.call();
--
--      return( out );
--}
--
--// im_grey: generate IM_BANDFMT_UCHAR [0,255] grey scale image
--VImage VImage::grey( int xsize, int ysize ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_grey" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      _vec.call();
--
--      return( out );
--}
--
--// im_feye: generate IM_BANDFMT_FLOAT [-1,1] frequency/amplitude image
--VImage VImage::feye( int xsize, int ysize, double factor ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_feye" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      *((double*) _vec.data(3)) = factor;
--      _vec.call();
--
--      return( out );
--}
--
--// im_fgrey: generate IM_BANDFMT_FLOAT [0,1] grey scale image
--VImage VImage::fgrey( int xsize, int ysize ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_fgrey" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      _vec.call();
--
--      return( out );
--}
--
--// im_fzone: generate IM_BANDFMT_FLOAT [-1,1] zone plate image
--VImage VImage::fzone( int size ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_fzone" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = size;
--      _vec.call();
--
--      return( out );
--}
--
--// im_make_xy: generate image with pixel value equal to coordinate
--VImage VImage::make_xy( int xsize, int ysize ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_make_xy" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      _vec.call();
--
--      return( out );
--}
--
--// im_sines: generate 2D sine image
--VImage VImage::sines( int xsize, int ysize, double horfreq, double verfreq ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_sines" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = xsize;
--      *((int*) _vec.data(2)) = ysize;
--      *((double*) _vec.data(3)) = horfreq;
--      *((double*) _vec.data(4)) = verfreq;
--      _vec.call();
--
--      return( out );
--}
--
--// im_zone: generate IM_BANDFMT_UCHAR [0,255] zone plate image
--VImage VImage::zone( int size ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_zone" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = size;
--      _vec.call();
--
--      return( out );
--}
--
--
--// bodies for package resample
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_rightshift_size: decrease size by a power-of-two factor
--VImage VImage::rightshift_size( int xshift, int yshift, int band_fmt ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_rightshift_size" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((int*) _vec.data(2)) = xshift;
--      *((int*) _vec.data(3)) = yshift;
--      *((int*) _vec.data(4)) = band_fmt;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_shrink: shrink image by xfac, yfac times
--VImage VImage::shrink( double xfac, double yfac ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_shrink" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = xfac;
--      *((double*) _vec.data(3)) = yfac;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_stretch3: stretch 3%, sub-pixel displace by xdisp/ydisp
--VImage VImage::stretch3( double xdisp, double ydisp ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_stretch3" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      *((double*) _vec.data(2)) = xdisp;
--      *((double*) _vec.data(3)) = ydisp;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_affinei: affine transform
--VImage VImage::affinei( char* interpolate, double a, double b, double c, double d, double dx, double dy, int x, int y, int w, int h ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_affinei" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      if( vips__input_interpolate_init( &_vec.data(2), interpolate ) )
--              verror();
--      *((double*) _vec.data(3)) = a;
--      *((double*) _vec.data(4)) = b;
--      *((double*) _vec.data(5)) = c;
--      *((double*) _vec.data(6)) = d;
--      *((double*) _vec.data(7)) = dx;
--      *((double*) _vec.data(8)) = dy;
--      *((int*) _vec.data(9)) = x;
--      *((int*) _vec.data(10)) = y;
--      *((int*) _vec.data(11)) = w;
--      *((int*) _vec.data(12)) = h;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--// im_affinei_all: affine transform of whole image
--VImage VImage::affinei_all( char* interpolate, double a, double b, double c, double d, double dx, double dy ) throw( VError )
--{
--      VImage in = *this;
--      VImage out;
--
--      Vargv _vec( "im_affinei_all" );
--
--      _vec.data(0) = in.image();
--      _vec.data(1) = out.image();
--      if( vips__input_interpolate_init( &_vec.data(2), interpolate ) )
--              verror();
--      *((double*) _vec.data(3)) = a;
--      *((double*) _vec.data(4)) = b;
--      *((double*) _vec.data(5)) = c;
--      *((double*) _vec.data(6)) = d;
--      *((double*) _vec.data(7)) = dx;
--      *((double*) _vec.data(8)) = dy;
--      _vec.call();
--      out._ref->addref( in._ref );
--
--      return( out );
--}
--
--
--// bodies for package video
--// this file automatically generated from
--// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013
--// im_video_test: test video grabber
--VImage VImage::video_test( int brightness, int error ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_video_test" );
--
--      _vec.data(0) = out.image();
--      *((int*) _vec.data(1)) = brightness;
--      *((int*) _vec.data(2)) = error;
--      _vec.call();
--
--      return( out );
--}
--
--// im_video_v4l1: grab a video frame with v4l1
--VImage VImage::video_v4l1( char* device, int channel, int brightness, int colour, int contrast, int hue, int ngrabs ) throw( VError )
--{
--      VImage out;
--
--      Vargv _vec( "im_video_v4l1" );
--
--      _vec.data(0) = out.image();
--      _vec.data(1) = (im_object) device;
--      *((int*) _vec.data(2)) = channel;
--      *((int*) _vec.data(3)) = brightness;
--      *((int*) _vec.data(4)) = colour;
--      *((int*) _vec.data(5)) = contrast;
--      *((int*) _vec.data(6)) = hue;
--      *((int*) _vec.data(7)) = ngrabs;
--      _vec.call();
--
--      return( out );
--}
--
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/libvipsCC/VMask.cc vips-7.38.5/libvipsCC/VMask.cc
---- vips-7.38.5-vanilla/libvipsCC/VMask.cc     2014-07-17 23:48:36.237794473 -0400
-+++ vips-7.38.5/libvipsCC/VMask.cc     1969-12-31 19:00:00.000000000 -0500
-@@ -1,662 +0,0 @@
--// Object part of VMask class
--
--/*
--
--    Copyright (C) 1991-2001 The National Gallery
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
--
--    You should have received a copy of the GNU Lesser 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
--
-- */
--
--/*
--
--    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
--
-- */
--
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif /*HAVE_CONFIG_H*/
--#include <vips/intl.h>
--
--#include <cstdlib>
--#include <cmath>
--
--#include <vips/vips.h>
--
--#include <vips/vipscpp.h>
--
--#ifdef WITH_DMALLOC
--#include <dmalloc.h>
--#endif /*WITH_DMALLOC*/
--
--VIPS_NAMESPACE_START
--
--/* Functions for VMask - refcounting layer over VPMask.
-- */
--
--VMask::~VMask()
--{
--      ref->nrefs--;
--      if( !ref->nrefs )
--              delete ref;
--}
--
--VMask &VMask::operator=( const VMask &a )
--{ 
--      // Loosing ref to LHS
--      ref->nrefs--;
--
--      if( ref->nrefs > 0 )
--              // Need fresh refblock
--              ref = new refblock;
--      else 
--              // Recycle old refblock
--              delete ref->pmask;
--
--      // LHS now points to RHS
--      ref = a.ref; 
--      ref->nrefs++; 
--      
--      return( *this ); 
--}
--
--// Make sure this is a private copy of pmask --- dup if nrefs != 1
--void VMask::make_private()
--{
--      if( ref->nrefs > 1 ) {
--              // Make fresh refblock
--              refblock *ref2 = new refblock;
--
--              // And copy the mask
--              ref2->pmask = ref->pmask->dup();
--              ref->nrefs--;
--              ref = ref2;
--      }
--}
--
--void VMask::ostream_print( std::ostream &file ) const
--{
--      file << *(ref->pmask);
--}
--
--// Embed INTMASK in VIMask
--void VIMask::embed( INTMASK *i ) throw( VError )
--{
--      if( ref->pmask )
--              verror( "embed: VIMask not empty" );
--      ref->pmask = new _private_detail::VPIMask( i );
--}
--
--// Type conversions: implicit INTMASK to DOUBLEMASK 
--VIMask::operator VDMask()
--{
--      VDMask out( xsize(), ysize() );
--
--      out.mask().dptr->scale = scale();
--      out.mask().dptr->offset = offset();
--
--      for( int i = 0; i < size(); i++ )
--              out[i] = (*this)[i];
--
--      return( out );
--}
--
--
--// Forward ref of VImage class
--class VImage;
--
--// Type conversions: implicit DOUBLEMASK to INTMASK
--VDMask::operator VIMask()
--{
--      VIMask out( xsize(), ysize() );
--
--      out.mask().iptr->scale = int( scale() );
--      out.mask().iptr->offset = int( offset() );
--
--      for( int i = 0; i < size(); i++ )
--              out[i] = (int) rint( (*this)[i] );
--
--      return( out );
--}
--
--// Type conversions: implicit DOUBLEMASK to VImage
--VDMask::operator VImage() throw( VError )
--{
--      VImage out;
--
--      if( im_mask2vips( mask().dptr, out.image() ) )
--              verror();
--
--      return( out );
--}
--
--// ... and INTMASK to VImage
--VIMask::operator VImage() { return( VImage( VDMask( *this ) ) ); }
--
--// Embed DOUBLEMASK in VDMask
--void VDMask::embed( DOUBLEMASK *i ) throw( VError )
--{
--      if( ref->pmask )
--              verror( "embed: VDMask not empty" );
--      ref->pmask = new _private_detail::VPDMask( i );
--}
--
--/* Functions for P*Mask - layer over im_*_*mask() functions.
-- */
--
--// Create empty imask
--_private_detail::VPIMask::VPIMask( int xsize, int ysize ) throw( VError )
--{
--      if( !(data.iptr = im_create_imask( "VPIMask::VPIMask", xsize, ysize )) )
--              verror();
--      type = _private_detail::VPMask::INT;
--}
--
--// Init from vector
--_private_detail::VPIMask::VPIMask( int xsize, int ysize, 
--      int scale, int offset, std::vector<int> coeff )
--      throw( VError )
--{
--      int i;
--
--      if( !(data.iptr = im_create_imask( "VPIMask::VPIMask", xsize, ysize )) )
--              verror();
--      type = _private_detail::VPMask::INT;
--
--      data.iptr->scale = scale;
--      data.iptr->offset = offset;
--      for( i = 0; i < xsize * ysize; i++ )
--              data.iptr->coeff[i] = coeff[i];
--}
--
--// Create from filename
--_private_detail::VPIMask::VPIMask( const char *name ) throw( VError )
--{
--      if( !(data.iptr = im_read_imask( (char *) name )) )
--              verror();
--      type = _private_detail::VPMask::INT;
--}
--
--// Create from existing INTMASK
--_private_detail::VPIMask::VPIMask( INTMASK *imask )
--{
--      data.iptr = imask;
--      type = _private_detail::VPMask::INT;
--}
--
--// Create empty
--_private_detail::VPIMask::VPIMask()
--{
--      data.iptr = 0;
--      type = _private_detail::VPMask::UNASSIGNED;
--}
--
--_private_detail::VPIMask::~VPIMask()
--{
--      if( data.iptr ) {
--              im_free_imask( data.iptr );
--              data.iptr = 0;
--              type = _private_detail::VPMask::UNASSIGNED;
--      }
--}
--
--// Duplicate -- we are a VPIMask, return a new VPIMask which is a copy of us.
--// Return as a VPMask tho'.
--_private_detail::VPMask *_private_detail::VPIMask::dup() const throw( VError )
--{
--      _private_detail::VPIMask *out = new _private_detail::VPIMask();
--
--      INTMASK *msk;
--      if( !(msk = im_dup_imask( data.iptr, "VPIMask::dup" )) ) {
--              delete out;
--              verror();
--      }
--      out->embed( msk );
--
--      return( out );
--}
--
--// Insert INTMASK pointer
--void _private_detail::VPIMask::embed( INTMASK *msk ) throw( VError )
--{
--      if( type != _private_detail::VPMask::UNASSIGNED )
--              verror( "VPIMask::embed: VPIMask not empty" );
--
--      data.iptr = msk;
--      type = _private_detail::VPMask::INT;
--}
--
--int _private_detail::VPIMask::xsize() const throw( VError )
--{
--      if( !data.iptr ) 
--              verror( "xsize: mask not set" );
--
--      return( data.iptr->xsize );
--}
--
--int _private_detail::VPIMask::ysize() const throw( VError )
--{
--      if( !data.iptr ) 
--              verror( "ysize: mask not set" );
--
--      return( data.iptr->ysize );
--}
--
--int _private_detail::VPIMask::scale() const throw( VError )
--{
--      if( !data.iptr ) 
--              verror( "scale: mask not set" );
--
--      return( data.iptr->scale );
--}
--
--int _private_detail::VPIMask::offset() const throw( VError )
--{
--      if( !data.iptr ) 
--              verror( "offset: mask not set" );
--
--      return( data.iptr->offset );
--}
--
--const char *_private_detail::VPIMask::filename() const throw( VError )
--{
--      if( !data.iptr ) 
--              verror( "filename: mask not set" );
--
--      return( data.iptr->filename );
--}
--
--void _private_detail::VPIMask::ostream_print( std::ostream &file ) const 
--      throw( VError )
--{
--      if( !data.iptr )
--              verror( "internal error #7447234" );
--      
--      int i, j;
--      int *p = data.iptr->coeff;
--
--      file << this->xsize() << "\t" << this->ysize() << "\t";
--      file << this->scale() << "\t" << this->offset() << "\n";
--
--      for( i = 0; i < this->ysize(); i++ ) {
--              for( j = 0; j < this->xsize(); j++ )
--                      file << *p++ << "\t";
--
--              file << "\n";
--      }
--}
--
--// Extract start of int array
--int *_private_detail::VPIMask::array() const 
--{ 
--      return( data.iptr->coeff ); 
--}
--
--// Create empty dmask
--_private_detail::VPDMask::VPDMask( int xsize, int ysize ) throw( VError )
--{
--      if( !(data.dptr = im_create_dmask( "VPDMask::VPDMask", xsize, ysize )) )
--              verror();
--      type = _private_detail::VPMask::DOUBLE;
--}
--
--// Create from vector
--_private_detail::VPDMask::VPDMask( int xsize, int ysize, 
--      double scale, double offset, std::vector<double> coeff ) throw( VError )
--{
--      int i;
--
--      if( !(data.dptr = im_create_dmask( "VPDMask::VPDMask", xsize, ysize )) )
--              verror();
--      type = _private_detail::VPMask::DOUBLE;
--
--      data.dptr->scale = scale;
--      data.dptr->offset = offset;
--      for( i = 0; i < xsize * ysize; i++ )
--              data.dptr->coeff[i] = coeff[i];
--}
--
--// Create from filename
--_private_detail::VPDMask::VPDMask( const char *name ) throw( VError )
--{
--      if( !(data.dptr = im_read_dmask( (char *) name )) )
--              verror();
--      type = _private_detail::VPMask::DOUBLE;
--}
--
--// Create empty
--_private_detail::VPDMask::VPDMask()
--{
--      data.dptr = 0;
--      type = _private_detail::VPMask::UNASSIGNED;
--}
--
--// Create from existing DOUBLEMASK
--_private_detail::VPDMask::VPDMask( DOUBLEMASK *dmask )
--{
--      data.dptr = dmask;
--      type = _private_detail::VPMask::DOUBLE;
--}
--
--_private_detail::VPDMask::~VPDMask()
--{
--      if( data.dptr ) {
--              im_free_dmask( data.dptr );
--              data.dptr = 0;
--              type = _private_detail::VPMask::UNASSIGNED;
--      }
--}
--
--// Duplicate -- we are a VPIMask, return a new VPIMask which is a copy of us.
--// Return as a VPMask tho'.
--_private_detail::VPMask *_private_detail::VPDMask::dup() const throw( VError )
--{
--      _private_detail::VPDMask *out = new _private_detail::VPDMask();
--
--      DOUBLEMASK *msk;
--      if( !(msk = im_dup_dmask( data.dptr, "VPDMask::dup" )) ) {
--              delete out;
--              verror();
--      }
--      out->embed( msk );
--
--      return( out );
--}
--
--// Insert DOUBLEMASK pointer
--void _private_detail::VPDMask::embed( DOUBLEMASK *msk ) throw( VError )
--{
--      if( type != _private_detail::VPMask::UNASSIGNED )
--              verror( "VPDMask::embed: VPDMask not empty" );
--
--      data.dptr = msk;
--      type = _private_detail::VPMask::DOUBLE;
--}
--
--int _private_detail::VPDMask::xsize() const throw( VError )
--{
--      if( !data.dptr ) 
--              verror( "xsize: mask not set" );
--
--      return( data.dptr->xsize );
--}
--
--int _private_detail::VPDMask::ysize() const throw( VError )
--{
--      if( !data.dptr ) 
--              verror( "ysize: mask not set" );
--
--      return( data.dptr->ysize );
--}
--
--double _private_detail::VPDMask::scale() const throw( VError )
--{
--      if( !data.dptr ) 
--              verror( "scale: mask not set" );
--
--      return( data.dptr->scale );
--}
--
--double _private_detail::VPDMask::offset() const throw( VError )
--{
--      if( !data.dptr ) 
--              verror( "offset: mask not set" );
--
--      return( data.dptr->offset );
--}
--
--const char *_private_detail::VPDMask::filename() const throw( VError )
--{
--      if( !data.dptr ) 
--              verror( "filename: mask not set" );
--
--      return( data.dptr->filename );
--}
--
--void _private_detail::VPDMask::ostream_print( std::ostream &file ) const 
--      throw( VError )
--{
--      if( !data.dptr )
--              verror( "internal error #7447234" );
--      
--      int i, j;
--      double *p = data.dptr->coeff;
--
--      file << this->xsize() << "\t" << this->ysize() << "\t";
--      file << this->scale() << "\t" << this->offset() << "\n";
--
--      for( i = 0; i < this->ysize(); i++ ) {
--              for( j = 0; j < this->xsize(); j++ )
--                      file << *p++ << "\t";
--
--              file << "\n";
--      }
--}
--
--// Extract data pointer
--double *_private_detail::VPDMask::array() const 
--{ 
--      return( data.dptr->coeff ); 
--}
--
--// Build functions
--VIMask VIMask::gauss( double sig, double minamp ) throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_gauss_imask( "VIMask::gauss", sig, minamp )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VIMask VIMask::gauss_sep( double sig, double minamp ) throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_gauss_imask_sep( "VIMask::gauss", sig, minamp )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::gauss( double sig, double minamp ) throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_gauss_dmask( "VDMask::gauss", sig, minamp )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VIMask VIMask::log( double sig, double minamp ) throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_log_imask( "VIMask::log", sig, minamp )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::log( double sig, double minamp ) throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_log_dmask( "VDMask::log", sig, minamp )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--// Manipulation functions
--VIMask VIMask::rotate45() throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_rotate_imask45( mask().iptr, "VIMask::rotate45" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VIMask VIMask::rotate90() throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_rotate_imask90( mask().iptr, "VIMask::rotate90" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::rotate45() throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_rotate_dmask45( mask().dptr, "VDMask::rotate45" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::rotate90() throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_rotate_dmask90( mask().dptr, "VDMask::rotate90" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::trn() throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_mattrn( mask().dptr, "VDMask::trn" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::inv() throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_matinv( mask().dptr, "VDMask::inv" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::mul( VDMask m ) throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_matmul( mask().dptr, m.mask().dptr, "VDMask::mul" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VDMask VDMask::cat( VDMask m ) throw( VError )
--{
--      VDMask out;
--      DOUBLEMASK *msk;
--
--      if( !(msk = im_matcat( mask().dptr, m.mask().dptr, "VDMask::cat" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--VIMask VDMask::scalei() throw( VError )
--{
--      VIMask out;
--      INTMASK *msk;
--
--      if( !(msk = im_scale_dmask( mask().dptr, "VDMask::scalei" )) )
--              verror();
--      out.embed( msk );
--
--      return( out );
--}
--
--// Arithmetic on a VIMask ... just cast and use VDMask
--VDMask VIMask::trn() throw( VError ) 
--      { return( ((VDMask)*this).trn() ); }
--VDMask VIMask::inv() throw( VError ) 
--      { return( ((VDMask)*this).inv() ); }
--VDMask VIMask::cat( VDMask a ) throw( VError ) 
--      { return( ((VDMask)*this).cat( a ) ); }
--VDMask VIMask::mul( VDMask a ) throw( VError ) 
--      { return( ((VDMask)*this).mul( a ) ); }
--
--// Overload [] to get linear array subscript.
--// Our caller may write to the result, so make sure we have a private
--// copy.
--// Involves function call, slow anyway, so do range checking
--int &VIMask::operator[]( int x ) throw( VError )
--{ 
--      if( ref->nrefs != 1 )
--              make_private();
--
--      if( x > size() )
--              verror( "VIMask::operator[]: subscript out of range" );
--
--      return( ((_private_detail::VPIMask *)ref->pmask)->array()[x] ); 
--}
--
--double &VDMask::operator[]( int x ) throw( VError )
--{ 
--      if( ref->nrefs != 1 )
--              make_private();
--
--      if( x > size() )
--              verror( "VDMask::operator[]: subscript out of range" );
--
--      return( ((_private_detail::VPDMask *)ref->pmask)->array()[x] ); 
--}
--
--VIPS_NAMESPACE_END
-diff -u --recursive --new-file vips-7.38.5-vanilla/Makefile.am vips-7.38.5/Makefile.am
---- vips-7.38.5-vanilla/Makefile.am    2014-07-17 23:48:36.206794473 -0400
-+++ vips-7.38.5/Makefile.am    2014-07-17 23:49:32.827792979 -0400
-@@ -1,23 +1,9 @@
--# turn off libvipsCC if C++ is disabled
--if ENABLE_CXX
--C_COMPILE_DIR = libvipsCC
--C_DIST_DIR =
--C_PKGCONFIG = vipsCC.pc
--
--# turn on Python if we can (requires C++)
--if HAVE_PYTHON
--P_COMPILE_DIR = swig
--P_DIST_DIR =
--endif
--
--else
- C_COMPILE_DIR =
--C_DIST_DIR = libvipsCC 
-+C_DIST_DIR = 
- C_PKGCONFIG =
- P_COMPILE_DIR =
- P_DIST_DIR = swig
--endif
- SUBDIRS = \
-       libvips \
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/Makefile.am vips-7.38.5/swig/Makefile.am
---- vips-7.38.5-vanilla/swig/Makefile.am       2014-07-17 23:48:36.206794473 -0400
-+++ vips-7.38.5/swig/Makefile.am       2014-07-17 23:49:32.827792979 -0400
-@@ -1,5 +1,2 @@
--SUBDIRS = \
--      vipsCC 
--
- EXTRA_DIST = \
-       test   
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/__init__.py vips-7.38.5/swig/vipsCC/__init__.py
---- vips-7.38.5-vanilla/swig/vipsCC/__init__.py        2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/__init__.py        1969-12-31 19:00:00.000000000 -0500
-@@ -1 +0,0 @@
--__all__=["VImage","VMask","VError","VDisplay"]
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/Makefile.am vips-7.38.5/swig/vipsCC/Makefile.am
---- vips-7.38.5-vanilla/swig/vipsCC/Makefile.am        2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/Makefile.am        1969-12-31 19:00:00.000000000 -0500
-@@ -1,58 +0,0 @@
--# Let make substitute the value of PYTHON_INCLUDES rather than auto*
--# this makes it easier to support multiple python installs
--AM_CPPFLAGS = \
--      -I${top_srcdir}/libvips/include \
--      -I${top_srcdir}/libvipsCC/include \
--      @VIPS_CFLAGS@ \
--      @VIPS_INCLUDES@ \
--      $(PYTHON_INCLUDES)
--
--# we install to a directory inside the python area, since we are a module
--vipsccdir = $(pyexecdir)/vipsCC
--
--vipscc_PYTHON = VImage.py VDisplay.py VError.py VMask.py __init__.py
--
--# I tried making a suffix rule for this (and defining SUFFIXES) but I couldn't
--# get it to work, how annoying 
--# FIXME at some point
--#
--# need an expanded VImage.h ... SWIG's preprocessor b0rks on includes inside
--# class definitions
--vimagemodule.cxx: VImage.i
--      cpp -DSWIG -E $(top_srcdir)/libvipsCC/include/vips/VImage.h > VImage.h
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--
--vdisplaymodule.cxx: VDisplay.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--verrormodule.cxx: VError.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--vmaskmodule.cxx: VMask.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--
--vipscc_LTLIBRARIES = vimagemodule.la vdisplaymodule.la verrormodule.la vmaskmodule.la
--
--# maybe there's a clever way to avoid repeating the link stuff 4 times
--# vimagemodule uses the C API as well, so it needs libvips too
--vimagemodule_la_LDFLAGS = -module -avoid-version 
--vimagemodule_la_LIBADD = ../../libvipsCC/libvipsCC.la ../../libvips/libvips.la $(VIPS_LIBS)
--nodist_vimagemodule_la_SOURCES = vimagemodule.cxx 
--
--vdisplaymodule_la_LDFLAGS = -module -avoid-version 
--vdisplaymodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_vdisplaymodule_la_SOURCES = vdisplaymodule.cxx 
--
--verrormodule_la_LDFLAGS = -module -avoid-version 
--verrormodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_verrormodule_la_SOURCES = verrormodule.cxx 
--
--vmaskmodule_la_LDFLAGS = -module -avoid-version 
--vmaskmodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_vmaskmodule_la_SOURCES = vmaskmodule.cxx 
--
--CLEANFILES = VImage.h 
--
--EXTRA_DIST = \
--      VImage.i VDisplay.i VError.i VMask.i __init__.py \
--      vimagemodule.cxx \
--      verrormodule.cxx vdisplaymodule.cxx vmaskmodule.cxx \
--      VImage.py VDisplay.py VError.py VMask.py
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/Makefile.in vips-7.38.5/swig/vipsCC/Makefile.in
---- vips-7.38.5-vanilla/swig/vipsCC/Makefile.in        2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/Makefile.in        1969-12-31 19:00:00.000000000 -0500
-@@ -1,895 +0,0 @@
--# Makefile.in generated by automake 1.13.3 from Makefile.am.
--# @configure_input@
--
--# Copyright (C) 1994-2013 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@
--am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
--am__make_running_with_option = \
--  case $${target_option-} in \
--      ?) ;; \
--      *) echo "am__make_running_with_option: internal error: invalid" \
--              "target option '$${target_option-}' specified" >&2; \
--         exit 1;; \
--  esac; \
--  has_opt=no; \
--  sane_makeflags=$$MAKEFLAGS; \
--  if $(am__is_gnu_make); then \
--    sane_makeflags=$$MFLAGS; \
--  else \
--    case $$MAKEFLAGS in \
--      *\\[\ \ ]*) \
--        bs=\\; \
--        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
--          | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
--    esac; \
--  fi; \
--  skip_next=no; \
--  strip_trailopt () \
--  { \
--    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
--  }; \
--  for flg in $$sane_makeflags; do \
--    test $$skip_next = yes && { skip_next=no; continue; }; \
--    case $$flg in \
--      *=*|--*) continue;; \
--        -*I) strip_trailopt 'I'; skip_next=yes;; \
--      -*I?*) strip_trailopt 'I';; \
--        -*O) strip_trailopt 'O'; skip_next=yes;; \
--      -*O?*) strip_trailopt 'O';; \
--        -*l) strip_trailopt 'l'; skip_next=yes;; \
--      -*l?*) strip_trailopt 'l';; \
--      -[dEDm]) skip_next=yes;; \
--      -[JT]) skip_next=yes;; \
--    esac; \
--    case $$flg in \
--      *$$target_option*) has_opt=yes; break;; \
--    esac; \
--  done; \
--  test $$has_opt = yes
--am__make_dryrun = (target_option=n; $(am__make_running_with_option))
--am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
--pkgdatadir = $(datadir)/@PACKAGE@
--pkgincludedir = $(includedir)/@PACKAGE@
--pkglibdir = $(libdir)/@PACKAGE@
--pkglibexecdir = $(libexecdir)/@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@
--subdir = swig/vipsCC
--DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
--      $(top_srcdir)/depcomp $(vipscc_PYTHON) \
--      $(top_srcdir)/py-compile
--ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
--am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
--      $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/acinclude.m4 \
--      $(top_srcdir)/configure.ac
--am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
--      $(ACLOCAL_M4)
--mkinstalldirs = $(install_sh) -d
--CONFIG_HEADER = $(top_builddir)/config.h
--CONFIG_CLEAN_FILES =
--CONFIG_CLEAN_VPATH_FILES =
--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 = f=`echo $$p | sed -e 's|^.*/||'`;
--am__install_max = 40
--am__nobase_strip_setup = \
--  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
--am__nobase_strip = \
--  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
--am__nobase_list = $(am__nobase_strip_setup); \
--  for p in $$list; do echo "$$p $$p"; done | \
--  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
--  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
--    if (++n[$$2] == $(am__install_max)) \
--      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
--    END { for (dir in files) print dir, files[dir] }'
--am__base_list = \
--  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
--  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
--am__uninstall_files_from_dir = { \
--  test -z "$$files" \
--    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
--    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
--         $(am__cd) "$$dir" && rm -f $$files; }; \
--  }
--am__installdirs = "$(DESTDIR)$(vipsccdir)" "$(DESTDIR)$(vipsccdir)"
--LTLIBRARIES = $(vipscc_LTLIBRARIES)
--am__DEPENDENCIES_1 =
--vdisplaymodule_la_DEPENDENCIES = ../../libvipsCC/libvipsCC.la \
--      $(am__DEPENDENCIES_1)
--nodist_vdisplaymodule_la_OBJECTS = vdisplaymodule.lo
--vdisplaymodule_la_OBJECTS = $(nodist_vdisplaymodule_la_OBJECTS)
--AM_V_lt = $(am__v_lt_@AM_V@)
--am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
--am__v_lt_0 = --silent
--am__v_lt_1 = 
--vdisplaymodule_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
--      $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
--      $(AM_CXXFLAGS) $(CXXFLAGS) $(vdisplaymodule_la_LDFLAGS) \
--      $(LDFLAGS) -o $@
--verrormodule_la_DEPENDENCIES = ../../libvipsCC/libvipsCC.la \
--      $(am__DEPENDENCIES_1)
--nodist_verrormodule_la_OBJECTS = verrormodule.lo
--verrormodule_la_OBJECTS = $(nodist_verrormodule_la_OBJECTS)
--verrormodule_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
--      $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
--      $(AM_CXXFLAGS) $(CXXFLAGS) $(verrormodule_la_LDFLAGS) \
--      $(LDFLAGS) -o $@
--vimagemodule_la_DEPENDENCIES = ../../libvipsCC/libvipsCC.la \
--      ../../libvips/libvips.la $(am__DEPENDENCIES_1)
--nodist_vimagemodule_la_OBJECTS = vimagemodule.lo
--vimagemodule_la_OBJECTS = $(nodist_vimagemodule_la_OBJECTS)
--vimagemodule_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
--      $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
--      $(AM_CXXFLAGS) $(CXXFLAGS) $(vimagemodule_la_LDFLAGS) \
--      $(LDFLAGS) -o $@
--vmaskmodule_la_DEPENDENCIES = ../../libvipsCC/libvipsCC.la \
--      $(am__DEPENDENCIES_1)
--nodist_vmaskmodule_la_OBJECTS = vmaskmodule.lo
--vmaskmodule_la_OBJECTS = $(nodist_vmaskmodule_la_OBJECTS)
--vmaskmodule_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
--      $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
--      $(AM_CXXFLAGS) $(CXXFLAGS) $(vmaskmodule_la_LDFLAGS) \
--      $(LDFLAGS) -o $@
--AM_V_P = $(am__v_P_@AM_V@)
--am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
--am__v_P_0 = false
--am__v_P_1 = :
--AM_V_GEN = $(am__v_GEN_@AM_V@)
--am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
--am__v_GEN_0 = @echo "  GEN     " $@;
--am__v_GEN_1 = 
--AM_V_at = $(am__v_at_@AM_V@)
--am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
--am__v_at_0 = @
--am__v_at_1 = 
--DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
--depcomp = $(SHELL) $(top_srcdir)/depcomp
--am__depfiles_maybe = depfiles
--am__mv = mv -f
--CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
--      $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
--LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
--      $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
--      $(AM_CXXFLAGS) $(CXXFLAGS)
--AM_V_CXX = $(am__v_CXX_@AM_V@)
--am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
--am__v_CXX_0 = @echo "  CXX     " $@;
--am__v_CXX_1 = 
--CXXLD = $(CXX)
--CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
--      $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
--      $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
--AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
--am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
--am__v_CXXLD_0 = @echo "  CXXLD   " $@;
--am__v_CXXLD_1 = 
--SOURCES = $(nodist_vdisplaymodule_la_SOURCES) \
--      $(nodist_verrormodule_la_SOURCES) \
--      $(nodist_vimagemodule_la_SOURCES) \
--      $(nodist_vmaskmodule_la_SOURCES)
--DIST_SOURCES =
--am__can_run_installinfo = \
--  case $$AM_UPDATE_INFO_DIR in \
--    n|no|NO) false;; \
--    *) (install-info --version) >/dev/null 2>&1;; \
--  esac
--am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
--am__pep3147_tweak = \
--  sed -e 's|\.py$$||' -e 's|[^/]*$$|__pycache__/&.*.py|'
--py_compile = $(top_srcdir)/py-compile
--am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
--# Read a list of newline-separated strings from the standard input,
--# and print each of them once, without duplicates.  Input order is
--# *not* preserved.
--am__uniquify_input = $(AWK) '\
--  BEGIN { nonempty = 0; } \
--  { items[$$0] = 1; nonempty = 1; } \
--  END { if (nonempty) { for (i in items) print i; }; } \
--'
--# Make sure the list of sources is unique.  This is necessary because,
--# e.g., the same source file might be shared among _SOURCES variables
--# for different programs/libraries.
--am__define_uniq_tagged_files = \
--  list='$(am__tagged_files)'; \
--  unique=`for i in $$list; do \
--    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
--  done | $(am__uniquify_input)`
--ETAGS = etags
--CTAGS = ctags
--DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
--ACLOCAL = @ACLOCAL@
--AMTAR = @AMTAR@
--AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
--AR = @AR@
--AS = @AS@
--AUTOCONF = @AUTOCONF@
--AUTOHEADER = @AUTOHEADER@
--AUTOMAKE = @AUTOMAKE@
--AWK = @AWK@
--CATALOGS = @CATALOGS@
--CATOBJEXT = @CATOBJEXT@
--CC = @CC@
--CCDEPMODE = @CCDEPMODE@
--CFITSIO_CFLAGS = @CFITSIO_CFLAGS@
--CFITSIO_LIBS = @CFITSIO_LIBS@
--CFLAGS = @CFLAGS@
--CPP = @CPP@
--CPPFLAGS = @CPPFLAGS@
--CXX = @CXX@
--CXXCPP = @CXXCPP@
--CXXDEPMODE = @CXXDEPMODE@
--CXXFLAGS = @CXXFLAGS@
--CYGPATH_W = @CYGPATH_W@
--DATADIRNAME = @DATADIRNAME@
--DEFS = @DEFS@
--DEPDIR = @DEPDIR@
--DLLTOOL = @DLLTOOL@
--DLLWRAP = @DLLWRAP@
--DSYMUTIL = @DSYMUTIL@
--DUMPBIN = @DUMPBIN@
--ECHO_C = @ECHO_C@
--ECHO_N = @ECHO_N@
--ECHO_T = @ECHO_T@
--EGREP = @EGREP@
--EXEEXT = @EXEEXT@
--EXIF_CFLAGS = @EXIF_CFLAGS@
--EXIF_LIBS = @EXIF_LIBS@
--FFTW_CFLAGS = @FFTW_CFLAGS@
--FFTW_LIBS = @FFTW_LIBS@
--FGREP = @FGREP@
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--GMOFILES = @GMOFILES@
--GMSGFMT = @GMSGFMT@
--GREP = @GREP@
--GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
--GTHREAD_LIBS = @GTHREAD_LIBS@
--GTKDOC_CHECK = @GTKDOC_CHECK@
--GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
--GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
--GTKDOC_MKPDF = @GTKDOC_MKPDF@
--GTKDOC_REBASE = @GTKDOC_REBASE@
--HTML_DIR = @HTML_DIR@
--IMAGE_MAGICK_CFLAGS = @IMAGE_MAGICK_CFLAGS@
--IMAGE_MAGICK_LIBS = @IMAGE_MAGICK_LIBS@
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--INSTALL_PROGRAM = @INSTALL_PROGRAM@
--INSTALL_SCRIPT = @INSTALL_SCRIPT@
--INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
--INSTOBJEXT = @INSTOBJEXT@
--INTLLIBS = @INTLLIBS@
--INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
--INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
--INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
--INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
--INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
--INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
--INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
--INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
--JPEG_INCLUDES = @JPEG_INCLUDES@
--JPEG_LIBS = @JPEG_LIBS@
--LCMS_CFLAGS = @LCMS_CFLAGS@
--LCMS_LIBS = @LCMS_LIBS@
--LD = @LD@
--LDFLAGS = @LDFLAGS@
--LIBOBJS = @LIBOBJS@
--LIBRARY_AGE = @LIBRARY_AGE@
--LIBRARY_CURRENT = @LIBRARY_CURRENT@
--LIBRARY_REVISION = @LIBRARY_REVISION@
--LIBS = @LIBS@
--LIBTOOL = @LIBTOOL@
--LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
--LIBWEBP_LIBS = @LIBWEBP_LIBS@
--LIPO = @LIPO@
--LN_S = @LN_S@
--LTLIBOBJS = @LTLIBOBJS@
--MAGICK_CFLAGS = @MAGICK_CFLAGS@
--MAGICK_LIBS = @MAGICK_LIBS@
--MAGICK_WAND_CFLAGS = @MAGICK_WAND_CFLAGS@
--MAGICK_WAND_LIBS = @MAGICK_WAND_LIBS@
--MAKEINFO = @MAKEINFO@
--MANIFEST_TOOL = @MANIFEST_TOOL@
--MATIO_CFLAGS = @MATIO_CFLAGS@
--MATIO_LIBS = @MATIO_LIBS@
--MKDIR_P = @MKDIR_P@
--MKINSTALLDIRS = @MKINSTALLDIRS@
--MONOTONIC_CFLAGS = @MONOTONIC_CFLAGS@
--MONOTONIC_LIBS = @MONOTONIC_LIBS@
--MSGFMT = @MSGFMT@
--MSGFMT_OPTS = @MSGFMT_OPTS@
--NM = @NM@
--NMEDIT = @NMEDIT@
--OBJDUMP = @OBJDUMP@
--OBJEXT = @OBJEXT@
--OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
--OPENEXR_LIBS = @OPENEXR_LIBS@
--OPENSLIDE_CFLAGS = @OPENSLIDE_CFLAGS@
--OPENSLIDE_LIBS = @OPENSLIDE_LIBS@
--ORC_CFLAGS = @ORC_CFLAGS@
--ORC_LIBS = @ORC_LIBS@
--OTOOL = @OTOOL@
--OTOOL64 = @OTOOL64@
--PACKAGE = @PACKAGE@
--PACKAGES_USED = @PACKAGES_USED@
--PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
--PACKAGE_NAME = @PACKAGE_NAME@
--PACKAGE_STRING = @PACKAGE_STRING@
--PACKAGE_TARNAME = @PACKAGE_TARNAME@
--PACKAGE_URL = @PACKAGE_URL@
--PACKAGE_VERSION = @PACKAGE_VERSION@
--PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
--PANGOFT2_LIBS = @PANGOFT2_LIBS@
--PATH_SEPARATOR = @PATH_SEPARATOR@
--PKG_CONFIG = @PKG_CONFIG@
--PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
--PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
--PNG_CFLAGS = @PNG_CFLAGS@
--PNG_INCLUDES = @PNG_INCLUDES@
--PNG_LIBS = @PNG_LIBS@
--POFILES = @POFILES@
--POSUB = @POSUB@
--PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
--PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
--PYTHON = @PYTHON@
--PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
--PYTHON_INCLUDES = @PYTHON_INCLUDES@
--PYTHON_PLATFORM = @PYTHON_PLATFORM@
--PYTHON_PREFIX = @PYTHON_PREFIX@
--PYTHON_VERSION = @PYTHON_VERSION@
--RANLIB = @RANLIB@
--REQUIRED_CFLAGS = @REQUIRED_CFLAGS@
--REQUIRED_LIBS = @REQUIRED_LIBS@
--SED = @SED@
--SET_MAKE = @SET_MAKE@
--SHELL = @SHELL@
--STRIP = @STRIP@
--THREADS_CFLAGS = @THREADS_CFLAGS@
--THREADS_LIBS = @THREADS_LIBS@
--TIFF_CFLAGS = @TIFF_CFLAGS@
--TIFF_INCLUDES = @TIFF_INCLUDES@
--TIFF_LIBS = @TIFF_LIBS@
--TYPE_INIT_CFLAGS = @TYPE_INIT_CFLAGS@
--TYPE_INIT_LIBS = @TYPE_INIT_LIBS@
--USE_NLS = @USE_NLS@
--VERSION = @VERSION@
--VIPS_CFLAGS = @VIPS_CFLAGS@
--VIPS_CXX_LIBS = @VIPS_CXX_LIBS@
--VIPS_EXEEXT = @VIPS_EXEEXT@
--VIPS_INCLUDES = @VIPS_INCLUDES@
--VIPS_LIBDIR = @VIPS_LIBDIR@
--VIPS_LIBS = @VIPS_LIBS@
--VIPS_MAJOR_VERSION = @VIPS_MAJOR_VERSION@
--VIPS_MICRO_VERSION = @VIPS_MICRO_VERSION@
--VIPS_MINOR_VERSION = @VIPS_MINOR_VERSION@
--VIPS_VERSION = @VIPS_VERSION@
--VIPS_VERSION_STRING = @VIPS_VERSION_STRING@
--XGETTEXT = @XGETTEXT@
--XMKMF = @XMKMF@
--X_CFLAGS = @X_CFLAGS@
--X_EXTRA_LIBS = @X_EXTRA_LIBS@
--X_LIBS = @X_LIBS@
--X_PRE_LIBS = @X_PRE_LIBS@
--ZIP_INCLUDES = @ZIP_INCLUDES@
--ZIP_LIBS = @ZIP_LIBS@
--abs_builddir = @abs_builddir@
--abs_srcdir = @abs_srcdir@
--abs_top_builddir = @abs_top_builddir@
--abs_top_srcdir = @abs_top_srcdir@
--ac_ct_AR = @ac_ct_AR@
--ac_ct_CC = @ac_ct_CC@
--ac_ct_CXX = @ac_ct_CXX@
--ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
--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@
--pdfdir = @pdfdir@
--pkgpyexecdir = @pkgpyexecdir@
--pkgpythondir = @pkgpythondir@
--prefix = @prefix@
--program_transform_name = @program_transform_name@
--psdir = @psdir@
--pyexecdir = @pyexecdir@
--pythondir = @pythondir@
--sbindir = @sbindir@
--sharedstatedir = @sharedstatedir@
--srcdir = @srcdir@
--sysconfdir = @sysconfdir@
--target_alias = @target_alias@
--top_build_prefix = @top_build_prefix@
--top_builddir = @top_builddir@
--top_srcdir = @top_srcdir@
--vips_introspection_sources = @vips_introspection_sources@
--
--# Let make substitute the value of PYTHON_INCLUDES rather than auto*
--# this makes it easier to support multiple python installs
--AM_CPPFLAGS = \
--      -I${top_srcdir}/libvips/include \
--      -I${top_srcdir}/libvipsCC/include \
--      @VIPS_CFLAGS@ \
--      @VIPS_INCLUDES@ \
--      $(PYTHON_INCLUDES)
--
--
--# we install to a directory inside the python area, since we are a module
--vipsccdir = $(pyexecdir)/vipsCC
--vipscc_PYTHON = VImage.py VDisplay.py VError.py VMask.py __init__.py
--vipscc_LTLIBRARIES = vimagemodule.la vdisplaymodule.la verrormodule.la vmaskmodule.la
--
--# maybe there's a clever way to avoid repeating the link stuff 4 times
--# vimagemodule uses the C API as well, so it needs libvips too
--vimagemodule_la_LDFLAGS = -module -avoid-version 
--vimagemodule_la_LIBADD = ../../libvipsCC/libvipsCC.la ../../libvips/libvips.la $(VIPS_LIBS)
--nodist_vimagemodule_la_SOURCES = vimagemodule.cxx 
--vdisplaymodule_la_LDFLAGS = -module -avoid-version 
--vdisplaymodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_vdisplaymodule_la_SOURCES = vdisplaymodule.cxx 
--verrormodule_la_LDFLAGS = -module -avoid-version 
--verrormodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_verrormodule_la_SOURCES = verrormodule.cxx 
--vmaskmodule_la_LDFLAGS = -module -avoid-version 
--vmaskmodule_la_LIBADD = ../../libvipsCC/libvipsCC.la $(VIPS_LIBS)
--nodist_vmaskmodule_la_SOURCES = vmaskmodule.cxx 
--CLEANFILES = VImage.h 
--EXTRA_DIST = \
--      VImage.i VDisplay.i VError.i VMask.i __init__.py \
--      vimagemodule.cxx \
--      verrormodule.cxx vdisplaymodule.cxx vmaskmodule.cxx \
--      VImage.py VDisplay.py VError.py VMask.py
--
--all: all-am
--
--.SUFFIXES:
--.SUFFIXES: .cxx .lo .o .obj
--$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
--      @for dep in $?; do \
--        case '$(am__configure_deps)' in \
--          *$$dep*) \
--            ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
--              && { if test -f $@; then exit 0; else break; fi; }; \
--            exit 1;; \
--        esac; \
--      done; \
--      echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign swig/vipsCC/Makefile'; \
--      $(am__cd) $(top_srcdir) && \
--        $(AUTOMAKE) --foreign swig/vipsCC/Makefile
--.PRECIOUS: Makefile
--Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
--      @case '$?' in \
--        *config.status*) \
--          cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
--        *) \
--          echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
--          cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
--      esac;
--
--$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--
--$(top_srcdir)/configure:  $(am__configure_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
--      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
--$(am__aclocal_m4_deps):
--
--install-vipsccLTLIBRARIES: $(vipscc_LTLIBRARIES)
--      @$(NORMAL_INSTALL)
--      @list='$(vipscc_LTLIBRARIES)'; test -n "$(vipsccdir)" || list=; \
--      list2=; for p in $$list; do \
--        if test -f $$p; then \
--          list2="$$list2 $$p"; \
--        else :; fi; \
--      done; \
--      test -z "$$list2" || { \
--        echo " $(MKDIR_P) '$(DESTDIR)$(vipsccdir)'"; \
--        $(MKDIR_P) "$(DESTDIR)$(vipsccdir)" || exit 1; \
--        echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(vipsccdir)'"; \
--        $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(vipsccdir)"; \
--      }
--
--uninstall-vipsccLTLIBRARIES:
--      @$(NORMAL_UNINSTALL)
--      @list='$(vipscc_LTLIBRARIES)'; test -n "$(vipsccdir)" || list=; \
--      for p in $$list; do \
--        $(am__strip_dir) \
--        echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(vipsccdir)/$$f'"; \
--        $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(vipsccdir)/$$f"; \
--      done
--
--clean-vipsccLTLIBRARIES:
--      -test -z "$(vipscc_LTLIBRARIES)" || rm -f $(vipscc_LTLIBRARIES)
--      @list='$(vipscc_LTLIBRARIES)'; \
--      locs=`for p in $$list; do echo $$p; done | \
--            sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
--            sort -u`; \
--      test -z "$$locs" || { \
--        echo rm -f $${locs}; \
--        rm -f $${locs}; \
--      }
--
--vdisplaymodule.la: $(vdisplaymodule_la_OBJECTS) $(vdisplaymodule_la_DEPENDENCIES) $(EXTRA_vdisplaymodule_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(vdisplaymodule_la_LINK) -rpath $(vipsccdir) $(vdisplaymodule_la_OBJECTS) $(vdisplaymodule_la_LIBADD) $(LIBS)
--
--verrormodule.la: $(verrormodule_la_OBJECTS) $(verrormodule_la_DEPENDENCIES) $(EXTRA_verrormodule_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(verrormodule_la_LINK) -rpath $(vipsccdir) $(verrormodule_la_OBJECTS) $(verrormodule_la_LIBADD) $(LIBS)
--
--vimagemodule.la: $(vimagemodule_la_OBJECTS) $(vimagemodule_la_DEPENDENCIES) $(EXTRA_vimagemodule_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(vimagemodule_la_LINK) -rpath $(vipsccdir) $(vimagemodule_la_OBJECTS) $(vimagemodule_la_LIBADD) $(LIBS)
--
--vmaskmodule.la: $(vmaskmodule_la_OBJECTS) $(vmaskmodule_la_DEPENDENCIES) $(EXTRA_vmaskmodule_la_DEPENDENCIES) 
--      $(AM_V_CXXLD)$(vmaskmodule_la_LINK) -rpath $(vipsccdir) $(vmaskmodule_la_OBJECTS) $(vmaskmodule_la_LIBADD) $(LIBS)
--
--mostlyclean-compile:
--      -rm -f *.$(OBJEXT)
--
--distclean-compile:
--      -rm -f *.tab.c
--
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdisplaymodule.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verrormodule.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vimagemodule.Plo@am__quote@
--@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmaskmodule.Plo@am__quote@
--
--.cxx.o:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
--
--.cxx.obj:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
--
--.cxx.lo:
--@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
--@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
--@AMDEP_TRUE@@am__fastdepCXX_FALSE@    DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
--@am__fastdepCXX_FALSE@        $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
--
--mostlyclean-libtool:
--      -rm -f *.lo
--
--clean-libtool:
--      -rm -rf .libs _libs
--install-vipsccPYTHON: $(vipscc_PYTHON)
--      @$(NORMAL_INSTALL)
--      @list='$(vipscc_PYTHON)'; dlist=; list2=; test -n "$(vipsccdir)" || list=; \
--      if test -n "$$list"; then \
--        echo " $(MKDIR_P) '$(DESTDIR)$(vipsccdir)'"; \
--        $(MKDIR_P) "$(DESTDIR)$(vipsccdir)" || exit 1; \
--      fi; \
--      for p in $$list; do \
--        if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
--        if test -f $$b$$p; then \
--          $(am__strip_dir) \
--          dlist="$$dlist $$f"; \
--          list2="$$list2 $$b$$p"; \
--        else :; fi; \
--      done; \
--      for file in $$list2; do echo $$file; done | $(am__base_list) | \
--      while read files; do \
--        echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(vipsccdir)'"; \
--        $(INSTALL_DATA) $$files "$(DESTDIR)$(vipsccdir)" || exit $$?; \
--      done || exit $$?; \
--      if test -n "$$dlist"; then \
--        $(am__py_compile) --destdir "$(DESTDIR)" \
--                          --basedir "$(vipsccdir)" $$dlist; \
--      else :; fi
--
--uninstall-vipsccPYTHON:
--      @$(NORMAL_UNINSTALL)
--      @list='$(vipscc_PYTHON)'; test -n "$(vipsccdir)" || list=; \
--      py_files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
--      test -n "$$py_files" || exit 0; \
--      dir='$(DESTDIR)$(vipsccdir)'; \
--      pyc_files=`echo "$$py_files" | sed 's|$$|c|'`; \
--      pyo_files=`echo "$$py_files" | sed 's|$$|o|'`; \
--      py_files_pep3147=`echo "$$py_files" | $(am__pep3147_tweak)`; \
--      echo "$$py_files_pep3147";\
--      pyc_files_pep3147=`echo "$$py_files_pep3147" | sed 's|$$|c|'`; \
--      pyo_files_pep3147=`echo "$$py_files_pep3147" | sed 's|$$|o|'`; \
--      st=0; \
--      for files in \
--        "$$py_files" \
--        "$$pyc_files" \
--        "$$pyo_files" \
--        "$$pyc_files_pep3147" \
--        "$$pyo_files_pep3147" \
--      ; do \
--        $(am__uninstall_files_from_dir) || st=$$?; \
--      done; \
--      exit $$st
--
--ID: $(am__tagged_files)
--      $(am__define_uniq_tagged_files); mkid -fID $$unique
--tags: tags-am
--TAGS: tags
--
--tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      set x; \
--      here=`pwd`; \
--      $(am__define_uniq_tagged_files); \
--      shift; \
--      if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
--        test -n "$$unique" || unique=$$empty_fix; \
--        if test $$# -gt 0; then \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            "$$@" $$unique; \
--        else \
--          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
--            $$unique; \
--        fi; \
--      fi
--ctags: ctags-am
--
--CTAGS: ctags
--ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
--      $(am__define_uniq_tagged_files); \
--      test -z "$(CTAGS_ARGS)$$unique" \
--        || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
--           $$unique
--
--GTAGS:
--      here=`$(am__cd) $(top_builddir) && pwd` \
--        && $(am__cd) $(top_srcdir) \
--        && gtags -i $(GTAGS_ARGS) "$$here"
--cscopelist: cscopelist-am
--
--cscopelist-am: $(am__tagged_files)
--      list='$(am__tagged_files)'; \
--      case "$(srcdir)" in \
--        [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
--        *) sdir=$(subdir)/$(srcdir) ;; \
--      esac; \
--      for i in $$list; do \
--        if test -f "$$i"; then \
--          echo "$(subdir)/$$i"; \
--        else \
--          echo "$$sdir/$$i"; \
--        fi; \
--      done >> $(top_builddir)/cscope.files
--
--distclean-tags:
--      -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
--
--distdir: $(DISTFILES)
--      @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 "$(distdir)/$$file"; then \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
--            cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
--            find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
--          fi; \
--          cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
--        else \
--          test -f "$(distdir)/$$file" \
--          || cp -p $$d/$$file "$(distdir)/$$file" \
--          || exit 1; \
--        fi; \
--      done
--check-am: all-am
--check: check-am
--all-am: Makefile $(LTLIBRARIES)
--installdirs:
--      for dir in "$(DESTDIR)$(vipsccdir)" "$(DESTDIR)$(vipsccdir)"; 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:
--      if test -z '$(STRIP)'; then \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--            install; \
--      else \
--        $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
--          install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
--          "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
--      fi
--mostlyclean-generic:
--
--clean-generic:
--      -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
--
--distclean-generic:
--      -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
--      -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
--
--maintainer-clean-generic:
--      @echo "This command is intended for maintainers to use"
--      @echo "it deletes files that may require special tools to rebuild."
--clean: clean-am
--
--clean-am: clean-generic clean-libtool clean-vipsccLTLIBRARIES \
--      mostlyclean-am
--
--distclean: distclean-am
--      -rm -rf ./$(DEPDIR)
--      -rm -f Makefile
--distclean-am: clean-am distclean-compile distclean-generic \
--      distclean-tags
--
--dvi: dvi-am
--
--dvi-am:
--
--html: html-am
--
--html-am:
--
--info: info-am
--
--info-am:
--
--install-data-am: install-vipsccLTLIBRARIES install-vipsccPYTHON
--
--install-dvi: install-dvi-am
--
--install-dvi-am:
--
--install-exec-am:
--
--install-html: install-html-am
--
--install-html-am:
--
--install-info: install-info-am
--
--install-info-am:
--
--install-man:
--
--install-pdf: install-pdf-am
--
--install-pdf-am:
--
--install-ps: install-ps-am
--
--install-ps-am:
--
--installcheck-am:
--
--maintainer-clean: maintainer-clean-am
--      -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-vipsccLTLIBRARIES uninstall-vipsccPYTHON
--
--.MAKE: install-am install-strip
--
--.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
--      clean-libtool clean-vipsccLTLIBRARIES cscopelist-am ctags \
--      ctags-am distclean distclean-compile distclean-generic \
--      distclean-libtool distclean-tags distdir dvi dvi-am html \
--      html-am info info-am install install-am install-data \
--      install-data-am install-dvi install-dvi-am install-exec \
--      install-exec-am install-html install-html-am install-info \
--      install-info-am install-man install-pdf install-pdf-am \
--      install-ps install-ps-am install-strip \
--      install-vipsccLTLIBRARIES install-vipsccPYTHON installcheck \
--      installcheck-am installdirs maintainer-clean \
--      maintainer-clean-generic mostlyclean mostlyclean-compile \
--      mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
--      tags tags-am uninstall uninstall-am \
--      uninstall-vipsccLTLIBRARIES uninstall-vipsccPYTHON
--
--
--# I tried making a suffix rule for this (and defining SUFFIXES) but I couldn't
--# get it to work, how annoying 
--# FIXME at some point
--#
--# need an expanded VImage.h ... SWIG's preprocessor b0rks on includes inside
--# class definitions
--vimagemodule.cxx: VImage.i
--      cpp -DSWIG -E $(top_srcdir)/libvipsCC/include/vips/VImage.h > VImage.h
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--
--vdisplaymodule.cxx: VDisplay.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--verrormodule.cxx: VError.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--vmaskmodule.cxx: VMask.i
--      swig -python -c++ -interface $(@:.cxx=) -I$(top_srcdir)/libvipsCC/include -o $@ $<
--
--# 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 -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VDisplay.i vips-7.38.5/swig/vipsCC/VDisplay.i
---- vips-7.38.5-vanilla/swig/vipsCC/VDisplay.i 2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VDisplay.i 1969-12-31 19:00:00.000000000 -0500
-@@ -1,15 +0,0 @@
--/* SWIG interface file for VDisplay.
-- */
--
--%module VDisplay
--%{
--#include <vips/vipscpp.h>
--%}
--
--%import "VError.i"
--
--/* Need to override assignment to get refcounting working.
-- */
--%rename(__assign__) *::operator=;
--
--%include vips/VDisplay.h
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/vdisplaymodule.cxx vips-7.38.5/swig/vipsCC/vdisplaymodule.cxx
---- vips-7.38.5-vanilla/swig/vipsCC/vdisplaymodule.cxx 2014-07-17 23:48:36.211794473 -0400
-+++ vips-7.38.5/swig/vipsCC/vdisplaymodule.cxx 1969-12-31 19:00:00.000000000 -0500
-@@ -1,4117 +0,0 @@
--/* ----------------------------------------------------------------------------
-- * This file was automatically generated by SWIG (http://www.swig.org).
-- * Version 2.0.10
-- * 
-- * This file is not intended to be easily readable and contains a number of 
-- * coding conventions designed to improve portability and efficiency. Do not make
-- * changes to this file unless you know what you are doing--modify the SWIG 
-- * interface file instead. 
-- * ----------------------------------------------------------------------------- */
--
--#define SWIGPYTHON
--#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
--
--
--#ifdef __cplusplus
--/* SwigValueWrapper is described in swig.swg */
--template<typename T> class SwigValueWrapper {
--  struct SwigMovePointer {
--    T *ptr;
--    SwigMovePointer(T *p) : ptr(p) { }
--    ~SwigMovePointer() { delete ptr; }
--    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
--  } pointer;
--  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
--  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
--public:
--  SwigValueWrapper() : pointer(0) { }
--  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
--  operator T&() const { return *pointer.ptr; }
--  T *operator&() { return pointer.ptr; }
--};
--
--template <typename T> T SwigValueInit() {
--  return T();
--}
--#endif
--
--/* -----------------------------------------------------------------------------
-- *  This section contains generic SWIG labels for method/variable
-- *  declarations/attributes, and other compiler dependent labels.
-- * ----------------------------------------------------------------------------- */
--
--/* template workaround for compilers that cannot correctly implement the C++ standard */
--#ifndef SWIGTEMPLATEDISAMBIGUATOR
--# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# elif defined(__HP_aCC)
--/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
--/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# else
--#  define SWIGTEMPLATEDISAMBIGUATOR
--# endif
--#endif
--
--/* inline attribute */
--#ifndef SWIGINLINE
--# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
--#   define SWIGINLINE inline
--# else
--#   define SWIGINLINE
--# endif
--#endif
--
--/* attribute recognised by some compilers to avoid 'unused' warnings */
--#ifndef SWIGUNUSED
--# if defined(__GNUC__)
--#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
--#     define SWIGUNUSED __attribute__ ((__unused__)) 
--#   else
--#     define SWIGUNUSED
--#   endif
--# elif defined(__ICC)
--#   define SWIGUNUSED __attribute__ ((__unused__)) 
--# else
--#   define SWIGUNUSED 
--# endif
--#endif
--
--#ifndef SWIG_MSC_UNSUPPRESS_4505
--# if defined(_MSC_VER)
--#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
--# endif 
--#endif
--
--#ifndef SWIGUNUSEDPARM
--# ifdef __cplusplus
--#   define SWIGUNUSEDPARM(p)
--# else
--#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
--# endif
--#endif
--
--/* internal SWIG method */
--#ifndef SWIGINTERN
--# define SWIGINTERN static SWIGUNUSED
--#endif
--
--/* internal inline SWIG method */
--#ifndef SWIGINTERNINLINE
--# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
--#endif
--
--/* exporting methods */
--#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
--#  ifndef GCC_HASCLASSVISIBILITY
--#    define GCC_HASCLASSVISIBILITY
--#  endif
--#endif
--
--#ifndef SWIGEXPORT
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   if defined(STATIC_LINKED)
--#     define SWIGEXPORT
--#   else
--#     define SWIGEXPORT __declspec(dllexport)
--#   endif
--# else
--#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
--#     define SWIGEXPORT __attribute__ ((visibility("default")))
--#   else
--#     define SWIGEXPORT
--#   endif
--# endif
--#endif
--
--/* calling conventions for Windows */
--#ifndef SWIGSTDCALL
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   define SWIGSTDCALL __stdcall
--# else
--#   define SWIGSTDCALL
--# endif 
--#endif
--
--/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
--#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
--# define _CRT_SECURE_NO_DEPRECATE
--#endif
--
--/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
--#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
--# define _SCL_SECURE_NO_DEPRECATE
--#endif
--
--
--
--/* Python.h has to appear first */
--#include <Python.h>
--
--/* -----------------------------------------------------------------------------
-- * swigrun.swg
-- *
-- * This file contains generic C API SWIG runtime support for pointer
-- * type checking.
-- * ----------------------------------------------------------------------------- */
--
--/* This should only be incremented when either the layout of swig_type_info changes,
--   or for whatever reason, the runtime changes incompatibly */
--#define SWIG_RUNTIME_VERSION "4"
--
--/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
--#ifdef SWIG_TYPE_TABLE
--# define SWIG_QUOTE_STRING(x) #x
--# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
--# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
--#else
--# define SWIG_TYPE_TABLE_NAME
--#endif
--
--/*
--  You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
--  creating a static or dynamic library from the SWIG runtime code.
--  In 99.9% of the cases, SWIG just needs to declare them as 'static'.
--  
--  But only do this if strictly necessary, ie, if you have problems
--  with your compiler or suchlike.
--*/
--
--#ifndef SWIGRUNTIME
--# define SWIGRUNTIME SWIGINTERN
--#endif
--
--#ifndef SWIGRUNTIMEINLINE
--# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
--#endif
--
--/*  Generic buffer size */
--#ifndef SWIG_BUFFER_SIZE
--# define SWIG_BUFFER_SIZE 1024
--#endif
--
--/* Flags for pointer conversions */
--#define SWIG_POINTER_DISOWN        0x1
--#define SWIG_CAST_NEW_MEMORY       0x2
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_OWN           0x1
--
--
--/* 
--   Flags/methods for returning states.
--   
--   The SWIG conversion methods, as ConvertPtr, return an integer 
--   that tells if the conversion was successful or not. And if not,
--   an error code can be returned (see swigerrors.swg for the codes).
--   
--   Use the following macros/flags to set or process the returning
--   states.
--   
--   In old versions of SWIG, code such as the following was usually written:
--
--     if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
--       // success code
--     } else {
--       //fail code
--     }
--
--   Now you can be more explicit:
--
--    int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--    } else {
--      // fail code
--    }
--
--   which is the same really, but now you can also do
--
--    Type *ptr;
--    int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--      if (SWIG_IsNewObj(res) {
--        ...
--      delete *ptr;
--      } else {
--        ...
--      }
--    } else {
--      // fail code
--    }
--    
--   I.e., now SWIG_ConvertPtr can return new objects and you can
--   identify the case and take care of the deallocation. Of course that
--   also requires SWIG_ConvertPtr to return new result values, such as
--
--      int SWIG_ConvertPtr(obj, ptr,...) {         
--        if (<obj is ok>) {                           
--          if (<need new object>) {                   
--            *ptr = <ptr to new allocated object>; 
--            return SWIG_NEWOBJ;                      
--          } else {                                   
--            *ptr = <ptr to old object>;              
--            return SWIG_OLDOBJ;                      
--          }                                  
--        } else {                                     
--          return SWIG_BADOBJ;                
--        }                                            
--      }
--
--   Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
--   more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
--   SWIG errors code.
--
--   Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
--   allows to return the 'cast rank', for example, if you have this
--
--       int food(double)
--       int fooi(int);
--
--   and you call
-- 
--      food(1)   // cast rank '1'  (1 -> 1.0)
--      fooi(1)   // cast rank '0'
--
--   just use the SWIG_AddCast()/SWIG_CheckState()
--*/
--
--#define SWIG_OK                    (0) 
--#define SWIG_ERROR                 (-1)
--#define SWIG_IsOK(r)               (r >= 0)
--#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
--
--/* The CastRankLimit says how many bits are used for the cast rank */
--#define SWIG_CASTRANKLIMIT         (1 << 8)
--/* The NewMask denotes the object was created (using new/malloc) */
--#define SWIG_NEWOBJMASK            (SWIG_CASTRANKLIMIT  << 1)
--/* The TmpMask is for in/out typemaps that use temporal objects */
--#define SWIG_TMPOBJMASK            (SWIG_NEWOBJMASK << 1)
--/* Simple returning values */
--#define SWIG_BADOBJ                (SWIG_ERROR)
--#define SWIG_OLDOBJ                (SWIG_OK)
--#define SWIG_NEWOBJ                (SWIG_OK | SWIG_NEWOBJMASK)
--#define SWIG_TMPOBJ                (SWIG_OK | SWIG_TMPOBJMASK)
--/* Check, add and del mask methods */
--#define SWIG_AddNewMask(r)         (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
--#define SWIG_DelNewMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
--#define SWIG_IsNewObj(r)           (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
--#define SWIG_AddTmpMask(r)         (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
--#define SWIG_DelTmpMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
--#define SWIG_IsTmpObj(r)           (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
--
--/* Cast-Rank Mode */
--#if defined(SWIG_CASTRANK_MODE)
--#  ifndef SWIG_TypeRank
--#    define SWIG_TypeRank             unsigned long
--#  endif
--#  ifndef SWIG_MAXCASTRANK            /* Default cast allowed */
--#    define SWIG_MAXCASTRANK          (2)
--#  endif
--#  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
--#  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
--SWIGINTERNINLINE int SWIG_AddCast(int r) { 
--  return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
--}
--SWIGINTERNINLINE int SWIG_CheckState(int r) { 
--  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
--}
--#else /* no cast-rank mode */
--#  define SWIG_AddCast(r) (r)
--#  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
--#endif
--
--
--#include <string.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef void *(*swig_converter_func)(void *, int *);
--typedef struct swig_type_info *(*swig_dycast_func)(void **);
--
--/* Structure to store information on one type */
--typedef struct swig_type_info {
--  const char             *name;                       /* mangled name of this type */
--  const char             *str;                        /* human readable name of this type */
--  swig_dycast_func        dcast;              /* dynamic cast function down a hierarchy */
--  struct swig_cast_info  *cast;                       /* linked list of types that can cast into this type */
--  void                   *clientdata;         /* language specific type data */
--  int                    owndata;             /* flag if the structure owns the clientdata */
--} swig_type_info;
--
--/* Structure to store a type and conversion function used for casting */
--typedef struct swig_cast_info {
--  swig_type_info         *type;                       /* pointer to type that is equivalent to this type */
--  swig_converter_func     converter;          /* function to cast the void pointers */
--  struct swig_cast_info  *next;                       /* pointer to next cast in linked list */
--  struct swig_cast_info  *prev;                       /* pointer to the previous cast */
--} swig_cast_info;
--
--/* Structure used to store module information
-- * Each module generates one structure like this, and the runtime collects
-- * all of these structures and stores them in a circularly linked list.*/
--typedef struct swig_module_info {
--  swig_type_info         **types;             /* Array of pointers to swig_type_info structures that are in this module */
--  size_t                 size;                        /* Number of types in this module */
--  struct swig_module_info *next;              /* Pointer to next element in circularly linked list */
--  swig_type_info         **type_initial;      /* Array of initially generated type structures */
--  swig_cast_info         **cast_initial;      /* Array of initially generated casting structures */
--  void                    *clientdata;                /* Language specific module data */
--} swig_module_info;
--
--/* 
--  Compare two type names skipping the space characters, therefore
--  "char*" == "char *" and "Class<int>" == "Class<int >", etc.
--
--  Return 0 when the two name types are equivalent, as in
--  strncmp, but skipping ' '.
--*/
--SWIGRUNTIME int
--SWIG_TypeNameComp(const char *f1, const char *l1,
--                const char *f2, const char *l2) {
--  for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
--    while ((*f1 == ' ') && (f1 != l1)) ++f1;
--    while ((*f2 == ' ') && (f2 != l2)) ++f2;
--    if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
--  }
--  return (int)((l1 - f1) - (l2 - f2));
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
--*/
--SWIGRUNTIME int
--SWIG_TypeCmp(const char *nb, const char *tb) {
--  int equiv = 1;
--  const char* te = tb + strlen(tb);
--  const char* ne = nb;
--  while (equiv != 0 && *ne) {
--    for (nb = ne; *ne; ++ne) {
--      if (*ne == '|') break;
--    }
--    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
--    if (*ne) ++ne;
--  }
--  return equiv;
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if not equal, 1 if equal
--*/
--SWIGRUNTIME int
--SWIG_TypeEquiv(const char *nb, const char *tb) {
--  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
--}
--
--/*
--  Check the typename
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheck(const char *c, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (strcmp(iter->type->name, c) == 0) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/* 
--  Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (iter->type == from) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/*
--  Cast a pointer up an inheritance hierarchy
--*/
--SWIGRUNTIMEINLINE void *
--SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
--  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
--}
--
--/* 
--   Dynamic pointer casting. Down an inheritance hierarchy
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
--  swig_type_info *lastty = ty;
--  if (!ty || !ty->dcast) return ty;
--  while (ty && (ty->dcast)) {
--    ty = (*ty->dcast)(ptr);
--    if (ty) lastty = ty;
--  }
--  return lastty;
--}
--
--/*
--  Return the name associated with this type
--*/
--SWIGRUNTIMEINLINE const char *
--SWIG_TypeName(const swig_type_info *ty) {
--  return ty->name;
--}
--
--/*
--  Return the pretty name associated with this type,
--  that is an unmangled type name in a form presentable to the user.
--*/
--SWIGRUNTIME const char *
--SWIG_TypePrettyName(const swig_type_info *type) {
--  /* The "str" field contains the equivalent pretty names of the
--     type, separated by vertical-bar characters.  We choose
--     to print the last name, as it is often (?) the most
--     specific. */
--  if (!type) return NULL;
--  if (type->str != NULL) {
--    const char *last_name = type->str;
--    const char *s;
--    for (s = type->str; *s; s++)
--      if (*s == '|') last_name = s+1;
--    return last_name;
--  }
--  else
--    return type->name;
--}
--
--/* 
--   Set the clientdata field for a type
--*/
--SWIGRUNTIME void
--SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
--  swig_cast_info *cast = ti->cast;
--  /* if (ti->clientdata == clientdata) return; */
--  ti->clientdata = clientdata;
--  
--  while (cast) {
--    if (!cast->converter) {
--      swig_type_info *tc = cast->type;
--      if (!tc->clientdata) {
--      SWIG_TypeClientData(tc, clientdata);
--      }
--    }    
--    cast = cast->next;
--  }
--}
--SWIGRUNTIME void
--SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
--  SWIG_TypeClientData(ti, clientdata);
--  ti->owndata = 1;
--}
--  
--/*
--  Search for a swig_type_info structure only by mangled name
--  Search is a O(log #types)
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_MangledTypeQueryModule(swig_module_info *start, 
--                            swig_module_info *end, 
--                          const char *name) {
--  swig_module_info *iter = start;
--  do {
--    if (iter->size) {
--      register size_t l = 0;
--      register size_t r = iter->size - 1;
--      do {
--      /* since l+r >= 0, we can (>> 1) instead (/ 2) */
--      register size_t i = (l + r) >> 1; 
--      const char *iname = iter->types[i]->name;
--      if (iname) {
--        register int compare = strcmp(name, iname);
--        if (compare == 0) {       
--          return iter->types[i];
--        } else if (compare < 0) {
--          if (i) {
--            r = i - 1;
--          } else {
--            break;
--          }
--        } else if (compare > 0) {
--          l = i + 1;
--        }
--      } else {
--        break; /* should never happen */
--      }
--      } while (l <= r);
--    }
--    iter = iter->next;
--  } while (iter != end);
--  return 0;
--}
--
--/*
--  Search for a swig_type_info structure for either a mangled name or a human readable name.
--  It first searches the mangled names of the types, which is a O(log #types)
--  If a type is not found it then searches the human readable names, which is O(#types).
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeQueryModule(swig_module_info *start, 
--                     swig_module_info *end, 
--                   const char *name) {
--  /* STEP 1: Search the name field using binary search */
--  swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
--  if (ret) {
--    return ret;
--  } else {
--    /* STEP 2: If the type hasn't been found, do a complete search
--       of the str field (the human readable name) */
--    swig_module_info *iter = start;
--    do {
--      register size_t i = 0;
--      for (; i < iter->size; ++i) {
--      if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
--        return iter->types[i];
--      }
--      iter = iter->next;
--    } while (iter != end);
--  }
--  
--  /* neither found a match */
--  return 0;
--}
--
--/* 
--   Pack binary data into a string
--*/
--SWIGRUNTIME char *
--SWIG_PackData(char *c, void *ptr, size_t sz) {
--  static const char hex[17] = "0123456789abcdef";
--  register const unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu =  u + sz;
--  for (; u != eu; ++u) {
--    register unsigned char uu = *u;
--    *(c++) = hex[(uu & 0xf0) >> 4];
--    *(c++) = hex[uu & 0xf];
--  }
--  return c;
--}
--
--/* 
--   Unpack binary data from a string
--*/
--SWIGRUNTIME const char *
--SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
--  register unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu = u + sz;
--  for (; u != eu; ++u) {
--    register char d = *(c++);
--    register unsigned char uu;
--    if ((d >= '0') && (d <= '9'))
--      uu = ((d - '0') << 4);
--    else if ((d >= 'a') && (d <= 'f'))
--      uu = ((d - ('a'-10)) << 4);
--    else 
--      return (char *) 0;
--    d = *(c++);
--    if ((d >= '0') && (d <= '9'))
--      uu |= (d - '0');
--    else if ((d >= 'a') && (d <= 'f'))
--      uu |= (d - ('a'-10));
--    else 
--      return (char *) 0;
--    *u = uu;
--  }
--  return c;
--}
--
--/* 
--   Pack 'void *' into a string buffer.
--*/
--SWIGRUNTIME char *
--SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
--  char *r = buff;
--  if ((2*sizeof(void *) + 2) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,&ptr,sizeof(void *));
--  if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
--  strcpy(r,name);
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      *ptr = (void *) 0;
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sizeof(void *));
--}
--
--SWIGRUNTIME char *
--SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
--  char *r = buff;
--  size_t lname = (name ? strlen(name) : 0);
--  if ((2*sz + 2 + lname) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,ptr,sz);
--  if (lname) {
--    strncpy(r,name,lname+1);
--  } else {
--    *r = 0;
--  }
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      memset(ptr,0,sz);
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sz);
--}
--
--#ifdef __cplusplus
--}
--#endif
--
--/*  Errors in SWIG */
--#define  SWIG_UnknownError               -1 
--#define  SWIG_IOError            -2 
--#define  SWIG_RuntimeError       -3 
--#define  SWIG_IndexError         -4 
--#define  SWIG_TypeError          -5 
--#define  SWIG_DivisionByZero     -6 
--#define  SWIG_OverflowError      -7 
--#define  SWIG_SyntaxError        -8 
--#define  SWIG_ValueError         -9 
--#define  SWIG_SystemError        -10
--#define  SWIG_AttributeError     -11
--#define  SWIG_MemoryError        -12 
--#define  SWIG_NullReferenceError   -13
--
--
--
--/* Compatibility macros for Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--
--#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
--#define PyInt_Check(x) PyLong_Check(x)
--#define PyInt_AsLong(x) PyLong_AsLong(x)
--#define PyInt_FromLong(x) PyLong_FromLong(x)
--#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
--#define PyString_Check(name) PyBytes_Check(name)
--#define PyString_FromString(x) PyUnicode_FromString(x)
--#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
--#define PyString_AsString(str) PyBytes_AsString(str)
--#define PyString_Size(str) PyBytes_Size(str)  
--#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
--#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
--#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
--#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
--
--#endif
--
--#ifndef Py_TYPE
--#  define Py_TYPE(op) ((op)->ob_type)
--#endif
--
--/* SWIG APIs for compatibility of both Python 2 & 3 */
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_FromFormat PyUnicode_FromFormat
--#else
--#  define SWIG_Python_str_FromFormat PyString_FromFormat
--#endif
--
--
--/* Warning: This function will allocate a new string in Python 3,
-- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
-- */
--SWIGINTERN char*
--SWIG_Python_str_AsChar(PyObject *str)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  char *cstr;
--  char *newstr;
--  Py_ssize_t len;
--  str = PyUnicode_AsUTF8String(str);
--  PyBytes_AsStringAndSize(str, &cstr, &len);
--  newstr = (char *) malloc(len+1);
--  memcpy(newstr, cstr, len+1);
--  Py_XDECREF(str);
--  return newstr;
--#else
--  return PyString_AsString(str);
--#endif
--}
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
--#else
--#  define SWIG_Python_str_DelForPy3(x) 
--#endif
--
--
--SWIGINTERN PyObject*
--SWIG_Python_str_FromChar(const char *c)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  return PyUnicode_FromString(c); 
--#else
--  return PyString_FromString(c);
--#endif
--}
--
--/* Add PyOS_snprintf for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
--#  define PyOS_snprintf _snprintf
--# else
--#  define PyOS_snprintf snprintf
--# endif
--#endif
--
--/* A crude PyString_FromFormat implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--
--#ifndef SWIG_PYBUFFER_SIZE
--# define SWIG_PYBUFFER_SIZE 1024
--#endif
--
--static PyObject *
--PyString_FromFormat(const char *fmt, ...) {
--  va_list ap;
--  char buf[SWIG_PYBUFFER_SIZE * 2];
--  int res;
--  va_start(ap, fmt);
--  res = vsnprintf(buf, sizeof(buf), fmt, ap);
--  va_end(ap);
--  return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
--}
--#endif
--
--/* Add PyObject_Del for old Pythons */
--#if PY_VERSION_HEX < 0x01060000
--# define PyObject_Del(op) PyMem_DEL((op))
--#endif
--#ifndef PyObject_DEL
--# define PyObject_DEL PyObject_Del
--#endif
--
--/* A crude PyExc_StopIteration exception for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# ifndef PyExc_StopIteration
--#  define PyExc_StopIteration PyExc_RuntimeError
--# endif
--# ifndef PyObject_GenericGetAttr
--#  define PyObject_GenericGetAttr 0
--# endif
--#endif
--
--/* Py_NotImplemented is defined in 2.1 and up. */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef Py_NotImplemented
--#  define Py_NotImplemented PyExc_RuntimeError
--# endif
--#endif
--
--/* A crude PyString_AsStringAndSize implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef PyString_AsStringAndSize
--#  define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
--# endif
--#endif
--
--/* PySequence_Size for old Pythons */
--#if PY_VERSION_HEX < 0x02000000
--# ifndef PySequence_Size
--#  define PySequence_Size PySequence_Length
--# endif
--#endif
--
--/* PyBool_FromLong for old Pythons */
--#if PY_VERSION_HEX < 0x02030000
--static
--PyObject *PyBool_FromLong(long ok)
--{
--  PyObject *result = ok ? Py_True : Py_False;
--  Py_INCREF(result);
--  return result;
--}
--#endif
--
--/* Py_ssize_t for old Pythons */
--/* This code is as recommended by: */
--/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
--#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
--typedef int Py_ssize_t;
--# define PY_SSIZE_T_MAX INT_MAX
--# define PY_SSIZE_T_MIN INT_MIN
--typedef inquiry lenfunc;
--typedef intargfunc ssizeargfunc;
--typedef intintargfunc ssizessizeargfunc;
--typedef intobjargproc ssizeobjargproc;
--typedef intintobjargproc ssizessizeobjargproc;
--typedef getreadbufferproc readbufferproc;
--typedef getwritebufferproc writebufferproc;
--typedef getsegcountproc segcountproc;
--typedef getcharbufferproc charbufferproc;
--static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
--{
--  long result = 0;
--  PyObject *i = PyNumber_Int(x);
--  if (i) {
--    result = PyInt_AsLong(i);
--    Py_DECREF(i);
--  }
--  return result;
--}
--#endif
--
--#if PY_VERSION_HEX < 0x02050000
--#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
--#endif
--
--#if PY_VERSION_HEX < 0x02040000
--#define Py_VISIT(op)                          \
--  do {                                                \
--    if (op) {                                 \
--      int vret = visit((op), arg);            \
--      if (vret)                                       \
--        return vret;                          \
--    }                                         \
--  } while (0)
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef struct {
--  PyTypeObject type;
--  PyNumberMethods as_number;
--  PyMappingMethods as_mapping;
--  PySequenceMethods as_sequence;
--  PyBufferProcs as_buffer;
--  PyObject *name, *slots;
--} PyHeapTypeObject;
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef destructor freefunc;
--#endif
--
--#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
--     (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
--     (PY_MAJOR_VERSION > 3))
--# define SWIGPY_USE_CAPSULE
--# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
--#endif
--
--#if PY_VERSION_HEX < 0x03020000
--#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
--#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
--#endif
--
--/* -----------------------------------------------------------------------------
-- * error manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIME PyObject*
--SWIG_Python_ErrorType(int code) {
--  PyObject* type = 0;
--  switch(code) {
--  case SWIG_MemoryError:
--    type = PyExc_MemoryError;
--    break;
--  case SWIG_IOError:
--    type = PyExc_IOError;
--    break;
--  case SWIG_RuntimeError:
--    type = PyExc_RuntimeError;
--    break;
--  case SWIG_IndexError:
--    type = PyExc_IndexError;
--    break;
--  case SWIG_TypeError:
--    type = PyExc_TypeError;
--    break;
--  case SWIG_DivisionByZero:
--    type = PyExc_ZeroDivisionError;
--    break;
--  case SWIG_OverflowError:
--    type = PyExc_OverflowError;
--    break;
--  case SWIG_SyntaxError:
--    type = PyExc_SyntaxError;
--    break;
--  case SWIG_ValueError:
--    type = PyExc_ValueError;
--    break;
--  case SWIG_SystemError:
--    type = PyExc_SystemError;
--    break;
--  case SWIG_AttributeError:
--    type = PyExc_AttributeError;
--    break;
--  default:
--    type = PyExc_RuntimeError;
--  }
--  return type;
--}
--
--
--SWIGRUNTIME void
--SWIG_Python_AddErrorMsg(const char* mesg)
--{
--  PyObject *type = 0;
--  PyObject *value = 0;
--  PyObject *traceback = 0;
--
--  if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
--  if (value) {
--    char *tmp;
--    PyObject *old_str = PyObject_Str(value);
--    PyErr_Clear();
--    Py_XINCREF(type);
--
--    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(old_str);
--    Py_DECREF(value);
--  } else {
--    PyErr_SetString(PyExc_RuntimeError, mesg);
--  }
--}
--
--#if defined(SWIG_PYTHON_NO_THREADS)
--#  if defined(SWIG_PYTHON_THREADS)
--#    undef SWIG_PYTHON_THREADS
--#  endif
--#endif
--#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
--#  if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
--#    if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
--#      define SWIG_PYTHON_USE_GIL
--#    endif
--#  endif
--#  if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
--#    ifndef SWIG_PYTHON_INITIALIZE_THREADS
--#     define SWIG_PYTHON_INITIALIZE_THREADS  PyEval_InitThreads() 
--#    endif
--#    ifdef __cplusplus /* C++ code */
--       class SWIG_Python_Thread_Block {
--         bool status;
--         PyGILState_STATE state;
--       public:
--         void end() { if (status) { PyGILState_Release(state); status = false;} }
--         SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
--         ~SWIG_Python_Thread_Block() { end(); }
--       };
--       class SWIG_Python_Thread_Allow {
--         bool status;
--         PyThreadState *save;
--       public:
--         void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
--         SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
--         ~SWIG_Python_Thread_Allow() { end(); }
--       };
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   SWIG_Python_Thread_Block _swig_thread_block
--#      define SWIG_PYTHON_THREAD_END_BLOCK     _swig_thread_block.end()
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   SWIG_Python_Thread_Allow _swig_thread_allow
--#      define SWIG_PYTHON_THREAD_END_ALLOW     _swig_thread_allow.end()
--#    else /* C code */
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
--#      define SWIG_PYTHON_THREAD_END_BLOCK     PyGILState_Release(_swig_thread_block)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   PyThreadState *_swig_thread_allow = PyEval_SaveThread()
--#      define SWIG_PYTHON_THREAD_END_ALLOW     PyEval_RestoreThread(_swig_thread_allow)
--#    endif
--#  else /* Old thread way, not implemented, user must provide it */
--#    if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
--#      define SWIG_PYTHON_INITIALIZE_THREADS
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
--#      define SWIG_PYTHON_THREAD_END_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
--#      define SWIG_PYTHON_THREAD_END_ALLOW
--#    endif
--#  endif
--#else /* No thread support */
--#  define SWIG_PYTHON_INITIALIZE_THREADS
--#  define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#  define SWIG_PYTHON_THREAD_END_BLOCK
--#  define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#  define SWIG_PYTHON_THREAD_END_ALLOW
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Python API portion that goes into the runtime
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Constant declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Constant Types */
--#define SWIG_PY_POINTER 4
--#define SWIG_PY_BINARY  5
--
--/* Constant information structure */
--typedef struct swig_const_info {
--  int type;
--  char *name;
--  long lvalue;
--  double dvalue;
--  void   *pvalue;
--  swig_type_info **ptype;
--} swig_const_info;
--
--
--/* -----------------------------------------------------------------------------
-- * Wrapper of PyInstanceMethod_New() used in Python 3
-- * It is exported to the generated module, used for -fastproxy
-- * ----------------------------------------------------------------------------- */
--#if PY_VERSION_HEX >= 0x03000000
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
--{
--  return PyInstanceMethod_New(func);
--}
--#else
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
--{
--  return NULL;
--}
--#endif
--
--#ifdef __cplusplus
--}
--#endif
--
--
--/* -----------------------------------------------------------------------------
-- * pyrun.swg
-- *
-- * This file contains the runtime support for Python modules
-- * and includes code for managing global variables and pointer
-- * type checking.
-- *
-- * ----------------------------------------------------------------------------- */
--
--/* Common SWIG API */
--
--/* for raw pointers */
--#define SWIG_Python_ConvertPtr(obj, pptr, type, flags)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
--#define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Python_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
--
--#ifdef SWIGPYTHON_BUILTIN
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(self, ptr, type, flags)
--#else
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--#endif
--
--#define SWIG_InternalNewPointerObj(ptr, type, flags)  SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--
--#define SWIG_CheckImplicit(ty)                          SWIG_Python_CheckImplicit(ty) 
--#define SWIG_AcquirePtr(ptr, src)                       SWIG_Python_AcquirePtr(ptr, src)
--#define swig_owntype                                    int
--
--/* for raw packed data */
--#define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--/* for class or struct pointers */
--#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_NewInstanceObj(ptr, type, flags)           SWIG_NewPointerObj(ptr, type, flags)
--
--/* for C or C++ function pointers */
--#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
--#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
--
--/* for C++ member pointers, ie, member methods */
--#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--
--/* Runtime API */
--
--#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
--#define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
--#define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
--
--#define SWIG_SetErrorObj                                SWIG_Python_SetErrorObj                            
--#define SWIG_SetErrorMsg                              SWIG_Python_SetErrorMsg                            
--#define SWIG_ErrorType(code)                          SWIG_Python_ErrorType(code)                        
--#define SWIG_Error(code, msg)                         SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) 
--#define SWIG_fail                                     goto fail                                          
--
--
--/* Runtime API implementation */
--
--/* Error manipulation */
--
--SWIGINTERN void 
--SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
--  PyErr_SetObject(errtype, obj);
--  Py_DECREF(obj);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--SWIGINTERN void 
--SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--  PyErr_SetString(errtype, msg);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--#define SWIG_Python_Raise(obj, type, desc)  SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
--
--/* Set a constant value */
--
--#if defined(SWIGPYTHON_BUILTIN)
--
--SWIGINTERN void
--SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
--  PyObject *s = PyString_InternFromString(key);
--  PyList_Append(seq, s);
--  Py_DECREF(s);
--}
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);
--  if (public_interface)
--    SwigPyBuiltin_AddPublicSymbol(public_interface, name);
--}
--
--#else
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);                            
--}
--
--#endif
--
--/* Append a value to the result obj */
--
--SWIGINTERN PyObject*
--SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
--#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyList_Check(result)) {
--      PyObject *o2 = result;
--      result = PyList_New(1);
--      PyList_SetItem(result, 0, o2);
--    }
--    PyList_Append(result,obj);
--    Py_DECREF(obj);
--  }
--  return result;
--#else
--  PyObject*   o2;
--  PyObject*   o3;
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyTuple_Check(result)) {
--      o2 = result;
--      result = PyTuple_New(1);
--      PyTuple_SET_ITEM(result, 0, o2);
--    }
--    o3 = PyTuple_New(1);
--    PyTuple_SET_ITEM(o3, 0, obj);
--    o2 = result;
--    result = PySequence_Concat(o2, o3);
--    Py_DECREF(o2);
--    Py_DECREF(o3);
--  }
--  return result;
--#endif
--}
--
--/* Unpack the argument tuple */
--
--SWIGINTERN int
--SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
--{
--  if (!args) {
--    if (!min && !max) {
--      return 1;
--    } else {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", 
--                 name, (min == max ? "" : "at least "), (int)min);
--      return 0;
--    }
--  }  
--  if (!PyTuple_Check(args)) {
--    if (min <= 1 && max >= 1) {
--      register int i;
--      objs[0] = args;
--      for (i = 1; i < max; ++i) {
--      objs[i] = 0;
--      }
--      return 2;
--    }
--    PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
--    return 0;
--  } else {
--    register Py_ssize_t l = PyTuple_GET_SIZE(args);
--    if (l < min) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at least "), (int)min, (int)l);
--      return 0;
--    } else if (l > max) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at most "), (int)max, (int)l);
--      return 0;
--    } else {
--      register int i;
--      for (i = 0; i < l; ++i) {
--      objs[i] = PyTuple_GET_ITEM(args, i);
--      }
--      for (; l < max; ++l) {
--      objs[l] = 0;
--      }
--      return i + 1;
--    }    
--  }
--}
--
--/* A functor is a function object with one single object argument */
--#if PY_VERSION_HEX >= 0x02020000
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunctionObjArgs(functor, obj, NULL);
--#else
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunction(functor, "O", obj);
--#endif
--
--/*
--  Helper for static pointer initialization for both C and C++ code, for example
--  static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
--*/
--#ifdef __cplusplus
--#define SWIG_STATIC_POINTER(var)  var
--#else
--#define SWIG_STATIC_POINTER(var)  var = 0; if (!var) var
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Pointer declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_NOSHADOW       (SWIG_POINTER_OWN      << 1)
--#define SWIG_POINTER_NEW            (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
--
--#define SWIG_POINTER_IMPLICIT_CONV  (SWIG_POINTER_DISOWN   << 1)
--
--#define SWIG_BUILTIN_TP_INIT      (SWIG_POINTER_OWN << 2)
--#define SWIG_BUILTIN_INIT         (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*  How to access Py_None */
--#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#  ifndef SWIG_PYTHON_NO_BUILD_NONE
--#    ifndef SWIG_PYTHON_BUILD_NONE
--#      define SWIG_PYTHON_BUILD_NONE
--#    endif
--#  endif
--#endif
--
--#ifdef SWIG_PYTHON_BUILD_NONE
--#  ifdef Py_None
--#   undef Py_None
--#   define Py_None SWIG_Py_None()
--#  endif
--SWIGRUNTIMEINLINE PyObject * 
--_SWIG_Py_None(void)
--{
--  PyObject *none = Py_BuildValue((char*)"");
--  Py_DECREF(none);
--  return none;
--}
--SWIGRUNTIME PyObject * 
--SWIG_Py_None(void)
--{
--  static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
--  return none;
--}
--#endif
--
--/* The python void return value */
--
--SWIGRUNTIMEINLINE PyObject * 
--SWIG_Py_Void(void)
--{
--  PyObject *none = Py_None;
--  Py_INCREF(none);
--  return none;
--}
--
--/* SwigPyClientData */
--
--typedef struct {
--  PyObject *klass;
--  PyObject *newraw;
--  PyObject *newargs;
--  PyObject *destroy;
--  int delargs;
--  int implicitconv;
--  PyTypeObject *pytype;
--} SwigPyClientData;
--
--SWIGRUNTIMEINLINE int 
--SWIG_Python_CheckImplicit(swig_type_info *ty)
--{
--  SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
--  return data ? data->implicitconv : 0;
--}
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_ExceptionType(swig_type_info *desc) {
--  SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
--  PyObject *klass = data ? data->klass : 0;
--  return (klass ? klass : PyExc_RuntimeError);
--}
--
--
--SWIGRUNTIME SwigPyClientData * 
--SwigPyClientData_New(PyObject* obj)
--{
--  if (!obj) {
--    return 0;
--  } else {
--    SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
--    /* the klass element */
--    data->klass = obj;
--    Py_INCREF(data->klass);
--    /* the newraw method and newargs arguments used to create a new raw instance */
--    if (PyClass_Check(obj)) {
--      data->newraw = 0;
--      data->newargs = obj;
--      Py_INCREF(obj);
--    } else {
--#if (PY_VERSION_HEX < 0x02020000)
--      data->newraw = 0;
--#else
--      data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
--#endif
--      if (data->newraw) {
--      Py_INCREF(data->newraw);
--      data->newargs = PyTuple_New(1);
--      PyTuple_SetItem(data->newargs, 0, obj);
--      } else {
--      data->newargs = obj;
--      }
--      Py_INCREF(data->newargs);
--    }
--    /* the destroy method, aka as the C++ delete method */
--    data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      data->destroy = 0;
--    }
--    if (data->destroy) {
--      int flags;
--      Py_INCREF(data->destroy);
--      flags = PyCFunction_GET_FLAGS(data->destroy);
--#ifdef METH_O
--      data->delargs = !(flags & (METH_O));
--#else
--      data->delargs = 0;
--#endif
--    } else {
--      data->delargs = 0;
--    }
--    data->implicitconv = 0;
--    data->pytype = 0;
--    return data;
--  }
--}
--
--SWIGRUNTIME void 
--SwigPyClientData_Del(SwigPyClientData *data) {
--  Py_XDECREF(data->newraw);
--  Py_XDECREF(data->newargs);
--  Py_XDECREF(data->destroy);
--}
--
--/* =============== SwigPyObject =====================*/
--
--typedef struct {
--  PyObject_HEAD
--  void *ptr;
--  swig_type_info *ty;
--  int own;
--  PyObject *next;
--#ifdef SWIGPYTHON_BUILTIN
--  PyObject *dict;
--#endif
--} SwigPyObject;
--
--SWIGRUNTIME PyObject *
--SwigPyObject_long(SwigPyObject *v)
--{
--  return PyLong_FromVoidPtr(v->ptr);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_format(const char* fmt, SwigPyObject *v)
--{
--  PyObject *res = NULL;
--  PyObject *args = PyTuple_New(1);
--  if (args) {
--    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
--      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
--      if (ofmt) {
--#if PY_VERSION_HEX >= 0x03000000
--      res = PyUnicode_Format(ofmt,args);
--#else
--      res = PyString_Format(ofmt,args);
--#endif
--      Py_DECREF(ofmt);
--      }
--      Py_DECREF(args);
--    }
--  }
--  return res;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_oct(SwigPyObject *v)
--{
--  return SwigPyObject_format("%o",v);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_hex(SwigPyObject *v)
--{
--  return SwigPyObject_format("%x",v);
--}
--
--SWIGRUNTIME PyObject *
--#ifdef METH_NOARGS
--SwigPyObject_repr(SwigPyObject *v)
--#else
--SwigPyObject_repr(SwigPyObject *v, PyObject *args)
--#endif
--{
--  const char *name = SWIG_TypePrettyName(v->ty);
--  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
--  if (v->next) {
--# ifdef METH_NOARGS
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
--# else
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
--# endif
--# if PY_VERSION_HEX >= 0x03000000
--    PyObject *joined = PyUnicode_Concat(repr, nrep);
--    Py_DecRef(repr);
--    Py_DecRef(nrep);
--    repr = joined;
--# else
--    PyString_ConcatAndDel(&repr,nrep);
--# endif
--  }
--  return repr;  
--}
--
--SWIGRUNTIME int
--SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char *str;
--#ifdef METH_NOARGS
--  PyObject *repr = SwigPyObject_repr(v);
--#else
--  PyObject *repr = SwigPyObject_repr(v, NULL);
--#endif
--  if (repr) {
--    str = SWIG_Python_str_AsChar(repr); 
--    fputs(str, fp);
--    SWIG_Python_str_DelForPy3(str);
--    Py_DECREF(repr);
--    return 0; 
--  } else {
--    return 1; 
--  }
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_str(SwigPyObject *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
--    SWIG_Python_str_FromChar(result) : 0;
--}
--
--SWIGRUNTIME int
--SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
--{
--  void *i = v->ptr;
--  void *j = w->ptr;
--  return (i < j) ? -1 : ((i > j) ? 1 : 0);
--}
--
--/* Added for Python 3.x, would it also be useful for Python 2.x? */
--SWIGRUNTIME PyObject*
--SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
--{
--  PyObject* res;
--  if( op != Py_EQ && op != Py_NE ) {
--    Py_INCREF(Py_NotImplemented);
--    return Py_NotImplemented;
--  }
--  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
--  return res;  
--}
--
--
--SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
--
--#ifdef SWIGPYTHON_BUILTIN
--static swig_type_info *SwigPyObject_stype = 0;
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--    SwigPyClientData *cd;
--    assert(SwigPyObject_stype);
--    cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--    assert(cd);
--    assert(cd->pytype);
--    return cd->pytype;
--}
--#else
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
--  return type;
--}
--#endif
--
--SWIGRUNTIMEINLINE int
--SwigPyObject_Check(PyObject *op) {
--#ifdef SWIGPYTHON_BUILTIN
--  PyTypeObject *target_tp = SwigPyObject_type();
--  if (PyType_IsSubtype(op->ob_type, target_tp))
--    return 1;
--  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
--#else
--  return (Py_TYPE(op) == SwigPyObject_type())
--    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
--#endif
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
--
--SWIGRUNTIME void
--SwigPyObject_dealloc(PyObject *v)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  PyObject *next = sobj->next;
--  if (sobj->own == SWIG_POINTER_OWN) {
--    swig_type_info *ty = sobj->ty;
--    SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--    PyObject *destroy = data ? data->destroy : 0;
--    if (destroy) {
--      /* destroy is always a VARARGS method */
--      PyObject *res;
--      if (data->delargs) {
--      /* we need to create a temporary object to carry the destroy operation */
--      PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
--      res = SWIG_Python_CallFunctor(destroy, tmp);
--      Py_DECREF(tmp);
--      } else {
--      PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
--      PyObject *mself = PyCFunction_GET_SELF(destroy);
--      res = ((*meth)(mself, v));
--      }
--      Py_XDECREF(res);
--    } 
--#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
--    else {
--      const char *name = SWIG_TypePrettyName(ty);
--      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
--    }
--#endif
--  } 
--  Py_XDECREF(next);
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyObject* 
--SwigPyObject_append(PyObject* v, PyObject* next)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--#ifndef METH_O
--  PyObject *tmp = 0;
--  if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
--  next = tmp;
--#endif
--  if (!SwigPyObject_Check(next)) {
--    return NULL;
--  }
--  sobj->next = next;
--  Py_INCREF(next);
--  return SWIG_Py_Void();
--}
--
--SWIGRUNTIME PyObject* 
--#ifdef METH_NOARGS
--SwigPyObject_next(PyObject* v)
--#else
--SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  if (sobj->next) {    
--    Py_INCREF(sobj->next);
--    return sobj->next;
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_disown(PyObject *v)
--#else
--SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = 0;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_acquire(PyObject *v)
--#else
--SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = SWIG_POINTER_OWN;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--SwigPyObject_own(PyObject *v, PyObject *args)
--{
--  PyObject *val = 0;
--#if (PY_VERSION_HEX < 0x02020000)
--  if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
--#elif (PY_VERSION_HEX < 0x02050000)
--  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
--#else
--  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
--#endif
--    {
--      return NULL;
--    } 
--  else
--    {
--      SwigPyObject *sobj = (SwigPyObject *)v;
--      PyObject *obj = PyBool_FromLong(sobj->own);
--      if (val) {
--#ifdef METH_NOARGS
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v);
--      } else {
--        SwigPyObject_disown(v);
--      }
--#else
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v,args);
--      } else {
--        SwigPyObject_disown(v,args);
--      }
--#endif
--      } 
--      return obj;
--    }
--}
--
--#ifdef METH_O
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#else
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#endif
--
--#if PY_VERSION_HEX < 0x02020000
--SWIGINTERN PyObject *
--SwigPyObject_getattr(SwigPyObject *sobj,char *name)
--{
--  return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
--}
--#endif
--
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_TypeOnce(void) {
--  static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
--
--  static PyNumberMethods SwigPyObject_as_number = {
--    (binaryfunc)0, /*nb_add*/
--    (binaryfunc)0, /*nb_subtract*/
--    (binaryfunc)0, /*nb_multiply*/
--    /* nb_divide removed in Python 3 */
--#if PY_VERSION_HEX < 0x03000000
--    (binaryfunc)0, /*nb_divide*/
--#endif
--    (binaryfunc)0, /*nb_remainder*/
--    (binaryfunc)0, /*nb_divmod*/
--    (ternaryfunc)0,/*nb_power*/
--    (unaryfunc)0,  /*nb_negative*/
--    (unaryfunc)0,  /*nb_positive*/
--    (unaryfunc)0,  /*nb_absolute*/
--    (inquiry)0,    /*nb_nonzero*/
--    0,                   /*nb_invert*/
--    0,                   /*nb_lshift*/
--    0,                   /*nb_rshift*/
--    0,                   /*nb_and*/
--    0,                   /*nb_xor*/
--    0,                   /*nb_or*/
--#if PY_VERSION_HEX < 0x03000000
--    0,   /*nb_coerce*/
--#endif
--    (unaryfunc)SwigPyObject_long, /*nb_int*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_long, /*nb_long*/
--#else
--    0, /*nb_reserved*/
--#endif
--    (unaryfunc)0,                 /*nb_float*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
--    (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
--#endif
--#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
--#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
--#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
--#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
--    0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
--#endif
--  };
--
--  static PyTypeObject swigpyobject_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyObject",               /* tp_name */
--      sizeof(SwigPyObject),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyObject_print,        /* tp_print */
--#if PY_VERSION_HEX < 0x02020000
--      (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
--#else
--      (getattrfunc)0,                       /* tp_getattr */
--#endif
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX >= 0x03000000
--    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
--#else
--      (cmpfunc)SwigPyObject_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyObject_repr,          /* tp_repr */
--      &SwigPyObject_as_number,              /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyObject_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigobject_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      swigobject_methods,                   /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpyobject_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpyobject_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpyobject_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpyobject_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
--{
--  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
--  if (sobj) {
--    sobj->ptr  = ptr;
--    sobj->ty   = ty;
--    sobj->own  = own;
--    sobj->next = 0;
--  }
--  return (PyObject *)sobj;
--}
--
--/* -----------------------------------------------------------------------------
-- * Implements a simple Swig Packed type, and use it instead of string
-- * ----------------------------------------------------------------------------- */
--
--typedef struct {
--  PyObject_HEAD
--  void *pack;
--  swig_type_info *ty;
--  size_t size;
--} SwigPyPacked;
--
--SWIGRUNTIME int
--SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char result[SWIG_BUFFER_SIZE];
--  fputs("<Swig Packed ", fp); 
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    fputs("at ", fp); 
--    fputs(result, fp); 
--  }
--  fputs(v->ty->name,fp); 
--  fputs(">", fp);
--  return 0; 
--}
--  
--SWIGRUNTIME PyObject *
--SwigPyPacked_repr(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
--  }  
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_str(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
--    return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromChar(v->ty->name);
--  }  
--}
--
--SWIGRUNTIME int
--SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
--{
--  size_t i = v->size;
--  size_t j = w->size;
--  int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
--  return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
--}
--
--SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
--  return type;
--}
--
--SWIGRUNTIMEINLINE int
--SwigPyPacked_Check(PyObject *op) {
--  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
--    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
--}
--
--SWIGRUNTIME void
--SwigPyPacked_dealloc(PyObject *v)
--{
--  if (SwigPyPacked_Check(v)) {
--    SwigPyPacked *sobj = (SwigPyPacked *) v;
--    free(sobj->pack);
--  }
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_TypeOnce(void) {
--  static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
--  static PyTypeObject swigpypacked_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX>=0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyPacked",               /* tp_name */
--      sizeof(SwigPyPacked),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyPacked_print,        /* tp_print */
--      (getattrfunc)0,                       /* tp_getattr */
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX>=0x03000000
--      0, /* tp_reserved in 3.0.1 */
--#else
--      (cmpfunc)SwigPyPacked_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyPacked_repr,          /* tp_repr */
--      0,                                    /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyPacked_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigpacked_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      0,                                    /* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      0,                                    /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpypacked_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpypacked_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpypacked_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpypacked_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
--{
--  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
--  if (sobj) {
--    void *pack = malloc(size);
--    if (pack) {
--      memcpy(pack, ptr, size);
--      sobj->pack = pack;
--      sobj->ty   = ty;
--      sobj->size = size;
--    } else {
--      PyObject_DEL((PyObject *) sobj);
--      sobj = 0;
--    }
--  }
--  return (PyObject *) sobj;
--}
--
--SWIGRUNTIME swig_type_info *
--SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
--{
--  if (SwigPyPacked_Check(obj)) {
--    SwigPyPacked *sobj = (SwigPyPacked *)obj;
--    if (sobj->size != size) return 0;
--    memcpy(ptr, sobj->pack, size);
--    return sobj->ty;
--  } else {
--    return 0;
--  }
--}
--
--/* -----------------------------------------------------------------------------
-- * pointers/data manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIMEINLINE PyObject *
--_SWIG_This(void)
--{
--    return SWIG_Python_str_FromChar("this");
--}
--
--static PyObject *swig_this = NULL;
--
--SWIGRUNTIME PyObject *
--SWIG_This(void)
--{
--  if (swig_this == NULL)
--    swig_this = _SWIG_This();
--  return swig_this;
--}
--
--/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
--
--/* TODO: I don't know how to implement the fast getset in Python 3 right now */
--#if PY_VERSION_HEX>=0x03000000
--#define SWIG_PYTHON_SLOW_GETSET_THIS 
--#endif
--
--SWIGRUNTIME SwigPyObject *
--SWIG_Python_GetSwigThis(PyObject *pyobj) 
--{
--  PyObject *obj;
--
--  if (SwigPyObject_Check(pyobj))
--    return (SwigPyObject *) pyobj;
--
--#ifdef SWIGPYTHON_BUILTIN
--  (void)obj;
--# ifdef PyWeakref_CheckProxy
--  if (PyWeakref_CheckProxy(pyobj)) {
--    pyobj = PyWeakref_GET_OBJECT(pyobj);
--    if (pyobj && SwigPyObject_Check(pyobj))
--      return (SwigPyObject*) pyobj;
--  }
--# endif
--  return NULL;
--#else
--
--  obj = 0;
--
--#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
--  if (PyInstance_Check(pyobj)) {
--    obj = _PyInstance_Lookup(pyobj, SWIG_This());      
--  } else {
--    PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
--    if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
--    } else {
--#ifdef PyWeakref_CheckProxy
--      if (PyWeakref_CheckProxy(pyobj)) {
--      PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
--      return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
--      }
--#endif
--      obj = PyObject_GetAttr(pyobj,SWIG_This());
--      if (obj) {
--      Py_DECREF(obj);
--      } else {
--      if (PyErr_Occurred()) PyErr_Clear();
--      return 0;
--      }
--    }
--  }
--#else
--  obj = PyObject_GetAttr(pyobj,SWIG_This());
--  if (obj) {
--    Py_DECREF(obj);
--  } else {
--    if (PyErr_Occurred()) PyErr_Clear();
--    return 0;
--  }
--#endif
--  if (obj && !SwigPyObject_Check(obj)) {
--    /* a PyObject is called 'this', try to get the 'real this'
--       SwigPyObject from it */ 
--    return SWIG_Python_GetSwigThis(obj);
--  }
--  return (SwigPyObject *)obj;
--#endif
--}
--
--/* Acquire a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_AcquirePtr(PyObject *obj, int own) {
--  if (own == SWIG_POINTER_OWN) {
--    SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
--    if (sobj) {
--      int oldown = sobj->own;
--      sobj->own = own;
--      return oldown;
--    }
--  }
--  return 0;
--}
--
--/* Convert a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
--  int res;
--  SwigPyObject *sobj;
--
--  if (!obj)
--    return SWIG_ERROR;
--  if (obj == Py_None) {
--    if (ptr)
--      *ptr = 0;
--    return SWIG_OK;
--  }
--
--  res = SWIG_ERROR;
--
--  sobj = SWIG_Python_GetSwigThis(obj);
--  if (own)
--    *own = 0;
--  while (sobj) {
--    void *vptr = sobj->ptr;
--    if (ty) {
--      swig_type_info *to = sobj->ty;
--      if (to == ty) {
--        /* no type cast needed */
--        if (ptr) *ptr = vptr;
--        break;
--      } else {
--        swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--        if (!tc) {
--          sobj = (SwigPyObject *)sobj->next;
--        } else {
--          if (ptr) {
--            int newmemory = 0;
--            *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--            if (newmemory == SWIG_CAST_NEW_MEMORY) {
--              assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
--              if (own)
--                *own = *own | SWIG_CAST_NEW_MEMORY;
--            }
--          }
--          break;
--        }
--      }
--    } else {
--      if (ptr) *ptr = vptr;
--      break;
--    }
--  }
--  if (sobj) {
--    if (own)
--      *own = *own | sobj->own;
--    if (flags & SWIG_POINTER_DISOWN) {
--      sobj->own = 0;
--    }
--    res = SWIG_OK;
--  } else {
--    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
--      SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--      if (data && !data->implicitconv) {
--        PyObject *klass = data->klass;
--        if (klass) {
--          PyObject *impconv;
--          data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
--          impconv = SWIG_Python_CallFunctor(klass, obj);
--          data->implicitconv = 0;
--          if (PyErr_Occurred()) {
--            PyErr_Clear();
--            impconv = 0;
--          }
--          if (impconv) {
--            SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
--            if (iobj) {
--              void *vptr;
--              res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
--              if (SWIG_IsOK(res)) {
--                if (ptr) {
--                  *ptr = vptr;
--                  /* transfer the ownership to 'ptr' */
--                  iobj->own = 0;
--                  res = SWIG_AddCast(res);
--                  res = SWIG_AddNewMask(res);
--                } else {
--                  res = SWIG_AddCast(res);                
--                }
--              }
--            }
--            Py_DECREF(impconv);
--          }
--        }
--      }
--    }
--  }
--  return res;
--}
--
--/* Convert a function ptr value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
--  if (!PyCFunction_Check(obj)) {
--    return SWIG_ConvertPtr(obj, ptr, ty, 0);
--  } else {
--    void *vptr = 0;
--    
--    /* here we get the method pointer for callbacks */
--    const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
--    const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
--    if (desc)
--      desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
--    if (!desc) 
--      return SWIG_ERROR;
--    if (ty) {
--      swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
--      if (tc) {
--        int newmemory = 0;
--        *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--        assert(!newmemory); /* newmemory handling not yet implemented */
--      } else {
--        return SWIG_ERROR;
--      }
--    } else {
--      *ptr = vptr;
--    }
--    return SWIG_OK;
--  }
--}
--
--/* Convert a packed value value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
--  swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
--  if (!to) return SWIG_ERROR;
--  if (ty) {
--    if (to != ty) {
--      /* check type cast? */
--      swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--      if (!tc) return SWIG_ERROR;
--    }
--  }
--  return SWIG_OK;
--}  
--
--/* -----------------------------------------------------------------------------
-- * Create a new pointer object
-- * ----------------------------------------------------------------------------- */
--
--/*
--  Create a new instance object, without calling __init__, and set the
--  'this' attribute.
--*/
--
--SWIGRUNTIME PyObject* 
--SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
--{
--#if (PY_VERSION_HEX >= 0x02020000)
--  PyObject *inst = 0;
--  PyObject *newraw = data->newraw;
--  if (newraw) {
--    inst = PyObject_Call(newraw, data->newargs, NULL);
--    if (inst) {
--#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
--      PyObject **dictptr = _PyObject_GetDictPtr(inst);
--      if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      if (dict == NULL) {
--        dict = PyDict_New();
--        *dictptr = dict;
--        PyDict_SetItem(dict, SWIG_This(), swig_this);
--      }
--      }
--#else
--      PyObject *key = SWIG_This();
--      PyObject_SetAttr(inst, key, swig_this);
--#endif
--    }
--  } else {
--#if PY_VERSION_HEX >= 0x03000000
--    inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
--    if (inst) {
--      PyObject_SetAttr(inst, SWIG_This(), swig_this);
--      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
--    }
--#else
--    PyObject *dict = PyDict_New();
--    if (dict) {
--      PyDict_SetItem(dict, SWIG_This(), swig_this);
--      inst = PyInstance_NewRaw(data->newargs, dict);
--      Py_DECREF(dict);
--    }
--#endif
--  }
--  return inst;
--#else
--#if (PY_VERSION_HEX >= 0x02010000)
--  PyObject *inst = 0;
--  PyObject *dict = PyDict_New();
--  if (dict) {
--    PyDict_SetItem(dict, SWIG_This(), swig_this);
--    inst = PyInstance_NewRaw(data->newargs, dict);
--    Py_DECREF(dict);
--  }
--  return (PyObject *) inst;
--#else
--  PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
--  if (inst == NULL) {
--    return NULL;
--  }
--  inst->in_class = (PyClassObject *)data->newargs;
--  Py_INCREF(inst->in_class);
--  inst->in_dict = PyDict_New();
--  if (inst->in_dict == NULL) {
--    Py_DECREF(inst);
--    return NULL;
--  }
--#ifdef Py_TPFLAGS_HAVE_WEAKREFS
--  inst->in_weakreflist = NULL;
--#endif
--#ifdef Py_TPFLAGS_GC
--  PyObject_GC_Init(inst);
--#endif
--  PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
--  return (PyObject *) inst;
--#endif
--#endif
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
--{
-- PyObject *dict;
--#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
-- PyObject **dictptr = _PyObject_GetDictPtr(inst);
-- if (dictptr != NULL) {
--   dict = *dictptr;
--   if (dict == NULL) {
--     dict = PyDict_New();
--     *dictptr = dict;
--   }
--   PyDict_SetItem(dict, SWIG_This(), swig_this);
--   return;
-- }
--#endif
-- dict = PyObject_GetAttrString(inst, (char*)"__dict__");
-- PyDict_SetItem(dict, SWIG_This(), swig_this);
-- Py_DECREF(dict);
--} 
--
--
--SWIGINTERN PyObject *
--SWIG_Python_InitShadowInstance(PyObject *args) {
--  PyObject *obj[2];
--  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
--    return NULL;
--  } else {
--    SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
--    if (sthis) {
--      SwigPyObject_append((PyObject*) sthis, obj[1]);
--    } else {
--      SWIG_Python_SetSwigThis(obj[0], obj[1]);
--    }
--    return SWIG_Py_Void();
--  }
--}
--
--/* Create a new pointer object */
--
--SWIGRUNTIME PyObject *
--SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
--  SwigPyClientData *clientdata;
--  PyObject * robj;
--  int own;
--
--  if (!ptr)
--    return SWIG_Py_Void();
--
--  clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
--  own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
--  if (clientdata && clientdata->pytype) {
--    SwigPyObject *newobj;
--    if (flags & SWIG_BUILTIN_TP_INIT) {
--      newobj = (SwigPyObject*) self;
--      if (newobj->ptr) {
--        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
--        while (newobj->next)
--        newobj = (SwigPyObject *) newobj->next;
--        newobj->next = next_self;
--        newobj = (SwigPyObject *)next_self;
--      }
--    } else {
--      newobj = PyObject_New(SwigPyObject, clientdata->pytype);
--    }
--    if (newobj) {
--      newobj->ptr = ptr;
--      newobj->ty = type;
--      newobj->own = own;
--      newobj->next = 0;
--#ifdef SWIGPYTHON_BUILTIN
--      newobj->dict = 0;
--#endif
--      return (PyObject*) newobj;
--    }
--    return SWIG_Py_Void();
--  }
--
--  assert(!(flags & SWIG_BUILTIN_TP_INIT));
--
--  robj = SwigPyObject_New(ptr, type, own);
--  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
--    PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
--    Py_DECREF(robj);
--    robj = inst;
--  }
--  return robj;
--}
--
--/* Create a new packed object */
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
--  return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
--}
--
--/* -----------------------------------------------------------------------------*
-- *  Get type list 
-- * -----------------------------------------------------------------------------*/
--
--#ifdef SWIG_LINK_RUNTIME
--void *SWIG_ReturnGlobalTypeList(void *);
--#endif
--
--SWIGRUNTIME swig_module_info *
--SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
--  static void *type_pointer = (void *)0;
--  /* first check if module already created */
--  if (!type_pointer) {
--#ifdef SWIG_LINK_RUNTIME
--    type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
--#else
--# ifdef SWIGPY_USE_CAPSULE
--    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
--# else
--    type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
--                                  (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
--# endif
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      type_pointer = (void *)0;
--    }
--#endif
--  }
--  return (swig_module_info *) type_pointer;
--}
--
--#if PY_MAJOR_VERSION < 2
--/* PyModule_AddObject function was introduced in Python 2.0.  The following function
--   is copied out of Python/modsupport.c in python version 2.3.4 */
--SWIGINTERN int
--PyModule_AddObject(PyObject *m, char *name, PyObject *o)
--{
--  PyObject *dict;
--  if (!PyModule_Check(m)) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs module as first arg");
--    return SWIG_ERROR;
--  }
--  if (!o) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs non-NULL value");
--    return SWIG_ERROR;
--  }
--  
--  dict = PyModule_GetDict(m);
--  if (dict == NULL) {
--    /* Internal error -- modules must have a dict! */
--    PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
--               PyModule_GetName(m));
--    return SWIG_ERROR;
--  }
--  if (PyDict_SetItemString(dict, name, o))
--    return SWIG_ERROR;
--  Py_DECREF(o);
--  return SWIG_OK;
--}
--#endif
--
--SWIGRUNTIME void
--#ifdef SWIGPY_USE_CAPSULE
--SWIG_Python_DestroyModule(PyObject *obj)
--#else
--SWIG_Python_DestroyModule(void *vptr)
--#endif
--{
--#ifdef SWIGPY_USE_CAPSULE
--  swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
--#else
--  swig_module_info *swig_module = (swig_module_info *) vptr;
--#endif
--  swig_type_info **types = swig_module->types;
--  size_t i;
--  for (i =0; i < swig_module->size; ++i) {
--    swig_type_info *ty = types[i];
--    if (ty->owndata) {
--      SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
--      if (data) SwigPyClientData_Del(data);
--    }
--  }
--  Py_DECREF(SWIG_This());
--  swig_this = NULL;
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetModule(swig_module_info *swig_module) {
--#if PY_VERSION_HEX >= 0x03000000
-- /* Add a dummy module object into sys.modules */
--  PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
--#else
--  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
--  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
--#endif
--#ifdef SWIGPY_USE_CAPSULE
--  PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#else
--  PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#endif
--}
--
--/* The python cached type query */
--SWIGRUNTIME PyObject *
--SWIG_Python_TypeCache(void) {
--  static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
--  return cache;
--}
--
--SWIGRUNTIME swig_type_info *
--SWIG_Python_TypeQuery(const char *type)
--{
--  PyObject *cache = SWIG_Python_TypeCache();
--  PyObject *key = SWIG_Python_str_FromChar(type); 
--  PyObject *obj = PyDict_GetItem(cache, key);
--  swig_type_info *descriptor;
--  if (obj) {
--#ifdef SWIGPY_USE_CAPSULE
--    descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
--#else
--    descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
--#endif
--  } else {
--    swig_module_info *swig_module = SWIG_GetModule(0);
--    descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
--    if (descriptor) {
--#ifdef SWIGPY_USE_CAPSULE
--      obj = PyCapsule_New((void*) descriptor, NULL, NULL);
--#else
--      obj = PyCObject_FromVoidPtr(descriptor, NULL);
--#endif
--      PyDict_SetItem(cache, key, obj);
--      Py_DECREF(obj);
--    }
--  }
--  Py_DECREF(key);
--  return descriptor;
--}
--
--/* 
--   For backward compatibility only
--*/
--#define SWIG_POINTER_EXCEPTION  0
--#define SWIG_arg_fail(arg)      SWIG_Python_ArgFail(arg)
--#define SWIG_MustGetPtr(p, type, argnum, flags)  SWIG_Python_MustGetPtr(p, type, argnum, flags)
--
--SWIGRUNTIME int
--SWIG_Python_AddErrMesg(const char* mesg, int infront)
--{  
--  if (PyErr_Occurred()) {
--    PyObject *type = 0;
--    PyObject *value = 0;
--    PyObject *traceback = 0;
--    PyErr_Fetch(&type, &value, &traceback);
--    if (value) {
--      char *tmp;
--      PyObject *old_str = PyObject_Str(value);
--      Py_XINCREF(type);
--      PyErr_Clear();
--      if (infront) {
--      PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
--      } else {
--      PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--      }
--      SWIG_Python_str_DelForPy3(tmp);
--      Py_DECREF(old_str);
--    }
--    return 1;
--  } else {
--    return 0;
--  }
--}
--  
--SWIGRUNTIME int
--SWIG_Python_ArgFail(int argnum)
--{
--  if (PyErr_Occurred()) {
--    /* add information about failing argument */
--    char mesg[256];
--    PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
--    return SWIG_Python_AddErrMesg(mesg, 1);
--  } else {
--    return 0;
--  }
--}
--
--SWIGRUNTIMEINLINE const char *
--SwigPyObject_GetDesc(PyObject *self)
--{
--  SwigPyObject *v = (SwigPyObject *)self;
--  swig_type_info *ty = v ? v->ty : 0;
--  return ty ? ty->str : "";
--}
--
--SWIGRUNTIME void
--SWIG_Python_TypeError(const char *type, PyObject *obj)
--{
--  if (type) {
--#if defined(SWIG_COBJECT_TYPES)
--    if (obj && SwigPyObject_Check(obj)) {
--      const char *otype = (const char *) SwigPyObject_GetDesc(obj);
--      if (otype) {
--      PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
--                   type, otype);
--      return;
--      }
--    } else 
--#endif      
--    {
--      const char *otype = (obj ? obj->ob_type->tp_name : 0); 
--      if (otype) {
--      PyObject *str = PyObject_Str(obj);
--      const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
--      if (cstr) {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
--                     type, otype, cstr);
--          SWIG_Python_str_DelForPy3(cstr);
--      } else {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
--                     type, otype);
--      }
--      Py_XDECREF(str);
--      return;
--      }
--    }   
--    PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
--  } else {
--    PyErr_Format(PyExc_TypeError, "unexpected type is received");
--  }
--}
--
--
--/* Convert a pointer value, signal an exception on a type mismatch */
--SWIGRUNTIME void *
--SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
--  void *result;
--  if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
--    PyErr_Clear();
--#if SWIG_POINTER_EXCEPTION
--    if (flags) {
--      SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
--      SWIG_Python_ArgFail(argnum);
--    }
--#endif
--  }
--  return result;
--}
--
--#ifdef SWIGPYTHON_BUILTIN
--SWIGRUNTIME int
--SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
--  PyTypeObject *tp = obj->ob_type;
--  PyObject *descr;
--  PyObject *encoded_name;
--  descrsetfunc f;
--  int res;
--
--# ifdef Py_USING_UNICODE
--  if (PyString_Check(name)) {
--    name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
--    if (!name)
--      return -1;
--  } else if (!PyUnicode_Check(name))
--# else
--  if (!PyString_Check(name))
--# endif
--  {
--    PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
--    return -1;
--  } else {
--    Py_INCREF(name);
--  }
--
--  if (!tp->tp_dict) {
--    if (PyType_Ready(tp) < 0)
--      goto done;
--  }
--
--  res = -1;
--  descr = _PyType_Lookup(tp, name);
--  f = NULL;
--  if (descr != NULL)
--    f = descr->ob_type->tp_descr_set;
--  if (!f) {
--    if (PyString_Check(name)) {
--      encoded_name = name;
--      Py_INCREF(name);
--    } else {
--      encoded_name = PyUnicode_AsUTF8String(name);
--    }
--    PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
--    Py_DECREF(encoded_name);
--  } else {
--    res = f(descr, obj, value);
--  }
--  
--  done:
--  Py_DECREF(name);
--  return res;
--}
--#endif
--
--
--#ifdef __cplusplus
--}
--#endif
--
--
--
--#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
--
--#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else 
--
--
--
--/* -------- TYPES TABLE (BEGIN) -------- */
--
--#define SWIGTYPE_p_char swig_types[0]
--#define SWIGTYPE_p_im_col_tab_disp swig_types[1]
--#define SWIGTYPE_p_matrix swig_types[2]
--#define SWIGTYPE_p_vips__VDisplay swig_types[3]
--#define SWIGTYPE_p_vips__VError swig_types[4]
--#define SWIGTYPE_p_void swig_types[5]
--static swig_type_info *swig_types[7];
--static swig_module_info swig_module = {swig_types, 6, 0, 0, 0, 0};
--#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
--#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
--
--/* -------- TYPES TABLE (END) -------- */
--
--#if (PY_VERSION_HEX <= 0x02000000)
--# if !defined(SWIG_PYTHON_CLASSIC)
--#  error "This python version requires swig to be run with the '-classic' option"
--# endif
--#endif
--
--/*-----------------------------------------------
--              @(target):= vdisplaymodule.so
--  ------------------------------------------------*/
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_init    PyInit_vdisplaymodule
--
--#else
--#  define SWIG_init    initvdisplaymodule
--
--#endif
--#define SWIG_name    "vdisplaymodule"
--
--#define SWIGVERSION 0x020010 
--#define SWIG_VERSION SWIGVERSION
--
--
--#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) 
--#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) 
--
--
--#include <stdexcept>
--
--
--namespace swig {
--  class SwigPtr_PyObject {
--  protected:
--    PyObject *_obj;
--
--  public:
--    SwigPtr_PyObject() :_obj(0)
--    {
--    }
--
--    SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
--    {
--      Py_XINCREF(_obj);      
--    }
--    
--    SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
--    {
--      if (initial_ref) {
--        Py_XINCREF(_obj);
--      }
--    }
--    
--    SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) 
--    {
--      Py_XINCREF(item._obj);
--      Py_XDECREF(_obj);
--      _obj = item._obj;
--      return *this;      
--    }
--    
--    ~SwigPtr_PyObject() 
--    {
--      Py_XDECREF(_obj);
--    }
--    
--    operator PyObject *() const
--    {
--      return _obj;
--    }
--
--    PyObject *operator->() const
--    {
--      return _obj;
--    }
--  };
--}
--
--
--namespace swig {
--  struct SwigVar_PyObject : SwigPtr_PyObject {
--    SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
--    
--    SwigVar_PyObject & operator = (PyObject* obj)
--    {
--      Py_XDECREF(_obj);
--      _obj = obj;
--      return *this;      
--    }
--  };
--}
--
--
--#include <vips/vipscpp.h>
--
--
--SWIGINTERNINLINE PyObject*
--  SWIG_From_int  (int value)
--{
--  return PyInt_FromLong((long) value);
--}
--
--
--SWIGINTERN swig_type_info*
--SWIG_pchar_descriptor(void)
--{
--  static int init = 0;
--  static swig_type_info* info = 0;
--  if (!init) {
--    info = SWIG_TypeQuery("_p_char");
--    init = 1;
--  }
--  return info;
--}
--
--
--SWIGINTERN int
--SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
--{
--#if PY_VERSION_HEX>=0x03000000
--  if (PyUnicode_Check(obj))
--#else  
--  if (PyString_Check(obj))
--#endif
--  {
--    char *cstr; Py_ssize_t len;
--#if PY_VERSION_HEX>=0x03000000
--    if (!alloc && cptr) {
--        /* We can't allow converting without allocation, since the internal
--           representation of string in Python 3 is UCS-2/UCS-4 but we require
--           a UTF-8 representation.
--           TODO(bhy) More detailed explanation */
--        return SWIG_RuntimeError;
--    }
--    obj = PyUnicode_AsUTF8String(obj);
--    PyBytes_AsStringAndSize(obj, &cstr, &len);
--    if(alloc) *alloc = SWIG_NEWOBJ;
--#else
--    PyString_AsStringAndSize(obj, &cstr, &len);
--#endif
--    if (cptr) {
--      if (alloc) {
--      /* 
--         In python the user should not be able to modify the inner
--         string representation. To warranty that, if you define
--         SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
--         buffer is always returned.
--
--         The default behavior is just to return the pointer value,
--         so, be careful.
--      */ 
--#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
--      if (*alloc != SWIG_OLDOBJ) 
--#else
--      if (*alloc == SWIG_NEWOBJ) 
--#endif
--        {
--          *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
--          *alloc = SWIG_NEWOBJ;
--        }
--      else {
--        *cptr = cstr;
--        *alloc = SWIG_OLDOBJ;
--      }
--      } else {
--        #if PY_VERSION_HEX>=0x03000000
--        assert(0); /* Should never reach here in Python 3 */
--        #endif
--      *cptr = SWIG_Python_str_AsChar(obj);
--      }
--    }
--    if (psize) *psize = len + 1;
--#if PY_VERSION_HEX>=0x03000000
--    Py_XDECREF(obj);
--#endif
--    return SWIG_OK;
--  } else {
--    swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--    if (pchar_descriptor) {
--      void* vptr = 0;
--      if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
--      if (cptr) *cptr = (char *) vptr;
--      if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
--      if (alloc) *alloc = SWIG_OLDOBJ;
--      return SWIG_OK;
--      }
--    }
--  }
--  return SWIG_TypeError;
--}
--
--
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--SWIGINTERN PyObject *_wrap_new_VDisplay__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDisplay *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VDisplay",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VDisplay" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = (vips::VDisplay *)new vips::VDisplay((char const *)arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDisplay, SWIG_POINTER_NEW |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDisplay__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VDisplay")) SWIG_fail;
--  result = (vips::VDisplay *)new vips::VDisplay();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDisplay, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDisplay__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *arg1 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDisplay *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VDisplay",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VDisplay" "', argument " "1"" of type '" "vips::VDisplay const &""'"); 
--  }
--  if (!argp1) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VDisplay" "', argument " "1"" of type '" "vips::VDisplay const &""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDisplay * >(argp1);
--  result = (vips::VDisplay *)new vips::VDisplay((vips::VDisplay const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDisplay, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDisplay(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[2];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VDisplay__SWIG_1(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_vips__VDisplay, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VDisplay__SWIG_2(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VDisplay__SWIG_0(self, args);
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VDisplay'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VDisplay::VDisplay(char const *)\n"
--    "    vips::VDisplay::VDisplay()\n"
--    "    vips::VDisplay::VDisplay(vips::VDisplay const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDisplay___assign__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *arg1 = (vips::VDisplay *) 0 ;
--  vips::VDisplay *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDisplay *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDisplay___assign__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDisplay, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDisplay___assign__" "', argument " "1"" of type '" "vips::VDisplay *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDisplay * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VDisplay___assign__" "', argument " "2"" of type '" "vips::VDisplay const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VDisplay___assign__" "', argument " "2"" of type '" "vips::VDisplay const &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VDisplay * >(argp2);
--  result = (vips::VDisplay *) &(arg1)->operator =((vips::VDisplay const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDisplay, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VDisplay(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *arg1 = (vips::VDisplay *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VDisplay",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDisplay, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VDisplay" "', argument " "1"" of type '" "vips::VDisplay *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDisplay * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDisplay_disp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *arg1 = (vips::VDisplay *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  void *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDisplay_disp",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDisplay, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDisplay_disp" "', argument " "1"" of type '" "vips::VDisplay const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDisplay * >(argp1);
--  result = (void *)((vips::VDisplay const *)arg1)->disp();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDisplay_luts(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDisplay *arg1 = (vips::VDisplay *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  im_col_tab_disp *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDisplay_luts",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDisplay, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDisplay_luts" "', argument " "1"" of type '" "vips::VDisplay const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDisplay * >(argp1);
--  try {
--    result = (im_col_tab_disp *)((vips::VDisplay const *)arg1)->luts();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_im_col_tab_disp, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VDisplay_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VDisplay, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--static PyMethodDef SwigMethods[] = {
--       { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
--       { (char *)"new_VDisplay", _wrap_new_VDisplay, METH_VARARGS, NULL},
--       { (char *)"VDisplay___assign__", _wrap_VDisplay___assign__, METH_VARARGS, NULL},
--       { (char *)"delete_VDisplay", _wrap_delete_VDisplay, METH_VARARGS, NULL},
--       { (char *)"VDisplay_disp", _wrap_VDisplay_disp, METH_VARARGS, NULL},
--       { (char *)"VDisplay_luts", _wrap_VDisplay_luts, METH_VARARGS, NULL},
--       { (char *)"VDisplay_swigregister", VDisplay_swigregister, METH_VARARGS, NULL},
--       { NULL, NULL, 0, NULL }
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
--
--static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_im_col_tab_disp = {"_p_im_col_tab_disp", "im_col_tab_disp *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_matrix = {"_p_matrix", "matrix *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VDisplay = {"_p_vips__VDisplay", "vips::VDisplay *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VError = {"_p_vips__VError", "vips::VError *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
--
--static swig_type_info *swig_type_initial[] = {
--  &_swigt__p_char,
--  &_swigt__p_im_col_tab_disp,
--  &_swigt__p_matrix,
--  &_swigt__p_vips__VDisplay,
--  &_swigt__p_vips__VError,
--  &_swigt__p_void,
--};
--
--static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_im_col_tab_disp[] = {  {&_swigt__p_im_col_tab_disp, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_matrix[] = {  {&_swigt__p_matrix, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VDisplay[] = {  {&_swigt__p_vips__VDisplay, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VError[] = {  {&_swigt__p_vips__VError, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_void[] = {  {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
--
--static swig_cast_info *swig_cast_initial[] = {
--  _swigc__p_char,
--  _swigc__p_im_col_tab_disp,
--  _swigc__p_matrix,
--  _swigc__p_vips__VDisplay,
--  _swigc__p_vips__VError,
--  _swigc__p_void,
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
--
--static swig_const_info swig_const_table[] = {
--{0, 0, 0, 0.0, 0, 0}};
--
--#ifdef __cplusplus
--}
--#endif
--/* -----------------------------------------------------------------------------
-- * Type initialization:
-- * This problem is tough by the requirement that no dynamic 
-- * memory is used. Also, since swig_type_info structures store pointers to 
-- * swig_cast_info structures and swig_cast_info structures store pointers back
-- * to swig_type_info structures, we need some lookup code at initialization. 
-- * The idea is that swig generates all the structures that are needed. 
-- * The runtime then collects these partially filled structures. 
-- * The SWIG_InitializeModule function takes these initial arrays out of 
-- * swig_module, and does all the lookup, filling in the swig_module.types
-- * array with the correct data and linking the correct swig_cast_info
-- * structures together.
-- *
-- * The generated swig_type_info structures are assigned staticly to an initial 
-- * array. We just loop through that array, and handle each type individually.
-- * First we lookup if this type has been already loaded, and if so, use the
-- * loaded structure instead of the generated one. Then we have to fill in the
-- * cast linked list. The cast data is initially stored in something like a
-- * two-dimensional array. Each row corresponds to a type (there are the same
-- * number of rows as there are in the swig_type_initial array). Each entry in
-- * a column is one of the swig_cast_info structures for that type.
-- * The cast_initial array is actually an array of arrays, because each row has
-- * a variable number of columns. So to actually build the cast linked list,
-- * we find the array of casts associated with the type, and loop through it 
-- * adding the casts to the list. The one last trick we need to do is making
-- * sure the type pointer in the swig_cast_info struct is correct.
-- *
-- * First off, we lookup the cast->type name to see if it is already loaded. 
-- * There are three cases to handle:
-- *  1) If the cast->type has already been loaded AND the type we are adding
-- *     casting info to has not been loaded (it is in this module), THEN we
-- *     replace the cast->type pointer with the type pointer that has already
-- *     been loaded.
-- *  2) If BOTH types (the one we are adding casting info to, and the 
-- *     cast->type) are loaded, THEN the cast info has already been loaded by
-- *     the previous module so we just ignore it.
-- *  3) Finally, if cast->type has not already been loaded, then we add that
-- *     swig_cast_info to the linked list (because the cast->type) pointer will
-- *     be correct.
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#if 0
--} /* c-mode */
--#endif
--#endif
--
--#if 0
--#define SWIGRUNTIME_DEBUG
--#endif
--
--
--SWIGRUNTIME void
--SWIG_InitializeModule(void *clientdata) {
--  size_t i;
--  swig_module_info *module_head, *iter;
--  int found, init;
--  
--  /* check to see if the circular list has been setup, if not, set it up */
--  if (swig_module.next==0) {
--    /* Initialize the swig_module */
--    swig_module.type_initial = swig_type_initial;
--    swig_module.cast_initial = swig_cast_initial;
--    swig_module.next = &swig_module;
--    init = 1;
--  } else {
--    init = 0;
--  }
--  
--  /* Try and load any already created modules */
--  module_head = SWIG_GetModule(clientdata);
--  if (!module_head) {
--    /* This is the first module loaded for this interpreter */
--    /* so set the swig module into the interpreter */
--    SWIG_SetModule(clientdata, &swig_module);
--    module_head = &swig_module;
--  } else {
--    /* the interpreter has loaded a SWIG module, but has it loaded this one? */
--    found=0;
--    iter=module_head;
--    do {
--      if (iter==&swig_module) {
--        found=1;
--        break;
--      }
--      iter=iter->next;
--    } while (iter!= module_head);
--    
--    /* if the is found in the list, then all is done and we may leave */
--    if (found) return;
--    /* otherwise we must add out module into the list */
--    swig_module.next = module_head->next;
--    module_head->next = &swig_module;
--  }
--  
--  /* When multiple interpeters are used, a module could have already been initialized in
--       a different interpreter, but not yet have a pointer in this interpreter.
--       In this case, we do not want to continue adding types... everything should be
--       set up already */
--  if (init == 0) return;
--  
--  /* Now work on filling in swig_module.types */
--#ifdef SWIGRUNTIME_DEBUG
--  printf("SWIG_InitializeModule: size %d\n", swig_module.size);
--#endif
--  for (i = 0; i < swig_module.size; ++i) {
--    swig_type_info *type = 0;
--    swig_type_info *ret;
--    swig_cast_info *cast;
--    
--#ifdef SWIGRUNTIME_DEBUG
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--#endif
--    
--    /* if there is another module already loaded */
--    if (swig_module.next != &swig_module) {
--      type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
--    }
--    if (type) {
--      /* Overwrite clientdata field */
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: found type %s\n", type->name);
--#endif
--      if (swig_module.type_initial[i]->clientdata) {
--        type->clientdata = swig_module.type_initial[i]->clientdata;
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
--#endif
--      }
--    } else {
--      type = swig_module.type_initial[i];
--    }
--    
--    /* Insert casting types */
--    cast = swig_module.cast_initial[i];
--    while (cast->type) {
--      /* Don't need to add information already in the list */
--      ret = 0;
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
--#endif
--      if (swig_module.next != &swig_module) {
--        ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
--#ifdef SWIGRUNTIME_DEBUG
--        if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
--#endif
--      }
--      if (ret) {
--        if (type == swig_module.type_initial[i]) {
--#ifdef SWIGRUNTIME_DEBUG
--          printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
--#endif
--          cast->type = ret;
--          ret = 0;
--        } else {
--          /* Check for casting already in the list */
--          swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
--#ifdef SWIGRUNTIME_DEBUG
--          if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
--#endif
--          if (!ocast) ret = 0;
--        }
--      }
--      
--      if (!ret) {
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
--#endif
--        if (type->cast) {
--          type->cast->prev = cast;
--          cast->next = type->cast;
--        }
--        type->cast = cast;
--      }
--      cast++;
--    }
--    /* Set entry in modules->types array equal to the type */
--    swig_module.types[i] = type;
--  }
--  swig_module.types[i] = 0;
--  
--#ifdef SWIGRUNTIME_DEBUG
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--  for (i = 0; i < swig_module.size; ++i) {
--    int j = 0;
--    swig_cast_info *cast = swig_module.cast_initial[i];
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--    while (cast->type) {
--      printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
--      cast++;
--      ++j;
--    }
--    printf("---- Total casts: %d\n",j);
--  }
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--#endif
--}
--
--/* This function will propagate the clientdata field of type to
--* any new swig_type_info structures that have been added into the list
--* of equivalent types.  It is like calling
--* SWIG_TypeClientData(type, clientdata) a second time.
--*/
--SWIGRUNTIME void
--SWIG_PropagateClientData(void) {
--  size_t i;
--  swig_cast_info *equiv;
--  static int init_run = 0;
--  
--  if (init_run) return;
--  init_run = 1;
--  
--  for (i = 0; i < swig_module.size; i++) {
--    if (swig_module.types[i]->clientdata) {
--      equiv = swig_module.types[i]->cast;
--      while (equiv) {
--        if (!equiv->converter) {
--          if (equiv->type && !equiv->type->clientdata)
--          SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
--        }
--        equiv = equiv->next;
--      }
--    }
--  }
--}
--
--#ifdef __cplusplus
--#if 0
--{
--  /* c-mode */
--#endif
--}
--#endif
--
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--  
--  /* Python-specific SWIG API */
--#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
--#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
--#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
--  
--  /* -----------------------------------------------------------------------------
--   * global variable support code.
--   * ----------------------------------------------------------------------------- */
--  
--  typedef struct swig_globalvar {
--    char       *name;                  /* Name of global variable */
--    PyObject *(*get_attr)(void);       /* Return the current value */
--    int       (*set_attr)(PyObject *); /* Set the value */
--    struct swig_globalvar *next;
--  } swig_globalvar;
--  
--  typedef struct swig_varlinkobject {
--    PyObject_HEAD
--    swig_globalvar *vars;
--  } swig_varlinkobject;
--  
--  SWIGINTERN PyObject *
--  swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
--#if PY_VERSION_HEX >= 0x03000000
--    return PyUnicode_InternFromString("<Swig global variables>");
--#else
--    return PyString_FromString("<Swig global variables>");
--#endif
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_str(swig_varlinkobject *v) {
--#if PY_VERSION_HEX >= 0x03000000
--    PyObject *str = PyUnicode_InternFromString("(");
--    PyObject *tail;
--    PyObject *joined;
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      tail = PyUnicode_FromString(var->name);
--      joined = PyUnicode_Concat(str, tail);
--      Py_DecRef(str);
--      Py_DecRef(tail);
--      str = joined;
--      if (var->next) {
--        tail = PyUnicode_InternFromString(", ");
--        joined = PyUnicode_Concat(str, tail);
--        Py_DecRef(str);
--        Py_DecRef(tail);
--        str = joined;
--      }
--    }
--    tail = PyUnicode_InternFromString(")");
--    joined = PyUnicode_Concat(str, tail);
--    Py_DecRef(str);
--    Py_DecRef(tail);
--    str = joined;
--#else
--    PyObject *str = PyString_FromString("(");
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      PyString_ConcatAndDel(&str,PyString_FromString(var->name));
--      if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
--    }
--    PyString_ConcatAndDel(&str,PyString_FromString(")"));
--#endif
--    return str;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
--    char *tmp;
--    PyObject *str = swig_varlink_str(v);
--    fprintf(fp,"Swig global variables ");
--    fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(str);
--    return 0;
--  }
--  
--  SWIGINTERN void
--  swig_varlink_dealloc(swig_varlinkobject *v) {
--    swig_globalvar *var = v->vars;
--    while (var) {
--      swig_globalvar *n = var->next;
--      free(var->name);
--      free(var);
--      var = n;
--    }
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_getattr(swig_varlinkobject *v, char *n) {
--    PyObject *res = NULL;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->get_attr)();
--        break;
--      }
--      var = var->next;
--    }
--    if (res == NULL && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
--    int res = 1;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->set_attr)(p);
--        break;
--      }
--      var = var->next;
--    }
--    if (res == 1 && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN PyTypeObject*
--  swig_varlink_type(void) {
--    static char varlink__doc__[] = "Swig var link object";
--    static PyTypeObject varlink_type;
--    static int type_init = 0;
--    if (!type_init) {
--      const PyTypeObject tmp = {
--        /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--        PyVarObject_HEAD_INIT(NULL, 0)
--#else
--        PyObject_HEAD_INIT(NULL)
--        0,                                  /* ob_size */
--#endif
--        (char *)"swigvarlink",              /* tp_name */
--        sizeof(swig_varlinkobject),         /* tp_basicsize */
--        0,                                  /* tp_itemsize */
--        (destructor) swig_varlink_dealloc,  /* tp_dealloc */
--        (printfunc) swig_varlink_print,     /* tp_print */
--        (getattrfunc) swig_varlink_getattr, /* tp_getattr */
--        (setattrfunc) swig_varlink_setattr, /* tp_setattr */
--        0,                                  /* tp_compare */
--        (reprfunc) swig_varlink_repr,       /* tp_repr */
--        0,                                  /* tp_as_number */
--        0,                                  /* tp_as_sequence */
--        0,                                  /* tp_as_mapping */
--        0,                                  /* tp_hash */
--        0,                                  /* tp_call */
--        (reprfunc) swig_varlink_str,        /* tp_str */
--        0,                                  /* tp_getattro */
--        0,                                  /* tp_setattro */
--        0,                                  /* tp_as_buffer */
--        0,                                  /* tp_flags */
--        varlink__doc__,                     /* tp_doc */
--        0,                                  /* tp_traverse */
--        0,                                  /* tp_clear */
--        0,                                  /* tp_richcompare */
--        0,                                  /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--        0,                                  /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--        0,                                  /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--        0,0,0,0                             /* tp_alloc -> tp_next */
--#endif
--      };
--      varlink_type = tmp;
--      type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--      varlink_type.ob_type = &PyType_Type;
--#else
--      if (PyType_Ready(&varlink_type) < 0)
--      return NULL;
--#endif
--    }
--    return &varlink_type;
--  }
--  
--  /* Create a variable linking object for use later */
--  SWIGINTERN PyObject *
--  SWIG_Python_newvarlink(void) {
--    swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
--    if (result) {
--      result->vars = 0;
--    }
--    return ((PyObject*) result);
--  }
--  
--  SWIGINTERN void 
--  SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
--    swig_varlinkobject *v = (swig_varlinkobject *) p;
--    swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
--    if (gv) {
--      size_t size = strlen(name)+1;
--      gv->name = (char *)malloc(size);
--      if (gv->name) {
--        strncpy(gv->name,name,size);
--        gv->get_attr = get_attr;
--        gv->set_attr = set_attr;
--        gv->next = v->vars;
--      }
--    }
--    v->vars = gv;
--  }
--  
--  SWIGINTERN PyObject *
--  SWIG_globals(void) {
--    static PyObject *_SWIG_globals = 0; 
--    if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();  
--    return _SWIG_globals;
--  }
--  
--  /* -----------------------------------------------------------------------------
--   * constants/methods manipulation
--   * ----------------------------------------------------------------------------- */
--  
--  /* Install Constants */
--  SWIGINTERN void
--  SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
--    PyObject *obj = 0;
--    size_t i;
--    for (i = 0; constants[i].type; ++i) {
--      switch(constants[i].type) {
--      case SWIG_PY_POINTER:
--        obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
--        break;
--      case SWIG_PY_BINARY:
--        obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
--        break;
--      default:
--        obj = 0;
--        break;
--      }
--      if (obj) {
--        PyDict_SetItemString(d, constants[i].name, obj);
--        Py_DECREF(obj);
--      }
--    }
--  }
--  
--  /* -----------------------------------------------------------------------------*/
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  /* -----------------------------------------------------------------------------*/
--  
--  SWIGINTERN void
--  SWIG_Python_FixMethods(PyMethodDef *methods,
--    swig_const_info *const_table,
--    swig_type_info **types,
--    swig_type_info **types_initial) {
--    size_t i;
--    for (i = 0; methods[i].ml_name; ++i) {
--      const char *c = methods[i].ml_doc;
--      if (c && (c = strstr(c, "swig_ptr: "))) {
--        int j;
--        swig_const_info *ci = 0;
--        const char *name = c + 10;
--        for (j = 0; const_table[j].type; ++j) {
--          if (strncmp(const_table[j].name, name, 
--              strlen(const_table[j].name)) == 0) {
--            ci = &(const_table[j]);
--            break;
--          }
--        }
--        if (ci) {
--          void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
--          if (ptr) {
--            size_t shift = (ci->ptype) - types;
--            swig_type_info *ty = types_initial[shift];
--            size_t ldoc = (c - methods[i].ml_doc);
--            size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
--            char *ndoc = (char*)malloc(ldoc + lptr + 10);
--            if (ndoc) {
--              char *buff = ndoc;
--              strncpy(buff, methods[i].ml_doc, ldoc);
--              buff += ldoc;
--              strncpy(buff, "swig_ptr: ", 10);
--              buff += 10;
--              SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
--              methods[i].ml_doc = ndoc;
--            }
--          }
--        }
--      }
--    }
--  } 
--  
--#ifdef __cplusplus
--}
--#endif
--
--/* -----------------------------------------------------------------------------*
-- *  Partial Init method
-- * -----------------------------------------------------------------------------*/
--
--#ifdef __cplusplus
--extern "C"
--#endif
--
--SWIGEXPORT 
--#if PY_VERSION_HEX >= 0x03000000
--PyObject*
--#else
--void
--#endif
--SWIG_init(void) {
--  PyObject *m, *d, *md;
--#if PY_VERSION_HEX >= 0x03000000
--  static struct PyModuleDef SWIG_module = {
--# if PY_VERSION_HEX >= 0x03020000
--    PyModuleDef_HEAD_INIT,
--# else
--    {
--      PyObject_HEAD_INIT(NULL)
--      NULL, /* m_init */
--      0,    /* m_index */
--      NULL, /* m_copy */
--    },
--# endif
--    (char *) SWIG_name,
--    NULL,
--    -1,
--    SwigMethods,
--    NULL,
--    NULL,
--    NULL,
--    NULL
--  };
--#endif
--  
--#if defined(SWIGPYTHON_BUILTIN)
--  static SwigPyClientData SwigPyObject_clientdata = {
--    0, 0, 0, 0, 0, 0, 0
--  };
--  static PyGetSetDef this_getset_def = {
--    (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
--  };
--  static SwigPyGetSet thisown_getset_closure = {
--    (PyCFunction) SwigPyObject_own,
--    (PyCFunction) SwigPyObject_own
--  };
--  static PyGetSetDef thisown_getset_def = {
--    (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
--  };
--  PyObject *metatype_args;
--  PyTypeObject *builtin_pytype;
--  int builtin_base_count;
--  swig_type_info *builtin_basetype;
--  PyObject *tuple;
--  PyGetSetDescrObject *static_getset;
--  PyTypeObject *metatype;
--  SwigPyClientData *cd;
--  PyObject *public_interface, *public_symbol;
--  PyObject *this_descr;
--  PyObject *thisown_descr;
--  int i;
--  
--  (void)builtin_pytype;
--  (void)builtin_base_count;
--  (void)builtin_basetype;
--  (void)tuple;
--  (void)static_getset;
--  
--  /* metatype is used to implement static member variables. */
--  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
--  assert(metatype_args);
--  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
--  assert(metatype);
--  Py_DECREF(metatype_args);
--  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
--  assert(PyType_Ready(metatype) >= 0);
--#endif
--  
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  m = PyModule_Create(&SWIG_module);
--#else
--  m = Py_InitModule((char *) SWIG_name, SwigMethods);
--#endif
--  md = d = PyModule_GetDict(m);
--  (void)md;
--  
--  SWIG_InitializeModule(0);
--  
--#ifdef SWIGPYTHON_BUILTIN
--  SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
--  assert(SwigPyObject_stype);
--  cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--  if (!cd) {
--    SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
--    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
--  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
--    PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
--# if PY_VERSION_HEX >= 0x03000000
--    return NULL;
--# else
--    return;
--# endif
--  }
--  
--  /* All objects have a 'this' attribute */
--  this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
--  (void)this_descr;
--  
--  /* All objects have a 'thisown' attribute */
--  thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
--  (void)thisown_descr;
--  
--  public_interface = PyList_New(0);
--  public_symbol = 0;
--  (void)public_symbol;
--  
--  PyDict_SetItemString(md, "__all__", public_interface);
--  Py_DECREF(public_interface);
--  for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
--  for (i = 0; swig_const_table[i].name != 0; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
--#endif
--  
--  SWIG_InstallConstants(d,swig_const_table);
--  
--  SWIG_Python_SetConstant(d, "VDisplay_BARCO",SWIG_From_int(static_cast< int >(vips::VDisplay::BARCO)));
--  SWIG_Python_SetConstant(d, "VDisplay_DUMB",SWIG_From_int(static_cast< int >(vips::VDisplay::DUMB)));
--#if PY_VERSION_HEX >= 0x03000000
--  return m;
--#else
--  return;
--#endif
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VDisplay.py vips-7.38.5/swig/vipsCC/VDisplay.py
---- vips-7.38.5-vanilla/swig/vipsCC/VDisplay.py        2014-07-17 23:48:36.211794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VDisplay.py        1969-12-31 19:00:00.000000000 -0500
-@@ -1,93 +0,0 @@
--# This file was automatically generated by SWIG (http://www.swig.org).
--# Version 2.0.10
--#
--# Do not make changes to this file unless you know what you are doing--modify
--# the SWIG interface file instead.
--
--
--
--from sys import version_info
--if version_info >= (2,6,0):
--    def swig_import_helper():
--        from os.path import dirname
--        import imp
--        fp = None
--        try:
--            fp, pathname, description = imp.find_module('vdisplaymodule', [dirname(__file__)])
--        except ImportError:
--            import vdisplaymodule
--            return vdisplaymodule
--        if fp is not None:
--            try:
--                _mod = imp.load_module('vdisplaymodule', fp, pathname, description)
--            finally:
--                fp.close()
--            return _mod
--    vdisplaymodule = swig_import_helper()
--    del swig_import_helper
--else:
--    import vdisplaymodule
--del version_info
--try:
--    _swig_property = property
--except NameError:
--    pass # Python < 2.2 doesn't have 'property'.
--def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
--    if (name == "thisown"): return self.this.own(value)
--    if (name == "this"):
--        if type(value).__name__ == 'SwigPyObject':
--            self.__dict__[name] = value
--            return
--    method = class_type.__swig_setmethods__.get(name,None)
--    if method: return method(self,value)
--    if (not static):
--        self.__dict__[name] = value
--    else:
--        raise AttributeError("You cannot add attributes to %s" % self)
--
--def _swig_setattr(self,class_type,name,value):
--    return _swig_setattr_nondynamic(self,class_type,name,value,0)
--
--def _swig_getattr(self,class_type,name):
--    if (name == "thisown"): return self.this.own()
--    method = class_type.__swig_getmethods__.get(name,None)
--    if method: return method(self)
--    raise AttributeError(name)
--
--def _swig_repr(self):
--    try: strthis = "proxy of " + self.this.__repr__()
--    except: strthis = ""
--    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
--
--try:
--    _object = object
--    _newclass = 1
--except AttributeError:
--    class _object : pass
--    _newclass = 0
--
--
--import VError
--class VDisplay(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VDisplay, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, VDisplay, name)
--    __repr__ = _swig_repr
--    BARCO = vdisplaymodule.VDisplay_BARCO
--    DUMB = vdisplaymodule.VDisplay_DUMB
--    def __init__(self, *args): 
--        this = vdisplaymodule.new_VDisplay(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def __assign__(self, *args): return vdisplaymodule.VDisplay___assign__(self, *args)
--    __swig_destroy__ = vdisplaymodule.delete_VDisplay
--    __del__ = lambda self : None;
--    def disp(self): return vdisplaymodule.VDisplay_disp(self)
--    def luts(self): return vdisplaymodule.VDisplay_luts(self)
--VDisplay_swigregister = vdisplaymodule.VDisplay_swigregister
--VDisplay_swigregister(VDisplay)
--
--# This file is compatible with both classic and new-style classes.
--
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VError.i vips-7.38.5/swig/vipsCC/VError.i
---- vips-7.38.5-vanilla/swig/vipsCC/VError.i   2014-07-17 23:48:36.209794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VError.i   1969-12-31 19:00:00.000000000 -0500
-@@ -1,19 +0,0 @@
--/* SWIG interface file for VError.
-- */
--
--%module VError
--%{
--#include <vips/vipscpp.h>
--%}
--
--%include "std_except.i"
--%include "std_string.i"
--
--%include vips/VError.h
--
--%extend vips::VError {
--        const char *__str__ () {
--                return $self->what ();
--        }
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/verrormodule.cxx vips-7.38.5/swig/vipsCC/verrormodule.cxx
---- vips-7.38.5-vanilla/swig/vipsCC/verrormodule.cxx   2014-07-17 23:48:36.211794473 -0400
-+++ vips-7.38.5/swig/vipsCC/verrormodule.cxx   1969-12-31 19:00:00.000000000 -0500
-@@ -1,4593 +0,0 @@
--/* ----------------------------------------------------------------------------
-- * This file was automatically generated by SWIG (http://www.swig.org).
-- * Version 2.0.10
-- * 
-- * This file is not intended to be easily readable and contains a number of 
-- * coding conventions designed to improve portability and efficiency. Do not make
-- * changes to this file unless you know what you are doing--modify the SWIG 
-- * interface file instead. 
-- * ----------------------------------------------------------------------------- */
--
--#define SWIGPYTHON
--#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
--
--
--#ifdef __cplusplus
--/* SwigValueWrapper is described in swig.swg */
--template<typename T> class SwigValueWrapper {
--  struct SwigMovePointer {
--    T *ptr;
--    SwigMovePointer(T *p) : ptr(p) { }
--    ~SwigMovePointer() { delete ptr; }
--    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
--  } pointer;
--  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
--  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
--public:
--  SwigValueWrapper() : pointer(0) { }
--  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
--  operator T&() const { return *pointer.ptr; }
--  T *operator&() { return pointer.ptr; }
--};
--
--template <typename T> T SwigValueInit() {
--  return T();
--}
--#endif
--
--/* -----------------------------------------------------------------------------
-- *  This section contains generic SWIG labels for method/variable
-- *  declarations/attributes, and other compiler dependent labels.
-- * ----------------------------------------------------------------------------- */
--
--/* template workaround for compilers that cannot correctly implement the C++ standard */
--#ifndef SWIGTEMPLATEDISAMBIGUATOR
--# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# elif defined(__HP_aCC)
--/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
--/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# else
--#  define SWIGTEMPLATEDISAMBIGUATOR
--# endif
--#endif
--
--/* inline attribute */
--#ifndef SWIGINLINE
--# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
--#   define SWIGINLINE inline
--# else
--#   define SWIGINLINE
--# endif
--#endif
--
--/* attribute recognised by some compilers to avoid 'unused' warnings */
--#ifndef SWIGUNUSED
--# if defined(__GNUC__)
--#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
--#     define SWIGUNUSED __attribute__ ((__unused__)) 
--#   else
--#     define SWIGUNUSED
--#   endif
--# elif defined(__ICC)
--#   define SWIGUNUSED __attribute__ ((__unused__)) 
--# else
--#   define SWIGUNUSED 
--# endif
--#endif
--
--#ifndef SWIG_MSC_UNSUPPRESS_4505
--# if defined(_MSC_VER)
--#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
--# endif 
--#endif
--
--#ifndef SWIGUNUSEDPARM
--# ifdef __cplusplus
--#   define SWIGUNUSEDPARM(p)
--# else
--#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
--# endif
--#endif
--
--/* internal SWIG method */
--#ifndef SWIGINTERN
--# define SWIGINTERN static SWIGUNUSED
--#endif
--
--/* internal inline SWIG method */
--#ifndef SWIGINTERNINLINE
--# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
--#endif
--
--/* exporting methods */
--#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
--#  ifndef GCC_HASCLASSVISIBILITY
--#    define GCC_HASCLASSVISIBILITY
--#  endif
--#endif
--
--#ifndef SWIGEXPORT
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   if defined(STATIC_LINKED)
--#     define SWIGEXPORT
--#   else
--#     define SWIGEXPORT __declspec(dllexport)
--#   endif
--# else
--#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
--#     define SWIGEXPORT __attribute__ ((visibility("default")))
--#   else
--#     define SWIGEXPORT
--#   endif
--# endif
--#endif
--
--/* calling conventions for Windows */
--#ifndef SWIGSTDCALL
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   define SWIGSTDCALL __stdcall
--# else
--#   define SWIGSTDCALL
--# endif 
--#endif
--
--/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
--#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
--# define _CRT_SECURE_NO_DEPRECATE
--#endif
--
--/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
--#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
--# define _SCL_SECURE_NO_DEPRECATE
--#endif
--
--
--
--/* Python.h has to appear first */
--#include <Python.h>
--
--/* -----------------------------------------------------------------------------
-- * swigrun.swg
-- *
-- * This file contains generic C API SWIG runtime support for pointer
-- * type checking.
-- * ----------------------------------------------------------------------------- */
--
--/* This should only be incremented when either the layout of swig_type_info changes,
--   or for whatever reason, the runtime changes incompatibly */
--#define SWIG_RUNTIME_VERSION "4"
--
--/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
--#ifdef SWIG_TYPE_TABLE
--# define SWIG_QUOTE_STRING(x) #x
--# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
--# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
--#else
--# define SWIG_TYPE_TABLE_NAME
--#endif
--
--/*
--  You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
--  creating a static or dynamic library from the SWIG runtime code.
--  In 99.9% of the cases, SWIG just needs to declare them as 'static'.
--  
--  But only do this if strictly necessary, ie, if you have problems
--  with your compiler or suchlike.
--*/
--
--#ifndef SWIGRUNTIME
--# define SWIGRUNTIME SWIGINTERN
--#endif
--
--#ifndef SWIGRUNTIMEINLINE
--# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
--#endif
--
--/*  Generic buffer size */
--#ifndef SWIG_BUFFER_SIZE
--# define SWIG_BUFFER_SIZE 1024
--#endif
--
--/* Flags for pointer conversions */
--#define SWIG_POINTER_DISOWN        0x1
--#define SWIG_CAST_NEW_MEMORY       0x2
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_OWN           0x1
--
--
--/* 
--   Flags/methods for returning states.
--   
--   The SWIG conversion methods, as ConvertPtr, return an integer 
--   that tells if the conversion was successful or not. And if not,
--   an error code can be returned (see swigerrors.swg for the codes).
--   
--   Use the following macros/flags to set or process the returning
--   states.
--   
--   In old versions of SWIG, code such as the following was usually written:
--
--     if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
--       // success code
--     } else {
--       //fail code
--     }
--
--   Now you can be more explicit:
--
--    int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--    } else {
--      // fail code
--    }
--
--   which is the same really, but now you can also do
--
--    Type *ptr;
--    int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--      if (SWIG_IsNewObj(res) {
--        ...
--      delete *ptr;
--      } else {
--        ...
--      }
--    } else {
--      // fail code
--    }
--    
--   I.e., now SWIG_ConvertPtr can return new objects and you can
--   identify the case and take care of the deallocation. Of course that
--   also requires SWIG_ConvertPtr to return new result values, such as
--
--      int SWIG_ConvertPtr(obj, ptr,...) {         
--        if (<obj is ok>) {                           
--          if (<need new object>) {                   
--            *ptr = <ptr to new allocated object>; 
--            return SWIG_NEWOBJ;                      
--          } else {                                   
--            *ptr = <ptr to old object>;              
--            return SWIG_OLDOBJ;                      
--          }                                  
--        } else {                                     
--          return SWIG_BADOBJ;                
--        }                                            
--      }
--
--   Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
--   more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
--   SWIG errors code.
--
--   Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
--   allows to return the 'cast rank', for example, if you have this
--
--       int food(double)
--       int fooi(int);
--
--   and you call
-- 
--      food(1)   // cast rank '1'  (1 -> 1.0)
--      fooi(1)   // cast rank '0'
--
--   just use the SWIG_AddCast()/SWIG_CheckState()
--*/
--
--#define SWIG_OK                    (0) 
--#define SWIG_ERROR                 (-1)
--#define SWIG_IsOK(r)               (r >= 0)
--#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
--
--/* The CastRankLimit says how many bits are used for the cast rank */
--#define SWIG_CASTRANKLIMIT         (1 << 8)
--/* The NewMask denotes the object was created (using new/malloc) */
--#define SWIG_NEWOBJMASK            (SWIG_CASTRANKLIMIT  << 1)
--/* The TmpMask is for in/out typemaps that use temporal objects */
--#define SWIG_TMPOBJMASK            (SWIG_NEWOBJMASK << 1)
--/* Simple returning values */
--#define SWIG_BADOBJ                (SWIG_ERROR)
--#define SWIG_OLDOBJ                (SWIG_OK)
--#define SWIG_NEWOBJ                (SWIG_OK | SWIG_NEWOBJMASK)
--#define SWIG_TMPOBJ                (SWIG_OK | SWIG_TMPOBJMASK)
--/* Check, add and del mask methods */
--#define SWIG_AddNewMask(r)         (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
--#define SWIG_DelNewMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
--#define SWIG_IsNewObj(r)           (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
--#define SWIG_AddTmpMask(r)         (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
--#define SWIG_DelTmpMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
--#define SWIG_IsTmpObj(r)           (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
--
--/* Cast-Rank Mode */
--#if defined(SWIG_CASTRANK_MODE)
--#  ifndef SWIG_TypeRank
--#    define SWIG_TypeRank             unsigned long
--#  endif
--#  ifndef SWIG_MAXCASTRANK            /* Default cast allowed */
--#    define SWIG_MAXCASTRANK          (2)
--#  endif
--#  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
--#  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
--SWIGINTERNINLINE int SWIG_AddCast(int r) { 
--  return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
--}
--SWIGINTERNINLINE int SWIG_CheckState(int r) { 
--  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
--}
--#else /* no cast-rank mode */
--#  define SWIG_AddCast(r) (r)
--#  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
--#endif
--
--
--#include <string.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef void *(*swig_converter_func)(void *, int *);
--typedef struct swig_type_info *(*swig_dycast_func)(void **);
--
--/* Structure to store information on one type */
--typedef struct swig_type_info {
--  const char             *name;                       /* mangled name of this type */
--  const char             *str;                        /* human readable name of this type */
--  swig_dycast_func        dcast;              /* dynamic cast function down a hierarchy */
--  struct swig_cast_info  *cast;                       /* linked list of types that can cast into this type */
--  void                   *clientdata;         /* language specific type data */
--  int                    owndata;             /* flag if the structure owns the clientdata */
--} swig_type_info;
--
--/* Structure to store a type and conversion function used for casting */
--typedef struct swig_cast_info {
--  swig_type_info         *type;                       /* pointer to type that is equivalent to this type */
--  swig_converter_func     converter;          /* function to cast the void pointers */
--  struct swig_cast_info  *next;                       /* pointer to next cast in linked list */
--  struct swig_cast_info  *prev;                       /* pointer to the previous cast */
--} swig_cast_info;
--
--/* Structure used to store module information
-- * Each module generates one structure like this, and the runtime collects
-- * all of these structures and stores them in a circularly linked list.*/
--typedef struct swig_module_info {
--  swig_type_info         **types;             /* Array of pointers to swig_type_info structures that are in this module */
--  size_t                 size;                        /* Number of types in this module */
--  struct swig_module_info *next;              /* Pointer to next element in circularly linked list */
--  swig_type_info         **type_initial;      /* Array of initially generated type structures */
--  swig_cast_info         **cast_initial;      /* Array of initially generated casting structures */
--  void                    *clientdata;                /* Language specific module data */
--} swig_module_info;
--
--/* 
--  Compare two type names skipping the space characters, therefore
--  "char*" == "char *" and "Class<int>" == "Class<int >", etc.
--
--  Return 0 when the two name types are equivalent, as in
--  strncmp, but skipping ' '.
--*/
--SWIGRUNTIME int
--SWIG_TypeNameComp(const char *f1, const char *l1,
--                const char *f2, const char *l2) {
--  for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
--    while ((*f1 == ' ') && (f1 != l1)) ++f1;
--    while ((*f2 == ' ') && (f2 != l2)) ++f2;
--    if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
--  }
--  return (int)((l1 - f1) - (l2 - f2));
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
--*/
--SWIGRUNTIME int
--SWIG_TypeCmp(const char *nb, const char *tb) {
--  int equiv = 1;
--  const char* te = tb + strlen(tb);
--  const char* ne = nb;
--  while (equiv != 0 && *ne) {
--    for (nb = ne; *ne; ++ne) {
--      if (*ne == '|') break;
--    }
--    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
--    if (*ne) ++ne;
--  }
--  return equiv;
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if not equal, 1 if equal
--*/
--SWIGRUNTIME int
--SWIG_TypeEquiv(const char *nb, const char *tb) {
--  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
--}
--
--/*
--  Check the typename
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheck(const char *c, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (strcmp(iter->type->name, c) == 0) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/* 
--  Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (iter->type == from) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/*
--  Cast a pointer up an inheritance hierarchy
--*/
--SWIGRUNTIMEINLINE void *
--SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
--  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
--}
--
--/* 
--   Dynamic pointer casting. Down an inheritance hierarchy
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
--  swig_type_info *lastty = ty;
--  if (!ty || !ty->dcast) return ty;
--  while (ty && (ty->dcast)) {
--    ty = (*ty->dcast)(ptr);
--    if (ty) lastty = ty;
--  }
--  return lastty;
--}
--
--/*
--  Return the name associated with this type
--*/
--SWIGRUNTIMEINLINE const char *
--SWIG_TypeName(const swig_type_info *ty) {
--  return ty->name;
--}
--
--/*
--  Return the pretty name associated with this type,
--  that is an unmangled type name in a form presentable to the user.
--*/
--SWIGRUNTIME const char *
--SWIG_TypePrettyName(const swig_type_info *type) {
--  /* The "str" field contains the equivalent pretty names of the
--     type, separated by vertical-bar characters.  We choose
--     to print the last name, as it is often (?) the most
--     specific. */
--  if (!type) return NULL;
--  if (type->str != NULL) {
--    const char *last_name = type->str;
--    const char *s;
--    for (s = type->str; *s; s++)
--      if (*s == '|') last_name = s+1;
--    return last_name;
--  }
--  else
--    return type->name;
--}
--
--/* 
--   Set the clientdata field for a type
--*/
--SWIGRUNTIME void
--SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
--  swig_cast_info *cast = ti->cast;
--  /* if (ti->clientdata == clientdata) return; */
--  ti->clientdata = clientdata;
--  
--  while (cast) {
--    if (!cast->converter) {
--      swig_type_info *tc = cast->type;
--      if (!tc->clientdata) {
--      SWIG_TypeClientData(tc, clientdata);
--      }
--    }    
--    cast = cast->next;
--  }
--}
--SWIGRUNTIME void
--SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
--  SWIG_TypeClientData(ti, clientdata);
--  ti->owndata = 1;
--}
--  
--/*
--  Search for a swig_type_info structure only by mangled name
--  Search is a O(log #types)
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_MangledTypeQueryModule(swig_module_info *start, 
--                            swig_module_info *end, 
--                          const char *name) {
--  swig_module_info *iter = start;
--  do {
--    if (iter->size) {
--      register size_t l = 0;
--      register size_t r = iter->size - 1;
--      do {
--      /* since l+r >= 0, we can (>> 1) instead (/ 2) */
--      register size_t i = (l + r) >> 1; 
--      const char *iname = iter->types[i]->name;
--      if (iname) {
--        register int compare = strcmp(name, iname);
--        if (compare == 0) {       
--          return iter->types[i];
--        } else if (compare < 0) {
--          if (i) {
--            r = i - 1;
--          } else {
--            break;
--          }
--        } else if (compare > 0) {
--          l = i + 1;
--        }
--      } else {
--        break; /* should never happen */
--      }
--      } while (l <= r);
--    }
--    iter = iter->next;
--  } while (iter != end);
--  return 0;
--}
--
--/*
--  Search for a swig_type_info structure for either a mangled name or a human readable name.
--  It first searches the mangled names of the types, which is a O(log #types)
--  If a type is not found it then searches the human readable names, which is O(#types).
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeQueryModule(swig_module_info *start, 
--                     swig_module_info *end, 
--                   const char *name) {
--  /* STEP 1: Search the name field using binary search */
--  swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
--  if (ret) {
--    return ret;
--  } else {
--    /* STEP 2: If the type hasn't been found, do a complete search
--       of the str field (the human readable name) */
--    swig_module_info *iter = start;
--    do {
--      register size_t i = 0;
--      for (; i < iter->size; ++i) {
--      if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
--        return iter->types[i];
--      }
--      iter = iter->next;
--    } while (iter != end);
--  }
--  
--  /* neither found a match */
--  return 0;
--}
--
--/* 
--   Pack binary data into a string
--*/
--SWIGRUNTIME char *
--SWIG_PackData(char *c, void *ptr, size_t sz) {
--  static const char hex[17] = "0123456789abcdef";
--  register const unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu =  u + sz;
--  for (; u != eu; ++u) {
--    register unsigned char uu = *u;
--    *(c++) = hex[(uu & 0xf0) >> 4];
--    *(c++) = hex[uu & 0xf];
--  }
--  return c;
--}
--
--/* 
--   Unpack binary data from a string
--*/
--SWIGRUNTIME const char *
--SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
--  register unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu = u + sz;
--  for (; u != eu; ++u) {
--    register char d = *(c++);
--    register unsigned char uu;
--    if ((d >= '0') && (d <= '9'))
--      uu = ((d - '0') << 4);
--    else if ((d >= 'a') && (d <= 'f'))
--      uu = ((d - ('a'-10)) << 4);
--    else 
--      return (char *) 0;
--    d = *(c++);
--    if ((d >= '0') && (d <= '9'))
--      uu |= (d - '0');
--    else if ((d >= 'a') && (d <= 'f'))
--      uu |= (d - ('a'-10));
--    else 
--      return (char *) 0;
--    *u = uu;
--  }
--  return c;
--}
--
--/* 
--   Pack 'void *' into a string buffer.
--*/
--SWIGRUNTIME char *
--SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
--  char *r = buff;
--  if ((2*sizeof(void *) + 2) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,&ptr,sizeof(void *));
--  if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
--  strcpy(r,name);
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      *ptr = (void *) 0;
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sizeof(void *));
--}
--
--SWIGRUNTIME char *
--SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
--  char *r = buff;
--  size_t lname = (name ? strlen(name) : 0);
--  if ((2*sz + 2 + lname) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,ptr,sz);
--  if (lname) {
--    strncpy(r,name,lname+1);
--  } else {
--    *r = 0;
--  }
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      memset(ptr,0,sz);
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sz);
--}
--
--#ifdef __cplusplus
--}
--#endif
--
--/*  Errors in SWIG */
--#define  SWIG_UnknownError               -1 
--#define  SWIG_IOError            -2 
--#define  SWIG_RuntimeError       -3 
--#define  SWIG_IndexError         -4 
--#define  SWIG_TypeError          -5 
--#define  SWIG_DivisionByZero     -6 
--#define  SWIG_OverflowError      -7 
--#define  SWIG_SyntaxError        -8 
--#define  SWIG_ValueError         -9 
--#define  SWIG_SystemError        -10
--#define  SWIG_AttributeError     -11
--#define  SWIG_MemoryError        -12 
--#define  SWIG_NullReferenceError   -13
--
--
--
--/* Compatibility macros for Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--
--#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
--#define PyInt_Check(x) PyLong_Check(x)
--#define PyInt_AsLong(x) PyLong_AsLong(x)
--#define PyInt_FromLong(x) PyLong_FromLong(x)
--#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
--#define PyString_Check(name) PyBytes_Check(name)
--#define PyString_FromString(x) PyUnicode_FromString(x)
--#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
--#define PyString_AsString(str) PyBytes_AsString(str)
--#define PyString_Size(str) PyBytes_Size(str)  
--#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
--#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
--#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
--#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
--
--#endif
--
--#ifndef Py_TYPE
--#  define Py_TYPE(op) ((op)->ob_type)
--#endif
--
--/* SWIG APIs for compatibility of both Python 2 & 3 */
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_FromFormat PyUnicode_FromFormat
--#else
--#  define SWIG_Python_str_FromFormat PyString_FromFormat
--#endif
--
--
--/* Warning: This function will allocate a new string in Python 3,
-- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
-- */
--SWIGINTERN char*
--SWIG_Python_str_AsChar(PyObject *str)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  char *cstr;
--  char *newstr;
--  Py_ssize_t len;
--  str = PyUnicode_AsUTF8String(str);
--  PyBytes_AsStringAndSize(str, &cstr, &len);
--  newstr = (char *) malloc(len+1);
--  memcpy(newstr, cstr, len+1);
--  Py_XDECREF(str);
--  return newstr;
--#else
--  return PyString_AsString(str);
--#endif
--}
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
--#else
--#  define SWIG_Python_str_DelForPy3(x) 
--#endif
--
--
--SWIGINTERN PyObject*
--SWIG_Python_str_FromChar(const char *c)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  return PyUnicode_FromString(c); 
--#else
--  return PyString_FromString(c);
--#endif
--}
--
--/* Add PyOS_snprintf for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
--#  define PyOS_snprintf _snprintf
--# else
--#  define PyOS_snprintf snprintf
--# endif
--#endif
--
--/* A crude PyString_FromFormat implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--
--#ifndef SWIG_PYBUFFER_SIZE
--# define SWIG_PYBUFFER_SIZE 1024
--#endif
--
--static PyObject *
--PyString_FromFormat(const char *fmt, ...) {
--  va_list ap;
--  char buf[SWIG_PYBUFFER_SIZE * 2];
--  int res;
--  va_start(ap, fmt);
--  res = vsnprintf(buf, sizeof(buf), fmt, ap);
--  va_end(ap);
--  return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
--}
--#endif
--
--/* Add PyObject_Del for old Pythons */
--#if PY_VERSION_HEX < 0x01060000
--# define PyObject_Del(op) PyMem_DEL((op))
--#endif
--#ifndef PyObject_DEL
--# define PyObject_DEL PyObject_Del
--#endif
--
--/* A crude PyExc_StopIteration exception for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# ifndef PyExc_StopIteration
--#  define PyExc_StopIteration PyExc_RuntimeError
--# endif
--# ifndef PyObject_GenericGetAttr
--#  define PyObject_GenericGetAttr 0
--# endif
--#endif
--
--/* Py_NotImplemented is defined in 2.1 and up. */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef Py_NotImplemented
--#  define Py_NotImplemented PyExc_RuntimeError
--# endif
--#endif
--
--/* A crude PyString_AsStringAndSize implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef PyString_AsStringAndSize
--#  define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
--# endif
--#endif
--
--/* PySequence_Size for old Pythons */
--#if PY_VERSION_HEX < 0x02000000
--# ifndef PySequence_Size
--#  define PySequence_Size PySequence_Length
--# endif
--#endif
--
--/* PyBool_FromLong for old Pythons */
--#if PY_VERSION_HEX < 0x02030000
--static
--PyObject *PyBool_FromLong(long ok)
--{
--  PyObject *result = ok ? Py_True : Py_False;
--  Py_INCREF(result);
--  return result;
--}
--#endif
--
--/* Py_ssize_t for old Pythons */
--/* This code is as recommended by: */
--/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
--#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
--typedef int Py_ssize_t;
--# define PY_SSIZE_T_MAX INT_MAX
--# define PY_SSIZE_T_MIN INT_MIN
--typedef inquiry lenfunc;
--typedef intargfunc ssizeargfunc;
--typedef intintargfunc ssizessizeargfunc;
--typedef intobjargproc ssizeobjargproc;
--typedef intintobjargproc ssizessizeobjargproc;
--typedef getreadbufferproc readbufferproc;
--typedef getwritebufferproc writebufferproc;
--typedef getsegcountproc segcountproc;
--typedef getcharbufferproc charbufferproc;
--static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
--{
--  long result = 0;
--  PyObject *i = PyNumber_Int(x);
--  if (i) {
--    result = PyInt_AsLong(i);
--    Py_DECREF(i);
--  }
--  return result;
--}
--#endif
--
--#if PY_VERSION_HEX < 0x02050000
--#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
--#endif
--
--#if PY_VERSION_HEX < 0x02040000
--#define Py_VISIT(op)                          \
--  do {                                                \
--    if (op) {                                 \
--      int vret = visit((op), arg);            \
--      if (vret)                                       \
--        return vret;                          \
--    }                                         \
--  } while (0)
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef struct {
--  PyTypeObject type;
--  PyNumberMethods as_number;
--  PyMappingMethods as_mapping;
--  PySequenceMethods as_sequence;
--  PyBufferProcs as_buffer;
--  PyObject *name, *slots;
--} PyHeapTypeObject;
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef destructor freefunc;
--#endif
--
--#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
--     (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
--     (PY_MAJOR_VERSION > 3))
--# define SWIGPY_USE_CAPSULE
--# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
--#endif
--
--#if PY_VERSION_HEX < 0x03020000
--#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
--#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
--#endif
--
--/* -----------------------------------------------------------------------------
-- * error manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIME PyObject*
--SWIG_Python_ErrorType(int code) {
--  PyObject* type = 0;
--  switch(code) {
--  case SWIG_MemoryError:
--    type = PyExc_MemoryError;
--    break;
--  case SWIG_IOError:
--    type = PyExc_IOError;
--    break;
--  case SWIG_RuntimeError:
--    type = PyExc_RuntimeError;
--    break;
--  case SWIG_IndexError:
--    type = PyExc_IndexError;
--    break;
--  case SWIG_TypeError:
--    type = PyExc_TypeError;
--    break;
--  case SWIG_DivisionByZero:
--    type = PyExc_ZeroDivisionError;
--    break;
--  case SWIG_OverflowError:
--    type = PyExc_OverflowError;
--    break;
--  case SWIG_SyntaxError:
--    type = PyExc_SyntaxError;
--    break;
--  case SWIG_ValueError:
--    type = PyExc_ValueError;
--    break;
--  case SWIG_SystemError:
--    type = PyExc_SystemError;
--    break;
--  case SWIG_AttributeError:
--    type = PyExc_AttributeError;
--    break;
--  default:
--    type = PyExc_RuntimeError;
--  }
--  return type;
--}
--
--
--SWIGRUNTIME void
--SWIG_Python_AddErrorMsg(const char* mesg)
--{
--  PyObject *type = 0;
--  PyObject *value = 0;
--  PyObject *traceback = 0;
--
--  if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
--  if (value) {
--    char *tmp;
--    PyObject *old_str = PyObject_Str(value);
--    PyErr_Clear();
--    Py_XINCREF(type);
--
--    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(old_str);
--    Py_DECREF(value);
--  } else {
--    PyErr_SetString(PyExc_RuntimeError, mesg);
--  }
--}
--
--#if defined(SWIG_PYTHON_NO_THREADS)
--#  if defined(SWIG_PYTHON_THREADS)
--#    undef SWIG_PYTHON_THREADS
--#  endif
--#endif
--#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
--#  if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
--#    if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
--#      define SWIG_PYTHON_USE_GIL
--#    endif
--#  endif
--#  if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
--#    ifndef SWIG_PYTHON_INITIALIZE_THREADS
--#     define SWIG_PYTHON_INITIALIZE_THREADS  PyEval_InitThreads() 
--#    endif
--#    ifdef __cplusplus /* C++ code */
--       class SWIG_Python_Thread_Block {
--         bool status;
--         PyGILState_STATE state;
--       public:
--         void end() { if (status) { PyGILState_Release(state); status = false;} }
--         SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
--         ~SWIG_Python_Thread_Block() { end(); }
--       };
--       class SWIG_Python_Thread_Allow {
--         bool status;
--         PyThreadState *save;
--       public:
--         void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
--         SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
--         ~SWIG_Python_Thread_Allow() { end(); }
--       };
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   SWIG_Python_Thread_Block _swig_thread_block
--#      define SWIG_PYTHON_THREAD_END_BLOCK     _swig_thread_block.end()
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   SWIG_Python_Thread_Allow _swig_thread_allow
--#      define SWIG_PYTHON_THREAD_END_ALLOW     _swig_thread_allow.end()
--#    else /* C code */
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
--#      define SWIG_PYTHON_THREAD_END_BLOCK     PyGILState_Release(_swig_thread_block)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   PyThreadState *_swig_thread_allow = PyEval_SaveThread()
--#      define SWIG_PYTHON_THREAD_END_ALLOW     PyEval_RestoreThread(_swig_thread_allow)
--#    endif
--#  else /* Old thread way, not implemented, user must provide it */
--#    if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
--#      define SWIG_PYTHON_INITIALIZE_THREADS
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
--#      define SWIG_PYTHON_THREAD_END_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
--#      define SWIG_PYTHON_THREAD_END_ALLOW
--#    endif
--#  endif
--#else /* No thread support */
--#  define SWIG_PYTHON_INITIALIZE_THREADS
--#  define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#  define SWIG_PYTHON_THREAD_END_BLOCK
--#  define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#  define SWIG_PYTHON_THREAD_END_ALLOW
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Python API portion that goes into the runtime
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Constant declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Constant Types */
--#define SWIG_PY_POINTER 4
--#define SWIG_PY_BINARY  5
--
--/* Constant information structure */
--typedef struct swig_const_info {
--  int type;
--  char *name;
--  long lvalue;
--  double dvalue;
--  void   *pvalue;
--  swig_type_info **ptype;
--} swig_const_info;
--
--
--/* -----------------------------------------------------------------------------
-- * Wrapper of PyInstanceMethod_New() used in Python 3
-- * It is exported to the generated module, used for -fastproxy
-- * ----------------------------------------------------------------------------- */
--#if PY_VERSION_HEX >= 0x03000000
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
--{
--  return PyInstanceMethod_New(func);
--}
--#else
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
--{
--  return NULL;
--}
--#endif
--
--#ifdef __cplusplus
--}
--#endif
--
--
--/* -----------------------------------------------------------------------------
-- * pyrun.swg
-- *
-- * This file contains the runtime support for Python modules
-- * and includes code for managing global variables and pointer
-- * type checking.
-- *
-- * ----------------------------------------------------------------------------- */
--
--/* Common SWIG API */
--
--/* for raw pointers */
--#define SWIG_Python_ConvertPtr(obj, pptr, type, flags)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
--#define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Python_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
--
--#ifdef SWIGPYTHON_BUILTIN
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(self, ptr, type, flags)
--#else
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--#endif
--
--#define SWIG_InternalNewPointerObj(ptr, type, flags)  SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--
--#define SWIG_CheckImplicit(ty)                          SWIG_Python_CheckImplicit(ty) 
--#define SWIG_AcquirePtr(ptr, src)                       SWIG_Python_AcquirePtr(ptr, src)
--#define swig_owntype                                    int
--
--/* for raw packed data */
--#define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--/* for class or struct pointers */
--#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_NewInstanceObj(ptr, type, flags)           SWIG_NewPointerObj(ptr, type, flags)
--
--/* for C or C++ function pointers */
--#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
--#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
--
--/* for C++ member pointers, ie, member methods */
--#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--
--/* Runtime API */
--
--#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
--#define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
--#define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
--
--#define SWIG_SetErrorObj                                SWIG_Python_SetErrorObj                            
--#define SWIG_SetErrorMsg                              SWIG_Python_SetErrorMsg                            
--#define SWIG_ErrorType(code)                          SWIG_Python_ErrorType(code)                        
--#define SWIG_Error(code, msg)                         SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) 
--#define SWIG_fail                                     goto fail                                          
--
--
--/* Runtime API implementation */
--
--/* Error manipulation */
--
--SWIGINTERN void 
--SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
--  PyErr_SetObject(errtype, obj);
--  Py_DECREF(obj);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--SWIGINTERN void 
--SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--  PyErr_SetString(errtype, msg);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--#define SWIG_Python_Raise(obj, type, desc)  SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
--
--/* Set a constant value */
--
--#if defined(SWIGPYTHON_BUILTIN)
--
--SWIGINTERN void
--SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
--  PyObject *s = PyString_InternFromString(key);
--  PyList_Append(seq, s);
--  Py_DECREF(s);
--}
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);
--  if (public_interface)
--    SwigPyBuiltin_AddPublicSymbol(public_interface, name);
--}
--
--#else
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);                            
--}
--
--#endif
--
--/* Append a value to the result obj */
--
--SWIGINTERN PyObject*
--SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
--#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyList_Check(result)) {
--      PyObject *o2 = result;
--      result = PyList_New(1);
--      PyList_SetItem(result, 0, o2);
--    }
--    PyList_Append(result,obj);
--    Py_DECREF(obj);
--  }
--  return result;
--#else
--  PyObject*   o2;
--  PyObject*   o3;
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyTuple_Check(result)) {
--      o2 = result;
--      result = PyTuple_New(1);
--      PyTuple_SET_ITEM(result, 0, o2);
--    }
--    o3 = PyTuple_New(1);
--    PyTuple_SET_ITEM(o3, 0, obj);
--    o2 = result;
--    result = PySequence_Concat(o2, o3);
--    Py_DECREF(o2);
--    Py_DECREF(o3);
--  }
--  return result;
--#endif
--}
--
--/* Unpack the argument tuple */
--
--SWIGINTERN int
--SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
--{
--  if (!args) {
--    if (!min && !max) {
--      return 1;
--    } else {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", 
--                 name, (min == max ? "" : "at least "), (int)min);
--      return 0;
--    }
--  }  
--  if (!PyTuple_Check(args)) {
--    if (min <= 1 && max >= 1) {
--      register int i;
--      objs[0] = args;
--      for (i = 1; i < max; ++i) {
--      objs[i] = 0;
--      }
--      return 2;
--    }
--    PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
--    return 0;
--  } else {
--    register Py_ssize_t l = PyTuple_GET_SIZE(args);
--    if (l < min) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at least "), (int)min, (int)l);
--      return 0;
--    } else if (l > max) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at most "), (int)max, (int)l);
--      return 0;
--    } else {
--      register int i;
--      for (i = 0; i < l; ++i) {
--      objs[i] = PyTuple_GET_ITEM(args, i);
--      }
--      for (; l < max; ++l) {
--      objs[l] = 0;
--      }
--      return i + 1;
--    }    
--  }
--}
--
--/* A functor is a function object with one single object argument */
--#if PY_VERSION_HEX >= 0x02020000
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunctionObjArgs(functor, obj, NULL);
--#else
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunction(functor, "O", obj);
--#endif
--
--/*
--  Helper for static pointer initialization for both C and C++ code, for example
--  static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
--*/
--#ifdef __cplusplus
--#define SWIG_STATIC_POINTER(var)  var
--#else
--#define SWIG_STATIC_POINTER(var)  var = 0; if (!var) var
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Pointer declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_NOSHADOW       (SWIG_POINTER_OWN      << 1)
--#define SWIG_POINTER_NEW            (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
--
--#define SWIG_POINTER_IMPLICIT_CONV  (SWIG_POINTER_DISOWN   << 1)
--
--#define SWIG_BUILTIN_TP_INIT      (SWIG_POINTER_OWN << 2)
--#define SWIG_BUILTIN_INIT         (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*  How to access Py_None */
--#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#  ifndef SWIG_PYTHON_NO_BUILD_NONE
--#    ifndef SWIG_PYTHON_BUILD_NONE
--#      define SWIG_PYTHON_BUILD_NONE
--#    endif
--#  endif
--#endif
--
--#ifdef SWIG_PYTHON_BUILD_NONE
--#  ifdef Py_None
--#   undef Py_None
--#   define Py_None SWIG_Py_None()
--#  endif
--SWIGRUNTIMEINLINE PyObject * 
--_SWIG_Py_None(void)
--{
--  PyObject *none = Py_BuildValue((char*)"");
--  Py_DECREF(none);
--  return none;
--}
--SWIGRUNTIME PyObject * 
--SWIG_Py_None(void)
--{
--  static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
--  return none;
--}
--#endif
--
--/* The python void return value */
--
--SWIGRUNTIMEINLINE PyObject * 
--SWIG_Py_Void(void)
--{
--  PyObject *none = Py_None;
--  Py_INCREF(none);
--  return none;
--}
--
--/* SwigPyClientData */
--
--typedef struct {
--  PyObject *klass;
--  PyObject *newraw;
--  PyObject *newargs;
--  PyObject *destroy;
--  int delargs;
--  int implicitconv;
--  PyTypeObject *pytype;
--} SwigPyClientData;
--
--SWIGRUNTIMEINLINE int 
--SWIG_Python_CheckImplicit(swig_type_info *ty)
--{
--  SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
--  return data ? data->implicitconv : 0;
--}
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_ExceptionType(swig_type_info *desc) {
--  SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
--  PyObject *klass = data ? data->klass : 0;
--  return (klass ? klass : PyExc_RuntimeError);
--}
--
--
--SWIGRUNTIME SwigPyClientData * 
--SwigPyClientData_New(PyObject* obj)
--{
--  if (!obj) {
--    return 0;
--  } else {
--    SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
--    /* the klass element */
--    data->klass = obj;
--    Py_INCREF(data->klass);
--    /* the newraw method and newargs arguments used to create a new raw instance */
--    if (PyClass_Check(obj)) {
--      data->newraw = 0;
--      data->newargs = obj;
--      Py_INCREF(obj);
--    } else {
--#if (PY_VERSION_HEX < 0x02020000)
--      data->newraw = 0;
--#else
--      data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
--#endif
--      if (data->newraw) {
--      Py_INCREF(data->newraw);
--      data->newargs = PyTuple_New(1);
--      PyTuple_SetItem(data->newargs, 0, obj);
--      } else {
--      data->newargs = obj;
--      }
--      Py_INCREF(data->newargs);
--    }
--    /* the destroy method, aka as the C++ delete method */
--    data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      data->destroy = 0;
--    }
--    if (data->destroy) {
--      int flags;
--      Py_INCREF(data->destroy);
--      flags = PyCFunction_GET_FLAGS(data->destroy);
--#ifdef METH_O
--      data->delargs = !(flags & (METH_O));
--#else
--      data->delargs = 0;
--#endif
--    } else {
--      data->delargs = 0;
--    }
--    data->implicitconv = 0;
--    data->pytype = 0;
--    return data;
--  }
--}
--
--SWIGRUNTIME void 
--SwigPyClientData_Del(SwigPyClientData *data) {
--  Py_XDECREF(data->newraw);
--  Py_XDECREF(data->newargs);
--  Py_XDECREF(data->destroy);
--}
--
--/* =============== SwigPyObject =====================*/
--
--typedef struct {
--  PyObject_HEAD
--  void *ptr;
--  swig_type_info *ty;
--  int own;
--  PyObject *next;
--#ifdef SWIGPYTHON_BUILTIN
--  PyObject *dict;
--#endif
--} SwigPyObject;
--
--SWIGRUNTIME PyObject *
--SwigPyObject_long(SwigPyObject *v)
--{
--  return PyLong_FromVoidPtr(v->ptr);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_format(const char* fmt, SwigPyObject *v)
--{
--  PyObject *res = NULL;
--  PyObject *args = PyTuple_New(1);
--  if (args) {
--    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
--      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
--      if (ofmt) {
--#if PY_VERSION_HEX >= 0x03000000
--      res = PyUnicode_Format(ofmt,args);
--#else
--      res = PyString_Format(ofmt,args);
--#endif
--      Py_DECREF(ofmt);
--      }
--      Py_DECREF(args);
--    }
--  }
--  return res;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_oct(SwigPyObject *v)
--{
--  return SwigPyObject_format("%o",v);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_hex(SwigPyObject *v)
--{
--  return SwigPyObject_format("%x",v);
--}
--
--SWIGRUNTIME PyObject *
--#ifdef METH_NOARGS
--SwigPyObject_repr(SwigPyObject *v)
--#else
--SwigPyObject_repr(SwigPyObject *v, PyObject *args)
--#endif
--{
--  const char *name = SWIG_TypePrettyName(v->ty);
--  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
--  if (v->next) {
--# ifdef METH_NOARGS
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
--# else
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
--# endif
--# if PY_VERSION_HEX >= 0x03000000
--    PyObject *joined = PyUnicode_Concat(repr, nrep);
--    Py_DecRef(repr);
--    Py_DecRef(nrep);
--    repr = joined;
--# else
--    PyString_ConcatAndDel(&repr,nrep);
--# endif
--  }
--  return repr;  
--}
--
--SWIGRUNTIME int
--SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char *str;
--#ifdef METH_NOARGS
--  PyObject *repr = SwigPyObject_repr(v);
--#else
--  PyObject *repr = SwigPyObject_repr(v, NULL);
--#endif
--  if (repr) {
--    str = SWIG_Python_str_AsChar(repr); 
--    fputs(str, fp);
--    SWIG_Python_str_DelForPy3(str);
--    Py_DECREF(repr);
--    return 0; 
--  } else {
--    return 1; 
--  }
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_str(SwigPyObject *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
--    SWIG_Python_str_FromChar(result) : 0;
--}
--
--SWIGRUNTIME int
--SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
--{
--  void *i = v->ptr;
--  void *j = w->ptr;
--  return (i < j) ? -1 : ((i > j) ? 1 : 0);
--}
--
--/* Added for Python 3.x, would it also be useful for Python 2.x? */
--SWIGRUNTIME PyObject*
--SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
--{
--  PyObject* res;
--  if( op != Py_EQ && op != Py_NE ) {
--    Py_INCREF(Py_NotImplemented);
--    return Py_NotImplemented;
--  }
--  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
--  return res;  
--}
--
--
--SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
--
--#ifdef SWIGPYTHON_BUILTIN
--static swig_type_info *SwigPyObject_stype = 0;
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--    SwigPyClientData *cd;
--    assert(SwigPyObject_stype);
--    cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--    assert(cd);
--    assert(cd->pytype);
--    return cd->pytype;
--}
--#else
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
--  return type;
--}
--#endif
--
--SWIGRUNTIMEINLINE int
--SwigPyObject_Check(PyObject *op) {
--#ifdef SWIGPYTHON_BUILTIN
--  PyTypeObject *target_tp = SwigPyObject_type();
--  if (PyType_IsSubtype(op->ob_type, target_tp))
--    return 1;
--  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
--#else
--  return (Py_TYPE(op) == SwigPyObject_type())
--    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
--#endif
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
--
--SWIGRUNTIME void
--SwigPyObject_dealloc(PyObject *v)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  PyObject *next = sobj->next;
--  if (sobj->own == SWIG_POINTER_OWN) {
--    swig_type_info *ty = sobj->ty;
--    SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--    PyObject *destroy = data ? data->destroy : 0;
--    if (destroy) {
--      /* destroy is always a VARARGS method */
--      PyObject *res;
--      if (data->delargs) {
--      /* we need to create a temporary object to carry the destroy operation */
--      PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
--      res = SWIG_Python_CallFunctor(destroy, tmp);
--      Py_DECREF(tmp);
--      } else {
--      PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
--      PyObject *mself = PyCFunction_GET_SELF(destroy);
--      res = ((*meth)(mself, v));
--      }
--      Py_XDECREF(res);
--    } 
--#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
--    else {
--      const char *name = SWIG_TypePrettyName(ty);
--      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
--    }
--#endif
--  } 
--  Py_XDECREF(next);
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyObject* 
--SwigPyObject_append(PyObject* v, PyObject* next)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--#ifndef METH_O
--  PyObject *tmp = 0;
--  if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
--  next = tmp;
--#endif
--  if (!SwigPyObject_Check(next)) {
--    return NULL;
--  }
--  sobj->next = next;
--  Py_INCREF(next);
--  return SWIG_Py_Void();
--}
--
--SWIGRUNTIME PyObject* 
--#ifdef METH_NOARGS
--SwigPyObject_next(PyObject* v)
--#else
--SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  if (sobj->next) {    
--    Py_INCREF(sobj->next);
--    return sobj->next;
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_disown(PyObject *v)
--#else
--SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = 0;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_acquire(PyObject *v)
--#else
--SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = SWIG_POINTER_OWN;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--SwigPyObject_own(PyObject *v, PyObject *args)
--{
--  PyObject *val = 0;
--#if (PY_VERSION_HEX < 0x02020000)
--  if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
--#elif (PY_VERSION_HEX < 0x02050000)
--  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
--#else
--  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
--#endif
--    {
--      return NULL;
--    } 
--  else
--    {
--      SwigPyObject *sobj = (SwigPyObject *)v;
--      PyObject *obj = PyBool_FromLong(sobj->own);
--      if (val) {
--#ifdef METH_NOARGS
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v);
--      } else {
--        SwigPyObject_disown(v);
--      }
--#else
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v,args);
--      } else {
--        SwigPyObject_disown(v,args);
--      }
--#endif
--      } 
--      return obj;
--    }
--}
--
--#ifdef METH_O
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#else
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#endif
--
--#if PY_VERSION_HEX < 0x02020000
--SWIGINTERN PyObject *
--SwigPyObject_getattr(SwigPyObject *sobj,char *name)
--{
--  return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
--}
--#endif
--
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_TypeOnce(void) {
--  static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
--
--  static PyNumberMethods SwigPyObject_as_number = {
--    (binaryfunc)0, /*nb_add*/
--    (binaryfunc)0, /*nb_subtract*/
--    (binaryfunc)0, /*nb_multiply*/
--    /* nb_divide removed in Python 3 */
--#if PY_VERSION_HEX < 0x03000000
--    (binaryfunc)0, /*nb_divide*/
--#endif
--    (binaryfunc)0, /*nb_remainder*/
--    (binaryfunc)0, /*nb_divmod*/
--    (ternaryfunc)0,/*nb_power*/
--    (unaryfunc)0,  /*nb_negative*/
--    (unaryfunc)0,  /*nb_positive*/
--    (unaryfunc)0,  /*nb_absolute*/
--    (inquiry)0,    /*nb_nonzero*/
--    0,                   /*nb_invert*/
--    0,                   /*nb_lshift*/
--    0,                   /*nb_rshift*/
--    0,                   /*nb_and*/
--    0,                   /*nb_xor*/
--    0,                   /*nb_or*/
--#if PY_VERSION_HEX < 0x03000000
--    0,   /*nb_coerce*/
--#endif
--    (unaryfunc)SwigPyObject_long, /*nb_int*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_long, /*nb_long*/
--#else
--    0, /*nb_reserved*/
--#endif
--    (unaryfunc)0,                 /*nb_float*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
--    (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
--#endif
--#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
--#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
--#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
--#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
--    0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
--#endif
--  };
--
--  static PyTypeObject swigpyobject_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyObject",               /* tp_name */
--      sizeof(SwigPyObject),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyObject_print,        /* tp_print */
--#if PY_VERSION_HEX < 0x02020000
--      (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
--#else
--      (getattrfunc)0,                       /* tp_getattr */
--#endif
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX >= 0x03000000
--    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
--#else
--      (cmpfunc)SwigPyObject_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyObject_repr,          /* tp_repr */
--      &SwigPyObject_as_number,              /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyObject_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigobject_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      swigobject_methods,                   /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpyobject_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpyobject_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpyobject_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpyobject_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
--{
--  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
--  if (sobj) {
--    sobj->ptr  = ptr;
--    sobj->ty   = ty;
--    sobj->own  = own;
--    sobj->next = 0;
--  }
--  return (PyObject *)sobj;
--}
--
--/* -----------------------------------------------------------------------------
-- * Implements a simple Swig Packed type, and use it instead of string
-- * ----------------------------------------------------------------------------- */
--
--typedef struct {
--  PyObject_HEAD
--  void *pack;
--  swig_type_info *ty;
--  size_t size;
--} SwigPyPacked;
--
--SWIGRUNTIME int
--SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char result[SWIG_BUFFER_SIZE];
--  fputs("<Swig Packed ", fp); 
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    fputs("at ", fp); 
--    fputs(result, fp); 
--  }
--  fputs(v->ty->name,fp); 
--  fputs(">", fp);
--  return 0; 
--}
--  
--SWIGRUNTIME PyObject *
--SwigPyPacked_repr(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
--  }  
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_str(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
--    return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromChar(v->ty->name);
--  }  
--}
--
--SWIGRUNTIME int
--SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
--{
--  size_t i = v->size;
--  size_t j = w->size;
--  int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
--  return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
--}
--
--SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
--  return type;
--}
--
--SWIGRUNTIMEINLINE int
--SwigPyPacked_Check(PyObject *op) {
--  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
--    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
--}
--
--SWIGRUNTIME void
--SwigPyPacked_dealloc(PyObject *v)
--{
--  if (SwigPyPacked_Check(v)) {
--    SwigPyPacked *sobj = (SwigPyPacked *) v;
--    free(sobj->pack);
--  }
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_TypeOnce(void) {
--  static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
--  static PyTypeObject swigpypacked_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX>=0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyPacked",               /* tp_name */
--      sizeof(SwigPyPacked),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyPacked_print,        /* tp_print */
--      (getattrfunc)0,                       /* tp_getattr */
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX>=0x03000000
--      0, /* tp_reserved in 3.0.1 */
--#else
--      (cmpfunc)SwigPyPacked_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyPacked_repr,          /* tp_repr */
--      0,                                    /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyPacked_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigpacked_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      0,                                    /* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      0,                                    /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpypacked_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpypacked_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpypacked_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpypacked_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
--{
--  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
--  if (sobj) {
--    void *pack = malloc(size);
--    if (pack) {
--      memcpy(pack, ptr, size);
--      sobj->pack = pack;
--      sobj->ty   = ty;
--      sobj->size = size;
--    } else {
--      PyObject_DEL((PyObject *) sobj);
--      sobj = 0;
--    }
--  }
--  return (PyObject *) sobj;
--}
--
--SWIGRUNTIME swig_type_info *
--SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
--{
--  if (SwigPyPacked_Check(obj)) {
--    SwigPyPacked *sobj = (SwigPyPacked *)obj;
--    if (sobj->size != size) return 0;
--    memcpy(ptr, sobj->pack, size);
--    return sobj->ty;
--  } else {
--    return 0;
--  }
--}
--
--/* -----------------------------------------------------------------------------
-- * pointers/data manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIMEINLINE PyObject *
--_SWIG_This(void)
--{
--    return SWIG_Python_str_FromChar("this");
--}
--
--static PyObject *swig_this = NULL;
--
--SWIGRUNTIME PyObject *
--SWIG_This(void)
--{
--  if (swig_this == NULL)
--    swig_this = _SWIG_This();
--  return swig_this;
--}
--
--/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
--
--/* TODO: I don't know how to implement the fast getset in Python 3 right now */
--#if PY_VERSION_HEX>=0x03000000
--#define SWIG_PYTHON_SLOW_GETSET_THIS 
--#endif
--
--SWIGRUNTIME SwigPyObject *
--SWIG_Python_GetSwigThis(PyObject *pyobj) 
--{
--  PyObject *obj;
--
--  if (SwigPyObject_Check(pyobj))
--    return (SwigPyObject *) pyobj;
--
--#ifdef SWIGPYTHON_BUILTIN
--  (void)obj;
--# ifdef PyWeakref_CheckProxy
--  if (PyWeakref_CheckProxy(pyobj)) {
--    pyobj = PyWeakref_GET_OBJECT(pyobj);
--    if (pyobj && SwigPyObject_Check(pyobj))
--      return (SwigPyObject*) pyobj;
--  }
--# endif
--  return NULL;
--#else
--
--  obj = 0;
--
--#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
--  if (PyInstance_Check(pyobj)) {
--    obj = _PyInstance_Lookup(pyobj, SWIG_This());      
--  } else {
--    PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
--    if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
--    } else {
--#ifdef PyWeakref_CheckProxy
--      if (PyWeakref_CheckProxy(pyobj)) {
--      PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
--      return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
--      }
--#endif
--      obj = PyObject_GetAttr(pyobj,SWIG_This());
--      if (obj) {
--      Py_DECREF(obj);
--      } else {
--      if (PyErr_Occurred()) PyErr_Clear();
--      return 0;
--      }
--    }
--  }
--#else
--  obj = PyObject_GetAttr(pyobj,SWIG_This());
--  if (obj) {
--    Py_DECREF(obj);
--  } else {
--    if (PyErr_Occurred()) PyErr_Clear();
--    return 0;
--  }
--#endif
--  if (obj && !SwigPyObject_Check(obj)) {
--    /* a PyObject is called 'this', try to get the 'real this'
--       SwigPyObject from it */ 
--    return SWIG_Python_GetSwigThis(obj);
--  }
--  return (SwigPyObject *)obj;
--#endif
--}
--
--/* Acquire a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_AcquirePtr(PyObject *obj, int own) {
--  if (own == SWIG_POINTER_OWN) {
--    SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
--    if (sobj) {
--      int oldown = sobj->own;
--      sobj->own = own;
--      return oldown;
--    }
--  }
--  return 0;
--}
--
--/* Convert a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
--  int res;
--  SwigPyObject *sobj;
--
--  if (!obj)
--    return SWIG_ERROR;
--  if (obj == Py_None) {
--    if (ptr)
--      *ptr = 0;
--    return SWIG_OK;
--  }
--
--  res = SWIG_ERROR;
--
--  sobj = SWIG_Python_GetSwigThis(obj);
--  if (own)
--    *own = 0;
--  while (sobj) {
--    void *vptr = sobj->ptr;
--    if (ty) {
--      swig_type_info *to = sobj->ty;
--      if (to == ty) {
--        /* no type cast needed */
--        if (ptr) *ptr = vptr;
--        break;
--      } else {
--        swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--        if (!tc) {
--          sobj = (SwigPyObject *)sobj->next;
--        } else {
--          if (ptr) {
--            int newmemory = 0;
--            *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--            if (newmemory == SWIG_CAST_NEW_MEMORY) {
--              assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
--              if (own)
--                *own = *own | SWIG_CAST_NEW_MEMORY;
--            }
--          }
--          break;
--        }
--      }
--    } else {
--      if (ptr) *ptr = vptr;
--      break;
--    }
--  }
--  if (sobj) {
--    if (own)
--      *own = *own | sobj->own;
--    if (flags & SWIG_POINTER_DISOWN) {
--      sobj->own = 0;
--    }
--    res = SWIG_OK;
--  } else {
--    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
--      SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--      if (data && !data->implicitconv) {
--        PyObject *klass = data->klass;
--        if (klass) {
--          PyObject *impconv;
--          data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
--          impconv = SWIG_Python_CallFunctor(klass, obj);
--          data->implicitconv = 0;
--          if (PyErr_Occurred()) {
--            PyErr_Clear();
--            impconv = 0;
--          }
--          if (impconv) {
--            SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
--            if (iobj) {
--              void *vptr;
--              res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
--              if (SWIG_IsOK(res)) {
--                if (ptr) {
--                  *ptr = vptr;
--                  /* transfer the ownership to 'ptr' */
--                  iobj->own = 0;
--                  res = SWIG_AddCast(res);
--                  res = SWIG_AddNewMask(res);
--                } else {
--                  res = SWIG_AddCast(res);                
--                }
--              }
--            }
--            Py_DECREF(impconv);
--          }
--        }
--      }
--    }
--  }
--  return res;
--}
--
--/* Convert a function ptr value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
--  if (!PyCFunction_Check(obj)) {
--    return SWIG_ConvertPtr(obj, ptr, ty, 0);
--  } else {
--    void *vptr = 0;
--    
--    /* here we get the method pointer for callbacks */
--    const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
--    const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
--    if (desc)
--      desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
--    if (!desc) 
--      return SWIG_ERROR;
--    if (ty) {
--      swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
--      if (tc) {
--        int newmemory = 0;
--        *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--        assert(!newmemory); /* newmemory handling not yet implemented */
--      } else {
--        return SWIG_ERROR;
--      }
--    } else {
--      *ptr = vptr;
--    }
--    return SWIG_OK;
--  }
--}
--
--/* Convert a packed value value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
--  swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
--  if (!to) return SWIG_ERROR;
--  if (ty) {
--    if (to != ty) {
--      /* check type cast? */
--      swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--      if (!tc) return SWIG_ERROR;
--    }
--  }
--  return SWIG_OK;
--}  
--
--/* -----------------------------------------------------------------------------
-- * Create a new pointer object
-- * ----------------------------------------------------------------------------- */
--
--/*
--  Create a new instance object, without calling __init__, and set the
--  'this' attribute.
--*/
--
--SWIGRUNTIME PyObject* 
--SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
--{
--#if (PY_VERSION_HEX >= 0x02020000)
--  PyObject *inst = 0;
--  PyObject *newraw = data->newraw;
--  if (newraw) {
--    inst = PyObject_Call(newraw, data->newargs, NULL);
--    if (inst) {
--#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
--      PyObject **dictptr = _PyObject_GetDictPtr(inst);
--      if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      if (dict == NULL) {
--        dict = PyDict_New();
--        *dictptr = dict;
--        PyDict_SetItem(dict, SWIG_This(), swig_this);
--      }
--      }
--#else
--      PyObject *key = SWIG_This();
--      PyObject_SetAttr(inst, key, swig_this);
--#endif
--    }
--  } else {
--#if PY_VERSION_HEX >= 0x03000000
--    inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
--    if (inst) {
--      PyObject_SetAttr(inst, SWIG_This(), swig_this);
--      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
--    }
--#else
--    PyObject *dict = PyDict_New();
--    if (dict) {
--      PyDict_SetItem(dict, SWIG_This(), swig_this);
--      inst = PyInstance_NewRaw(data->newargs, dict);
--      Py_DECREF(dict);
--    }
--#endif
--  }
--  return inst;
--#else
--#if (PY_VERSION_HEX >= 0x02010000)
--  PyObject *inst = 0;
--  PyObject *dict = PyDict_New();
--  if (dict) {
--    PyDict_SetItem(dict, SWIG_This(), swig_this);
--    inst = PyInstance_NewRaw(data->newargs, dict);
--    Py_DECREF(dict);
--  }
--  return (PyObject *) inst;
--#else
--  PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
--  if (inst == NULL) {
--    return NULL;
--  }
--  inst->in_class = (PyClassObject *)data->newargs;
--  Py_INCREF(inst->in_class);
--  inst->in_dict = PyDict_New();
--  if (inst->in_dict == NULL) {
--    Py_DECREF(inst);
--    return NULL;
--  }
--#ifdef Py_TPFLAGS_HAVE_WEAKREFS
--  inst->in_weakreflist = NULL;
--#endif
--#ifdef Py_TPFLAGS_GC
--  PyObject_GC_Init(inst);
--#endif
--  PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
--  return (PyObject *) inst;
--#endif
--#endif
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
--{
-- PyObject *dict;
--#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
-- PyObject **dictptr = _PyObject_GetDictPtr(inst);
-- if (dictptr != NULL) {
--   dict = *dictptr;
--   if (dict == NULL) {
--     dict = PyDict_New();
--     *dictptr = dict;
--   }
--   PyDict_SetItem(dict, SWIG_This(), swig_this);
--   return;
-- }
--#endif
-- dict = PyObject_GetAttrString(inst, (char*)"__dict__");
-- PyDict_SetItem(dict, SWIG_This(), swig_this);
-- Py_DECREF(dict);
--} 
--
--
--SWIGINTERN PyObject *
--SWIG_Python_InitShadowInstance(PyObject *args) {
--  PyObject *obj[2];
--  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
--    return NULL;
--  } else {
--    SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
--    if (sthis) {
--      SwigPyObject_append((PyObject*) sthis, obj[1]);
--    } else {
--      SWIG_Python_SetSwigThis(obj[0], obj[1]);
--    }
--    return SWIG_Py_Void();
--  }
--}
--
--/* Create a new pointer object */
--
--SWIGRUNTIME PyObject *
--SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
--  SwigPyClientData *clientdata;
--  PyObject * robj;
--  int own;
--
--  if (!ptr)
--    return SWIG_Py_Void();
--
--  clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
--  own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
--  if (clientdata && clientdata->pytype) {
--    SwigPyObject *newobj;
--    if (flags & SWIG_BUILTIN_TP_INIT) {
--      newobj = (SwigPyObject*) self;
--      if (newobj->ptr) {
--        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
--        while (newobj->next)
--        newobj = (SwigPyObject *) newobj->next;
--        newobj->next = next_self;
--        newobj = (SwigPyObject *)next_self;
--      }
--    } else {
--      newobj = PyObject_New(SwigPyObject, clientdata->pytype);
--    }
--    if (newobj) {
--      newobj->ptr = ptr;
--      newobj->ty = type;
--      newobj->own = own;
--      newobj->next = 0;
--#ifdef SWIGPYTHON_BUILTIN
--      newobj->dict = 0;
--#endif
--      return (PyObject*) newobj;
--    }
--    return SWIG_Py_Void();
--  }
--
--  assert(!(flags & SWIG_BUILTIN_TP_INIT));
--
--  robj = SwigPyObject_New(ptr, type, own);
--  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
--    PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
--    Py_DECREF(robj);
--    robj = inst;
--  }
--  return robj;
--}
--
--/* Create a new packed object */
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
--  return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
--}
--
--/* -----------------------------------------------------------------------------*
-- *  Get type list 
-- * -----------------------------------------------------------------------------*/
--
--#ifdef SWIG_LINK_RUNTIME
--void *SWIG_ReturnGlobalTypeList(void *);
--#endif
--
--SWIGRUNTIME swig_module_info *
--SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
--  static void *type_pointer = (void *)0;
--  /* first check if module already created */
--  if (!type_pointer) {
--#ifdef SWIG_LINK_RUNTIME
--    type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
--#else
--# ifdef SWIGPY_USE_CAPSULE
--    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
--# else
--    type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
--                                  (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
--# endif
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      type_pointer = (void *)0;
--    }
--#endif
--  }
--  return (swig_module_info *) type_pointer;
--}
--
--#if PY_MAJOR_VERSION < 2
--/* PyModule_AddObject function was introduced in Python 2.0.  The following function
--   is copied out of Python/modsupport.c in python version 2.3.4 */
--SWIGINTERN int
--PyModule_AddObject(PyObject *m, char *name, PyObject *o)
--{
--  PyObject *dict;
--  if (!PyModule_Check(m)) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs module as first arg");
--    return SWIG_ERROR;
--  }
--  if (!o) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs non-NULL value");
--    return SWIG_ERROR;
--  }
--  
--  dict = PyModule_GetDict(m);
--  if (dict == NULL) {
--    /* Internal error -- modules must have a dict! */
--    PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
--               PyModule_GetName(m));
--    return SWIG_ERROR;
--  }
--  if (PyDict_SetItemString(dict, name, o))
--    return SWIG_ERROR;
--  Py_DECREF(o);
--  return SWIG_OK;
--}
--#endif
--
--SWIGRUNTIME void
--#ifdef SWIGPY_USE_CAPSULE
--SWIG_Python_DestroyModule(PyObject *obj)
--#else
--SWIG_Python_DestroyModule(void *vptr)
--#endif
--{
--#ifdef SWIGPY_USE_CAPSULE
--  swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
--#else
--  swig_module_info *swig_module = (swig_module_info *) vptr;
--#endif
--  swig_type_info **types = swig_module->types;
--  size_t i;
--  for (i =0; i < swig_module->size; ++i) {
--    swig_type_info *ty = types[i];
--    if (ty->owndata) {
--      SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
--      if (data) SwigPyClientData_Del(data);
--    }
--  }
--  Py_DECREF(SWIG_This());
--  swig_this = NULL;
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetModule(swig_module_info *swig_module) {
--#if PY_VERSION_HEX >= 0x03000000
-- /* Add a dummy module object into sys.modules */
--  PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
--#else
--  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
--  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
--#endif
--#ifdef SWIGPY_USE_CAPSULE
--  PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#else
--  PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#endif
--}
--
--/* The python cached type query */
--SWIGRUNTIME PyObject *
--SWIG_Python_TypeCache(void) {
--  static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
--  return cache;
--}
--
--SWIGRUNTIME swig_type_info *
--SWIG_Python_TypeQuery(const char *type)
--{
--  PyObject *cache = SWIG_Python_TypeCache();
--  PyObject *key = SWIG_Python_str_FromChar(type); 
--  PyObject *obj = PyDict_GetItem(cache, key);
--  swig_type_info *descriptor;
--  if (obj) {
--#ifdef SWIGPY_USE_CAPSULE
--    descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
--#else
--    descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
--#endif
--  } else {
--    swig_module_info *swig_module = SWIG_GetModule(0);
--    descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
--    if (descriptor) {
--#ifdef SWIGPY_USE_CAPSULE
--      obj = PyCapsule_New((void*) descriptor, NULL, NULL);
--#else
--      obj = PyCObject_FromVoidPtr(descriptor, NULL);
--#endif
--      PyDict_SetItem(cache, key, obj);
--      Py_DECREF(obj);
--    }
--  }
--  Py_DECREF(key);
--  return descriptor;
--}
--
--/* 
--   For backward compatibility only
--*/
--#define SWIG_POINTER_EXCEPTION  0
--#define SWIG_arg_fail(arg)      SWIG_Python_ArgFail(arg)
--#define SWIG_MustGetPtr(p, type, argnum, flags)  SWIG_Python_MustGetPtr(p, type, argnum, flags)
--
--SWIGRUNTIME int
--SWIG_Python_AddErrMesg(const char* mesg, int infront)
--{  
--  if (PyErr_Occurred()) {
--    PyObject *type = 0;
--    PyObject *value = 0;
--    PyObject *traceback = 0;
--    PyErr_Fetch(&type, &value, &traceback);
--    if (value) {
--      char *tmp;
--      PyObject *old_str = PyObject_Str(value);
--      Py_XINCREF(type);
--      PyErr_Clear();
--      if (infront) {
--      PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
--      } else {
--      PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--      }
--      SWIG_Python_str_DelForPy3(tmp);
--      Py_DECREF(old_str);
--    }
--    return 1;
--  } else {
--    return 0;
--  }
--}
--  
--SWIGRUNTIME int
--SWIG_Python_ArgFail(int argnum)
--{
--  if (PyErr_Occurred()) {
--    /* add information about failing argument */
--    char mesg[256];
--    PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
--    return SWIG_Python_AddErrMesg(mesg, 1);
--  } else {
--    return 0;
--  }
--}
--
--SWIGRUNTIMEINLINE const char *
--SwigPyObject_GetDesc(PyObject *self)
--{
--  SwigPyObject *v = (SwigPyObject *)self;
--  swig_type_info *ty = v ? v->ty : 0;
--  return ty ? ty->str : "";
--}
--
--SWIGRUNTIME void
--SWIG_Python_TypeError(const char *type, PyObject *obj)
--{
--  if (type) {
--#if defined(SWIG_COBJECT_TYPES)
--    if (obj && SwigPyObject_Check(obj)) {
--      const char *otype = (const char *) SwigPyObject_GetDesc(obj);
--      if (otype) {
--      PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
--                   type, otype);
--      return;
--      }
--    } else 
--#endif      
--    {
--      const char *otype = (obj ? obj->ob_type->tp_name : 0); 
--      if (otype) {
--      PyObject *str = PyObject_Str(obj);
--      const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
--      if (cstr) {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
--                     type, otype, cstr);
--          SWIG_Python_str_DelForPy3(cstr);
--      } else {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
--                     type, otype);
--      }
--      Py_XDECREF(str);
--      return;
--      }
--    }   
--    PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
--  } else {
--    PyErr_Format(PyExc_TypeError, "unexpected type is received");
--  }
--}
--
--
--/* Convert a pointer value, signal an exception on a type mismatch */
--SWIGRUNTIME void *
--SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
--  void *result;
--  if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
--    PyErr_Clear();
--#if SWIG_POINTER_EXCEPTION
--    if (flags) {
--      SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
--      SWIG_Python_ArgFail(argnum);
--    }
--#endif
--  }
--  return result;
--}
--
--#ifdef SWIGPYTHON_BUILTIN
--SWIGRUNTIME int
--SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
--  PyTypeObject *tp = obj->ob_type;
--  PyObject *descr;
--  PyObject *encoded_name;
--  descrsetfunc f;
--  int res;
--
--# ifdef Py_USING_UNICODE
--  if (PyString_Check(name)) {
--    name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
--    if (!name)
--      return -1;
--  } else if (!PyUnicode_Check(name))
--# else
--  if (!PyString_Check(name))
--# endif
--  {
--    PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
--    return -1;
--  } else {
--    Py_INCREF(name);
--  }
--
--  if (!tp->tp_dict) {
--    if (PyType_Ready(tp) < 0)
--      goto done;
--  }
--
--  res = -1;
--  descr = _PyType_Lookup(tp, name);
--  f = NULL;
--  if (descr != NULL)
--    f = descr->ob_type->tp_descr_set;
--  if (!f) {
--    if (PyString_Check(name)) {
--      encoded_name = name;
--      Py_INCREF(name);
--    } else {
--      encoded_name = PyUnicode_AsUTF8String(name);
--    }
--    PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
--    Py_DECREF(encoded_name);
--  } else {
--    res = f(descr, obj, value);
--  }
--  
--  done:
--  Py_DECREF(name);
--  return res;
--}
--#endif
--
--
--#ifdef __cplusplus
--}
--#endif
--
--
--
--#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
--
--#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else 
--
--
--
--/* -------- TYPES TABLE (BEGIN) -------- */
--
--#define SWIGTYPE_p_char swig_types[0]
--#define SWIGTYPE_p_std__exception swig_types[1]
--#define SWIGTYPE_p_std__ostream swig_types[2]
--#define SWIGTYPE_p_vips__VError swig_types[3]
--static swig_type_info *swig_types[5];
--static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0};
--#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
--#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
--
--/* -------- TYPES TABLE (END) -------- */
--
--#if (PY_VERSION_HEX <= 0x02000000)
--# if !defined(SWIG_PYTHON_CLASSIC)
--#  error "This python version requires swig to be run with the '-classic' option"
--# endif
--#endif
--
--/*-----------------------------------------------
--              @(target):= verrormodule.so
--  ------------------------------------------------*/
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_init    PyInit_verrormodule
--
--#else
--#  define SWIG_init    initverrormodule
--
--#endif
--#define SWIG_name    "verrormodule"
--
--#define SWIGVERSION 0x020010 
--#define SWIG_VERSION SWIGVERSION
--
--
--#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) 
--#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) 
--
--
--#include <stdexcept>
--
--
--namespace swig {
--  class SwigPtr_PyObject {
--  protected:
--    PyObject *_obj;
--
--  public:
--    SwigPtr_PyObject() :_obj(0)
--    {
--    }
--
--    SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
--    {
--      Py_XINCREF(_obj);      
--    }
--    
--    SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
--    {
--      if (initial_ref) {
--        Py_XINCREF(_obj);
--      }
--    }
--    
--    SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) 
--    {
--      Py_XINCREF(item._obj);
--      Py_XDECREF(_obj);
--      _obj = item._obj;
--      return *this;      
--    }
--    
--    ~SwigPtr_PyObject() 
--    {
--      Py_XDECREF(_obj);
--    }
--    
--    operator PyObject *() const
--    {
--      return _obj;
--    }
--
--    PyObject *operator->() const
--    {
--      return _obj;
--    }
--  };
--}
--
--
--namespace swig {
--  struct SwigVar_PyObject : SwigPtr_PyObject {
--    SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
--    
--    SwigVar_PyObject & operator = (PyObject* obj)
--    {
--      Py_XDECREF(_obj);
--      _obj = obj;
--      return *this;      
--    }
--  };
--}
--
--
--#include <vips/vipscpp.h>
--
--
--#include <stdexcept>
--
--
--#include <string>
--
--
--SWIGINTERN swig_type_info*
--SWIG_pchar_descriptor(void)
--{
--  static int init = 0;
--  static swig_type_info* info = 0;
--  if (!init) {
--    info = SWIG_TypeQuery("_p_char");
--    init = 1;
--  }
--  return info;
--}
--
--
--SWIGINTERN int
--SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
--{
--#if PY_VERSION_HEX>=0x03000000
--  if (PyUnicode_Check(obj))
--#else  
--  if (PyString_Check(obj))
--#endif
--  {
--    char *cstr; Py_ssize_t len;
--#if PY_VERSION_HEX>=0x03000000
--    if (!alloc && cptr) {
--        /* We can't allow converting without allocation, since the internal
--           representation of string in Python 3 is UCS-2/UCS-4 but we require
--           a UTF-8 representation.
--           TODO(bhy) More detailed explanation */
--        return SWIG_RuntimeError;
--    }
--    obj = PyUnicode_AsUTF8String(obj);
--    PyBytes_AsStringAndSize(obj, &cstr, &len);
--    if(alloc) *alloc = SWIG_NEWOBJ;
--#else
--    PyString_AsStringAndSize(obj, &cstr, &len);
--#endif
--    if (cptr) {
--      if (alloc) {
--      /* 
--         In python the user should not be able to modify the inner
--         string representation. To warranty that, if you define
--         SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
--         buffer is always returned.
--
--         The default behavior is just to return the pointer value,
--         so, be careful.
--      */ 
--#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
--      if (*alloc != SWIG_OLDOBJ) 
--#else
--      if (*alloc == SWIG_NEWOBJ) 
--#endif
--        {
--          *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
--          *alloc = SWIG_NEWOBJ;
--        }
--      else {
--        *cptr = cstr;
--        *alloc = SWIG_OLDOBJ;
--      }
--      } else {
--        #if PY_VERSION_HEX>=0x03000000
--        assert(0); /* Should never reach here in Python 3 */
--        #endif
--      *cptr = SWIG_Python_str_AsChar(obj);
--      }
--    }
--    if (psize) *psize = len + 1;
--#if PY_VERSION_HEX>=0x03000000
--    Py_XDECREF(obj);
--#endif
--    return SWIG_OK;
--  } else {
--    swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--    if (pchar_descriptor) {
--      void* vptr = 0;
--      if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
--      if (cptr) *cptr = (char *) vptr;
--      if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
--      if (alloc) *alloc = SWIG_OLDOBJ;
--      return SWIG_OK;
--      }
--    }
--  }
--  return SWIG_TypeError;
--}
--
--
--SWIGINTERN int
--SWIG_AsPtr_std_string (PyObject * obj, std::string **val) 
--{
--  char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
--  if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
--    if (buf) {
--      if (val) *val = new std::string(buf, size - 1);
--      if (alloc == SWIG_NEWOBJ) delete[] buf;
--      return SWIG_NEWOBJ;
--    } else {
--      if (val) *val = 0;
--      return SWIG_OLDOBJ;
--    }
--  } else {
--    static int init = 0;
--    static swig_type_info* descriptor = 0;
--    if (!init) {
--      descriptor = SWIG_TypeQuery("std::string" " *");
--      init = 1;
--    }
--    if (descriptor) {
--      std::string *vptr;
--      int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
--      if (SWIG_IsOK(res) && val) *val = vptr;
--      return res;
--    }
--  }
--  return SWIG_ERROR;
--}
--
--
--
--
--
--#include <limits.h>
--#if !defined(SWIG_NO_LLONG_MAX)
--# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
--#   define LLONG_MAX __LONG_LONG_MAX__
--#   define LLONG_MIN (-LLONG_MAX - 1LL)
--#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
--# endif
--#endif
--
--
--SWIGINTERN int
--SWIG_AsVal_double (PyObject *obj, double *val)
--{
--  int res = SWIG_TypeError;
--  if (PyFloat_Check(obj)) {
--    if (val) *val = PyFloat_AsDouble(obj);
--    return SWIG_OK;
--  } else if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    double v = PyLong_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    double d = PyFloat_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = d;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      long v = PyLong_AsLong(obj);
--      if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
--      } else {
--      PyErr_Clear();
--      }
--    }
--  }
--#endif
--  return res;
--}
--
--
--#include <float.h>
--
--
--#include <math.h>
--
--
--SWIGINTERNINLINE int
--SWIG_CanCastAsInteger(double *d, double min, double max) {
--  double x = *d;
--  if ((min <= x && x <= max)) {
--   double fx = floor(x);
--   double cx = ceil(x);
--   double rd =  ((x - fx) < 0.5) ? fx : cx; /* simple rint */
--   if ((errno == EDOM) || (errno == ERANGE)) {
--     errno = 0;
--   } else {
--     double summ, reps, diff;
--     if (rd < x) {
--       diff = x - rd;
--     } else if (rd > x) {
--       diff = rd - x;
--     } else {
--       return 1;
--     }
--     summ = rd + x;
--     reps = diff/summ;
--     if (reps < 8*DBL_EPSILON) {
--       *d = rd;
--       return 1;
--     }
--   }
--  }
--  return 0;
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_long (PyObject *obj, long* val)
--{
--  if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    long v = PyLong_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    long v = PyInt_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      double d;
--      int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
--      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
--      if (val) *val = (long)(d);
--      return res;
--      }
--    }
--  }
--#endif
--  return SWIG_TypeError;
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_int (PyObject * obj, int *val)
--{
--  long v;
--  int res = SWIG_AsVal_long (obj, &v);
--  if (SWIG_IsOK(res)) {
--    if ((v < INT_MIN || v > INT_MAX)) {
--      return SWIG_OverflowError;
--    } else {
--      if (val) *val = static_cast< int >(v);
--    }
--  }  
--  return res;
--}
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_FromCharPtrAndSize(const char* carray, size_t size)
--{
--  if (carray) {
--    if (size > INT_MAX) {
--      swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--      return pchar_descriptor ? 
--      SWIG_InternalNewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
--    } else {
--#if PY_VERSION_HEX >= 0x03000000
--      return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
--#else
--      return PyString_FromStringAndSize(carray, static_cast< int >(size));
--#endif
--    }
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--
--SWIGINTERNINLINE PyObject * 
--SWIG_FromCharPtr(const char *cptr)
--{ 
--  return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
--}
--
--SWIGINTERN char const *vips_VError___str__(vips::VError *self){
--                return self->what ();
--        }
--#ifdef __cplusplus
--extern "C" {
--#endif
--SWIGINTERN PyObject *_wrap_new_VError__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::string arg1 ;
--  PyObject * obj0 = 0 ;
--  vips::VError *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VError",&obj0)) SWIG_fail;
--  {
--    std::string *ptr = (std::string *)0;
--    int res = SWIG_AsPtr_std_string(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_VError" "', argument " "1"" of type '" "std::string""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  result = (vips::VError *)new vips::VError(arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VError, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VError__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VError")) SWIG_fail;
--  result = (vips::VError *)new vips::VError();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VError, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VError(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[2];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VError__SWIG_1(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VError__SWIG_0(self, args);
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VError'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VError::VError(std::string)\n"
--    "    vips::VError::VError()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VError",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VError" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_perror__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VError_perror",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_perror" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VError_perror" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  (arg1)->perror((char const *)arg2);
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_perror__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VError_perror",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_perror" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  (arg1)->perror();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_perror(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 1) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VError, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_VError_perror__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VError, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VError_perror__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VError_perror'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VError::perror(char const *)\n"
--    "    vips::VError::perror()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_app__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  std::string arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VError *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VError_app",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_app" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  {
--    std::string *ptr = (std::string *)0;
--    int res = SWIG_AsPtr_std_string(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VError_app" "', argument " "2"" of type '" "std::string""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  result = (vips::VError *) &(arg1)->app(arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VError, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_app__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VError *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VError_app",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_app" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VError_app" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  result = (vips::VError *) &(arg1)->app(arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VError, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_app(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VError, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VError_app__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VError, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VError_app__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VError_app'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VError::app(std::string)\n"
--    "    vips::VError::app(int const)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_what(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VError_what",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_what" "', argument " "1"" of type '" "vips::VError const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  result = (char *)((vips::VError const *)arg1)->what();
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError_ostream_print(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  std::ostream *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VError_ostream_print",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError_ostream_print" "', argument " "1"" of type '" "vips::VError const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__ostream,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VError_ostream_print" "', argument " "2"" of type '" "std::ostream &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VError_ostream_print" "', argument " "2"" of type '" "std::ostream &""'"); 
--  }
--  arg2 = reinterpret_cast< std::ostream * >(argp2);
--  ((vips::VError const *)arg1)->ostream_print(*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VError___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VError *arg1 = (vips::VError *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VError___str__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VError, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VError___str__" "', argument " "1"" of type '" "vips::VError *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VError * >(argp1);
--  result = (char *)vips_VError___str__(arg1);
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VError, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap___lshift__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::ostream *arg1 = 0 ;
--  vips::VError *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::ostream *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:__lshift__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__ostream,  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "__lshift__" "', argument " "1"" of type '" "std::ostream &""'"); 
--  }
--  if (!argp1) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "__lshift__" "', argument " "1"" of type '" "std::ostream &""'"); 
--  }
--  arg1 = reinterpret_cast< std::ostream * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VError,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "__lshift__" "', argument " "2"" of type '" "vips::VError const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "__lshift__" "', argument " "2"" of type '" "vips::VError const &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VError * >(argp2);
--  result = (std::ostream *) &vips::operator <<(*arg1,(vips::VError const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__ostream, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_verror__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::string arg1 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:verror",&obj0)) SWIG_fail;
--  {
--    std::string *ptr = (std::string *)0;
--    int res = SWIG_AsPtr_std_string(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "verror" "', argument " "1"" of type '" "std::string""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    vips::verror(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_verror__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  
--  if (!PyArg_ParseTuple(args,(char *)":verror")) SWIG_fail;
--  try {
--    vips::verror();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_verror(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[2];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_verror__SWIG_1(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_verror__SWIG_0(self, args);
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'verror'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::verror(std::string)\n"
--    "    vips::verror()\n");
--  return 0;
--}
--
--
--static PyMethodDef SwigMethods[] = {
--       { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
--       { (char *)"new_VError", _wrap_new_VError, METH_VARARGS, NULL},
--       { (char *)"delete_VError", _wrap_delete_VError, METH_VARARGS, NULL},
--       { (char *)"VError_perror", _wrap_VError_perror, METH_VARARGS, NULL},
--       { (char *)"VError_app", _wrap_VError_app, METH_VARARGS, NULL},
--       { (char *)"VError_what", _wrap_VError_what, METH_VARARGS, NULL},
--       { (char *)"VError_ostream_print", _wrap_VError_ostream_print, METH_VARARGS, NULL},
--       { (char *)"VError___str__", _wrap_VError___str__, METH_VARARGS, NULL},
--       { (char *)"VError_swigregister", VError_swigregister, METH_VARARGS, NULL},
--       { (char *)"__lshift__", _wrap___lshift__, METH_VARARGS, NULL},
--       { (char *)"verror", _wrap_verror, METH_VARARGS, NULL},
--       { NULL, NULL, 0, NULL }
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
--
--static void *_p_vips__VErrorTo_p_std__exception(void *x, int *SWIGUNUSEDPARM(newmemory)) {
--    return (void *)((std::exception *)  ((vips::VError *) x));
--}
--static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__exception = {"_p_std__exception", "std::exception *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__ostream = {"_p_std__ostream", "std::ostream *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VError = {"_p_vips__VError", "vips::VError *", 0, 0, (void*)0, 0};
--
--static swig_type_info *swig_type_initial[] = {
--  &_swigt__p_char,
--  &_swigt__p_std__exception,
--  &_swigt__p_std__ostream,
--  &_swigt__p_vips__VError,
--};
--
--static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__exception[] = {  {&_swigt__p_std__exception, 0, 0, 0},  {&_swigt__p_vips__VError, _p_vips__VErrorTo_p_std__exception, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__ostream[] = {  {&_swigt__p_std__ostream, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VError[] = {  {&_swigt__p_vips__VError, 0, 0, 0},{0, 0, 0, 0}};
--
--static swig_cast_info *swig_cast_initial[] = {
--  _swigc__p_char,
--  _swigc__p_std__exception,
--  _swigc__p_std__ostream,
--  _swigc__p_vips__VError,
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
--
--static swig_const_info swig_const_table[] = {
--{0, 0, 0, 0.0, 0, 0}};
--
--#ifdef __cplusplus
--}
--#endif
--/* -----------------------------------------------------------------------------
-- * Type initialization:
-- * This problem is tough by the requirement that no dynamic 
-- * memory is used. Also, since swig_type_info structures store pointers to 
-- * swig_cast_info structures and swig_cast_info structures store pointers back
-- * to swig_type_info structures, we need some lookup code at initialization. 
-- * The idea is that swig generates all the structures that are needed. 
-- * The runtime then collects these partially filled structures. 
-- * The SWIG_InitializeModule function takes these initial arrays out of 
-- * swig_module, and does all the lookup, filling in the swig_module.types
-- * array with the correct data and linking the correct swig_cast_info
-- * structures together.
-- *
-- * The generated swig_type_info structures are assigned staticly to an initial 
-- * array. We just loop through that array, and handle each type individually.
-- * First we lookup if this type has been already loaded, and if so, use the
-- * loaded structure instead of the generated one. Then we have to fill in the
-- * cast linked list. The cast data is initially stored in something like a
-- * two-dimensional array. Each row corresponds to a type (there are the same
-- * number of rows as there are in the swig_type_initial array). Each entry in
-- * a column is one of the swig_cast_info structures for that type.
-- * The cast_initial array is actually an array of arrays, because each row has
-- * a variable number of columns. So to actually build the cast linked list,
-- * we find the array of casts associated with the type, and loop through it 
-- * adding the casts to the list. The one last trick we need to do is making
-- * sure the type pointer in the swig_cast_info struct is correct.
-- *
-- * First off, we lookup the cast->type name to see if it is already loaded. 
-- * There are three cases to handle:
-- *  1) If the cast->type has already been loaded AND the type we are adding
-- *     casting info to has not been loaded (it is in this module), THEN we
-- *     replace the cast->type pointer with the type pointer that has already
-- *     been loaded.
-- *  2) If BOTH types (the one we are adding casting info to, and the 
-- *     cast->type) are loaded, THEN the cast info has already been loaded by
-- *     the previous module so we just ignore it.
-- *  3) Finally, if cast->type has not already been loaded, then we add that
-- *     swig_cast_info to the linked list (because the cast->type) pointer will
-- *     be correct.
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#if 0
--} /* c-mode */
--#endif
--#endif
--
--#if 0
--#define SWIGRUNTIME_DEBUG
--#endif
--
--
--SWIGRUNTIME void
--SWIG_InitializeModule(void *clientdata) {
--  size_t i;
--  swig_module_info *module_head, *iter;
--  int found, init;
--  
--  /* check to see if the circular list has been setup, if not, set it up */
--  if (swig_module.next==0) {
--    /* Initialize the swig_module */
--    swig_module.type_initial = swig_type_initial;
--    swig_module.cast_initial = swig_cast_initial;
--    swig_module.next = &swig_module;
--    init = 1;
--  } else {
--    init = 0;
--  }
--  
--  /* Try and load any already created modules */
--  module_head = SWIG_GetModule(clientdata);
--  if (!module_head) {
--    /* This is the first module loaded for this interpreter */
--    /* so set the swig module into the interpreter */
--    SWIG_SetModule(clientdata, &swig_module);
--    module_head = &swig_module;
--  } else {
--    /* the interpreter has loaded a SWIG module, but has it loaded this one? */
--    found=0;
--    iter=module_head;
--    do {
--      if (iter==&swig_module) {
--        found=1;
--        break;
--      }
--      iter=iter->next;
--    } while (iter!= module_head);
--    
--    /* if the is found in the list, then all is done and we may leave */
--    if (found) return;
--    /* otherwise we must add out module into the list */
--    swig_module.next = module_head->next;
--    module_head->next = &swig_module;
--  }
--  
--  /* When multiple interpeters are used, a module could have already been initialized in
--       a different interpreter, but not yet have a pointer in this interpreter.
--       In this case, we do not want to continue adding types... everything should be
--       set up already */
--  if (init == 0) return;
--  
--  /* Now work on filling in swig_module.types */
--#ifdef SWIGRUNTIME_DEBUG
--  printf("SWIG_InitializeModule: size %d\n", swig_module.size);
--#endif
--  for (i = 0; i < swig_module.size; ++i) {
--    swig_type_info *type = 0;
--    swig_type_info *ret;
--    swig_cast_info *cast;
--    
--#ifdef SWIGRUNTIME_DEBUG
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--#endif
--    
--    /* if there is another module already loaded */
--    if (swig_module.next != &swig_module) {
--      type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
--    }
--    if (type) {
--      /* Overwrite clientdata field */
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: found type %s\n", type->name);
--#endif
--      if (swig_module.type_initial[i]->clientdata) {
--        type->clientdata = swig_module.type_initial[i]->clientdata;
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
--#endif
--      }
--    } else {
--      type = swig_module.type_initial[i];
--    }
--    
--    /* Insert casting types */
--    cast = swig_module.cast_initial[i];
--    while (cast->type) {
--      /* Don't need to add information already in the list */
--      ret = 0;
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
--#endif
--      if (swig_module.next != &swig_module) {
--        ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
--#ifdef SWIGRUNTIME_DEBUG
--        if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
--#endif
--      }
--      if (ret) {
--        if (type == swig_module.type_initial[i]) {
--#ifdef SWIGRUNTIME_DEBUG
--          printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
--#endif
--          cast->type = ret;
--          ret = 0;
--        } else {
--          /* Check for casting already in the list */
--          swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
--#ifdef SWIGRUNTIME_DEBUG
--          if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
--#endif
--          if (!ocast) ret = 0;
--        }
--      }
--      
--      if (!ret) {
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
--#endif
--        if (type->cast) {
--          type->cast->prev = cast;
--          cast->next = type->cast;
--        }
--        type->cast = cast;
--      }
--      cast++;
--    }
--    /* Set entry in modules->types array equal to the type */
--    swig_module.types[i] = type;
--  }
--  swig_module.types[i] = 0;
--  
--#ifdef SWIGRUNTIME_DEBUG
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--  for (i = 0; i < swig_module.size; ++i) {
--    int j = 0;
--    swig_cast_info *cast = swig_module.cast_initial[i];
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--    while (cast->type) {
--      printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
--      cast++;
--      ++j;
--    }
--    printf("---- Total casts: %d\n",j);
--  }
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--#endif
--}
--
--/* This function will propagate the clientdata field of type to
--* any new swig_type_info structures that have been added into the list
--* of equivalent types.  It is like calling
--* SWIG_TypeClientData(type, clientdata) a second time.
--*/
--SWIGRUNTIME void
--SWIG_PropagateClientData(void) {
--  size_t i;
--  swig_cast_info *equiv;
--  static int init_run = 0;
--  
--  if (init_run) return;
--  init_run = 1;
--  
--  for (i = 0; i < swig_module.size; i++) {
--    if (swig_module.types[i]->clientdata) {
--      equiv = swig_module.types[i]->cast;
--      while (equiv) {
--        if (!equiv->converter) {
--          if (equiv->type && !equiv->type->clientdata)
--          SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
--        }
--        equiv = equiv->next;
--      }
--    }
--  }
--}
--
--#ifdef __cplusplus
--#if 0
--{
--  /* c-mode */
--#endif
--}
--#endif
--
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--  
--  /* Python-specific SWIG API */
--#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
--#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
--#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
--  
--  /* -----------------------------------------------------------------------------
--   * global variable support code.
--   * ----------------------------------------------------------------------------- */
--  
--  typedef struct swig_globalvar {
--    char       *name;                  /* Name of global variable */
--    PyObject *(*get_attr)(void);       /* Return the current value */
--    int       (*set_attr)(PyObject *); /* Set the value */
--    struct swig_globalvar *next;
--  } swig_globalvar;
--  
--  typedef struct swig_varlinkobject {
--    PyObject_HEAD
--    swig_globalvar *vars;
--  } swig_varlinkobject;
--  
--  SWIGINTERN PyObject *
--  swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
--#if PY_VERSION_HEX >= 0x03000000
--    return PyUnicode_InternFromString("<Swig global variables>");
--#else
--    return PyString_FromString("<Swig global variables>");
--#endif
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_str(swig_varlinkobject *v) {
--#if PY_VERSION_HEX >= 0x03000000
--    PyObject *str = PyUnicode_InternFromString("(");
--    PyObject *tail;
--    PyObject *joined;
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      tail = PyUnicode_FromString(var->name);
--      joined = PyUnicode_Concat(str, tail);
--      Py_DecRef(str);
--      Py_DecRef(tail);
--      str = joined;
--      if (var->next) {
--        tail = PyUnicode_InternFromString(", ");
--        joined = PyUnicode_Concat(str, tail);
--        Py_DecRef(str);
--        Py_DecRef(tail);
--        str = joined;
--      }
--    }
--    tail = PyUnicode_InternFromString(")");
--    joined = PyUnicode_Concat(str, tail);
--    Py_DecRef(str);
--    Py_DecRef(tail);
--    str = joined;
--#else
--    PyObject *str = PyString_FromString("(");
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      PyString_ConcatAndDel(&str,PyString_FromString(var->name));
--      if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
--    }
--    PyString_ConcatAndDel(&str,PyString_FromString(")"));
--#endif
--    return str;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
--    char *tmp;
--    PyObject *str = swig_varlink_str(v);
--    fprintf(fp,"Swig global variables ");
--    fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(str);
--    return 0;
--  }
--  
--  SWIGINTERN void
--  swig_varlink_dealloc(swig_varlinkobject *v) {
--    swig_globalvar *var = v->vars;
--    while (var) {
--      swig_globalvar *n = var->next;
--      free(var->name);
--      free(var);
--      var = n;
--    }
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_getattr(swig_varlinkobject *v, char *n) {
--    PyObject *res = NULL;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->get_attr)();
--        break;
--      }
--      var = var->next;
--    }
--    if (res == NULL && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
--    int res = 1;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->set_attr)(p);
--        break;
--      }
--      var = var->next;
--    }
--    if (res == 1 && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN PyTypeObject*
--  swig_varlink_type(void) {
--    static char varlink__doc__[] = "Swig var link object";
--    static PyTypeObject varlink_type;
--    static int type_init = 0;
--    if (!type_init) {
--      const PyTypeObject tmp = {
--        /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--        PyVarObject_HEAD_INIT(NULL, 0)
--#else
--        PyObject_HEAD_INIT(NULL)
--        0,                                  /* ob_size */
--#endif
--        (char *)"swigvarlink",              /* tp_name */
--        sizeof(swig_varlinkobject),         /* tp_basicsize */
--        0,                                  /* tp_itemsize */
--        (destructor) swig_varlink_dealloc,  /* tp_dealloc */
--        (printfunc) swig_varlink_print,     /* tp_print */
--        (getattrfunc) swig_varlink_getattr, /* tp_getattr */
--        (setattrfunc) swig_varlink_setattr, /* tp_setattr */
--        0,                                  /* tp_compare */
--        (reprfunc) swig_varlink_repr,       /* tp_repr */
--        0,                                  /* tp_as_number */
--        0,                                  /* tp_as_sequence */
--        0,                                  /* tp_as_mapping */
--        0,                                  /* tp_hash */
--        0,                                  /* tp_call */
--        (reprfunc) swig_varlink_str,        /* tp_str */
--        0,                                  /* tp_getattro */
--        0,                                  /* tp_setattro */
--        0,                                  /* tp_as_buffer */
--        0,                                  /* tp_flags */
--        varlink__doc__,                     /* tp_doc */
--        0,                                  /* tp_traverse */
--        0,                                  /* tp_clear */
--        0,                                  /* tp_richcompare */
--        0,                                  /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--        0,                                  /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--        0,                                  /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--        0,0,0,0                             /* tp_alloc -> tp_next */
--#endif
--      };
--      varlink_type = tmp;
--      type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--      varlink_type.ob_type = &PyType_Type;
--#else
--      if (PyType_Ready(&varlink_type) < 0)
--      return NULL;
--#endif
--    }
--    return &varlink_type;
--  }
--  
--  /* Create a variable linking object for use later */
--  SWIGINTERN PyObject *
--  SWIG_Python_newvarlink(void) {
--    swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
--    if (result) {
--      result->vars = 0;
--    }
--    return ((PyObject*) result);
--  }
--  
--  SWIGINTERN void 
--  SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
--    swig_varlinkobject *v = (swig_varlinkobject *) p;
--    swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
--    if (gv) {
--      size_t size = strlen(name)+1;
--      gv->name = (char *)malloc(size);
--      if (gv->name) {
--        strncpy(gv->name,name,size);
--        gv->get_attr = get_attr;
--        gv->set_attr = set_attr;
--        gv->next = v->vars;
--      }
--    }
--    v->vars = gv;
--  }
--  
--  SWIGINTERN PyObject *
--  SWIG_globals(void) {
--    static PyObject *_SWIG_globals = 0; 
--    if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();  
--    return _SWIG_globals;
--  }
--  
--  /* -----------------------------------------------------------------------------
--   * constants/methods manipulation
--   * ----------------------------------------------------------------------------- */
--  
--  /* Install Constants */
--  SWIGINTERN void
--  SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
--    PyObject *obj = 0;
--    size_t i;
--    for (i = 0; constants[i].type; ++i) {
--      switch(constants[i].type) {
--      case SWIG_PY_POINTER:
--        obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
--        break;
--      case SWIG_PY_BINARY:
--        obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
--        break;
--      default:
--        obj = 0;
--        break;
--      }
--      if (obj) {
--        PyDict_SetItemString(d, constants[i].name, obj);
--        Py_DECREF(obj);
--      }
--    }
--  }
--  
--  /* -----------------------------------------------------------------------------*/
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  /* -----------------------------------------------------------------------------*/
--  
--  SWIGINTERN void
--  SWIG_Python_FixMethods(PyMethodDef *methods,
--    swig_const_info *const_table,
--    swig_type_info **types,
--    swig_type_info **types_initial) {
--    size_t i;
--    for (i = 0; methods[i].ml_name; ++i) {
--      const char *c = methods[i].ml_doc;
--      if (c && (c = strstr(c, "swig_ptr: "))) {
--        int j;
--        swig_const_info *ci = 0;
--        const char *name = c + 10;
--        for (j = 0; const_table[j].type; ++j) {
--          if (strncmp(const_table[j].name, name, 
--              strlen(const_table[j].name)) == 0) {
--            ci = &(const_table[j]);
--            break;
--          }
--        }
--        if (ci) {
--          void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
--          if (ptr) {
--            size_t shift = (ci->ptype) - types;
--            swig_type_info *ty = types_initial[shift];
--            size_t ldoc = (c - methods[i].ml_doc);
--            size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
--            char *ndoc = (char*)malloc(ldoc + lptr + 10);
--            if (ndoc) {
--              char *buff = ndoc;
--              strncpy(buff, methods[i].ml_doc, ldoc);
--              buff += ldoc;
--              strncpy(buff, "swig_ptr: ", 10);
--              buff += 10;
--              SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
--              methods[i].ml_doc = ndoc;
--            }
--          }
--        }
--      }
--    }
--  } 
--  
--#ifdef __cplusplus
--}
--#endif
--
--/* -----------------------------------------------------------------------------*
-- *  Partial Init method
-- * -----------------------------------------------------------------------------*/
--
--#ifdef __cplusplus
--extern "C"
--#endif
--
--SWIGEXPORT 
--#if PY_VERSION_HEX >= 0x03000000
--PyObject*
--#else
--void
--#endif
--SWIG_init(void) {
--  PyObject *m, *d, *md;
--#if PY_VERSION_HEX >= 0x03000000
--  static struct PyModuleDef SWIG_module = {
--# if PY_VERSION_HEX >= 0x03020000
--    PyModuleDef_HEAD_INIT,
--# else
--    {
--      PyObject_HEAD_INIT(NULL)
--      NULL, /* m_init */
--      0,    /* m_index */
--      NULL, /* m_copy */
--    },
--# endif
--    (char *) SWIG_name,
--    NULL,
--    -1,
--    SwigMethods,
--    NULL,
--    NULL,
--    NULL,
--    NULL
--  };
--#endif
--  
--#if defined(SWIGPYTHON_BUILTIN)
--  static SwigPyClientData SwigPyObject_clientdata = {
--    0, 0, 0, 0, 0, 0, 0
--  };
--  static PyGetSetDef this_getset_def = {
--    (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
--  };
--  static SwigPyGetSet thisown_getset_closure = {
--    (PyCFunction) SwigPyObject_own,
--    (PyCFunction) SwigPyObject_own
--  };
--  static PyGetSetDef thisown_getset_def = {
--    (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
--  };
--  PyObject *metatype_args;
--  PyTypeObject *builtin_pytype;
--  int builtin_base_count;
--  swig_type_info *builtin_basetype;
--  PyObject *tuple;
--  PyGetSetDescrObject *static_getset;
--  PyTypeObject *metatype;
--  SwigPyClientData *cd;
--  PyObject *public_interface, *public_symbol;
--  PyObject *this_descr;
--  PyObject *thisown_descr;
--  int i;
--  
--  (void)builtin_pytype;
--  (void)builtin_base_count;
--  (void)builtin_basetype;
--  (void)tuple;
--  (void)static_getset;
--  
--  /* metatype is used to implement static member variables. */
--  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
--  assert(metatype_args);
--  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
--  assert(metatype);
--  Py_DECREF(metatype_args);
--  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
--  assert(PyType_Ready(metatype) >= 0);
--#endif
--  
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  m = PyModule_Create(&SWIG_module);
--#else
--  m = Py_InitModule((char *) SWIG_name, SwigMethods);
--#endif
--  md = d = PyModule_GetDict(m);
--  (void)md;
--  
--  SWIG_InitializeModule(0);
--  
--#ifdef SWIGPYTHON_BUILTIN
--  SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
--  assert(SwigPyObject_stype);
--  cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--  if (!cd) {
--    SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
--    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
--  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
--    PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
--# if PY_VERSION_HEX >= 0x03000000
--    return NULL;
--# else
--    return;
--# endif
--  }
--  
--  /* All objects have a 'this' attribute */
--  this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
--  (void)this_descr;
--  
--  /* All objects have a 'thisown' attribute */
--  thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
--  (void)thisown_descr;
--  
--  public_interface = PyList_New(0);
--  public_symbol = 0;
--  (void)public_symbol;
--  
--  PyDict_SetItemString(md, "__all__", public_interface);
--  Py_DECREF(public_interface);
--  for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
--  for (i = 0; swig_const_table[i].name != 0; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
--#endif
--  
--  SWIG_InstallConstants(d,swig_const_table);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  return m;
--#else
--  return;
--#endif
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VError.py vips-7.38.5/swig/vipsCC/VError.py
---- vips-7.38.5-vanilla/swig/vipsCC/VError.py  2014-07-17 23:48:36.211794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VError.py  1969-12-31 19:00:00.000000000 -0500
-@@ -1,100 +0,0 @@
--# This file was automatically generated by SWIG (http://www.swig.org).
--# Version 2.0.10
--#
--# Do not make changes to this file unless you know what you are doing--modify
--# the SWIG interface file instead.
--
--
--
--from sys import version_info
--if version_info >= (2,6,0):
--    def swig_import_helper():
--        from os.path import dirname
--        import imp
--        fp = None
--        try:
--            fp, pathname, description = imp.find_module('verrormodule', [dirname(__file__)])
--        except ImportError:
--            import verrormodule
--            return verrormodule
--        if fp is not None:
--            try:
--                _mod = imp.load_module('verrormodule', fp, pathname, description)
--            finally:
--                fp.close()
--            return _mod
--    verrormodule = swig_import_helper()
--    del swig_import_helper
--else:
--    import verrormodule
--del version_info
--try:
--    _swig_property = property
--except NameError:
--    pass # Python < 2.2 doesn't have 'property'.
--def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
--    if (name == "thisown"): return self.this.own(value)
--    if (name == "this"):
--        if type(value).__name__ == 'SwigPyObject':
--            self.__dict__[name] = value
--            return
--    method = class_type.__swig_setmethods__.get(name,None)
--    if method: return method(self,value)
--    if (not static):
--        self.__dict__[name] = value
--    else:
--        raise AttributeError("You cannot add attributes to %s" % self)
--
--def _swig_setattr(self,class_type,name,value):
--    return _swig_setattr_nondynamic(self,class_type,name,value,0)
--
--def _swig_getattr(self,class_type,name):
--    if (name == "thisown"): return self.this.own()
--    method = class_type.__swig_getmethods__.get(name,None)
--    if method: return method(self)
--    raise AttributeError(name)
--
--def _swig_repr(self):
--    try: strthis = "proxy of " + self.this.__repr__()
--    except: strthis = ""
--    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
--
--try:
--    _object = object
--    _newclass = 1
--except AttributeError:
--    class _object : pass
--    _newclass = 0
--
--
--class VError(Exception):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VError, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, VError, name)
--    __repr__ = _swig_repr
--    def __init__(self, *args): 
--        this = verrormodule.new_VError(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    __swig_destroy__ = verrormodule.delete_VError
--    __del__ = lambda self : None;
--    def perror(self, *args): return verrormodule.VError_perror(self, *args)
--    def app(self, *args): return verrormodule.VError_app(self, *args)
--    def what(self): return verrormodule.VError_what(self)
--    def ostream_print(self, *args): return verrormodule.VError_ostream_print(self, *args)
--    def __str__(self): return verrormodule.VError___str__(self)
--VError_swigregister = verrormodule.VError_swigregister
--VError_swigregister(VError)
--
--
--def __lshift__(*args):
--  return verrormodule.__lshift__(*args)
--__lshift__ = verrormodule.__lshift__
--
--def verror(str=""):
--  return verrormodule.verror(str)
--verror = verrormodule.verror
--# This file is compatible with both classic and new-style classes.
--
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VImage.i vips-7.38.5/swig/vipsCC/VImage.i
---- vips-7.38.5-vanilla/swig/vipsCC/VImage.i   2014-07-17 23:48:36.207794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VImage.i   1969-12-31 19:00:00.000000000 -0500
-@@ -1,380 +0,0 @@
--/* SWIG interface file for vipsCC7
-- *
-- * 5/9/07
-- *      - use g_option_context_set_ignore_unknown_options() so we don't fail
-- *        on unrecognied -args (thanks Simon)
-- * 3/8/08
-- *      - add .tobuffer() / .frombuffer (), .tostring (), .fromstring ()
-- *        methods
-- *      - add PIL_mode_from_vips () and vips_from_PIL_mode () utility
-- *        functions
-- * 6/11/09
-- *      - arg, std::vector<vips::VImage> was missing the "vips::"
-- */
--
--%module VImage
--
--%{
--#include <vips/vipscpp.h>
--
--/* We need the C API too for the args init and some of the
-- * frombuffer/tobuffer stuff.
-- */
--#include <vips/vips.h>
--%}
--
--/* Need to override assignment to get refcounting working.
-- */
--%rename(__assign__) vips::VImage::operator=;
--
--%include "std_list.i"
--%include "std_complex.i"
--%include "std_vector.i"
--%include "std_except.i"
--%include "std_string.i"
--%include "cstring.i"
--%include "typemaps.i"
--
--%import "VError.i"
--%import "VMask.i"
--%import "VDisplay.i"
--
--namespace std {
--  %template(IntVector) vector<int>;
--  %template(DoubleVector) vector<double>;
--  %template(ImageVector) vector<vips::VImage>;
--}
--
--/* To get image data to and from VImage (eg. when interfacing with PIL) we
-- * need to be able to import and export Python buffer() objects. Add new
-- * methods to construct from and return pointer/length pairs, then wrap them
-- * ourselves with a couple of typemaps.
-- */
--
--%{
--struct VBuffer {
--  void *data;
--  size_t size;
--};
--%}
--
--%typemap (out) VBuffer {
--  $result = PyBuffer_FromMemory ($1.data, $1.size);
--}
--
--%typemap (in) VBuffer {
--  const char *buffer;
--  Py_ssize_t buffer_len;
--
--  if (PyObject_AsCharBuffer ($input, &buffer, &buffer_len) == -1) {
--    PyErr_SetString (PyExc_TypeError,"Type error. Unable to get char pointer from buffer");
--    return NULL;
--  }
--
--  $1.data = (void *) buffer;
--  $1.size = buffer_len;
--}
--
--/* Functions which return extra values though their parameters need special
-- * typemaps.
-- */
--
--// double maxpos_avg( double& maxpos_avg_y, double& maxpos_avg_out )
--%apply double *OUTPUT { double & maxpos_avg_y };
--%apply double *OUTPUT { double & maxpos_avg_out };
--
--// VImage system_image( char* system_image_in_format, char* system_image_out_format, char* system_image_command, char*& system_image_log ) 
--%cstring_output_allocate(char **system_image_log, g_free(*$1));
--
--// VImage segment( int& segment_segments ) 
--%apply int *OUTPUT { int & segment_segments };
--
--// VImage project( VImage& project_vout ) throw( VError );
--// nope ... not sure how to handle this one
--//%apply VImage *OUTPUT { VImage & project_vout };
--
--// VImage label_regions( int& label_regions_segments ) 
--%apply int *OUTPUT { int & label_regions_segments };
--
--// double correl( VImage correl_sec, int correl_xref, int correl_yref, int correl_xsec, int correl_ysec, int correl_hwindowsize, int correl_hsearchsize, int& correl_x, int& correl_y ) 
--%apply int *OUTPUT { int & correl_x };
--%apply int *OUTPUT { int & correl_y };
--
--// int _find_lroverlap( VImage _find_lroverlap_sec, int _find_lroverlap_bandno, int _find_lroverlap_xr, int _find_lroverlap_yr, int _find_lroverlap_xs, int _find_lroverlap_ys, int _find_lroverlap_halfcorrelation, int _find_lroverlap_halfarea, int& _find_lroverlap_dy0, double& _find_lroverlap_scale1, double& _find_lroverlap_angle1, double& _find_lroverlap_dx1, double& _find_lroverlap_dy1 ) 
--%apply int *OUTPUT { int & _find_lroverlap_dy0 };
--%apply double *OUTPUT { double & _find_lroverlap_scale1 };
--%apply double *OUTPUT { double & _find_lroverlap_angle1 };
--%apply double *OUTPUT { double & _find_lroverlap_dx1 };
--%apply double *OUTPUT { double & _find_lroverlap_dy1 };
--
--// int _find_tboverlap( VImage _find_tboverlap_sec, int _find_tboverlap_bandno, int _find_tboverlap_xr, int _find_tboverlap_yr, int _find_tboverlap_xs, int _find_tboverlap_ys, int _find_tboverlap_halfcorrelation, int _find_tboverlap_halfarea, int& _find_tboverlap_dy0, double& _find_tboverlap_scale1, double& _find_tboverlap_angle1, double& _find_tboverlap_dx1, double& _find_tboverlap_dy1 ) 
--%apply int *OUTPUT { int & _find_tboverlap_dy0 };
--%apply double *OUTPUT { double & _find_tboverlap_scale1 };
--%apply double *OUTPUT { double & _find_tboverlap_angle1 };
--%apply double *OUTPUT { double & _find_tboverlap_dx1 };
--%apply double *OUTPUT { double & _find_tboverlap_dy1 };
--
--// double maxpos_subpel( double& maxpos_subpel_y ) 
--%apply double *OUTPUT { double & maxpos_subpel_y };
--
--/* Need the expanded VImage.h in this directory, rather than the usual
-- * vips/VImage.h. SWIG b0rks on #include inside class definitions.
-- */
--%include VImage.h
--
--%extend vips::VImage {
--public:
--  VBuffer tobuffer () throw (VError)
--  {
--    VBuffer buffer;
--
--    buffer.data = $self->data ();
--    buffer.size = (size_t) $self->Xsize () * $self->Ysize () * 
--        IM_IMAGE_SIZEOF_PEL ($self->image ());
--
--    return buffer;
--  }
--
--  static VImage frombuffer (VBuffer buffer, int width, int height,
--    int bands, TBandFmt format) throw (VError)
--  {
--    return VImage (buffer.data, width, height, bands, format);
--  }
--
--  %cstring_output_allocate_size (char **buffer, int *buffer_len, im_free (*$1))
--
--  void tostring (char **buffer, int *buffer_len) throw (VError)
--  {
--    void *vips_memory;
--
--    /* Eval the vips image first. This may throw an exception and we want to
--     * make sure we do this before we try to malloc() space for the copy.
--     */
--    vips_memory = $self->data ();
--
--    /* We have to copy the image data to make a string that Python can
--     * manage. Use frombuffer() / tobuffer () if you want to avoid the copy
--     * and manage memory lifetime yourself.
--     */
--    *buffer_len = (size_t) $self->Xsize () * $self->Ysize () * 
--      IM_IMAGE_SIZEOF_PEL ($self->image ());
--    if (!(*buffer = (char *) im_malloc (NULL, *buffer_len))) 
--      verror ("Unable to allocate memory for image copy.");
--    memcpy (*buffer, vips_memory, *buffer_len);
--  }
--
--  static VImage fromstring (std::string buffer, int width, int height,
--    int bands, TBandFmt format) throw (VError)
--  {
--    void *vips_memory;
--    VImage result;
--
--    /* We have to copy the string, then add a callback to the VImage to free
--     * it when we free the VImage. Use frombuffer() / tobuffer () if you want 
--     * to avoid the copy and manage memory lifetime yourself.
--     */
--    if (!(vips_memory = im_malloc (NULL, buffer.length ()))) 
--      verror ("Unable to allocate memory for image copy.");
--
--    /* We have to use .c_str () since the string may not be contiguous.
--     */
--    memcpy (vips_memory, buffer.c_str (), buffer.length ());
--    result = VImage (vips_memory, width, height, bands, format);
--
--    if (im_add_close_callback (result.image (), 
--      (im_callback_fn) im_free, vips_memory, NULL))
--      verror ();
--
--    return result;
--  }
--}
--
--%pythoncode %{
--# try to guess a PIL mode string from a VIPS image
--def PIL_mode_from_vips (vim):
--  if vim.Bands () == 3 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'RGB'
--  elif vim.Bands () == 4 and vim.BandFmt () == VImage.FMTUCHAR and vim.Type () == VImage.RGB:
--    return 'RGBA'
--  elif vim.Bands () == 4 and vim.BandFmt () == VImage.FMTUCHAR and vim.Type () == VImage.CMYK:
--    return 'CMYK'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'L'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTINT:
--    return 'I'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTFLOAT:
--    return 'F'
--  elif vim.Bands () == 2 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'LA'
--  else:
--    raise ValueError ('unsupported vips -> pil image')
--
--# return vips (bands, format, type) for a PIL mode
--def vips_from_PIL_mode (mode):
--  if mode == 'RGB':
--    return (3, VImage.FMTUCHAR, VImage.RGB)
--  elif mode == 'RGBA':
--    return (4, VImage.FMTUCHAR, VImage.RGB)
--  elif mode == 'CMYK':
--    return (4, VImage.FMTUCHAR, VImage.CMYK)
--  elif mode == 'L':
--    return (1, VImage.FMTUCHAR, VImage.B_W)
--  elif mode == 'I':
--    return (1, VImage.FMTINT, VImage.B_W)
--  elif mode == 'F':
--    return (1, VImage.FMTFLOAT, VImage.B_W)
--  elif mode == 'LA':
--    return (2, VImage.FMTUCHAR, VImage.B_W)
--  else:
--    raise ValueError ('unsupported pil -> vips image')
--%}
--
--/* Helper code for vips_init().
-- */
--%{
--/* Turn on to print args.
--#define DEBUG
-- */
--
--/* Command-line args during parse.
-- */
--typedef struct _Args {
--  /* The n strings we alloc when we get from Python.
--   */
--  int n;
--  char **str;
--
--  /* argc/argv as processed by us.
--   */
--  int argc;
--  char **argv;
--} Args;
--
--#ifdef DEBUG
--static void
--args_print (Args *args)
--{
--  int i;
--
--  printf ("args_print: argc = %d\n", args->argc);
--  // +1 so we print the trailing NULL too
--  for (i = 0; i < args->argc + 1; i++)
--    printf ("\t%2d)\t%s\n", i, args->argv[i]);
--}
--#endif /*DEBUG*/
--
--static void
--args_free (Args *args)
--{
--  int i;
--
--  for (i = 0; i < args->n; i++)
--    IM_FREE (args->str[i]);
--  args->n = 0;
--  args->argc = 0;
--  IM_FREE (args->str);
--  IM_FREE (args->argv);
--  IM_FREE (args);
--}
--
--/* Get argv/argc from python.
-- */
--static Args *
--args_new (void)
--{
--  Args *args;
--  PyObject *av;
--  int i;
--  int n;
--
--  args = g_new (Args, 1);
--  args->n = 0;
--  args->str = NULL;
--  args->argc = 0;
--  args->argv = NULL;
--
--  if (!(av = PySys_GetObject ((char *) "argv"))) 
--    return (args);
--  if (!PyList_Check (av)) {
--    PyErr_Warn (PyExc_Warning, "ignoring sys.argv: "
--      "it must be a list of strings");
--    return args;
--  }
--
--  n = PyList_Size (av);
--  args->str = g_new (char *, n);
--  for (i = 0; i < n; i++)
--    args->str[i] = g_strdup (PyString_AsString (PyList_GetItem (av, i)));
--  args->n = n;
--
--  /* +1 for NULL termination.
--   */
--  args->argc = n;
--  args->argv = g_new (char *, n + 1);
--  for (i = 0; i < n; i++)
--    args->argv[i] = args->str[i];
--  args->argv[i] = NULL;
--
--  return args;
--}
--
--static void
--vips_fatal (const char *msg)
--{
--  char buf[256];
--
--  im_snprintf (buf, 256, "%s\n%s", msg, im_error_buffer());
--  im_error_clear ();
--  Py_FatalError (buf);
--}
--
--%}
--
--%init %{
--{
--  Args *args;
--        
--  args = args_new ();
--
--#ifdef DEBUG
--  printf ("on startup:\n");
--  args_print (args);
--#endif /*DEBUG*/
--        
--  if (im_init_world (args->argv[0])) {
--     args_free (args);
--     vips_fatal ("can't initialise module vips");
--  }
--
--  /* Now parse any GOptions. 
--   */
--  GError *error = NULL;
--  GOptionContext *context;
--
--  context = g_option_context_new ("- vips");
--  g_option_context_add_group (context, im_get_option_group());
--
--  g_option_context_set_ignore_unknown_options (context, TRUE);
--  if (!g_option_context_parse (context, 
--    &args->argc, &args->argv, &error)) {
--    g_option_context_free (context);
--    args_free (args);
--    im_error ("vipsmodule", "%s", error->message);
--    g_error_free (error);
--    vips_fatal ("can't initialise module vips");
--  }
--  g_option_context_free (context);
--
--#ifdef DEBUG
--  printf ("after parse:\n");
--  args_print (args);
--#endif /*DEBUG*/
--
--  // Write (possibly) modified argc/argv back again.
--  if (args->argv) 
--    PySys_SetArgv (args->argc, args->argv);
--
--  args_free (args);
--}
--%}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/vimagemodule.cxx vips-7.38.5/swig/vipsCC/vimagemodule.cxx
---- vips-7.38.5-vanilla/swig/vipsCC/vimagemodule.cxx   2014-07-17 23:48:36.211794473 -0400
-+++ vips-7.38.5/swig/vipsCC/vimagemodule.cxx   1969-12-31 19:00:00.000000000 -0500
-@@ -1,33595 +0,0 @@
--/* ----------------------------------------------------------------------------
-- * This file was automatically generated by SWIG (http://www.swig.org).
-- * Version 2.0.10
-- * 
-- * This file is not intended to be easily readable and contains a number of 
-- * coding conventions designed to improve portability and efficiency. Do not make
-- * changes to this file unless you know what you are doing--modify the SWIG 
-- * interface file instead. 
-- * ----------------------------------------------------------------------------- */
--
--#define SWIGPYTHON
--#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
--
--
--#ifdef __cplusplus
--/* SwigValueWrapper is described in swig.swg */
--template<typename T> class SwigValueWrapper {
--  struct SwigMovePointer {
--    T *ptr;
--    SwigMovePointer(T *p) : ptr(p) { }
--    ~SwigMovePointer() { delete ptr; }
--    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
--  } pointer;
--  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
--  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
--public:
--  SwigValueWrapper() : pointer(0) { }
--  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
--  operator T&() const { return *pointer.ptr; }
--  T *operator&() { return pointer.ptr; }
--};
--
--template <typename T> T SwigValueInit() {
--  return T();
--}
--#endif
--
--/* -----------------------------------------------------------------------------
-- *  This section contains generic SWIG labels for method/variable
-- *  declarations/attributes, and other compiler dependent labels.
-- * ----------------------------------------------------------------------------- */
--
--/* template workaround for compilers that cannot correctly implement the C++ standard */
--#ifndef SWIGTEMPLATEDISAMBIGUATOR
--# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# elif defined(__HP_aCC)
--/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
--/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# else
--#  define SWIGTEMPLATEDISAMBIGUATOR
--# endif
--#endif
--
--/* inline attribute */
--#ifndef SWIGINLINE
--# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
--#   define SWIGINLINE inline
--# else
--#   define SWIGINLINE
--# endif
--#endif
--
--/* attribute recognised by some compilers to avoid 'unused' warnings */
--#ifndef SWIGUNUSED
--# if defined(__GNUC__)
--#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
--#     define SWIGUNUSED __attribute__ ((__unused__)) 
--#   else
--#     define SWIGUNUSED
--#   endif
--# elif defined(__ICC)
--#   define SWIGUNUSED __attribute__ ((__unused__)) 
--# else
--#   define SWIGUNUSED 
--# endif
--#endif
--
--#ifndef SWIG_MSC_UNSUPPRESS_4505
--# if defined(_MSC_VER)
--#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
--# endif 
--#endif
--
--#ifndef SWIGUNUSEDPARM
--# ifdef __cplusplus
--#   define SWIGUNUSEDPARM(p)
--# else
--#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
--# endif
--#endif
--
--/* internal SWIG method */
--#ifndef SWIGINTERN
--# define SWIGINTERN static SWIGUNUSED
--#endif
--
--/* internal inline SWIG method */
--#ifndef SWIGINTERNINLINE
--# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
--#endif
--
--/* exporting methods */
--#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
--#  ifndef GCC_HASCLASSVISIBILITY
--#    define GCC_HASCLASSVISIBILITY
--#  endif
--#endif
--
--#ifndef SWIGEXPORT
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   if defined(STATIC_LINKED)
--#     define SWIGEXPORT
--#   else
--#     define SWIGEXPORT __declspec(dllexport)
--#   endif
--# else
--#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
--#     define SWIGEXPORT __attribute__ ((visibility("default")))
--#   else
--#     define SWIGEXPORT
--#   endif
--# endif
--#endif
--
--/* calling conventions for Windows */
--#ifndef SWIGSTDCALL
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   define SWIGSTDCALL __stdcall
--# else
--#   define SWIGSTDCALL
--# endif 
--#endif
--
--/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
--#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
--# define _CRT_SECURE_NO_DEPRECATE
--#endif
--
--/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
--#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
--# define _SCL_SECURE_NO_DEPRECATE
--#endif
--
--
--
--/* Python.h has to appear first */
--#include <Python.h>
--
--/* -----------------------------------------------------------------------------
-- * swigrun.swg
-- *
-- * This file contains generic C API SWIG runtime support for pointer
-- * type checking.
-- * ----------------------------------------------------------------------------- */
--
--/* This should only be incremented when either the layout of swig_type_info changes,
--   or for whatever reason, the runtime changes incompatibly */
--#define SWIG_RUNTIME_VERSION "4"
--
--/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
--#ifdef SWIG_TYPE_TABLE
--# define SWIG_QUOTE_STRING(x) #x
--# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
--# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
--#else
--# define SWIG_TYPE_TABLE_NAME
--#endif
--
--/*
--  You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
--  creating a static or dynamic library from the SWIG runtime code.
--  In 99.9% of the cases, SWIG just needs to declare them as 'static'.
--  
--  But only do this if strictly necessary, ie, if you have problems
--  with your compiler or suchlike.
--*/
--
--#ifndef SWIGRUNTIME
--# define SWIGRUNTIME SWIGINTERN
--#endif
--
--#ifndef SWIGRUNTIMEINLINE
--# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
--#endif
--
--/*  Generic buffer size */
--#ifndef SWIG_BUFFER_SIZE
--# define SWIG_BUFFER_SIZE 1024
--#endif
--
--/* Flags for pointer conversions */
--#define SWIG_POINTER_DISOWN        0x1
--#define SWIG_CAST_NEW_MEMORY       0x2
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_OWN           0x1
--
--
--/* 
--   Flags/methods for returning states.
--   
--   The SWIG conversion methods, as ConvertPtr, return an integer 
--   that tells if the conversion was successful or not. And if not,
--   an error code can be returned (see swigerrors.swg for the codes).
--   
--   Use the following macros/flags to set or process the returning
--   states.
--   
--   In old versions of SWIG, code such as the following was usually written:
--
--     if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
--       // success code
--     } else {
--       //fail code
--     }
--
--   Now you can be more explicit:
--
--    int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--    } else {
--      // fail code
--    }
--
--   which is the same really, but now you can also do
--
--    Type *ptr;
--    int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--      if (SWIG_IsNewObj(res) {
--        ...
--      delete *ptr;
--      } else {
--        ...
--      }
--    } else {
--      // fail code
--    }
--    
--   I.e., now SWIG_ConvertPtr can return new objects and you can
--   identify the case and take care of the deallocation. Of course that
--   also requires SWIG_ConvertPtr to return new result values, such as
--
--      int SWIG_ConvertPtr(obj, ptr,...) {         
--        if (<obj is ok>) {                           
--          if (<need new object>) {                   
--            *ptr = <ptr to new allocated object>; 
--            return SWIG_NEWOBJ;                      
--          } else {                                   
--            *ptr = <ptr to old object>;              
--            return SWIG_OLDOBJ;                      
--          }                                  
--        } else {                                     
--          return SWIG_BADOBJ;                
--        }                                            
--      }
--
--   Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
--   more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
--   SWIG errors code.
--
--   Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
--   allows to return the 'cast rank', for example, if you have this
--
--       int food(double)
--       int fooi(int);
--
--   and you call
-- 
--      food(1)   // cast rank '1'  (1 -> 1.0)
--      fooi(1)   // cast rank '0'
--
--   just use the SWIG_AddCast()/SWIG_CheckState()
--*/
--
--#define SWIG_OK                    (0) 
--#define SWIG_ERROR                 (-1)
--#define SWIG_IsOK(r)               (r >= 0)
--#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
--
--/* The CastRankLimit says how many bits are used for the cast rank */
--#define SWIG_CASTRANKLIMIT         (1 << 8)
--/* The NewMask denotes the object was created (using new/malloc) */
--#define SWIG_NEWOBJMASK            (SWIG_CASTRANKLIMIT  << 1)
--/* The TmpMask is for in/out typemaps that use temporal objects */
--#define SWIG_TMPOBJMASK            (SWIG_NEWOBJMASK << 1)
--/* Simple returning values */
--#define SWIG_BADOBJ                (SWIG_ERROR)
--#define SWIG_OLDOBJ                (SWIG_OK)
--#define SWIG_NEWOBJ                (SWIG_OK | SWIG_NEWOBJMASK)
--#define SWIG_TMPOBJ                (SWIG_OK | SWIG_TMPOBJMASK)
--/* Check, add and del mask methods */
--#define SWIG_AddNewMask(r)         (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
--#define SWIG_DelNewMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
--#define SWIG_IsNewObj(r)           (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
--#define SWIG_AddTmpMask(r)         (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
--#define SWIG_DelTmpMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
--#define SWIG_IsTmpObj(r)           (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
--
--/* Cast-Rank Mode */
--#if defined(SWIG_CASTRANK_MODE)
--#  ifndef SWIG_TypeRank
--#    define SWIG_TypeRank             unsigned long
--#  endif
--#  ifndef SWIG_MAXCASTRANK            /* Default cast allowed */
--#    define SWIG_MAXCASTRANK          (2)
--#  endif
--#  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
--#  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
--SWIGINTERNINLINE int SWIG_AddCast(int r) { 
--  return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
--}
--SWIGINTERNINLINE int SWIG_CheckState(int r) { 
--  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
--}
--#else /* no cast-rank mode */
--#  define SWIG_AddCast(r) (r)
--#  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
--#endif
--
--
--#include <string.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef void *(*swig_converter_func)(void *, int *);
--typedef struct swig_type_info *(*swig_dycast_func)(void **);
--
--/* Structure to store information on one type */
--typedef struct swig_type_info {
--  const char             *name;                       /* mangled name of this type */
--  const char             *str;                        /* human readable name of this type */
--  swig_dycast_func        dcast;              /* dynamic cast function down a hierarchy */
--  struct swig_cast_info  *cast;                       /* linked list of types that can cast into this type */
--  void                   *clientdata;         /* language specific type data */
--  int                    owndata;             /* flag if the structure owns the clientdata */
--} swig_type_info;
--
--/* Structure to store a type and conversion function used for casting */
--typedef struct swig_cast_info {
--  swig_type_info         *type;                       /* pointer to type that is equivalent to this type */
--  swig_converter_func     converter;          /* function to cast the void pointers */
--  struct swig_cast_info  *next;                       /* pointer to next cast in linked list */
--  struct swig_cast_info  *prev;                       /* pointer to the previous cast */
--} swig_cast_info;
--
--/* Structure used to store module information
-- * Each module generates one structure like this, and the runtime collects
-- * all of these structures and stores them in a circularly linked list.*/
--typedef struct swig_module_info {
--  swig_type_info         **types;             /* Array of pointers to swig_type_info structures that are in this module */
--  size_t                 size;                        /* Number of types in this module */
--  struct swig_module_info *next;              /* Pointer to next element in circularly linked list */
--  swig_type_info         **type_initial;      /* Array of initially generated type structures */
--  swig_cast_info         **cast_initial;      /* Array of initially generated casting structures */
--  void                    *clientdata;                /* Language specific module data */
--} swig_module_info;
--
--/* 
--  Compare two type names skipping the space characters, therefore
--  "char*" == "char *" and "Class<int>" == "Class<int >", etc.
--
--  Return 0 when the two name types are equivalent, as in
--  strncmp, but skipping ' '.
--*/
--SWIGRUNTIME int
--SWIG_TypeNameComp(const char *f1, const char *l1,
--                const char *f2, const char *l2) {
--  for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
--    while ((*f1 == ' ') && (f1 != l1)) ++f1;
--    while ((*f2 == ' ') && (f2 != l2)) ++f2;
--    if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
--  }
--  return (int)((l1 - f1) - (l2 - f2));
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
--*/
--SWIGRUNTIME int
--SWIG_TypeCmp(const char *nb, const char *tb) {
--  int equiv = 1;
--  const char* te = tb + strlen(tb);
--  const char* ne = nb;
--  while (equiv != 0 && *ne) {
--    for (nb = ne; *ne; ++ne) {
--      if (*ne == '|') break;
--    }
--    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
--    if (*ne) ++ne;
--  }
--  return equiv;
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if not equal, 1 if equal
--*/
--SWIGRUNTIME int
--SWIG_TypeEquiv(const char *nb, const char *tb) {
--  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
--}
--
--/*
--  Check the typename
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheck(const char *c, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (strcmp(iter->type->name, c) == 0) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/* 
--  Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (iter->type == from) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/*
--  Cast a pointer up an inheritance hierarchy
--*/
--SWIGRUNTIMEINLINE void *
--SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
--  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
--}
--
--/* 
--   Dynamic pointer casting. Down an inheritance hierarchy
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
--  swig_type_info *lastty = ty;
--  if (!ty || !ty->dcast) return ty;
--  while (ty && (ty->dcast)) {
--    ty = (*ty->dcast)(ptr);
--    if (ty) lastty = ty;
--  }
--  return lastty;
--}
--
--/*
--  Return the name associated with this type
--*/
--SWIGRUNTIMEINLINE const char *
--SWIG_TypeName(const swig_type_info *ty) {
--  return ty->name;
--}
--
--/*
--  Return the pretty name associated with this type,
--  that is an unmangled type name in a form presentable to the user.
--*/
--SWIGRUNTIME const char *
--SWIG_TypePrettyName(const swig_type_info *type) {
--  /* The "str" field contains the equivalent pretty names of the
--     type, separated by vertical-bar characters.  We choose
--     to print the last name, as it is often (?) the most
--     specific. */
--  if (!type) return NULL;
--  if (type->str != NULL) {
--    const char *last_name = type->str;
--    const char *s;
--    for (s = type->str; *s; s++)
--      if (*s == '|') last_name = s+1;
--    return last_name;
--  }
--  else
--    return type->name;
--}
--
--/* 
--   Set the clientdata field for a type
--*/
--SWIGRUNTIME void
--SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
--  swig_cast_info *cast = ti->cast;
--  /* if (ti->clientdata == clientdata) return; */
--  ti->clientdata = clientdata;
--  
--  while (cast) {
--    if (!cast->converter) {
--      swig_type_info *tc = cast->type;
--      if (!tc->clientdata) {
--      SWIG_TypeClientData(tc, clientdata);
--      }
--    }    
--    cast = cast->next;
--  }
--}
--SWIGRUNTIME void
--SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
--  SWIG_TypeClientData(ti, clientdata);
--  ti->owndata = 1;
--}
--  
--/*
--  Search for a swig_type_info structure only by mangled name
--  Search is a O(log #types)
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_MangledTypeQueryModule(swig_module_info *start, 
--                            swig_module_info *end, 
--                          const char *name) {
--  swig_module_info *iter = start;
--  do {
--    if (iter->size) {
--      register size_t l = 0;
--      register size_t r = iter->size - 1;
--      do {
--      /* since l+r >= 0, we can (>> 1) instead (/ 2) */
--      register size_t i = (l + r) >> 1; 
--      const char *iname = iter->types[i]->name;
--      if (iname) {
--        register int compare = strcmp(name, iname);
--        if (compare == 0) {       
--          return iter->types[i];
--        } else if (compare < 0) {
--          if (i) {
--            r = i - 1;
--          } else {
--            break;
--          }
--        } else if (compare > 0) {
--          l = i + 1;
--        }
--      } else {
--        break; /* should never happen */
--      }
--      } while (l <= r);
--    }
--    iter = iter->next;
--  } while (iter != end);
--  return 0;
--}
--
--/*
--  Search for a swig_type_info structure for either a mangled name or a human readable name.
--  It first searches the mangled names of the types, which is a O(log #types)
--  If a type is not found it then searches the human readable names, which is O(#types).
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeQueryModule(swig_module_info *start, 
--                     swig_module_info *end, 
--                   const char *name) {
--  /* STEP 1: Search the name field using binary search */
--  swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
--  if (ret) {
--    return ret;
--  } else {
--    /* STEP 2: If the type hasn't been found, do a complete search
--       of the str field (the human readable name) */
--    swig_module_info *iter = start;
--    do {
--      register size_t i = 0;
--      for (; i < iter->size; ++i) {
--      if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
--        return iter->types[i];
--      }
--      iter = iter->next;
--    } while (iter != end);
--  }
--  
--  /* neither found a match */
--  return 0;
--}
--
--/* 
--   Pack binary data into a string
--*/
--SWIGRUNTIME char *
--SWIG_PackData(char *c, void *ptr, size_t sz) {
--  static const char hex[17] = "0123456789abcdef";
--  register const unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu =  u + sz;
--  for (; u != eu; ++u) {
--    register unsigned char uu = *u;
--    *(c++) = hex[(uu & 0xf0) >> 4];
--    *(c++) = hex[uu & 0xf];
--  }
--  return c;
--}
--
--/* 
--   Unpack binary data from a string
--*/
--SWIGRUNTIME const char *
--SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
--  register unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu = u + sz;
--  for (; u != eu; ++u) {
--    register char d = *(c++);
--    register unsigned char uu;
--    if ((d >= '0') && (d <= '9'))
--      uu = ((d - '0') << 4);
--    else if ((d >= 'a') && (d <= 'f'))
--      uu = ((d - ('a'-10)) << 4);
--    else 
--      return (char *) 0;
--    d = *(c++);
--    if ((d >= '0') && (d <= '9'))
--      uu |= (d - '0');
--    else if ((d >= 'a') && (d <= 'f'))
--      uu |= (d - ('a'-10));
--    else 
--      return (char *) 0;
--    *u = uu;
--  }
--  return c;
--}
--
--/* 
--   Pack 'void *' into a string buffer.
--*/
--SWIGRUNTIME char *
--SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
--  char *r = buff;
--  if ((2*sizeof(void *) + 2) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,&ptr,sizeof(void *));
--  if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
--  strcpy(r,name);
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      *ptr = (void *) 0;
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sizeof(void *));
--}
--
--SWIGRUNTIME char *
--SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
--  char *r = buff;
--  size_t lname = (name ? strlen(name) : 0);
--  if ((2*sz + 2 + lname) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,ptr,sz);
--  if (lname) {
--    strncpy(r,name,lname+1);
--  } else {
--    *r = 0;
--  }
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      memset(ptr,0,sz);
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sz);
--}
--
--#ifdef __cplusplus
--}
--#endif
--
--/*  Errors in SWIG */
--#define  SWIG_UnknownError               -1 
--#define  SWIG_IOError            -2 
--#define  SWIG_RuntimeError       -3 
--#define  SWIG_IndexError         -4 
--#define  SWIG_TypeError          -5 
--#define  SWIG_DivisionByZero     -6 
--#define  SWIG_OverflowError      -7 
--#define  SWIG_SyntaxError        -8 
--#define  SWIG_ValueError         -9 
--#define  SWIG_SystemError        -10
--#define  SWIG_AttributeError     -11
--#define  SWIG_MemoryError        -12 
--#define  SWIG_NullReferenceError   -13
--
--
--
--/* Compatibility macros for Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--
--#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
--#define PyInt_Check(x) PyLong_Check(x)
--#define PyInt_AsLong(x) PyLong_AsLong(x)
--#define PyInt_FromLong(x) PyLong_FromLong(x)
--#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
--#define PyString_Check(name) PyBytes_Check(name)
--#define PyString_FromString(x) PyUnicode_FromString(x)
--#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
--#define PyString_AsString(str) PyBytes_AsString(str)
--#define PyString_Size(str) PyBytes_Size(str)  
--#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
--#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
--#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
--#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
--
--#endif
--
--#ifndef Py_TYPE
--#  define Py_TYPE(op) ((op)->ob_type)
--#endif
--
--/* SWIG APIs for compatibility of both Python 2 & 3 */
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_FromFormat PyUnicode_FromFormat
--#else
--#  define SWIG_Python_str_FromFormat PyString_FromFormat
--#endif
--
--
--/* Warning: This function will allocate a new string in Python 3,
-- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
-- */
--SWIGINTERN char*
--SWIG_Python_str_AsChar(PyObject *str)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  char *cstr;
--  char *newstr;
--  Py_ssize_t len;
--  str = PyUnicode_AsUTF8String(str);
--  PyBytes_AsStringAndSize(str, &cstr, &len);
--  newstr = (char *) malloc(len+1);
--  memcpy(newstr, cstr, len+1);
--  Py_XDECREF(str);
--  return newstr;
--#else
--  return PyString_AsString(str);
--#endif
--}
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
--#else
--#  define SWIG_Python_str_DelForPy3(x) 
--#endif
--
--
--SWIGINTERN PyObject*
--SWIG_Python_str_FromChar(const char *c)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  return PyUnicode_FromString(c); 
--#else
--  return PyString_FromString(c);
--#endif
--}
--
--/* Add PyOS_snprintf for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
--#  define PyOS_snprintf _snprintf
--# else
--#  define PyOS_snprintf snprintf
--# endif
--#endif
--
--/* A crude PyString_FromFormat implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--
--#ifndef SWIG_PYBUFFER_SIZE
--# define SWIG_PYBUFFER_SIZE 1024
--#endif
--
--static PyObject *
--PyString_FromFormat(const char *fmt, ...) {
--  va_list ap;
--  char buf[SWIG_PYBUFFER_SIZE * 2];
--  int res;
--  va_start(ap, fmt);
--  res = vsnprintf(buf, sizeof(buf), fmt, ap);
--  va_end(ap);
--  return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
--}
--#endif
--
--/* Add PyObject_Del for old Pythons */
--#if PY_VERSION_HEX < 0x01060000
--# define PyObject_Del(op) PyMem_DEL((op))
--#endif
--#ifndef PyObject_DEL
--# define PyObject_DEL PyObject_Del
--#endif
--
--/* A crude PyExc_StopIteration exception for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# ifndef PyExc_StopIteration
--#  define PyExc_StopIteration PyExc_RuntimeError
--# endif
--# ifndef PyObject_GenericGetAttr
--#  define PyObject_GenericGetAttr 0
--# endif
--#endif
--
--/* Py_NotImplemented is defined in 2.1 and up. */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef Py_NotImplemented
--#  define Py_NotImplemented PyExc_RuntimeError
--# endif
--#endif
--
--/* A crude PyString_AsStringAndSize implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef PyString_AsStringAndSize
--#  define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
--# endif
--#endif
--
--/* PySequence_Size for old Pythons */
--#if PY_VERSION_HEX < 0x02000000
--# ifndef PySequence_Size
--#  define PySequence_Size PySequence_Length
--# endif
--#endif
--
--/* PyBool_FromLong for old Pythons */
--#if PY_VERSION_HEX < 0x02030000
--static
--PyObject *PyBool_FromLong(long ok)
--{
--  PyObject *result = ok ? Py_True : Py_False;
--  Py_INCREF(result);
--  return result;
--}
--#endif
--
--/* Py_ssize_t for old Pythons */
--/* This code is as recommended by: */
--/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
--#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
--typedef int Py_ssize_t;
--# define PY_SSIZE_T_MAX INT_MAX
--# define PY_SSIZE_T_MIN INT_MIN
--typedef inquiry lenfunc;
--typedef intargfunc ssizeargfunc;
--typedef intintargfunc ssizessizeargfunc;
--typedef intobjargproc ssizeobjargproc;
--typedef intintobjargproc ssizessizeobjargproc;
--typedef getreadbufferproc readbufferproc;
--typedef getwritebufferproc writebufferproc;
--typedef getsegcountproc segcountproc;
--typedef getcharbufferproc charbufferproc;
--static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
--{
--  long result = 0;
--  PyObject *i = PyNumber_Int(x);
--  if (i) {
--    result = PyInt_AsLong(i);
--    Py_DECREF(i);
--  }
--  return result;
--}
--#endif
--
--#if PY_VERSION_HEX < 0x02050000
--#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
--#endif
--
--#if PY_VERSION_HEX < 0x02040000
--#define Py_VISIT(op)                          \
--  do {                                                \
--    if (op) {                                 \
--      int vret = visit((op), arg);            \
--      if (vret)                                       \
--        return vret;                          \
--    }                                         \
--  } while (0)
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef struct {
--  PyTypeObject type;
--  PyNumberMethods as_number;
--  PyMappingMethods as_mapping;
--  PySequenceMethods as_sequence;
--  PyBufferProcs as_buffer;
--  PyObject *name, *slots;
--} PyHeapTypeObject;
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef destructor freefunc;
--#endif
--
--#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
--     (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
--     (PY_MAJOR_VERSION > 3))
--# define SWIGPY_USE_CAPSULE
--# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
--#endif
--
--#if PY_VERSION_HEX < 0x03020000
--#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
--#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
--#endif
--
--/* -----------------------------------------------------------------------------
-- * error manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIME PyObject*
--SWIG_Python_ErrorType(int code) {
--  PyObject* type = 0;
--  switch(code) {
--  case SWIG_MemoryError:
--    type = PyExc_MemoryError;
--    break;
--  case SWIG_IOError:
--    type = PyExc_IOError;
--    break;
--  case SWIG_RuntimeError:
--    type = PyExc_RuntimeError;
--    break;
--  case SWIG_IndexError:
--    type = PyExc_IndexError;
--    break;
--  case SWIG_TypeError:
--    type = PyExc_TypeError;
--    break;
--  case SWIG_DivisionByZero:
--    type = PyExc_ZeroDivisionError;
--    break;
--  case SWIG_OverflowError:
--    type = PyExc_OverflowError;
--    break;
--  case SWIG_SyntaxError:
--    type = PyExc_SyntaxError;
--    break;
--  case SWIG_ValueError:
--    type = PyExc_ValueError;
--    break;
--  case SWIG_SystemError:
--    type = PyExc_SystemError;
--    break;
--  case SWIG_AttributeError:
--    type = PyExc_AttributeError;
--    break;
--  default:
--    type = PyExc_RuntimeError;
--  }
--  return type;
--}
--
--
--SWIGRUNTIME void
--SWIG_Python_AddErrorMsg(const char* mesg)
--{
--  PyObject *type = 0;
--  PyObject *value = 0;
--  PyObject *traceback = 0;
--
--  if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
--  if (value) {
--    char *tmp;
--    PyObject *old_str = PyObject_Str(value);
--    PyErr_Clear();
--    Py_XINCREF(type);
--
--    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(old_str);
--    Py_DECREF(value);
--  } else {
--    PyErr_SetString(PyExc_RuntimeError, mesg);
--  }
--}
--
--#if defined(SWIG_PYTHON_NO_THREADS)
--#  if defined(SWIG_PYTHON_THREADS)
--#    undef SWIG_PYTHON_THREADS
--#  endif
--#endif
--#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
--#  if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
--#    if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
--#      define SWIG_PYTHON_USE_GIL
--#    endif
--#  endif
--#  if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
--#    ifndef SWIG_PYTHON_INITIALIZE_THREADS
--#     define SWIG_PYTHON_INITIALIZE_THREADS  PyEval_InitThreads() 
--#    endif
--#    ifdef __cplusplus /* C++ code */
--       class SWIG_Python_Thread_Block {
--         bool status;
--         PyGILState_STATE state;
--       public:
--         void end() { if (status) { PyGILState_Release(state); status = false;} }
--         SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
--         ~SWIG_Python_Thread_Block() { end(); }
--       };
--       class SWIG_Python_Thread_Allow {
--         bool status;
--         PyThreadState *save;
--       public:
--         void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
--         SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
--         ~SWIG_Python_Thread_Allow() { end(); }
--       };
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   SWIG_Python_Thread_Block _swig_thread_block
--#      define SWIG_PYTHON_THREAD_END_BLOCK     _swig_thread_block.end()
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   SWIG_Python_Thread_Allow _swig_thread_allow
--#      define SWIG_PYTHON_THREAD_END_ALLOW     _swig_thread_allow.end()
--#    else /* C code */
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
--#      define SWIG_PYTHON_THREAD_END_BLOCK     PyGILState_Release(_swig_thread_block)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   PyThreadState *_swig_thread_allow = PyEval_SaveThread()
--#      define SWIG_PYTHON_THREAD_END_ALLOW     PyEval_RestoreThread(_swig_thread_allow)
--#    endif
--#  else /* Old thread way, not implemented, user must provide it */
--#    if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
--#      define SWIG_PYTHON_INITIALIZE_THREADS
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
--#      define SWIG_PYTHON_THREAD_END_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
--#      define SWIG_PYTHON_THREAD_END_ALLOW
--#    endif
--#  endif
--#else /* No thread support */
--#  define SWIG_PYTHON_INITIALIZE_THREADS
--#  define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#  define SWIG_PYTHON_THREAD_END_BLOCK
--#  define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#  define SWIG_PYTHON_THREAD_END_ALLOW
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Python API portion that goes into the runtime
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Constant declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Constant Types */
--#define SWIG_PY_POINTER 4
--#define SWIG_PY_BINARY  5
--
--/* Constant information structure */
--typedef struct swig_const_info {
--  int type;
--  char *name;
--  long lvalue;
--  double dvalue;
--  void   *pvalue;
--  swig_type_info **ptype;
--} swig_const_info;
--
--
--/* -----------------------------------------------------------------------------
-- * Wrapper of PyInstanceMethod_New() used in Python 3
-- * It is exported to the generated module, used for -fastproxy
-- * ----------------------------------------------------------------------------- */
--#if PY_VERSION_HEX >= 0x03000000
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
--{
--  return PyInstanceMethod_New(func);
--}
--#else
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
--{
--  return NULL;
--}
--#endif
--
--#ifdef __cplusplus
--}
--#endif
--
--
--/* -----------------------------------------------------------------------------
-- * pyrun.swg
-- *
-- * This file contains the runtime support for Python modules
-- * and includes code for managing global variables and pointer
-- * type checking.
-- *
-- * ----------------------------------------------------------------------------- */
--
--/* Common SWIG API */
--
--/* for raw pointers */
--#define SWIG_Python_ConvertPtr(obj, pptr, type, flags)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
--#define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Python_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
--
--#ifdef SWIGPYTHON_BUILTIN
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(self, ptr, type, flags)
--#else
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--#endif
--
--#define SWIG_InternalNewPointerObj(ptr, type, flags)  SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--
--#define SWIG_CheckImplicit(ty)                          SWIG_Python_CheckImplicit(ty) 
--#define SWIG_AcquirePtr(ptr, src)                       SWIG_Python_AcquirePtr(ptr, src)
--#define swig_owntype                                    int
--
--/* for raw packed data */
--#define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--/* for class or struct pointers */
--#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_NewInstanceObj(ptr, type, flags)           SWIG_NewPointerObj(ptr, type, flags)
--
--/* for C or C++ function pointers */
--#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
--#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
--
--/* for C++ member pointers, ie, member methods */
--#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--
--/* Runtime API */
--
--#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
--#define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
--#define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
--
--#define SWIG_SetErrorObj                                SWIG_Python_SetErrorObj                            
--#define SWIG_SetErrorMsg                              SWIG_Python_SetErrorMsg                            
--#define SWIG_ErrorType(code)                          SWIG_Python_ErrorType(code)                        
--#define SWIG_Error(code, msg)                         SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) 
--#define SWIG_fail                                     goto fail                                          
--
--
--/* Runtime API implementation */
--
--/* Error manipulation */
--
--SWIGINTERN void 
--SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
--  PyErr_SetObject(errtype, obj);
--  Py_DECREF(obj);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--SWIGINTERN void 
--SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--  PyErr_SetString(errtype, msg);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--#define SWIG_Python_Raise(obj, type, desc)  SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
--
--/* Set a constant value */
--
--#if defined(SWIGPYTHON_BUILTIN)
--
--SWIGINTERN void
--SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
--  PyObject *s = PyString_InternFromString(key);
--  PyList_Append(seq, s);
--  Py_DECREF(s);
--}
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);
--  if (public_interface)
--    SwigPyBuiltin_AddPublicSymbol(public_interface, name);
--}
--
--#else
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);                            
--}
--
--#endif
--
--/* Append a value to the result obj */
--
--SWIGINTERN PyObject*
--SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
--#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyList_Check(result)) {
--      PyObject *o2 = result;
--      result = PyList_New(1);
--      PyList_SetItem(result, 0, o2);
--    }
--    PyList_Append(result,obj);
--    Py_DECREF(obj);
--  }
--  return result;
--#else
--  PyObject*   o2;
--  PyObject*   o3;
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyTuple_Check(result)) {
--      o2 = result;
--      result = PyTuple_New(1);
--      PyTuple_SET_ITEM(result, 0, o2);
--    }
--    o3 = PyTuple_New(1);
--    PyTuple_SET_ITEM(o3, 0, obj);
--    o2 = result;
--    result = PySequence_Concat(o2, o3);
--    Py_DECREF(o2);
--    Py_DECREF(o3);
--  }
--  return result;
--#endif
--}
--
--/* Unpack the argument tuple */
--
--SWIGINTERN int
--SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
--{
--  if (!args) {
--    if (!min && !max) {
--      return 1;
--    } else {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", 
--                 name, (min == max ? "" : "at least "), (int)min);
--      return 0;
--    }
--  }  
--  if (!PyTuple_Check(args)) {
--    if (min <= 1 && max >= 1) {
--      register int i;
--      objs[0] = args;
--      for (i = 1; i < max; ++i) {
--      objs[i] = 0;
--      }
--      return 2;
--    }
--    PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
--    return 0;
--  } else {
--    register Py_ssize_t l = PyTuple_GET_SIZE(args);
--    if (l < min) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at least "), (int)min, (int)l);
--      return 0;
--    } else if (l > max) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at most "), (int)max, (int)l);
--      return 0;
--    } else {
--      register int i;
--      for (i = 0; i < l; ++i) {
--      objs[i] = PyTuple_GET_ITEM(args, i);
--      }
--      for (; l < max; ++l) {
--      objs[l] = 0;
--      }
--      return i + 1;
--    }    
--  }
--}
--
--/* A functor is a function object with one single object argument */
--#if PY_VERSION_HEX >= 0x02020000
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunctionObjArgs(functor, obj, NULL);
--#else
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunction(functor, "O", obj);
--#endif
--
--/*
--  Helper for static pointer initialization for both C and C++ code, for example
--  static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
--*/
--#ifdef __cplusplus
--#define SWIG_STATIC_POINTER(var)  var
--#else
--#define SWIG_STATIC_POINTER(var)  var = 0; if (!var) var
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Pointer declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_NOSHADOW       (SWIG_POINTER_OWN      << 1)
--#define SWIG_POINTER_NEW            (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
--
--#define SWIG_POINTER_IMPLICIT_CONV  (SWIG_POINTER_DISOWN   << 1)
--
--#define SWIG_BUILTIN_TP_INIT      (SWIG_POINTER_OWN << 2)
--#define SWIG_BUILTIN_INIT         (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*  How to access Py_None */
--#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#  ifndef SWIG_PYTHON_NO_BUILD_NONE
--#    ifndef SWIG_PYTHON_BUILD_NONE
--#      define SWIG_PYTHON_BUILD_NONE
--#    endif
--#  endif
--#endif
--
--#ifdef SWIG_PYTHON_BUILD_NONE
--#  ifdef Py_None
--#   undef Py_None
--#   define Py_None SWIG_Py_None()
--#  endif
--SWIGRUNTIMEINLINE PyObject * 
--_SWIG_Py_None(void)
--{
--  PyObject *none = Py_BuildValue((char*)"");
--  Py_DECREF(none);
--  return none;
--}
--SWIGRUNTIME PyObject * 
--SWIG_Py_None(void)
--{
--  static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
--  return none;
--}
--#endif
--
--/* The python void return value */
--
--SWIGRUNTIMEINLINE PyObject * 
--SWIG_Py_Void(void)
--{
--  PyObject *none = Py_None;
--  Py_INCREF(none);
--  return none;
--}
--
--/* SwigPyClientData */
--
--typedef struct {
--  PyObject *klass;
--  PyObject *newraw;
--  PyObject *newargs;
--  PyObject *destroy;
--  int delargs;
--  int implicitconv;
--  PyTypeObject *pytype;
--} SwigPyClientData;
--
--SWIGRUNTIMEINLINE int 
--SWIG_Python_CheckImplicit(swig_type_info *ty)
--{
--  SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
--  return data ? data->implicitconv : 0;
--}
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_ExceptionType(swig_type_info *desc) {
--  SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
--  PyObject *klass = data ? data->klass : 0;
--  return (klass ? klass : PyExc_RuntimeError);
--}
--
--
--SWIGRUNTIME SwigPyClientData * 
--SwigPyClientData_New(PyObject* obj)
--{
--  if (!obj) {
--    return 0;
--  } else {
--    SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
--    /* the klass element */
--    data->klass = obj;
--    Py_INCREF(data->klass);
--    /* the newraw method and newargs arguments used to create a new raw instance */
--    if (PyClass_Check(obj)) {
--      data->newraw = 0;
--      data->newargs = obj;
--      Py_INCREF(obj);
--    } else {
--#if (PY_VERSION_HEX < 0x02020000)
--      data->newraw = 0;
--#else
--      data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
--#endif
--      if (data->newraw) {
--      Py_INCREF(data->newraw);
--      data->newargs = PyTuple_New(1);
--      PyTuple_SetItem(data->newargs, 0, obj);
--      } else {
--      data->newargs = obj;
--      }
--      Py_INCREF(data->newargs);
--    }
--    /* the destroy method, aka as the C++ delete method */
--    data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      data->destroy = 0;
--    }
--    if (data->destroy) {
--      int flags;
--      Py_INCREF(data->destroy);
--      flags = PyCFunction_GET_FLAGS(data->destroy);
--#ifdef METH_O
--      data->delargs = !(flags & (METH_O));
--#else
--      data->delargs = 0;
--#endif
--    } else {
--      data->delargs = 0;
--    }
--    data->implicitconv = 0;
--    data->pytype = 0;
--    return data;
--  }
--}
--
--SWIGRUNTIME void 
--SwigPyClientData_Del(SwigPyClientData *data) {
--  Py_XDECREF(data->newraw);
--  Py_XDECREF(data->newargs);
--  Py_XDECREF(data->destroy);
--}
--
--/* =============== SwigPyObject =====================*/
--
--typedef struct {
--  PyObject_HEAD
--  void *ptr;
--  swig_type_info *ty;
--  int own;
--  PyObject *next;
--#ifdef SWIGPYTHON_BUILTIN
--  PyObject *dict;
--#endif
--} SwigPyObject;
--
--SWIGRUNTIME PyObject *
--SwigPyObject_long(SwigPyObject *v)
--{
--  return PyLong_FromVoidPtr(v->ptr);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_format(const char* fmt, SwigPyObject *v)
--{
--  PyObject *res = NULL;
--  PyObject *args = PyTuple_New(1);
--  if (args) {
--    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
--      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
--      if (ofmt) {
--#if PY_VERSION_HEX >= 0x03000000
--      res = PyUnicode_Format(ofmt,args);
--#else
--      res = PyString_Format(ofmt,args);
--#endif
--      Py_DECREF(ofmt);
--      }
--      Py_DECREF(args);
--    }
--  }
--  return res;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_oct(SwigPyObject *v)
--{
--  return SwigPyObject_format("%o",v);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_hex(SwigPyObject *v)
--{
--  return SwigPyObject_format("%x",v);
--}
--
--SWIGRUNTIME PyObject *
--#ifdef METH_NOARGS
--SwigPyObject_repr(SwigPyObject *v)
--#else
--SwigPyObject_repr(SwigPyObject *v, PyObject *args)
--#endif
--{
--  const char *name = SWIG_TypePrettyName(v->ty);
--  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
--  if (v->next) {
--# ifdef METH_NOARGS
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
--# else
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
--# endif
--# if PY_VERSION_HEX >= 0x03000000
--    PyObject *joined = PyUnicode_Concat(repr, nrep);
--    Py_DecRef(repr);
--    Py_DecRef(nrep);
--    repr = joined;
--# else
--    PyString_ConcatAndDel(&repr,nrep);
--# endif
--  }
--  return repr;  
--}
--
--SWIGRUNTIME int
--SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char *str;
--#ifdef METH_NOARGS
--  PyObject *repr = SwigPyObject_repr(v);
--#else
--  PyObject *repr = SwigPyObject_repr(v, NULL);
--#endif
--  if (repr) {
--    str = SWIG_Python_str_AsChar(repr); 
--    fputs(str, fp);
--    SWIG_Python_str_DelForPy3(str);
--    Py_DECREF(repr);
--    return 0; 
--  } else {
--    return 1; 
--  }
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_str(SwigPyObject *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
--    SWIG_Python_str_FromChar(result) : 0;
--}
--
--SWIGRUNTIME int
--SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
--{
--  void *i = v->ptr;
--  void *j = w->ptr;
--  return (i < j) ? -1 : ((i > j) ? 1 : 0);
--}
--
--/* Added for Python 3.x, would it also be useful for Python 2.x? */
--SWIGRUNTIME PyObject*
--SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
--{
--  PyObject* res;
--  if( op != Py_EQ && op != Py_NE ) {
--    Py_INCREF(Py_NotImplemented);
--    return Py_NotImplemented;
--  }
--  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
--  return res;  
--}
--
--
--SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
--
--#ifdef SWIGPYTHON_BUILTIN
--static swig_type_info *SwigPyObject_stype = 0;
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--    SwigPyClientData *cd;
--    assert(SwigPyObject_stype);
--    cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--    assert(cd);
--    assert(cd->pytype);
--    return cd->pytype;
--}
--#else
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
--  return type;
--}
--#endif
--
--SWIGRUNTIMEINLINE int
--SwigPyObject_Check(PyObject *op) {
--#ifdef SWIGPYTHON_BUILTIN
--  PyTypeObject *target_tp = SwigPyObject_type();
--  if (PyType_IsSubtype(op->ob_type, target_tp))
--    return 1;
--  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
--#else
--  return (Py_TYPE(op) == SwigPyObject_type())
--    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
--#endif
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
--
--SWIGRUNTIME void
--SwigPyObject_dealloc(PyObject *v)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  PyObject *next = sobj->next;
--  if (sobj->own == SWIG_POINTER_OWN) {
--    swig_type_info *ty = sobj->ty;
--    SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--    PyObject *destroy = data ? data->destroy : 0;
--    if (destroy) {
--      /* destroy is always a VARARGS method */
--      PyObject *res;
--      if (data->delargs) {
--      /* we need to create a temporary object to carry the destroy operation */
--      PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
--      res = SWIG_Python_CallFunctor(destroy, tmp);
--      Py_DECREF(tmp);
--      } else {
--      PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
--      PyObject *mself = PyCFunction_GET_SELF(destroy);
--      res = ((*meth)(mself, v));
--      }
--      Py_XDECREF(res);
--    } 
--#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
--    else {
--      const char *name = SWIG_TypePrettyName(ty);
--      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
--    }
--#endif
--  } 
--  Py_XDECREF(next);
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyObject* 
--SwigPyObject_append(PyObject* v, PyObject* next)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--#ifndef METH_O
--  PyObject *tmp = 0;
--  if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
--  next = tmp;
--#endif
--  if (!SwigPyObject_Check(next)) {
--    return NULL;
--  }
--  sobj->next = next;
--  Py_INCREF(next);
--  return SWIG_Py_Void();
--}
--
--SWIGRUNTIME PyObject* 
--#ifdef METH_NOARGS
--SwigPyObject_next(PyObject* v)
--#else
--SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  if (sobj->next) {    
--    Py_INCREF(sobj->next);
--    return sobj->next;
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_disown(PyObject *v)
--#else
--SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = 0;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_acquire(PyObject *v)
--#else
--SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = SWIG_POINTER_OWN;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--SwigPyObject_own(PyObject *v, PyObject *args)
--{
--  PyObject *val = 0;
--#if (PY_VERSION_HEX < 0x02020000)
--  if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
--#elif (PY_VERSION_HEX < 0x02050000)
--  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
--#else
--  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
--#endif
--    {
--      return NULL;
--    } 
--  else
--    {
--      SwigPyObject *sobj = (SwigPyObject *)v;
--      PyObject *obj = PyBool_FromLong(sobj->own);
--      if (val) {
--#ifdef METH_NOARGS
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v);
--      } else {
--        SwigPyObject_disown(v);
--      }
--#else
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v,args);
--      } else {
--        SwigPyObject_disown(v,args);
--      }
--#endif
--      } 
--      return obj;
--    }
--}
--
--#ifdef METH_O
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#else
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#endif
--
--#if PY_VERSION_HEX < 0x02020000
--SWIGINTERN PyObject *
--SwigPyObject_getattr(SwigPyObject *sobj,char *name)
--{
--  return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
--}
--#endif
--
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_TypeOnce(void) {
--  static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
--
--  static PyNumberMethods SwigPyObject_as_number = {
--    (binaryfunc)0, /*nb_add*/
--    (binaryfunc)0, /*nb_subtract*/
--    (binaryfunc)0, /*nb_multiply*/
--    /* nb_divide removed in Python 3 */
--#if PY_VERSION_HEX < 0x03000000
--    (binaryfunc)0, /*nb_divide*/
--#endif
--    (binaryfunc)0, /*nb_remainder*/
--    (binaryfunc)0, /*nb_divmod*/
--    (ternaryfunc)0,/*nb_power*/
--    (unaryfunc)0,  /*nb_negative*/
--    (unaryfunc)0,  /*nb_positive*/
--    (unaryfunc)0,  /*nb_absolute*/
--    (inquiry)0,    /*nb_nonzero*/
--    0,                   /*nb_invert*/
--    0,                   /*nb_lshift*/
--    0,                   /*nb_rshift*/
--    0,                   /*nb_and*/
--    0,                   /*nb_xor*/
--    0,                   /*nb_or*/
--#if PY_VERSION_HEX < 0x03000000
--    0,   /*nb_coerce*/
--#endif
--    (unaryfunc)SwigPyObject_long, /*nb_int*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_long, /*nb_long*/
--#else
--    0, /*nb_reserved*/
--#endif
--    (unaryfunc)0,                 /*nb_float*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
--    (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
--#endif
--#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
--#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
--#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
--#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
--    0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
--#endif
--  };
--
--  static PyTypeObject swigpyobject_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyObject",               /* tp_name */
--      sizeof(SwigPyObject),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyObject_print,        /* tp_print */
--#if PY_VERSION_HEX < 0x02020000
--      (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
--#else
--      (getattrfunc)0,                       /* tp_getattr */
--#endif
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX >= 0x03000000
--    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
--#else
--      (cmpfunc)SwigPyObject_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyObject_repr,          /* tp_repr */
--      &SwigPyObject_as_number,              /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyObject_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigobject_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      swigobject_methods,                   /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpyobject_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpyobject_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpyobject_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpyobject_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
--{
--  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
--  if (sobj) {
--    sobj->ptr  = ptr;
--    sobj->ty   = ty;
--    sobj->own  = own;
--    sobj->next = 0;
--  }
--  return (PyObject *)sobj;
--}
--
--/* -----------------------------------------------------------------------------
-- * Implements a simple Swig Packed type, and use it instead of string
-- * ----------------------------------------------------------------------------- */
--
--typedef struct {
--  PyObject_HEAD
--  void *pack;
--  swig_type_info *ty;
--  size_t size;
--} SwigPyPacked;
--
--SWIGRUNTIME int
--SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char result[SWIG_BUFFER_SIZE];
--  fputs("<Swig Packed ", fp); 
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    fputs("at ", fp); 
--    fputs(result, fp); 
--  }
--  fputs(v->ty->name,fp); 
--  fputs(">", fp);
--  return 0; 
--}
--  
--SWIGRUNTIME PyObject *
--SwigPyPacked_repr(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
--  }  
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_str(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
--    return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromChar(v->ty->name);
--  }  
--}
--
--SWIGRUNTIME int
--SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
--{
--  size_t i = v->size;
--  size_t j = w->size;
--  int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
--  return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
--}
--
--SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
--  return type;
--}
--
--SWIGRUNTIMEINLINE int
--SwigPyPacked_Check(PyObject *op) {
--  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
--    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
--}
--
--SWIGRUNTIME void
--SwigPyPacked_dealloc(PyObject *v)
--{
--  if (SwigPyPacked_Check(v)) {
--    SwigPyPacked *sobj = (SwigPyPacked *) v;
--    free(sobj->pack);
--  }
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_TypeOnce(void) {
--  static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
--  static PyTypeObject swigpypacked_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX>=0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyPacked",               /* tp_name */
--      sizeof(SwigPyPacked),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyPacked_print,        /* tp_print */
--      (getattrfunc)0,                       /* tp_getattr */
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX>=0x03000000
--      0, /* tp_reserved in 3.0.1 */
--#else
--      (cmpfunc)SwigPyPacked_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyPacked_repr,          /* tp_repr */
--      0,                                    /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyPacked_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigpacked_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      0,                                    /* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      0,                                    /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpypacked_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpypacked_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpypacked_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpypacked_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
--{
--  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
--  if (sobj) {
--    void *pack = malloc(size);
--    if (pack) {
--      memcpy(pack, ptr, size);
--      sobj->pack = pack;
--      sobj->ty   = ty;
--      sobj->size = size;
--    } else {
--      PyObject_DEL((PyObject *) sobj);
--      sobj = 0;
--    }
--  }
--  return (PyObject *) sobj;
--}
--
--SWIGRUNTIME swig_type_info *
--SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
--{
--  if (SwigPyPacked_Check(obj)) {
--    SwigPyPacked *sobj = (SwigPyPacked *)obj;
--    if (sobj->size != size) return 0;
--    memcpy(ptr, sobj->pack, size);
--    return sobj->ty;
--  } else {
--    return 0;
--  }
--}
--
--/* -----------------------------------------------------------------------------
-- * pointers/data manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIMEINLINE PyObject *
--_SWIG_This(void)
--{
--    return SWIG_Python_str_FromChar("this");
--}
--
--static PyObject *swig_this = NULL;
--
--SWIGRUNTIME PyObject *
--SWIG_This(void)
--{
--  if (swig_this == NULL)
--    swig_this = _SWIG_This();
--  return swig_this;
--}
--
--/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
--
--/* TODO: I don't know how to implement the fast getset in Python 3 right now */
--#if PY_VERSION_HEX>=0x03000000
--#define SWIG_PYTHON_SLOW_GETSET_THIS 
--#endif
--
--SWIGRUNTIME SwigPyObject *
--SWIG_Python_GetSwigThis(PyObject *pyobj) 
--{
--  PyObject *obj;
--
--  if (SwigPyObject_Check(pyobj))
--    return (SwigPyObject *) pyobj;
--
--#ifdef SWIGPYTHON_BUILTIN
--  (void)obj;
--# ifdef PyWeakref_CheckProxy
--  if (PyWeakref_CheckProxy(pyobj)) {
--    pyobj = PyWeakref_GET_OBJECT(pyobj);
--    if (pyobj && SwigPyObject_Check(pyobj))
--      return (SwigPyObject*) pyobj;
--  }
--# endif
--  return NULL;
--#else
--
--  obj = 0;
--
--#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
--  if (PyInstance_Check(pyobj)) {
--    obj = _PyInstance_Lookup(pyobj, SWIG_This());      
--  } else {
--    PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
--    if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
--    } else {
--#ifdef PyWeakref_CheckProxy
--      if (PyWeakref_CheckProxy(pyobj)) {
--      PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
--      return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
--      }
--#endif
--      obj = PyObject_GetAttr(pyobj,SWIG_This());
--      if (obj) {
--      Py_DECREF(obj);
--      } else {
--      if (PyErr_Occurred()) PyErr_Clear();
--      return 0;
--      }
--    }
--  }
--#else
--  obj = PyObject_GetAttr(pyobj,SWIG_This());
--  if (obj) {
--    Py_DECREF(obj);
--  } else {
--    if (PyErr_Occurred()) PyErr_Clear();
--    return 0;
--  }
--#endif
--  if (obj && !SwigPyObject_Check(obj)) {
--    /* a PyObject is called 'this', try to get the 'real this'
--       SwigPyObject from it */ 
--    return SWIG_Python_GetSwigThis(obj);
--  }
--  return (SwigPyObject *)obj;
--#endif
--}
--
--/* Acquire a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_AcquirePtr(PyObject *obj, int own) {
--  if (own == SWIG_POINTER_OWN) {
--    SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
--    if (sobj) {
--      int oldown = sobj->own;
--      sobj->own = own;
--      return oldown;
--    }
--  }
--  return 0;
--}
--
--/* Convert a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
--  int res;
--  SwigPyObject *sobj;
--
--  if (!obj)
--    return SWIG_ERROR;
--  if (obj == Py_None) {
--    if (ptr)
--      *ptr = 0;
--    return SWIG_OK;
--  }
--
--  res = SWIG_ERROR;
--
--  sobj = SWIG_Python_GetSwigThis(obj);
--  if (own)
--    *own = 0;
--  while (sobj) {
--    void *vptr = sobj->ptr;
--    if (ty) {
--      swig_type_info *to = sobj->ty;
--      if (to == ty) {
--        /* no type cast needed */
--        if (ptr) *ptr = vptr;
--        break;
--      } else {
--        swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--        if (!tc) {
--          sobj = (SwigPyObject *)sobj->next;
--        } else {
--          if (ptr) {
--            int newmemory = 0;
--            *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--            if (newmemory == SWIG_CAST_NEW_MEMORY) {
--              assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
--              if (own)
--                *own = *own | SWIG_CAST_NEW_MEMORY;
--            }
--          }
--          break;
--        }
--      }
--    } else {
--      if (ptr) *ptr = vptr;
--      break;
--    }
--  }
--  if (sobj) {
--    if (own)
--      *own = *own | sobj->own;
--    if (flags & SWIG_POINTER_DISOWN) {
--      sobj->own = 0;
--    }
--    res = SWIG_OK;
--  } else {
--    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
--      SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--      if (data && !data->implicitconv) {
--        PyObject *klass = data->klass;
--        if (klass) {
--          PyObject *impconv;
--          data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
--          impconv = SWIG_Python_CallFunctor(klass, obj);
--          data->implicitconv = 0;
--          if (PyErr_Occurred()) {
--            PyErr_Clear();
--            impconv = 0;
--          }
--          if (impconv) {
--            SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
--            if (iobj) {
--              void *vptr;
--              res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
--              if (SWIG_IsOK(res)) {
--                if (ptr) {
--                  *ptr = vptr;
--                  /* transfer the ownership to 'ptr' */
--                  iobj->own = 0;
--                  res = SWIG_AddCast(res);
--                  res = SWIG_AddNewMask(res);
--                } else {
--                  res = SWIG_AddCast(res);                
--                }
--              }
--            }
--            Py_DECREF(impconv);
--          }
--        }
--      }
--    }
--  }
--  return res;
--}
--
--/* Convert a function ptr value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
--  if (!PyCFunction_Check(obj)) {
--    return SWIG_ConvertPtr(obj, ptr, ty, 0);
--  } else {
--    void *vptr = 0;
--    
--    /* here we get the method pointer for callbacks */
--    const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
--    const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
--    if (desc)
--      desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
--    if (!desc) 
--      return SWIG_ERROR;
--    if (ty) {
--      swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
--      if (tc) {
--        int newmemory = 0;
--        *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--        assert(!newmemory); /* newmemory handling not yet implemented */
--      } else {
--        return SWIG_ERROR;
--      }
--    } else {
--      *ptr = vptr;
--    }
--    return SWIG_OK;
--  }
--}
--
--/* Convert a packed value value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
--  swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
--  if (!to) return SWIG_ERROR;
--  if (ty) {
--    if (to != ty) {
--      /* check type cast? */
--      swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--      if (!tc) return SWIG_ERROR;
--    }
--  }
--  return SWIG_OK;
--}  
--
--/* -----------------------------------------------------------------------------
-- * Create a new pointer object
-- * ----------------------------------------------------------------------------- */
--
--/*
--  Create a new instance object, without calling __init__, and set the
--  'this' attribute.
--*/
--
--SWIGRUNTIME PyObject* 
--SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
--{
--#if (PY_VERSION_HEX >= 0x02020000)
--  PyObject *inst = 0;
--  PyObject *newraw = data->newraw;
--  if (newraw) {
--    inst = PyObject_Call(newraw, data->newargs, NULL);
--    if (inst) {
--#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
--      PyObject **dictptr = _PyObject_GetDictPtr(inst);
--      if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      if (dict == NULL) {
--        dict = PyDict_New();
--        *dictptr = dict;
--        PyDict_SetItem(dict, SWIG_This(), swig_this);
--      }
--      }
--#else
--      PyObject *key = SWIG_This();
--      PyObject_SetAttr(inst, key, swig_this);
--#endif
--    }
--  } else {
--#if PY_VERSION_HEX >= 0x03000000
--    inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
--    if (inst) {
--      PyObject_SetAttr(inst, SWIG_This(), swig_this);
--      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
--    }
--#else
--    PyObject *dict = PyDict_New();
--    if (dict) {
--      PyDict_SetItem(dict, SWIG_This(), swig_this);
--      inst = PyInstance_NewRaw(data->newargs, dict);
--      Py_DECREF(dict);
--    }
--#endif
--  }
--  return inst;
--#else
--#if (PY_VERSION_HEX >= 0x02010000)
--  PyObject *inst = 0;
--  PyObject *dict = PyDict_New();
--  if (dict) {
--    PyDict_SetItem(dict, SWIG_This(), swig_this);
--    inst = PyInstance_NewRaw(data->newargs, dict);
--    Py_DECREF(dict);
--  }
--  return (PyObject *) inst;
--#else
--  PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
--  if (inst == NULL) {
--    return NULL;
--  }
--  inst->in_class = (PyClassObject *)data->newargs;
--  Py_INCREF(inst->in_class);
--  inst->in_dict = PyDict_New();
--  if (inst->in_dict == NULL) {
--    Py_DECREF(inst);
--    return NULL;
--  }
--#ifdef Py_TPFLAGS_HAVE_WEAKREFS
--  inst->in_weakreflist = NULL;
--#endif
--#ifdef Py_TPFLAGS_GC
--  PyObject_GC_Init(inst);
--#endif
--  PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
--  return (PyObject *) inst;
--#endif
--#endif
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
--{
-- PyObject *dict;
--#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
-- PyObject **dictptr = _PyObject_GetDictPtr(inst);
-- if (dictptr != NULL) {
--   dict = *dictptr;
--   if (dict == NULL) {
--     dict = PyDict_New();
--     *dictptr = dict;
--   }
--   PyDict_SetItem(dict, SWIG_This(), swig_this);
--   return;
-- }
--#endif
-- dict = PyObject_GetAttrString(inst, (char*)"__dict__");
-- PyDict_SetItem(dict, SWIG_This(), swig_this);
-- Py_DECREF(dict);
--} 
--
--
--SWIGINTERN PyObject *
--SWIG_Python_InitShadowInstance(PyObject *args) {
--  PyObject *obj[2];
--  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
--    return NULL;
--  } else {
--    SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
--    if (sthis) {
--      SwigPyObject_append((PyObject*) sthis, obj[1]);
--    } else {
--      SWIG_Python_SetSwigThis(obj[0], obj[1]);
--    }
--    return SWIG_Py_Void();
--  }
--}
--
--/* Create a new pointer object */
--
--SWIGRUNTIME PyObject *
--SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
--  SwigPyClientData *clientdata;
--  PyObject * robj;
--  int own;
--
--  if (!ptr)
--    return SWIG_Py_Void();
--
--  clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
--  own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
--  if (clientdata && clientdata->pytype) {
--    SwigPyObject *newobj;
--    if (flags & SWIG_BUILTIN_TP_INIT) {
--      newobj = (SwigPyObject*) self;
--      if (newobj->ptr) {
--        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
--        while (newobj->next)
--        newobj = (SwigPyObject *) newobj->next;
--        newobj->next = next_self;
--        newobj = (SwigPyObject *)next_self;
--      }
--    } else {
--      newobj = PyObject_New(SwigPyObject, clientdata->pytype);
--    }
--    if (newobj) {
--      newobj->ptr = ptr;
--      newobj->ty = type;
--      newobj->own = own;
--      newobj->next = 0;
--#ifdef SWIGPYTHON_BUILTIN
--      newobj->dict = 0;
--#endif
--      return (PyObject*) newobj;
--    }
--    return SWIG_Py_Void();
--  }
--
--  assert(!(flags & SWIG_BUILTIN_TP_INIT));
--
--  robj = SwigPyObject_New(ptr, type, own);
--  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
--    PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
--    Py_DECREF(robj);
--    robj = inst;
--  }
--  return robj;
--}
--
--/* Create a new packed object */
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
--  return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
--}
--
--/* -----------------------------------------------------------------------------*
-- *  Get type list 
-- * -----------------------------------------------------------------------------*/
--
--#ifdef SWIG_LINK_RUNTIME
--void *SWIG_ReturnGlobalTypeList(void *);
--#endif
--
--SWIGRUNTIME swig_module_info *
--SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
--  static void *type_pointer = (void *)0;
--  /* first check if module already created */
--  if (!type_pointer) {
--#ifdef SWIG_LINK_RUNTIME
--    type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
--#else
--# ifdef SWIGPY_USE_CAPSULE
--    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
--# else
--    type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
--                                  (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
--# endif
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      type_pointer = (void *)0;
--    }
--#endif
--  }
--  return (swig_module_info *) type_pointer;
--}
--
--#if PY_MAJOR_VERSION < 2
--/* PyModule_AddObject function was introduced in Python 2.0.  The following function
--   is copied out of Python/modsupport.c in python version 2.3.4 */
--SWIGINTERN int
--PyModule_AddObject(PyObject *m, char *name, PyObject *o)
--{
--  PyObject *dict;
--  if (!PyModule_Check(m)) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs module as first arg");
--    return SWIG_ERROR;
--  }
--  if (!o) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs non-NULL value");
--    return SWIG_ERROR;
--  }
--  
--  dict = PyModule_GetDict(m);
--  if (dict == NULL) {
--    /* Internal error -- modules must have a dict! */
--    PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
--               PyModule_GetName(m));
--    return SWIG_ERROR;
--  }
--  if (PyDict_SetItemString(dict, name, o))
--    return SWIG_ERROR;
--  Py_DECREF(o);
--  return SWIG_OK;
--}
--#endif
--
--SWIGRUNTIME void
--#ifdef SWIGPY_USE_CAPSULE
--SWIG_Python_DestroyModule(PyObject *obj)
--#else
--SWIG_Python_DestroyModule(void *vptr)
--#endif
--{
--#ifdef SWIGPY_USE_CAPSULE
--  swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
--#else
--  swig_module_info *swig_module = (swig_module_info *) vptr;
--#endif
--  swig_type_info **types = swig_module->types;
--  size_t i;
--  for (i =0; i < swig_module->size; ++i) {
--    swig_type_info *ty = types[i];
--    if (ty->owndata) {
--      SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
--      if (data) SwigPyClientData_Del(data);
--    }
--  }
--  Py_DECREF(SWIG_This());
--  swig_this = NULL;
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetModule(swig_module_info *swig_module) {
--#if PY_VERSION_HEX >= 0x03000000
-- /* Add a dummy module object into sys.modules */
--  PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
--#else
--  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
--  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
--#endif
--#ifdef SWIGPY_USE_CAPSULE
--  PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#else
--  PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#endif
--}
--
--/* The python cached type query */
--SWIGRUNTIME PyObject *
--SWIG_Python_TypeCache(void) {
--  static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
--  return cache;
--}
--
--SWIGRUNTIME swig_type_info *
--SWIG_Python_TypeQuery(const char *type)
--{
--  PyObject *cache = SWIG_Python_TypeCache();
--  PyObject *key = SWIG_Python_str_FromChar(type); 
--  PyObject *obj = PyDict_GetItem(cache, key);
--  swig_type_info *descriptor;
--  if (obj) {
--#ifdef SWIGPY_USE_CAPSULE
--    descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
--#else
--    descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
--#endif
--  } else {
--    swig_module_info *swig_module = SWIG_GetModule(0);
--    descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
--    if (descriptor) {
--#ifdef SWIGPY_USE_CAPSULE
--      obj = PyCapsule_New((void*) descriptor, NULL, NULL);
--#else
--      obj = PyCObject_FromVoidPtr(descriptor, NULL);
--#endif
--      PyDict_SetItem(cache, key, obj);
--      Py_DECREF(obj);
--    }
--  }
--  Py_DECREF(key);
--  return descriptor;
--}
--
--/* 
--   For backward compatibility only
--*/
--#define SWIG_POINTER_EXCEPTION  0
--#define SWIG_arg_fail(arg)      SWIG_Python_ArgFail(arg)
--#define SWIG_MustGetPtr(p, type, argnum, flags)  SWIG_Python_MustGetPtr(p, type, argnum, flags)
--
--SWIGRUNTIME int
--SWIG_Python_AddErrMesg(const char* mesg, int infront)
--{  
--  if (PyErr_Occurred()) {
--    PyObject *type = 0;
--    PyObject *value = 0;
--    PyObject *traceback = 0;
--    PyErr_Fetch(&type, &value, &traceback);
--    if (value) {
--      char *tmp;
--      PyObject *old_str = PyObject_Str(value);
--      Py_XINCREF(type);
--      PyErr_Clear();
--      if (infront) {
--      PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
--      } else {
--      PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--      }
--      SWIG_Python_str_DelForPy3(tmp);
--      Py_DECREF(old_str);
--    }
--    return 1;
--  } else {
--    return 0;
--  }
--}
--  
--SWIGRUNTIME int
--SWIG_Python_ArgFail(int argnum)
--{
--  if (PyErr_Occurred()) {
--    /* add information about failing argument */
--    char mesg[256];
--    PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
--    return SWIG_Python_AddErrMesg(mesg, 1);
--  } else {
--    return 0;
--  }
--}
--
--SWIGRUNTIMEINLINE const char *
--SwigPyObject_GetDesc(PyObject *self)
--{
--  SwigPyObject *v = (SwigPyObject *)self;
--  swig_type_info *ty = v ? v->ty : 0;
--  return ty ? ty->str : "";
--}
--
--SWIGRUNTIME void
--SWIG_Python_TypeError(const char *type, PyObject *obj)
--{
--  if (type) {
--#if defined(SWIG_COBJECT_TYPES)
--    if (obj && SwigPyObject_Check(obj)) {
--      const char *otype = (const char *) SwigPyObject_GetDesc(obj);
--      if (otype) {
--      PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
--                   type, otype);
--      return;
--      }
--    } else 
--#endif      
--    {
--      const char *otype = (obj ? obj->ob_type->tp_name : 0); 
--      if (otype) {
--      PyObject *str = PyObject_Str(obj);
--      const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
--      if (cstr) {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
--                     type, otype, cstr);
--          SWIG_Python_str_DelForPy3(cstr);
--      } else {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
--                     type, otype);
--      }
--      Py_XDECREF(str);
--      return;
--      }
--    }   
--    PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
--  } else {
--    PyErr_Format(PyExc_TypeError, "unexpected type is received");
--  }
--}
--
--
--/* Convert a pointer value, signal an exception on a type mismatch */
--SWIGRUNTIME void *
--SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
--  void *result;
--  if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
--    PyErr_Clear();
--#if SWIG_POINTER_EXCEPTION
--    if (flags) {
--      SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
--      SWIG_Python_ArgFail(argnum);
--    }
--#endif
--  }
--  return result;
--}
--
--#ifdef SWIGPYTHON_BUILTIN
--SWIGRUNTIME int
--SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
--  PyTypeObject *tp = obj->ob_type;
--  PyObject *descr;
--  PyObject *encoded_name;
--  descrsetfunc f;
--  int res;
--
--# ifdef Py_USING_UNICODE
--  if (PyString_Check(name)) {
--    name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
--    if (!name)
--      return -1;
--  } else if (!PyUnicode_Check(name))
--# else
--  if (!PyString_Check(name))
--# endif
--  {
--    PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
--    return -1;
--  } else {
--    Py_INCREF(name);
--  }
--
--  if (!tp->tp_dict) {
--    if (PyType_Ready(tp) < 0)
--      goto done;
--  }
--
--  res = -1;
--  descr = _PyType_Lookup(tp, name);
--  f = NULL;
--  if (descr != NULL)
--    f = descr->ob_type->tp_descr_set;
--  if (!f) {
--    if (PyString_Check(name)) {
--      encoded_name = name;
--      Py_INCREF(name);
--    } else {
--      encoded_name = PyUnicode_AsUTF8String(name);
--    }
--    PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
--    Py_DECREF(encoded_name);
--  } else {
--    res = f(descr, obj, value);
--  }
--  
--  done:
--  Py_DECREF(name);
--  return res;
--}
--#endif
--
--
--#ifdef __cplusplus
--}
--#endif
--
--
--
--#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
--
--#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else 
--
--
--
--  #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0) 
--
--
--/* -------- TYPES TABLE (BEGIN) -------- */
--
--#define SWIGTYPE_p_GType swig_types[0]
--#define SWIGTYPE_p_VBuffer swig_types[1]
--#define SWIGTYPE_p__VipsImage swig_types[2]
--#define SWIGTYPE_p_allocator_type swig_types[3]
--#define SWIGTYPE_p_char swig_types[4]
--#define SWIGTYPE_p_difference_type swig_types[5]
--#define SWIGTYPE_p_double swig_types[6]
--#define SWIGTYPE_p_float swig_types[7]
--#define SWIGTYPE_p_gboolean swig_types[8]
--#define SWIGTYPE_p_int swig_types[9]
--#define SWIGTYPE_p_matrix swig_types[10]
--#define SWIGTYPE_p_p_PyObject swig_types[11]
--#define SWIGTYPE_p_p_char swig_types[12]
--#define SWIGTYPE_p_size_t swig_types[13]
--#define SWIGTYPE_p_size_type swig_types[14]
--#define SWIGTYPE_p_std__allocatorT_double_t swig_types[15]
--#define SWIGTYPE_p_std__allocatorT_int_t swig_types[16]
--#define SWIGTYPE_p_std__allocatorT_vips__VImage_t swig_types[17]
--#define SWIGTYPE_p_std__invalid_argument swig_types[18]
--#define SWIGTYPE_p_std__vectorT__Tp__Alloc_t swig_types[19]
--#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[20]
--#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[21]
--#define SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t swig_types[22]
--#define SWIGTYPE_p_swig__SwigPyIterator swig_types[23]
--#define SWIGTYPE_p_value_type swig_types[24]
--#define SWIGTYPE_p_vips__VDMask swig_types[25]
--#define SWIGTYPE_p_vips__VDisplay swig_types[26]
--#define SWIGTYPE_p_vips__VError swig_types[27]
--#define SWIGTYPE_p_vips__VIMask swig_types[28]
--#define SWIGTYPE_p_vips__VImage swig_types[29]
--#define SWIGTYPE_p_void swig_types[30]
--static swig_type_info *swig_types[32];
--static swig_module_info swig_module = {swig_types, 31, 0, 0, 0, 0};
--#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
--#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
--
--/* -------- TYPES TABLE (END) -------- */
--
--#if (PY_VERSION_HEX <= 0x02000000)
--# if !defined(SWIG_PYTHON_CLASSIC)
--#  error "This python version requires swig to be run with the '-classic' option"
--# endif
--#endif
--
--/*-----------------------------------------------
--              @(target):= vimagemodule.so
--  ------------------------------------------------*/
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_init    PyInit_vimagemodule
--
--#else
--#  define SWIG_init    initvimagemodule
--
--#endif
--#define SWIG_name    "vimagemodule"
--
--#define SWIGVERSION 0x020010 
--#define SWIG_VERSION SWIGVERSION
--
--
--#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) 
--#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) 
--
--
--#include <stdexcept>
--
--
--namespace swig {
--  class SwigPtr_PyObject {
--  protected:
--    PyObject *_obj;
--
--  public:
--    SwigPtr_PyObject() :_obj(0)
--    {
--    }
--
--    SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
--    {
--      Py_XINCREF(_obj);      
--    }
--    
--    SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
--    {
--      if (initial_ref) {
--        Py_XINCREF(_obj);
--      }
--    }
--    
--    SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) 
--    {
--      Py_XINCREF(item._obj);
--      Py_XDECREF(_obj);
--      _obj = item._obj;
--      return *this;      
--    }
--    
--    ~SwigPtr_PyObject() 
--    {
--      Py_XDECREF(_obj);
--    }
--    
--    operator PyObject *() const
--    {
--      return _obj;
--    }
--
--    PyObject *operator->() const
--    {
--      return _obj;
--    }
--  };
--}
--
--
--namespace swig {
--  struct SwigVar_PyObject : SwigPtr_PyObject {
--    SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
--    
--    SwigVar_PyObject & operator = (PyObject* obj)
--    {
--      Py_XDECREF(_obj);
--      _obj = obj;
--      return *this;      
--    }
--  };
--}
--
--
--#include <vips/vipscpp.h>
--
--/* We need the C API too for the args init and some of the
-- * frombuffer/tobuffer stuff.
-- */
--#include <vips/vips.h>
--
--
--#include <iostream>
--
--#if PY_VERSION_HEX >= 0x03020000
--# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
--#else
--# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
--#endif
--
--
--#include <stdexcept>
--
--
--#if defined(__GNUC__)
--#  if __GNUC__ == 2 && __GNUC_MINOR <= 96
--#     define SWIG_STD_NOMODERN_STL
--#  endif
--#endif
--
--
--#include <string>
--#include <stdexcept>
--#include <stddef.h>
--
--
--  #include <stddef.h>
--
--
--namespace swig {
--  struct stop_iteration {
--  };
--
--  struct SwigPyIterator {
--  private:
--    SwigPtr_PyObject _seq;
--
--  protected:
--    SwigPyIterator(PyObject *seq) : _seq(seq)
--    {
--    }
--      
--  public:
--    virtual ~SwigPyIterator() {}
--
--    // Access iterator method, required by Python
--    virtual PyObject *value() const = 0;
--
--    // Forward iterator method, required by Python
--    virtual SwigPyIterator *incr(size_t n = 1) = 0;
--    
--    // Backward iterator method, very common in C++, but not required in Python
--    virtual SwigPyIterator *decr(size_t /*n*/ = 1)
--    {
--      throw stop_iteration();
--    }
--
--    // Random access iterator methods, but not required in Python
--    virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const
--    {
--      throw std::invalid_argument("operation not supported");
--    }
--
--    virtual bool equal (const SwigPyIterator &/*x*/) const
--    {
--      throw std::invalid_argument("operation not supported");
--    }
--    
--    // C++ common/needed methods
--    virtual SwigPyIterator *copy() const = 0;
--
--    PyObject *next()     
--    {
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
--      PyObject *obj = value();
--      incr();       
--      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
--      return obj;     
--    }
--
--    /* Make an alias for Python 3.x */
--    PyObject *__next__()
--    {
--      return next();
--    }
--
--    PyObject *previous()
--    {
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
--      decr();
--      PyObject *obj = value();
--      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads       
--      return obj;
--    }
--
--    SwigPyIterator *advance(ptrdiff_t n)
--    {
--      return  (n > 0) ?  incr(n) : decr(-n);
--    }
--      
--    bool operator == (const SwigPyIterator& x)  const
--    {
--      return equal(x);
--    }
--      
--    bool operator != (const SwigPyIterator& x) const
--    {
--      return ! operator==(x);
--    }
--      
--    SwigPyIterator& operator += (ptrdiff_t n)
--    {
--      return *advance(n);
--    }
--
--    SwigPyIterator& operator -= (ptrdiff_t n)
--    {
--      return *advance(-n);
--    }
--      
--    SwigPyIterator* operator + (ptrdiff_t n) const
--    {
--      return copy()->advance(n);
--    }
--
--    SwigPyIterator* operator - (ptrdiff_t n) const
--    {
--      return copy()->advance(-n);
--    }
--      
--    ptrdiff_t operator - (const SwigPyIterator& x) const
--    {
--      return x.distance(*this);
--    }
--      
--    static swig_type_info* descriptor() {
--      static int init = 0;
--      static swig_type_info* desc = 0;
--      if (!init) {
--      desc = SWIG_TypeQuery("swig::SwigPyIterator *");
--      init = 1;
--      }       
--      return desc;
--    }    
--  };
--
--#if defined(SWIGPYTHON_BUILTIN)
--  inline PyObject* make_output_iterator_builtin (PyObject *pyself)
--  {
--    Py_INCREF(pyself);
--    return pyself;
--  }
--#endif
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_double (PyObject *obj, double *val)
--{
--  int res = SWIG_TypeError;
--  if (PyFloat_Check(obj)) {
--    if (val) *val = PyFloat_AsDouble(obj);
--    return SWIG_OK;
--  } else if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    double v = PyLong_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    double d = PyFloat_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = d;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      long v = PyLong_AsLong(obj);
--      if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
--      } else {
--      PyErr_Clear();
--      }
--    }
--  }
--#endif
--  return res;
--}
--
--
--#include <float.h>
--
--
--#include <math.h>
--
--
--SWIGINTERNINLINE int
--SWIG_CanCastAsInteger(double *d, double min, double max) {
--  double x = *d;
--  if ((min <= x && x <= max)) {
--   double fx = floor(x);
--   double cx = ceil(x);
--   double rd =  ((x - fx) < 0.5) ? fx : cx; /* simple rint */
--   if ((errno == EDOM) || (errno == ERANGE)) {
--     errno = 0;
--   } else {
--     double summ, reps, diff;
--     if (rd < x) {
--       diff = x - rd;
--     } else if (rd > x) {
--       diff = rd - x;
--     } else {
--       return 1;
--     }
--     summ = rd + x;
--     reps = diff/summ;
--     if (reps < 8*DBL_EPSILON) {
--       *d = rd;
--       return 1;
--     }
--   }
--  }
--  return 0;
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) 
--{
--#if PY_VERSION_HEX < 0x03000000
--  if (PyInt_Check(obj)) {
--    long v = PyInt_AsLong(obj);
--    if (v >= 0) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      return SWIG_OverflowError;
--    }
--  } else
--#endif
--  if (PyLong_Check(obj)) {
--    unsigned long v = PyLong_AsUnsignedLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--#if PY_VERSION_HEX >= 0x03000000
--      {
--        long v = PyLong_AsLong(obj);
--        if (!PyErr_Occurred()) {
--          if (v < 0) {
--            return SWIG_OverflowError;
--          }
--        } else {
--          PyErr_Clear();
--        }
--      }
--#endif
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    unsigned long v = PyLong_AsUnsignedLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      double d;
--      int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
--      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
--      if (val) *val = (unsigned long)(d);
--      return res;
--      }
--    }
--  }
--#endif
--  return SWIG_TypeError;
--}
--
--
--SWIGINTERNINLINE int
--SWIG_AsVal_size_t (PyObject * obj, size_t *val)
--{
--  unsigned long v;
--  int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
--  if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v);
--  return res;
--}
--
--
--  #define SWIG_From_long   PyLong_FromLong 
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_From_ptrdiff_t  (ptrdiff_t value)
--{    
--  return SWIG_From_long  (static_cast< long >(value));
--}
--
--
--SWIGINTERNINLINE PyObject*
--  SWIG_From_bool  (bool value)
--{
--  return PyBool_FromLong(value ? 1 : 0);
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_long (PyObject *obj, long* val)
--{
--  if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    long v = PyLong_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    long v = PyInt_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      double d;
--      int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
--      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
--      if (val) *val = (long)(d);
--      return res;
--      }
--    }
--  }
--#endif
--  return SWIG_TypeError;
--}
--
--
--SWIGINTERNINLINE int
--SWIG_AsVal_ptrdiff_t (PyObject * obj, ptrdiff_t *val)
--{
--  long v;
--  int res = SWIG_AsVal_long (obj, val ? &v : 0);
--  if (SWIG_IsOK(res) && val) *val = static_cast< ptrdiff_t >(v);
--  return res;
--}
--
--
--#include <stdexcept>
--
--
--#include <algorithm>
--
--
--#include <list>
--
--
--#include <complex> 
--
--
--#include <vector>
--
--
--#include <string>
--
--
--namespace swig {  
--  template <class Type>
--  struct noconst_traits {
--    typedef Type noconst_type;
--  };
--
--  template <class Type>
--  struct noconst_traits<const Type> {
--    typedef Type noconst_type;
--  };
--
--  /*
--    type categories
--  */
--  struct pointer_category { };  
--  struct value_category { };
--
--  /*
--    General traits that provides type_name and type_info
--  */
--  template <class Type> struct traits { };
--
--  template <class Type>
--  inline const char* type_name() {
--    return traits<typename noconst_traits<Type >::noconst_type >::type_name();
--  }
--
--  template <class Type> 
--  struct traits_info {
--    static swig_type_info *type_query(std::string name) {
--      name += " *";
--      return SWIG_TypeQuery(name.c_str());
--    }    
--    static swig_type_info *type_info() {
--      static swig_type_info *info = type_query(type_name<Type>());
--      return info;
--    }
--  };
--
--  template <class Type>
--  inline swig_type_info *type_info() {
--    return traits_info<Type>::type_info();
--  }
--
--  /*
--    Partial specialization for pointers
--  */
--  template <class Type> struct traits <Type *> {
--    typedef pointer_category category;
--    static std::string make_ptr_name(const char* name) {
--      std::string ptrname = name;
--      ptrname += " *";
--      return ptrname;
--    }    
--    static const char* type_name() {
--      static std::string name = make_ptr_name(swig::type_name<Type>());
--      return name.c_str();
--    }
--  };
--
--  template <class Type, class Category> 
--  struct traits_as { };
-- 
--  template <class Type, class Category> 
--  struct traits_check { };
--
--}
--
--
--namespace swig {  
--  /*
--    Traits that provides the from method
--  */
--  template <class Type> struct traits_from_ptr {
--    static PyObject *from(Type *val, int owner = 0) {
--      return SWIG_InternalNewPointerObj(val, type_info<Type>(), owner);
--    }
--  };
--
--  template <class Type> struct traits_from {
--    static PyObject *from(const Type& val) {
--      return traits_from_ptr<Type>::from(new Type(val), 1);
--    }
--  };
--
--  template <class Type> struct traits_from<Type *> {
--    static PyObject *from(Type* val) {
--      return traits_from_ptr<Type>::from(val, 0);
--    }
--  };
--
--  template <class Type> struct traits_from<const Type *> {
--    static PyObject *from(const Type* val) {
--      return traits_from_ptr<Type>::from(const_cast<Type*>(val), 0);
--    }
--  };
--
--
--  template <class Type>
--  inline PyObject *from(const Type& val) {
--    return traits_from<Type>::from(val);
--  }
--
--  template <class Type>
--  inline PyObject *from_ptr(Type* val, int owner) {
--    return traits_from_ptr<Type>::from(val, owner);
--  }
--
--  /*
--    Traits that provides the asval/as/check method
--  */
--  template <class Type>
--  struct traits_asptr {   
--    static int asptr(PyObject *obj, Type **val) {
--      Type *p;
--      int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
--      if (SWIG_IsOK(res)) {
--      if (val) *val = p;
--      }
--      return res;
--    }
--  }; 
--
--  template <class Type>
--  inline int asptr(PyObject *obj, Type **vptr) {
--    return traits_asptr<Type>::asptr(obj, vptr);
--  }
--
--  template <class Type> 
--  struct traits_asval {
--    static int asval(PyObject *obj, Type *val) {
--      if (val) {
--      Type *p = 0;
--      int res = traits_asptr<Type>::asptr(obj, &p);
--      if (!SWIG_IsOK(res)) return res;        
--      if (p) {
--        typedef typename noconst_traits<Type>::noconst_type noconst_type;
--        *(const_cast<noconst_type*>(val)) = *p;
--        if (SWIG_IsNewObj(res)){
--          delete p;
--          res = SWIG_DelNewMask(res);
--        }
--        return res;
--      } else {
--        return SWIG_ERROR;
--      }
--      } else {
--      return traits_asptr<Type>::asptr(obj, (Type **)(0));
--      }
--    }
--  };
--
--  template <class Type> struct traits_asval<Type*> {
--    static int asval(PyObject *obj, Type **val) {
--      if (val) {
--        typedef typename noconst_traits<Type>::noconst_type noconst_type;
--        noconst_type *p = 0;
--        int res = traits_asptr<noconst_type>::asptr(obj,  &p);
--        if (SWIG_IsOK(res)) {
--          *(const_cast<noconst_type**>(val)) = p;
--      }
--      return res;
--      } else {
--      return traits_asptr<Type>::asptr(obj, (Type **)(0));
--      }
--    }
--  };
--  
--  template <class Type>
--  inline int asval(PyObject *obj, Type *val) {
--    return traits_asval<Type>::asval(obj, val);
--  }
--
--  template <class Type> 
--  struct traits_as<Type, value_category> {
--    static Type as(PyObject *obj, bool throw_error) {
--      Type v;
--      int res = asval(obj, &v);
--      if (!obj || !SWIG_IsOK(res)) {
--      if (!PyErr_Occurred()) {
--        ::SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      }
--      return v;
--    }
--  };
--
--  template <class Type> 
--  struct traits_as<Type, pointer_category> {
--    static Type as(PyObject *obj, bool throw_error) {
--      Type *v = 0;      
--      int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
--      if (SWIG_IsOK(res) && v) {
--      if (SWIG_IsNewObj(res)) {
--        Type r(*v);
--        delete v;
--        return r;
--      } else {
--        return *v;
--      }
--      } else {
--      // Uninitialized return value, no Type() constructor required.
--      static Type *v_def = (Type*) malloc(sizeof(Type));
--      if (!PyErr_Occurred()) {
--        SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      memset(v_def,0,sizeof(Type));
--      return *v_def;
--      }
--    }
--  };
--
--  template <class Type> 
--  struct traits_as<Type*, pointer_category> {
--    static Type* as(PyObject *obj, bool throw_error) {
--      Type *v = 0;      
--      int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
--      if (SWIG_IsOK(res)) {
--      return v;
--      } else {
--      if (!PyErr_Occurred()) {
--        SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      return 0;
--      }
--    }
--  };
--    
--  template <class Type>
--  inline Type as(PyObject *obj, bool te = false) {
--    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
--  }
--
--  template <class Type> 
--  struct traits_check<Type, value_category> {
--    static bool check(PyObject *obj) {
--      int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR;
--      return SWIG_IsOK(res) ? true : false;
--    }
--  };
--
--  template <class Type> 
--  struct traits_check<Type, pointer_category> {
--    static bool check(PyObject *obj) {
--      int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR;
--      return SWIG_IsOK(res) ? true : false;
--    }
--  };
--
--  template <class Type>
--  inline bool check(PyObject *obj) {
--    return traits_check<Type, typename traits<Type>::category>::check(obj);
--  }
--}
--
--
--#include <functional>
--
--namespace std {
--  template <>
--  struct less <PyObject *>: public binary_function<PyObject *, PyObject *, bool>
--  {
--    bool
--    operator()(PyObject * v, PyObject *w) const
--    { 
--      bool res;
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--      res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false;
--      /* This may fall into a case of inconsistent
--               eg. ObjA > ObjX > ObjB
--               but ObjA < ObjB
--      */
--      if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) )
--      {
--        /* Objects can't be compared, this mostly occurred in Python 3.0 */
--        /* Compare their ptr directly for a workaround */
--        res = (v < w);
--        PyErr_Clear();
--      }
--      SWIG_PYTHON_THREAD_END_BLOCK;
--      return res;
--    }
--  };
--
--  template <>
--  struct less <swig::SwigPtr_PyObject>: public binary_function<swig::SwigPtr_PyObject, swig::SwigPtr_PyObject, bool>
--  {
--    bool
--    operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w) const
--    {
--      return std::less<PyObject *>()(v, w);
--    }
--  };
--
--  template <>
--  struct less <swig::SwigVar_PyObject>: public binary_function<swig::SwigVar_PyObject, swig::SwigVar_PyObject, bool>
--  {
--    bool
--    operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w) const
--    {
--      return std::less<PyObject *>()(v, w);
--    }
--  };
--
--}
--
--namespace swig {
--  template <> struct traits<PyObject *> {
--    typedef value_category category;
--    static const char* type_name() { return "PyObject *"; }
--  };  
--
--  template <>  struct traits_asval<PyObject * > {   
--    typedef PyObject * value_type;
--    static int asval(PyObject *obj, value_type *val) {
--      if (val) *val = obj;
--      return SWIG_OK;
--    }
--  };
--
--  template <> 
--  struct traits_check<PyObject *, value_category> {
--    static bool check(PyObject *) {
--      return true;
--    }
--  };
--
--  template <>  struct traits_from<PyObject *> {
--    typedef PyObject * value_type;
--    static PyObject *from(const value_type& val) {
--      Py_XINCREF(val);
--      return val;
--    }
--  };
--  
--}
--
--namespace swig {
--  template <class Difference>
--  inline size_t
--  check_index(Difference i, size_t size, bool insert = false) {
--    if ( i < 0 ) {
--      if ((size_t) (-i) <= size)
--      return (size_t) (i + size);
--    } else if ( (size_t) i < size ) {
--      return (size_t) i;
--    } else if (insert && ((size_t) i == size)) {
--      return size;
--    }
--    throw std::out_of_range("index out of range");
--  }
--
--  template <class Difference>
--  void
--  slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) {
--    if (step == 0) {
--      throw std::invalid_argument("slice step cannot be zero");
--    } else if (step > 0) {
--      // Required range: 0 <= i < size, 0 <= j < size
--      if (i < 0) {
--        ii = 0;
--      } else if (i < (Difference)size) {
--        ii = i;
--      } else if (insert && (i >= (Difference)size)) {
--        ii = (Difference)size;
--      }
--      if ( j < 0 ) {
--        jj = 0;
--      } else {
--        jj = (j < (Difference)size) ? j : (Difference)size;
--      }
--    } else {
--      // Required range: -1 <= i < size-1, -1 <= j < size-1
--      if (i < -1) {
--        ii = -1;
--      } else if (i < (Difference) size) {
--        ii = i;
--      } else if (i >= (Difference)(size-1)) {
--        ii = (Difference)(size-1);
--      }
--      if (j < -1) {
--        jj = -1;
--      } else {
--        jj = (j < (Difference)size ) ? j : (Difference)(size-1);
--      }
--    }
--  }
--
--  template <class Sequence, class Difference>
--  inline typename Sequence::iterator
--  getpos(Sequence* self, Difference i)  {
--    typename Sequence::iterator pos = self->begin();
--    std::advance(pos, check_index(i,self->size()));
--    return pos;
--  }
--
--  template <class Sequence, class Difference>
--  inline typename Sequence::const_iterator
--  cgetpos(const Sequence* self, Difference i)  {
--    typename Sequence::const_iterator pos = self->begin();
--    std::advance(pos, check_index(i,self->size()));
--    return pos;
--  }
--
--  template <class Sequence, class Difference>
--  inline Sequence*
--  getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj);
--
--    if (step > 0) {
--      typename Sequence::const_iterator sb = self->begin();
--      typename Sequence::const_iterator se = self->begin();
--      std::advance(sb,ii);
--      std::advance(se,jj);
--      if (step == 1) {
--        return new Sequence(sb, se);
--      } else {
--        Sequence *sequence = new Sequence();
--        typename Sequence::const_iterator it = sb;
--        while (it!=se) {
--          sequence->push_back(*it);
--          for (Py_ssize_t c=0; c<step && it!=se; ++c)
--            it++;
--        }
--        return sequence;
--      } 
--    } else {
--      Sequence *sequence = new Sequence();
--      if (ii > jj) {
--        typename Sequence::const_reverse_iterator sb = self->rbegin();
--        typename Sequence::const_reverse_iterator se = self->rbegin();
--        std::advance(sb,size-ii-1);
--        std::advance(se,size-jj-1);
--        typename Sequence::const_reverse_iterator it = sb;
--        while (it!=se) {
--          sequence->push_back(*it);
--          for (Py_ssize_t c=0; c<-step && it!=se; ++c)
--            it++;
--        }
--      }
--      return sequence;
--    }
--  }
--
--  template <class Sequence, class Difference, class InputSeq>
--  inline void
--  setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj, true);
--    if (step > 0) {
--      if (jj < ii)
--        jj = ii;
--      if (step == 1) {
--        size_t ssize = jj - ii;
--        if (ssize <= is.size()) {
--          // expanding/staying the same size
--          typename Sequence::iterator sb = self->begin();
--          typename InputSeq::const_iterator isit = is.begin();
--          std::advance(sb,ii);
--          std::advance(isit, jj - ii);
--          self->insert(std::copy(is.begin(), isit, sb), isit, is.end());
--        } else {
--          // shrinking
--          typename Sequence::iterator sb = self->begin();
--          typename Sequence::iterator se = self->begin();
--          std::advance(sb,ii);
--          std::advance(se,jj);
--          self->erase(sb,se);
--          sb = self->begin();
--          std::advance(sb,ii);
--          self->insert(sb, is.begin(), is.end());
--        }
--      } else {
--        size_t replacecount = (jj - ii + step - 1) / step;
--        if (is.size() != replacecount) {
--          char msg[1024];
--          sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
--          throw std::invalid_argument(msg);
--        }
--        typename Sequence::const_iterator isit = is.begin();
--        typename Sequence::iterator it = self->begin();
--        std::advance(it,ii);
--        for (size_t rc=0; rc<replacecount; ++rc) {
--          *it++ = *isit++;
--          for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
--            it++;
--        }
--      }
--    } else {
--      if (jj > ii)
--        jj = ii;
--      size_t replacecount = (ii - jj - step - 1) / -step;
--      if (is.size() != replacecount) {
--        char msg[1024];
--        sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
--        throw std::invalid_argument(msg);
--      }
--      typename Sequence::const_iterator isit = is.begin();
--      typename Sequence::reverse_iterator it = self->rbegin();
--      std::advance(it,size-ii-1);
--      for (size_t rc=0; rc<replacecount; ++rc) {
--        *it++ = *isit++;
--        for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
--          it++;
--      }
--    }
--  }
--
--  template <class Sequence, class Difference>
--  inline void
--  delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj, true);
--    if (step > 0) {
--      if (jj > ii) {
--        typename Sequence::iterator sb = self->begin();
--        std::advance(sb,ii);
--        if (step == 1) {
--          typename Sequence::iterator se = self->begin();
--          std::advance(se,jj);
--          self->erase(sb,se);
--        } else {
--          typename Sequence::iterator it = sb;
--          size_t delcount = (jj - ii + step - 1) / step;
--          while (delcount) {
--            it = self->erase(it);
--            for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
--              it++;
--            delcount--;
--          }
--        }
--      }
--    } else {
--      if (ii > jj) {
--        typename Sequence::reverse_iterator sb = self->rbegin();
--        std::advance(sb,size-ii-1);
--        typename Sequence::reverse_iterator it = sb;
--        size_t delcount = (ii - jj - step - 1) / -step;
--        while (delcount) {
--          it = typename Sequence::reverse_iterator(self->erase((++it).base()));
--          for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
--            it++;
--          delcount--;
--        }
--      }
--    }
--  }
--}
--
--
--#if defined(__SUNPRO_CC) && defined(_RWSTD_VER)
--#  if !defined(SWIG_NO_STD_NOITERATOR_TRAITS_STL)
--#    define SWIG_STD_NOITERATOR_TRAITS_STL
--#  endif
--#endif
--
--#if !defined(SWIG_STD_NOITERATOR_TRAITS_STL)
--#include <iterator>
--#else
--namespace std {
--  template <class Iterator>
--  struct iterator_traits {
--    typedef ptrdiff_t difference_type;
--    typedef typename Iterator::value_type value_type;
--  };
--
--  template <class Iterator, class Category,class T, class Reference, class Pointer, class Distance>
--  struct iterator_traits<__reverse_bi_iterator<Iterator,Category,T,Reference,Pointer,Distance> > {
--    typedef Distance difference_type;
--    typedef T value_type;
--  };
--
--  template <class T>
--  struct iterator_traits<T*> {
--    typedef T value_type;
--    typedef ptrdiff_t difference_type;
--  };
--
--  template<typename _InputIterator>
--  inline typename iterator_traits<_InputIterator>::difference_type
--  distance(_InputIterator __first, _InputIterator __last)
--  {
--    typename iterator_traits<_InputIterator>::difference_type __n = 0;
--    while (__first != __last) {
--      ++__first; ++__n;
--    }
--    return __n;
--  }
--}
--#endif
--
--
--namespace swig {
--  template<typename OutIterator>
--  class SwigPyIterator_T :  public SwigPyIterator
--  {
--  public:
--    typedef OutIterator out_iterator;
--    typedef typename std::iterator_traits<out_iterator>::value_type value_type;    
--    typedef SwigPyIterator_T<out_iterator> self_type;
--
--    SwigPyIterator_T(out_iterator curr, PyObject *seq)
--      : SwigPyIterator(seq), current(curr)
--    {
--    }
--
--    const out_iterator& get_current() const
--    {
--      return current;
--    }
--
--    
--    bool equal (const SwigPyIterator &iter) const
--    {
--      const self_type *iters = dynamic_cast<const self_type *>(&iter);
--      if (iters) {
--      return (current == iters->get_current());
--      } else {
--      throw std::invalid_argument("bad iterator type");
--      }
--    }
--    
--    ptrdiff_t distance(const SwigPyIterator &iter) const
--    {
--      const self_type *iters = dynamic_cast<const self_type *>(&iter);
--      if (iters) {
--      return std::distance(current, iters->get_current());
--      } else {
--      throw std::invalid_argument("bad iterator type");
--      }
--    }    
--    
--  protected:
--    out_iterator current;
--  };
--  
--  template <class ValueType>
--  struct from_oper 
--  {
--    typedef const ValueType& argument_type;
--    typedef PyObject *result_type;
--    result_type operator()(argument_type v) const
--    {
--      return swig::from(v);
--    }
--  };
--
--  template<typename OutIterator, 
--         typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
--         typename FromOper = from_oper<ValueType> >
--  class SwigPyIteratorOpen_T :  public SwigPyIterator_T<OutIterator>
--  {
--  public:
--    FromOper from;
--    typedef OutIterator out_iterator;
--    typedef ValueType value_type;
--    typedef SwigPyIterator_T<out_iterator>  base;
--    typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
--    
--    SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq)
--      : SwigPyIterator_T<OutIterator>(curr, seq)
--    {
--    }
--    
--    PyObject *value() const {
--      return from(static_cast<const value_type&>(*(base::current)));
--    }
--    
--    SwigPyIterator *copy() const
--    {
--      return new self_type(*this);
--    }
--
--    SwigPyIterator *incr(size_t n = 1)
--    {
--      while (n--) {
--      ++base::current;
--      }
--      return this;
--    }
--
--    SwigPyIterator *decr(size_t n = 1)
--    {
--      while (n--) {
--      --base::current;
--      }
--      return this;
--    }
--  };
--
--  template<typename OutIterator, 
--         typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
--         typename FromOper = from_oper<ValueType> >
--  class SwigPyIteratorClosed_T :  public SwigPyIterator_T<OutIterator>
--  {
--  public:
--    FromOper from;
--    typedef OutIterator out_iterator;
--    typedef ValueType value_type;
--    typedef SwigPyIterator_T<out_iterator>  base;    
--    typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
--    
--    SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
--      : SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
--    {
--    }
--    
--    PyObject *value() const {
--      if (base::current == end) {
--      throw stop_iteration();
--      } else {
--      return from(static_cast<const value_type&>(*(base::current)));
--      }
--    }
--    
--    SwigPyIterator *copy() const
--    {
--      return new self_type(*this);
--    }
--
--    SwigPyIterator *incr(size_t n = 1)
--    {
--      while (n--) {
--      if (base::current == end) {
--        throw stop_iteration();
--      } else {
--        ++base::current;
--      }
--      }
--      return this;
--    }
--
--    SwigPyIterator *decr(size_t n = 1)
--    {
--      while (n--) {
--      if (base::current == begin) {
--        throw stop_iteration();
--      } else {
--        --base::current;
--      }
--      }
--      return this;
--    }
--
--  private:
--    out_iterator begin;
--    out_iterator end;
--  };
--
--  template<typename OutIter>
--  inline SwigPyIterator*
--  make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0)
--  {
--    return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq);
--  }
--
--  template<typename OutIter>
--  inline SwigPyIterator*
--  make_output_iterator(const OutIter& current, PyObject *seq = 0)
--  {
--    return new SwigPyIteratorOpen_T<OutIter>(current, seq);
--  }
--
--}
--
--
--namespace swig
--{
--  template <class T>
--  struct SwigPySequence_Ref
--  {
--    SwigPySequence_Ref(PyObject* seq, int index)
--      : _seq(seq), _index(index)
--    {
--    }
--    
--    operator T () const
--    {
--      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
--      try {
--      return swig::as<T>(item, true);
--      } catch (std::exception& e) {
--      char msg[1024];
--      sprintf(msg, "in sequence element %d ", _index);
--      if (!PyErr_Occurred()) {
--        ::SWIG_Error(SWIG_TypeError,  swig::type_name<T>());
--      }
--      SWIG_Python_AddErrorMsg(msg);
--      SWIG_Python_AddErrorMsg(e.what());
--      throw;
--      }
--    }
--
--    SwigPySequence_Ref& operator=(const T& v)
--    {
--      PySequence_SetItem(_seq, _index, swig::from<T>(v));
--      return *this;
--    }
--
--  private:
--    PyObject* _seq;
--    int _index;
--  };
--
--  template <class T>
--  struct SwigPySequence_ArrowProxy
--  {
--    SwigPySequence_ArrowProxy(const T& x): m_value(x) {}
--    const T* operator->() const { return &m_value; }
--    operator const T*() const { return &m_value; }
--    T m_value;
--  };
--
--  template <class T, class Reference >
--  struct SwigPySequence_InputIterator
--  {
--    typedef SwigPySequence_InputIterator<T, Reference > self;
--
--    typedef std::random_access_iterator_tag iterator_category;
--    typedef Reference reference;
--    typedef T value_type;
--    typedef T* pointer;
--    typedef int difference_type;
--
--    SwigPySequence_InputIterator()
--    {
--    }
--
--    SwigPySequence_InputIterator(PyObject* seq, int index)
--      : _seq(seq), _index(index)
--    {
--    }
--
--    reference operator*() const
--    {
--      return reference(_seq, _index);
--    }
--
--    SwigPySequence_ArrowProxy<T>
--    operator->() const {
--      return SwigPySequence_ArrowProxy<T>(operator*());
--    }
--
--    bool operator==(const self& ri) const
--    {
--      return (_index == ri._index) && (_seq == ri._seq);
--    }
--
--    bool operator!=(const self& ri) const
--    {
--      return !(operator==(ri));
--    }
--
--    self& operator ++ ()
--    {
--      ++_index;
--      return *this;
--    }
--
--    self& operator -- ()
--    {
--      --_index;
--      return *this;
--    }
--
--    self& operator += (difference_type n)
--    {
--      _index += n;
--      return *this;
--    }
--
--    self operator +(difference_type n) const
--    {
--      return self(_seq, _index + n);
--    }
--
--    self& operator -= (difference_type n)
--    {
--      _index -= n;
--      return *this;
--    }
--
--    self operator -(difference_type n) const
--    {
--      return self(_seq, _index - n);
--    }
--
--    difference_type operator - (const self& ri) const
--    {
--      return _index - ri._index;
--    }
--
--    bool operator < (const self& ri) const
--    {
--      return _index < ri._index;
--    }
--
--    reference
--    operator[](difference_type n) const
--    {
--      return reference(_seq, _index + n);
--    }
--
--  private:
--    PyObject* _seq;
--    difference_type _index;
--  };
--
--  template <class T>
--  struct SwigPySequence_Cont
--  {
--    typedef SwigPySequence_Ref<T> reference;
--    typedef const SwigPySequence_Ref<T> const_reference;
--    typedef T value_type;
--    typedef T* pointer;
--    typedef int difference_type;
--    typedef int size_type;
--    typedef const pointer const_pointer;
--    typedef SwigPySequence_InputIterator<T, reference> iterator;
--    typedef SwigPySequence_InputIterator<T, const_reference> const_iterator;
--
--    SwigPySequence_Cont(PyObject* seq) : _seq(0)
--    {
--      if (!PySequence_Check(seq)) {
--      throw std::invalid_argument("a sequence is expected");
--      }
--      _seq = seq;
--      Py_INCREF(_seq);
--    }
--
--    ~SwigPySequence_Cont()
--    {
--      Py_XDECREF(_seq);
--    }
--
--    size_type size() const
--    {
--      return static_cast<size_type>(PySequence_Size(_seq));
--    }
--
--    bool empty() const
--    {
--      return size() == 0;
--    }
--
--    iterator begin()
--    {
--      return iterator(_seq, 0);
--    }
--
--    const_iterator begin() const
--    {
--      return const_iterator(_seq, 0);
--    }
--
--    iterator end()
--    {
--      return iterator(_seq, size());
--    }
--
--    const_iterator end() const
--    {
--      return const_iterator(_seq, size());
--    }
--
--    reference operator[](difference_type n)
--    {
--      return reference(_seq, n);
--    }
--
--    const_reference operator[](difference_type n)  const
--    {
--      return const_reference(_seq, n);
--    }
--
--    bool check(bool set_err = true) const
--    {
--      int s = size();
--      for (int i = 0; i < s; ++i) {
--      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
--      if (!swig::check<value_type>(item)) {
--        if (set_err) {
--          char msg[1024];
--          sprintf(msg, "in sequence element %d", i);
--          SWIG_Error(SWIG_RuntimeError, msg);
--        }
--        return false;
--      }
--      }
--      return true;
--    }
--
--  private:
--    PyObject* _seq;
--  };
--
--}
--
--
--#include <limits.h>
--#if !defined(SWIG_NO_LLONG_MAX)
--# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
--#   define LLONG_MAX __LONG_LONG_MAX__
--#   define LLONG_MIN (-LLONG_MAX - 1LL)
--#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
--# endif
--#endif
--
--
--SWIGINTERN int
--SWIG_AsVal_int (PyObject * obj, int *val)
--{
--  long v;
--  int res = SWIG_AsVal_long (obj, &v);
--  if (SWIG_IsOK(res)) {
--    if ((v < INT_MIN || v > INT_MAX)) {
--      return SWIG_OverflowError;
--    } else {
--      if (val) *val = static_cast< int >(v);
--    }
--  }  
--  return res;
--}
--
--
--SWIGINTERNINLINE PyObject*
--  SWIG_From_int  (int value)
--{
--  return PyInt_FromLong((long) value);
--}
--
--
--namespace swig {
--  template <> struct traits<int > {
--    typedef value_category category;
--    static const char* type_name() { return"int"; }
--  };  
--  template <>  struct traits_asval<int > {   
--    typedef int value_type;
--    static int asval(PyObject *obj, value_type *val) { 
--      return SWIG_AsVal_int (obj, val);
--    }
--  };
--  template <>  struct traits_from<int > {
--    typedef int value_type;
--    static PyObject *from(const value_type& val) {
--      return SWIG_From_int  (val);
--    }
--  };
--}
--
--
--namespace swig {
--  template <class SwigPySeq, class Seq>
--  inline void
--  assign(const SwigPySeq& swigpyseq, Seq* seq) {
--    // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
--    typedef typename SwigPySeq::value_type value_type;
--    typename SwigPySeq::const_iterator it = swigpyseq.begin();
--    for (;it != swigpyseq.end(); ++it) {
--      seq->insert(seq->end(),(value_type)(*it));
--    }
--  }
--
--  template <class Seq, class T = typename Seq::value_type >
--  struct traits_asptr_stdseq {
--    typedef Seq sequence;
--    typedef T value_type;
--
--    static int asptr(PyObject *obj, sequence **seq) {
--      if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) {
--      sequence *p;
--      if (::SWIG_ConvertPtr(obj,(void**)&p,
--                            swig::type_info<sequence>(),0) == SWIG_OK) {
--        if (seq) *seq = p;
--        return SWIG_OLDOBJ;
--      }
--      } else if (PySequence_Check(obj)) {
--      try {
--        SwigPySequence_Cont<value_type> swigpyseq(obj);
--        if (seq) {
--          sequence *pseq = new sequence();
--          assign(swigpyseq, pseq);
--          *seq = pseq;
--          return SWIG_NEWOBJ;
--        } else {
--          return swigpyseq.check() ? SWIG_OK : SWIG_ERROR;
--        }
--      } catch (std::exception& e) {
--        if (seq) {
--          if (!PyErr_Occurred()) {
--            PyErr_SetString(PyExc_TypeError, e.what());
--          }
--        }
--        return SWIG_ERROR;
--      }
--      }
--      return SWIG_ERROR;
--    }
--  };
--
--  template <class Seq, class T = typename Seq::value_type >
--  struct traits_from_stdseq {
--    typedef Seq sequence;
--    typedef T value_type;
--    typedef typename Seq::size_type size_type;
--    typedef typename sequence::const_iterator const_iterator;
--
--    static PyObject *from(const sequence& seq) {
--#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS
--      swig_type_info *desc = swig::type_info<sequence>();
--      if (desc && desc->clientdata) {
--      return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN);
--      }
--#endif
--      size_type size = seq.size();
--      if (size <= (size_type)INT_MAX) {
--      PyObject *obj = PyTuple_New((int)size);
--      int i = 0;
--      for (const_iterator it = seq.begin();
--           it != seq.end(); ++it, ++i) {
--        PyTuple_SetItem(obj,i,swig::from<value_type>(*it));
--      }
--      return obj;
--      } else {
--      PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python");
--      return NULL;
--      }
--    }
--  };
--}
--
--
--  namespace swig {
--    template <class T>
--    struct traits_asptr<std::vector<T> >  {
--      static int asptr(PyObject *obj, std::vector<T> **vec) {
--      return traits_asptr_stdseq<std::vector<T> >::asptr(obj, vec);
--      }
--    };
--    
--    template <class T>
--    struct traits_from<std::vector<T> > {
--      static PyObject *from(const std::vector<T>& vec) {
--      return traits_from_stdseq<std::vector<T> >::from(vec);
--      }
--    };
--  }
--
--
--      namespace swig {
--      template <>  struct traits<std::vector<int, std::allocator< int > > > {
--        typedef pointer_category category;
--        static const char* type_name() {
--          return "std::vector<" "int" "," "std::allocator< int >" " >";
--        }
--      };
--      }
--    
--SWIGINTERN swig::SwigPyIterator *std_vector_Sl_int_Sg__iterator(std::vector< int > *self,PyObject **PYTHON_SELF){
--      return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
--    }
--SWIGINTERN bool std_vector_Sl_int_Sg____nonzero__(std::vector< int > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN bool std_vector_Sl_int_Sg____bool__(std::vector< int > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN std::vector< int >::size_type std_vector_Sl_int_Sg____len__(std::vector< int > const *self){
--      return self->size();
--    }
--
--SWIGINTERNINLINE PyObject* 
--SWIG_From_unsigned_SS_long  (unsigned long value)
--{
--  return (value > LONG_MAX) ?
--    PyLong_FromUnsignedLong(value) : PyLong_FromLong(static_cast< long >(value)); 
--}
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_From_size_t  (size_t value)
--{    
--  return SWIG_From_unsigned_SS_long  (static_cast< unsigned long >(value));
--}
--
--SWIGINTERN std::vector< int >::value_type std_vector_Sl_int_Sg__pop(std::vector< int > *self){
--      if (self->size() == 0)
--      throw std::out_of_range("pop from empty container");
--      std::vector<int,std::allocator< int > >::value_type x = self->back();
--      self->pop_back();
--      return x;
--    }
--SWIGINTERN std::vector< int,std::allocator< int > > *std_vector_Sl_int_Sg____getslice__(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j){
--      return swig::getslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____setslice____SWIG_0(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j,std::vector< int,std::allocator< int > > const &v=std::vector< int,std::allocator< int > >()){
--      swig::setslice(self, i, j, 1, v);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____delslice__(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j){
--      swig::delslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____delitem____SWIG_0(std::vector< int > *self,std::vector< int >::difference_type i){
--      self->erase(swig::getpos(self,i));
--    }
--SWIGINTERN std::vector< int,std::allocator< int > > *std_vector_Sl_int_Sg____getitem____SWIG_0(std::vector< int > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return NULL;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<int,std::allocator< int > >::difference_type id = i;
--      std::vector<int,std::allocator< int > >::difference_type jd = j;
--      return swig::getslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_0(std::vector< int > *self,PySliceObject *slice,std::vector< int,std::allocator< int > > const &v){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<int,std::allocator< int > >::difference_type id = i;
--      std::vector<int,std::allocator< int > >::difference_type jd = j;
--      swig::setslice(self, id, jd, step, v);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_1(std::vector< int > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<int,std::allocator< int > >::difference_type id = i;
--      std::vector<int,std::allocator< int > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____delitem____SWIG_1(std::vector< int > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<int,std::allocator< int > >::difference_type id = i;
--      std::vector<int,std::allocator< int > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN std::vector< int >::value_type const &std_vector_Sl_int_Sg____getitem____SWIG_1(std::vector< int > const *self,std::vector< int >::difference_type i){
--      return *(swig::cgetpos(self, i));
--    }
--SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_2(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::value_type const &x){
--      *(swig::getpos(self,i)) = x;
--    }
--SWIGINTERN void std_vector_Sl_int_Sg__append(std::vector< int > *self,std::vector< int >::value_type const &x){
--      self->push_back(x);
--    }
--
--  #define SWIG_From_double   PyFloat_FromDouble 
--
--
--namespace swig {
--  template <> struct traits<double > {
--    typedef value_category category;
--    static const char* type_name() { return"double"; }
--  };  
--  template <>  struct traits_asval<double > {   
--    typedef double value_type;
--    static int asval(PyObject *obj, value_type *val) { 
--      return SWIG_AsVal_double (obj, val);
--    }
--  };
--  template <>  struct traits_from<double > {
--    typedef double value_type;
--    static PyObject *from(const value_type& val) {
--      return SWIG_From_double  (val);
--    }
--  };
--}
--
--
--      namespace swig {
--      template <>  struct traits<std::vector<double, std::allocator< double > > > {
--        typedef pointer_category category;
--        static const char* type_name() {
--          return "std::vector<" "double" "," "std::allocator< double >" " >";
--        }
--      };
--      }
--    
--SWIGINTERN swig::SwigPyIterator *std_vector_Sl_double_Sg__iterator(std::vector< double > *self,PyObject **PYTHON_SELF){
--      return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
--    }
--SWIGINTERN bool std_vector_Sl_double_Sg____nonzero__(std::vector< double > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN bool std_vector_Sl_double_Sg____bool__(std::vector< double > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN std::vector< double >::size_type std_vector_Sl_double_Sg____len__(std::vector< double > const *self){
--      return self->size();
--    }
--SWIGINTERN std::vector< double >::value_type std_vector_Sl_double_Sg__pop(std::vector< double > *self){
--      if (self->size() == 0)
--      throw std::out_of_range("pop from empty container");
--      std::vector<double,std::allocator< double > >::value_type x = self->back();
--      self->pop_back();
--      return x;
--    }
--SWIGINTERN std::vector< double,std::allocator< double > > *std_vector_Sl_double_Sg____getslice__(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j){
--      return swig::getslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____setslice____SWIG_0(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j,std::vector< double,std::allocator< double > > const &v=std::vector< double,std::allocator< double > >()){
--      swig::setslice(self, i, j, 1, v);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____delslice__(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j){
--      swig::delslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____delitem____SWIG_0(std::vector< double > *self,std::vector< double >::difference_type i){
--      self->erase(swig::getpos(self,i));
--    }
--SWIGINTERN std::vector< double,std::allocator< double > > *std_vector_Sl_double_Sg____getitem____SWIG_0(std::vector< double > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return NULL;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<double,std::allocator< double > >::difference_type id = i;
--      std::vector<double,std::allocator< double > >::difference_type jd = j;
--      return swig::getslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_0(std::vector< double > *self,PySliceObject *slice,std::vector< double,std::allocator< double > > const &v){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<double,std::allocator< double > >::difference_type id = i;
--      std::vector<double,std::allocator< double > >::difference_type jd = j;
--      swig::setslice(self, id, jd, step, v);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_1(std::vector< double > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<double,std::allocator< double > >::difference_type id = i;
--      std::vector<double,std::allocator< double > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____delitem____SWIG_1(std::vector< double > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<double,std::allocator< double > >::difference_type id = i;
--      std::vector<double,std::allocator< double > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN std::vector< double >::value_type const &std_vector_Sl_double_Sg____getitem____SWIG_1(std::vector< double > const *self,std::vector< double >::difference_type i){
--      return *(swig::cgetpos(self, i));
--    }
--SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_2(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::value_type const &x){
--      *(swig::getpos(self,i)) = x;
--    }
--SWIGINTERN void std_vector_Sl_double_Sg__append(std::vector< double > *self,std::vector< double >::value_type const &x){
--      self->push_back(x);
--    }
--
--  namespace swig {
--    template <>  struct traits<vips::VImage > {
--      typedef pointer_category category;
--      static const char* type_name() { return"vips::VImage"; }
--    };
--  }
--
--
--      namespace swig {
--      template <>  struct traits<std::vector<vips::VImage, std::allocator< vips::VImage > > > {
--        typedef pointer_category category;
--        static const char* type_name() {
--          return "std::vector<" "vips::VImage" "," "std::allocator< vips::VImage >" " >";
--        }
--      };
--      }
--    
--SWIGINTERN swig::SwigPyIterator *std_vector_Sl_vips_VImage_Sg__iterator(std::vector< vips::VImage > *self,PyObject **PYTHON_SELF){
--      return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
--    }
--SWIGINTERN bool std_vector_Sl_vips_VImage_Sg____nonzero__(std::vector< vips::VImage > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN bool std_vector_Sl_vips_VImage_Sg____bool__(std::vector< vips::VImage > const *self){
--      return !(self->empty());
--    }
--SWIGINTERN std::vector< vips::VImage >::size_type std_vector_Sl_vips_VImage_Sg____len__(std::vector< vips::VImage > const *self){
--      return self->size();
--    }
--SWIGINTERN std::vector< vips::VImage >::value_type std_vector_Sl_vips_VImage_Sg__pop(std::vector< vips::VImage > *self){
--      if (self->size() == 0)
--      throw std::out_of_range("pop from empty container");
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::value_type x = self->back();
--      self->pop_back();
--      return x;
--    }
--SWIGINTERN std::vector< vips::VImage,std::allocator< vips::VImage > > *std_vector_Sl_vips_VImage_Sg____getslice__(std::vector< vips::VImage > *self,std::vector< vips::VImage >::difference_type i,std::vector< vips::VImage >::difference_type j){
--      return swig::getslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____setslice____SWIG_0(std::vector< vips::VImage > *self,std::vector< vips::VImage >::difference_type i,std::vector< vips::VImage >::difference_type j,std::vector< vips::VImage,std::allocator< vips::VImage > > const &v=std::vector< vips::VImage,std::allocator< vips::VImage > >()){
--      swig::setslice(self, i, j, 1, v);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____delslice__(std::vector< vips::VImage > *self,std::vector< vips::VImage >::difference_type i,std::vector< vips::VImage >::difference_type j){
--      swig::delslice(self, i, j, 1);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____delitem____SWIG_0(std::vector< vips::VImage > *self,std::vector< vips::VImage >::difference_type i){
--      self->erase(swig::getpos(self,i));
--    }
--SWIGINTERN std::vector< vips::VImage,std::allocator< vips::VImage > > *std_vector_Sl_vips_VImage_Sg____getitem____SWIG_0(std::vector< vips::VImage > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return NULL;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type id = i;
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type jd = j;
--      return swig::getslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____setitem____SWIG_0(std::vector< vips::VImage > *self,PySliceObject *slice,std::vector< vips::VImage,std::allocator< vips::VImage > > const &v){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type id = i;
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type jd = j;
--      swig::setslice(self, id, jd, step, v);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____setitem____SWIG_1(std::vector< vips::VImage > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type id = i;
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____delitem____SWIG_1(std::vector< vips::VImage > *self,PySliceObject *slice){
--      Py_ssize_t i, j, step;
--      if( !PySlice_Check(slice) ) {
--        SWIG_Error(SWIG_TypeError, "Slice object expected.");
--        return;
--      }
--      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type id = i;
--      std::vector<vips::VImage,std::allocator< vips::VImage > >::difference_type jd = j;
--      swig::delslice(self, id, jd, step);
--    }
--SWIGINTERN std::vector< vips::VImage >::value_type const &std_vector_Sl_vips_VImage_Sg____getitem____SWIG_1(std::vector< vips::VImage > const *self,std::vector< vips::VImage >::difference_type i){
--      return *(swig::cgetpos(self, i));
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg____setitem____SWIG_2(std::vector< vips::VImage > *self,std::vector< vips::VImage >::difference_type i,std::vector< vips::VImage >::value_type const &x){
--      *(swig::getpos(self,i)) = x;
--    }
--SWIGINTERN void std_vector_Sl_vips_VImage_Sg__append(std::vector< vips::VImage > *self,std::vector< vips::VImage >::value_type const &x){
--      self->push_back(x);
--    }
--
--struct VBuffer {
--  void *data;
--  size_t size;
--};
--
--
--SWIGINTERN swig_type_info*
--SWIG_pchar_descriptor(void)
--{
--  static int init = 0;
--  static swig_type_info* info = 0;
--  if (!init) {
--    info = SWIG_TypeQuery("_p_char");
--    init = 1;
--  }
--  return info;
--}
--
--
--SWIGINTERN int
--SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
--{
--#if PY_VERSION_HEX>=0x03000000
--  if (PyUnicode_Check(obj))
--#else  
--  if (PyString_Check(obj))
--#endif
--  {
--    char *cstr; Py_ssize_t len;
--#if PY_VERSION_HEX>=0x03000000
--    if (!alloc && cptr) {
--        /* We can't allow converting without allocation, since the internal
--           representation of string in Python 3 is UCS-2/UCS-4 but we require
--           a UTF-8 representation.
--           TODO(bhy) More detailed explanation */
--        return SWIG_RuntimeError;
--    }
--    obj = PyUnicode_AsUTF8String(obj);
--    PyBytes_AsStringAndSize(obj, &cstr, &len);
--    if(alloc) *alloc = SWIG_NEWOBJ;
--#else
--    PyString_AsStringAndSize(obj, &cstr, &len);
--#endif
--    if (cptr) {
--      if (alloc) {
--      /* 
--         In python the user should not be able to modify the inner
--         string representation. To warranty that, if you define
--         SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
--         buffer is always returned.
--
--         The default behavior is just to return the pointer value,
--         so, be careful.
--      */ 
--#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
--      if (*alloc != SWIG_OLDOBJ) 
--#else
--      if (*alloc == SWIG_NEWOBJ) 
--#endif
--        {
--          *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
--          *alloc = SWIG_NEWOBJ;
--        }
--      else {
--        *cptr = cstr;
--        *alloc = SWIG_OLDOBJ;
--      }
--      } else {
--        #if PY_VERSION_HEX>=0x03000000
--        assert(0); /* Should never reach here in Python 3 */
--        #endif
--      *cptr = SWIG_Python_str_AsChar(obj);
--      }
--    }
--    if (psize) *psize = len + 1;
--#if PY_VERSION_HEX>=0x03000000
--    Py_XDECREF(obj);
--#endif
--    return SWIG_OK;
--  } else {
--    swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--    if (pchar_descriptor) {
--      void* vptr = 0;
--      if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
--      if (cptr) *cptr = (char *) vptr;
--      if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
--      if (alloc) *alloc = SWIG_OLDOBJ;
--      return SWIG_OK;
--      }
--    }
--  }
--  return SWIG_TypeError;
--}
--
--
--
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_From_float  (float value)
--{    
--  return SWIG_From_double  (value);
--}
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_From_short  (short value)
--{    
--  return SWIG_From_long  (value);
--}
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_FromCharPtrAndSize(const char* carray, size_t size)
--{
--  if (carray) {
--    if (size > INT_MAX) {
--      swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--      return pchar_descriptor ? 
--      SWIG_InternalNewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
--    } else {
--#if PY_VERSION_HEX >= 0x03000000
--      return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
--#else
--      return PyString_FromStringAndSize(carray, static_cast< int >(size));
--#endif
--    }
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--
--SWIGINTERNINLINE PyObject * 
--SWIG_FromCharPtr(const char *cptr)
--{ 
--  return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_float (PyObject * obj, float *val)
--{
--  double v;
--  int res = SWIG_AsVal_double (obj, &v);
--  if (SWIG_IsOK(res)) {
--    if ((v < -FLT_MAX || v > FLT_MAX)) {
--      return SWIG_OverflowError;
--    } else {
--      if (val) *val = static_cast< float >(v);
--    }
--  }  
--  return res;
--}
--
--
--SWIGINTERNINLINE PyObject*
--SWIG_From_std_complex_Sl_double_Sg_  (/*@SWIG:/usr/share/swig2.0/typemaps/swigmacros.swg,104,%ifcplusplus@*/
--
--const std::complex<double>&
--
--
--
--/*@SWIG@*/ c)
--{
--  return PyComplex_FromDoubles(std::real(c), std::imag(c));
--}
--
--SWIGINTERN VBuffer vips_VImage_tobuffer(vips::VImage *self){
--    VBuffer buffer;
--
--    buffer.data = self->data ();
--    buffer.size = (size_t) self->Xsize () * self->Ysize () * 
--        IM_IMAGE_SIZEOF_PEL (self->image ());
--
--    return buffer;
--  }
--SWIGINTERN vips::VImage vips_VImage_frombuffer(VBuffer buffer,int width,int height,int bands,vips::VImage::TBandFmt format){
--    return VImage (buffer.data, width, height, bands, format);
--  }
--SWIGINTERN void vips_VImage_tostring(vips::VImage *self,char **buffer,int *buffer_len){
--    void *vips_memory;
--
--    /* Eval the vips image first. This may throw an exception and we want to
--     * make sure we do this before we try to malloc() space for the copy.
--     */
--    vips_memory = self->data ();
--
--    /* We have to copy the image data to make a string that Python can
--     * manage. Use frombuffer() / tobuffer () if you want to avoid the copy
--     * and manage memory lifetime yourself.
--     */
--    *buffer_len = (size_t) self->Xsize () * self->Ysize () * 
--      IM_IMAGE_SIZEOF_PEL (self->image ());
--    if (!(*buffer = (char *) im_malloc (NULL, *buffer_len))) 
--      verror ("Unable to allocate memory for image copy.");
--    memcpy (*buffer, vips_memory, *buffer_len);
--  }
--
--SWIGINTERN int
--SWIG_AsPtr_std_string (PyObject * obj, std::string **val) 
--{
--  char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
--  if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
--    if (buf) {
--      if (val) *val = new std::string(buf, size - 1);
--      if (alloc == SWIG_NEWOBJ) delete[] buf;
--      return SWIG_NEWOBJ;
--    } else {
--      if (val) *val = 0;
--      return SWIG_OLDOBJ;
--    }
--  } else {
--    static int init = 0;
--    static swig_type_info* descriptor = 0;
--    if (!init) {
--      descriptor = SWIG_TypeQuery("std::string" " *");
--      init = 1;
--    }
--    if (descriptor) {
--      std::string *vptr;
--      int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
--      if (SWIG_IsOK(res) && val) *val = vptr;
--      return res;
--    }
--  }
--  return SWIG_ERROR;
--}
--
--SWIGINTERN vips::VImage vips_VImage_fromstring(std::string buffer,int width,int height,int bands,vips::VImage::TBandFmt format){
--    void *vips_memory;
--    VImage result;
--
--    /* We have to copy the string, then add a callback to the VImage to free
--     * it when we free the VImage. Use frombuffer() / tobuffer () if you want 
--     * to avoid the copy and manage memory lifetime yourself.
--     */
--    if (!(vips_memory = im_malloc (NULL, buffer.length ()))) 
--      verror ("Unable to allocate memory for image copy.");
--
--    /* We have to use .c_str () since the string may not be contiguous.
--     */
--    memcpy (vips_memory, buffer.c_str (), buffer.length ());
--    result = VImage (vips_memory, width, height, bands, format);
--
--    if (im_add_close_callback (result.image (), 
--      (im_callback_fn) im_free, vips_memory, NULL))
--      verror ();
--
--    return result;
--  }
--
--/* Turn on to print args.
--#define DEBUG
-- */
--
--/* Command-line args during parse.
-- */
--typedef struct _Args {
--  /* The n strings we alloc when we get from Python.
--   */
--  int n;
--  char **str;
--
--  /* argc/argv as processed by us.
--   */
--  int argc;
--  char **argv;
--} Args;
--
--#ifdef DEBUG
--static void
--args_print (Args *args)
--{
--  int i;
--
--  printf ("args_print: argc = %d\n", args->argc);
--  // +1 so we print the trailing NULL too
--  for (i = 0; i < args->argc + 1; i++)
--    printf ("\t%2d)\t%s\n", i, args->argv[i]);
--}
--#endif /*DEBUG*/
--
--static void
--args_free (Args *args)
--{
--  int i;
--
--  for (i = 0; i < args->n; i++)
--    IM_FREE (args->str[i]);
--  args->n = 0;
--  args->argc = 0;
--  IM_FREE (args->str);
--  IM_FREE (args->argv);
--  IM_FREE (args);
--}
--
--/* Get argv/argc from python.
-- */
--static Args *
--args_new (void)
--{
--  Args *args;
--  PyObject *av;
--  int i;
--  int n;
--
--  args = g_new (Args, 1);
--  args->n = 0;
--  args->str = NULL;
--  args->argc = 0;
--  args->argv = NULL;
--
--  if (!(av = PySys_GetObject ((char *) "argv"))) 
--    return (args);
--  if (!PyList_Check (av)) {
--    PyErr_Warn (PyExc_Warning, "ignoring sys.argv: "
--      "it must be a list of strings");
--    return args;
--  }
--
--  n = PyList_Size (av);
--  args->str = g_new (char *, n);
--  for (i = 0; i < n; i++)
--    args->str[i] = g_strdup (PyString_AsString (PyList_GetItem (av, i)));
--  args->n = n;
--
--  /* +1 for NULL termination.
--   */
--  args->argc = n;
--  args->argv = g_new (char *, n + 1);
--  for (i = 0; i < n; i++)
--    args->argv[i] = args->str[i];
--  args->argv[i] = NULL;
--
--  return args;
--}
--
--static void
--vips_fatal (const char *msg)
--{
--  char buf[256];
--
--  im_snprintf (buf, 256, "%s\n%s", msg, im_error_buffer());
--  im_error_clear ();
--  Py_FatalError (buf);
--}
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_SwigPyIterator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_value",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_value" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (PyObject *)((swig::SwigPyIterator const *)arg1)->value();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = result;
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  size_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_incr",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_incr" "', argument " "2"" of type '" "size_t""'");
--  } 
--  arg2 = static_cast< size_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *)(arg1)->incr(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_incr",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (swig::SwigPyIterator *)(arg1)->incr();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_incr(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 1) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_SwigPyIterator_incr__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_SwigPyIterator_incr__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'SwigPyIterator_incr'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    swig::SwigPyIterator::incr(size_t)\n"
--    "    swig::SwigPyIterator::incr()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  size_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_decr",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_decr" "', argument " "2"" of type '" "size_t""'");
--  } 
--  arg2 = static_cast< size_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *)(arg1)->decr(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_decr",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (swig::SwigPyIterator *)(arg1)->decr();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_decr(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 1) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_SwigPyIterator_decr__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_SwigPyIterator_decr__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'SwigPyIterator_decr'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    swig::SwigPyIterator::decr(size_t)\n"
--    "    swig::SwigPyIterator::decr()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_distance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  swig::SwigPyIterator *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  ptrdiff_t result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_distance",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_distance" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
--  try {
--    result = ((swig::SwigPyIterator const *)arg1)->distance((swig::SwigPyIterator const &)*arg2);
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_ptrdiff_t(static_cast< ptrdiff_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_equal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  swig::SwigPyIterator *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_equal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_equal" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
--  try {
--    result = (bool)((swig::SwigPyIterator const *)arg1)->equal((swig::SwigPyIterator const &)*arg2);
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_copy",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_copy" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->copy();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_next(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_next",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_next" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (PyObject *)(arg1)->next();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = result;
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___next__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator___next__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___next__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (PyObject *)(arg1)->__next__();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = result;
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_previous(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_previous",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_previous" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  try {
--    result = (PyObject *)(arg1)->previous();
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = result;
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator_advance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  ptrdiff_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_advance",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_advance" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_advance" "', argument " "2"" of type '" "ptrdiff_t""'");
--  } 
--  arg2 = static_cast< ptrdiff_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *)(arg1)->advance(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  swig::SwigPyIterator *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___eq__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___eq__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
--  result = (bool)((swig::SwigPyIterator const *)arg1)->operator ==((swig::SwigPyIterator const &)*arg2);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___ne__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  swig::SwigPyIterator *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___ne__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___ne__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
--  result = (bool)((swig::SwigPyIterator const *)arg1)->operator !=((swig::SwigPyIterator const &)*arg2);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___iadd__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  ptrdiff_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___iadd__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___iadd__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___iadd__" "', argument " "2"" of type '" "ptrdiff_t""'");
--  } 
--  arg2 = static_cast< ptrdiff_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *) &(arg1)->operator +=(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___isub__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  ptrdiff_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___isub__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___isub__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___isub__" "', argument " "2"" of type '" "ptrdiff_t""'");
--  } 
--  arg2 = static_cast< ptrdiff_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *) &(arg1)->operator -=(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___add__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  ptrdiff_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___add__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___add__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___add__" "', argument " "2"" of type '" "ptrdiff_t""'");
--  } 
--  arg2 = static_cast< ptrdiff_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator +(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  ptrdiff_t arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___sub__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "ptrdiff_t""'");
--  } 
--  arg2 = static_cast< ptrdiff_t >(val2);
--  try {
--    result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator -(arg2);
--  }
--  catch(swig::stop_iteration &_e) {
--    {
--      (void)_e;
--      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
--      SWIG_fail;
--    }
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
--  swig::SwigPyIterator *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  ptrdiff_t result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___sub__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
--  }
--  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
--  }
--  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
--  result = ((swig::SwigPyIterator const *)arg1)->operator -((swig::SwigPyIterator const &)*arg2);
--  resultobj = SWIG_From_ptrdiff_t(static_cast< ptrdiff_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_SwigPyIterator___sub__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_swig__SwigPyIterator, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_SwigPyIterator___sub____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_SwigPyIterator___sub____SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  Py_INCREF(Py_NotImplemented);
--  return Py_NotImplemented;
--}
--
--
--SWIGINTERN PyObject *SwigPyIterator_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_swig__SwigPyIterator, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_IntVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  PyObject **arg2 = (PyObject **) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  arg2 = &obj0;
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_iterator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_iterator" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (swig::SwigPyIterator *)std_vector_Sl_int_Sg__iterator(arg1,arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector___nonzero__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___nonzero__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (bool)std_vector_Sl_int_Sg____nonzero__((std::vector< int > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector___bool__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___bool__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (bool)std_vector_Sl_int_Sg____bool__((std::vector< int > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector___len__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___len__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = std_vector_Sl_int_Sg____len__((std::vector< int > const *)arg1);
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::value_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_pop",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  try {
--    result = (std::vector< int >::value_type)std_vector_Sl_int_Sg__pop(arg1);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  std::vector< int >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< int,std::allocator< int > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___getslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< int >::difference_type >(val3);
--  try {
--    result = (std::vector< int,std::allocator< int > > *)std_vector_Sl_int_Sg____getslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  std::vector< int >::difference_type arg3 ;
--  std::vector< int,std::allocator< int > > *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  int res4 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:IntVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< int >::difference_type >(val3);
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    res4 = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res4)) {
--      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
--    }
--    arg4 = ptr;
--  }
--  try {
--    std_vector_Sl_int_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< int,std::allocator< int > > const &)*arg4);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  std::vector< int >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< int >::difference_type >(val3);
--  try {
--    std_vector_Sl_int_Sg____setslice____SWIG_0(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setslice__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_IntVector___setslice____SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<int,std::allocator< int > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_IntVector___setslice____SWIG_0(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___setslice__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::__setslice__(std::vector< int >::difference_type,std::vector< int >::difference_type,std::vector< int,std::allocator< int > > const &)\n"
--    "    std::vector< int >::__setslice__(std::vector< int >::difference_type,std::vector< int >::difference_type)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  std::vector< int >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___delslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< int >::difference_type >(val3);
--  try {
--    std_vector_Sl_int_Sg____delslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  try {
--    std_vector_Sl_int_Sg____delitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< int,std::allocator< int > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    result = (std::vector< int,std::allocator< int > > *)std_vector_Sl_int_Sg____getitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  std::vector< int,std::allocator< int > > *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res3 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    res3 = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
--    }
--    arg3 = ptr;
--  }
--  try {
--    std_vector_Sl_int_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< int,std::allocator< int > > const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___setitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_int_Sg____setitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_int_Sg____delitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___delitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_IntVector___delitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_IntVector___delitem____SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___delitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::__delitem__(std::vector< int >::difference_type)\n"
--    "    std::vector< int >::__delitem__(PySliceObject *)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< int >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getitem__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  try {
--    result = (std::vector< int >::value_type *) &std_vector_Sl_int_Sg____getitem____SWIG_1((std::vector< int > const *)arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___getitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_IntVector___getitem____SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_IntVector___getitem____SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___getitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::__getitem__(PySliceObject *)\n"
--    "    std::vector< int >::__getitem__(std::vector< int >::difference_type) const\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::difference_type arg2 ;
--  std::vector< int >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< int >::value_type temp3 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< int >::value_type >(val3);
--  arg3 = &temp3;
--  try {
--    std_vector_Sl_int_Sg____setitem____SWIG_2(arg1,arg2,(int const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector___setitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_IntVector___setitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<int,std::allocator< int > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_IntVector___setitem____SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_IntVector___setitem____SWIG_2(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___setitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::__setitem__(PySliceObject *,std::vector< int,std::allocator< int > > const &)\n"
--    "    std::vector< int >::__setitem__(PySliceObject *)\n"
--    "    std::vector< int >::__setitem__(std::vector< int >::difference_type,std::vector< int >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  std::vector< int >::value_type temp2 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_append",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_append" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_append" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< int >::value_type >(val2);
--  arg2 = &temp2;
--  std_vector_Sl_int_Sg__append(arg1,(int const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_IntVector")) SWIG_fail;
--  result = (std::vector< int > *)new std::vector< int >();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = 0 ;
--  int res1 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  std::vector< int > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_IntVector",&obj0)) SWIG_fail;
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    res1 = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int > const &""'"); 
--    }
--    arg1 = ptr;
--  }
--  result = (std::vector< int > *)new std::vector< int >((std::vector< int > const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_empty",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_empty" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (bool)((std::vector< int > const *)arg1)->empty();
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_size",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_size" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = ((std::vector< int > const *)arg1)->size();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_clear",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_clear" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  (arg1)->clear();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int > *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_swap",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_swap" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector< int > &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector< int > &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< int > * >(argp2);
--  (arg1)->swap(*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  SwigValueWrapper< std::allocator< int > > result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_get_allocator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_get_allocator" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = ((std::vector< int > const *)arg1)->get_allocator();
--  resultobj = SWIG_NewPointerObj((new std::vector< int >::allocator_type(static_cast< const std::vector< int >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_int_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_begin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_begin" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (arg1)->begin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_end",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_end" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (arg1)->end();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rbegin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rbegin" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (arg1)->rbegin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rend",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rend" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (arg1)->rend();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int >::size_type arg1 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_IntVector",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< int >::size_type >(val1);
--  result = (std::vector< int > *)new std::vector< int >(arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_pop_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop_back" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  (arg1)->pop_back();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_resize",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::size_type >(val2);
--  (arg1)->resize(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::iterator arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< int >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_erase",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::iterator arg2 ;
--  std::vector< int >::iterator arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  swig::SwigPyIterator *iter3 = 0 ;
--  int res3 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< int >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--    }
--  }
--  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res3) || !iter3) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector< int >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter3);
--    if (iter_t) {
--      arg3 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector< int >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2,arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_erase(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
--      if (_v) {
--        return _wrap_IntVector_erase__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
--      if (_v) {
--        swig::SwigPyIterator *iter = 0;
--        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
--        if (_v) {
--          return _wrap_IntVector_erase__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_erase'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::erase(std::vector< int >::iterator)\n"
--    "    std::vector< int >::erase(std::vector< int >::iterator,std::vector< int >::iterator)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int >::size_type arg1 ;
--  std::vector< int >::value_type *arg2 = 0 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  std::vector< int >::value_type temp2 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< int > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_IntVector",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< int >::size_type >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IntVector" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< int >::value_type >(val2);
--  arg2 = &temp2;
--  result = (std::vector< int > *)new std::vector< int >(arg1,(std::vector< int >::value_type const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_IntVector(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_IntVector__SWIG_0(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      return _wrap_new_IntVector__SWIG_2(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_IntVector__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_new_IntVector__SWIG_3(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_IntVector'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::vector()\n"
--    "    std::vector< int >::vector(std::vector< int > const &)\n"
--    "    std::vector< int >::vector(std::vector< int >::size_type)\n"
--    "    std::vector< int >::vector(std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  std::vector< int >::value_type temp2 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_push_back",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_push_back" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_push_back" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< int >::value_type >(val2);
--  arg2 = &temp2;
--  (arg1)->push_back((std::vector< int >::value_type const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_front",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_front" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (std::vector< int >::value_type *) &((std::vector< int > const *)arg1)->front();
--  resultobj = SWIG_From_int(static_cast< int >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_back" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = (std::vector< int >::value_type *) &((std::vector< int > const *)arg1)->back();
--  resultobj = SWIG_From_int(static_cast< int >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::size_type arg2 ;
--  std::vector< int >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< int >::value_type temp3 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_assign" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_assign" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::size_type >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_assign" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< int >::value_type >(val3);
--  arg3 = &temp3;
--  (arg1)->assign(arg2,(std::vector< int >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::size_type arg2 ;
--  std::vector< int >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< int >::value_type temp3 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::size_type >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_resize" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< int >::value_type >(val3);
--  arg3 = &temp3;
--  (arg1)->resize(arg2,(std::vector< int >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_resize(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_IntVector_resize__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_IntVector_resize__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_resize'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::resize(std::vector< int >::size_type)\n"
--    "    std::vector< int >::resize(std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::iterator arg2 ;
--  std::vector< int >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  std::vector< int >::value_type temp3 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< int >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< int >::value_type >(val3);
--  arg3 = &temp3;
--  result = (arg1)->insert(arg2,(std::vector< int >::value_type const &)*arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::iterator arg2 ;
--  std::vector< int >::size_type arg3 ;
--  std::vector< int >::value_type *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  size_t val3 ;
--  int ecode3 = 0 ;
--  std::vector< int >::value_type temp4 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:IntVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
--    }
--  }
--  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg3 = static_cast< std::vector< int >::size_type >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IntVector_insert" "', argument " "4"" of type '" "std::vector< int >::value_type""'");
--  } 
--  temp4 = static_cast< std::vector< int >::value_type >(val4);
--  arg4 = &temp4;
--  (arg1)->insert(arg2,arg3,(std::vector< int >::value_type const &)*arg4);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_insert(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_IntVector_insert__SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
--      if (_v) {
--        {
--          int res = SWIG_AsVal_size_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            return _wrap_IntVector_insert__SWIG_1(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_insert'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< int >::insert(std::vector< int >::iterator,std::vector< int >::value_type const &)\n"
--    "    std::vector< int >::insert(std::vector< int >::iterator,std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  std::vector< int >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_reserve",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_reserve" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_reserve" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< int >::size_type >(val2);
--  (arg1)->reserve(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_IntVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< int >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_capacity",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_capacity" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  result = ((std::vector< int > const *)arg1)->capacity();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_IntVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_IntVector",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntVector" "', argument " "1"" of type '" "std::vector< int > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *IntVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_DoubleVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  PyObject **arg2 = (PyObject **) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  arg2 = &obj0;
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_iterator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_iterator" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (swig::SwigPyIterator *)std_vector_Sl_double_Sg__iterator(arg1,arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___nonzero__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___nonzero__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (bool)std_vector_Sl_double_Sg____nonzero__((std::vector< double > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___bool__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___bool__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (bool)std_vector_Sl_double_Sg____bool__((std::vector< double > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___len__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___len__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = std_vector_Sl_double_Sg____len__((std::vector< double > const *)arg1);
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::value_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_pop",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  try {
--    result = (std::vector< double >::value_type)std_vector_Sl_double_Sg__pop(arg1);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  std::vector< double >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< double,std::allocator< double > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___getslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< double >::difference_type >(val3);
--  try {
--    result = (std::vector< double,std::allocator< double > > *)std_vector_Sl_double_Sg____getslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  std::vector< double >::difference_type arg3 ;
--  std::vector< double,std::allocator< double > > *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  int res4 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< double >::difference_type >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    res4 = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res4)) {
--      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
--    }
--    arg4 = ptr;
--  }
--  try {
--    std_vector_Sl_double_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< double,std::allocator< double > > const &)*arg4);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  std::vector< double >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< double >::difference_type >(val3);
--  try {
--    std_vector_Sl_double_Sg____setslice____SWIG_0(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setslice__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_DoubleVector___setslice____SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<double,std::allocator< double > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_DoubleVector___setslice____SWIG_0(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___setslice__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::__setslice__(std::vector< double >::difference_type,std::vector< double >::difference_type,std::vector< double,std::allocator< double > > const &)\n"
--    "    std::vector< double >::__setslice__(std::vector< double >::difference_type,std::vector< double >::difference_type)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  std::vector< double >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___delslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< double >::difference_type >(val3);
--  try {
--    std_vector_Sl_double_Sg____delslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  try {
--    std_vector_Sl_double_Sg____delitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< double,std::allocator< double > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    result = (std::vector< double,std::allocator< double > > *)std_vector_Sl_double_Sg____getitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  std::vector< double,std::allocator< double > > *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res3 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    res3 = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
--    }
--    arg3 = ptr;
--  }
--  try {
--    std_vector_Sl_double_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___setitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_double_Sg____setitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_double_Sg____delitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___delitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_DoubleVector___delitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_DoubleVector___delitem____SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___delitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::__delitem__(std::vector< double >::difference_type)\n"
--    "    std::vector< double >::__delitem__(PySliceObject *)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< double >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  try {
--    result = (std::vector< double >::value_type *) &std_vector_Sl_double_Sg____getitem____SWIG_1((std::vector< double > const *)arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___getitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_DoubleVector___getitem____SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_DoubleVector___getitem____SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___getitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::__getitem__(PySliceObject *)\n"
--    "    std::vector< double >::__getitem__(std::vector< double >::difference_type) const\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::difference_type arg2 ;
--  std::vector< double >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< double >::value_type temp3 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< double >::value_type >(val3);
--  arg3 = &temp3;
--  try {
--    std_vector_Sl_double_Sg____setitem____SWIG_2(arg1,arg2,(double const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector___setitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_DoubleVector___setitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_DoubleVector___setitem____SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_DoubleVector___setitem____SWIG_2(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___setitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::__setitem__(PySliceObject *,std::vector< double,std::allocator< double > > const &)\n"
--    "    std::vector< double >::__setitem__(PySliceObject *)\n"
--    "    std::vector< double >::__setitem__(std::vector< double >::difference_type,std::vector< double >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  std::vector< double >::value_type temp2 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_append",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_append" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_append" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< double >::value_type >(val2);
--  arg2 = &temp2;
--  std_vector_Sl_double_Sg__append(arg1,(double const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_DoubleVector")) SWIG_fail;
--  result = (std::vector< double > *)new std::vector< double >();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = 0 ;
--  int res1 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  std::vector< double > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleVector",&obj0)) SWIG_fail;
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    res1 = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double > const &""'"); 
--    }
--    arg1 = ptr;
--  }
--  result = (std::vector< double > *)new std::vector< double >((std::vector< double > const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_empty",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_empty" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (bool)((std::vector< double > const *)arg1)->empty();
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_size",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_size" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = ((std::vector< double > const *)arg1)->size();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_clear",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_clear" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  (arg1)->clear();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double > *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_swap",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_swap" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector< double > &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector< double > &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< double > * >(argp2);
--  (arg1)->swap(*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  SwigValueWrapper< std::allocator< double > > result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_get_allocator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_get_allocator" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = ((std::vector< double > const *)arg1)->get_allocator();
--  resultobj = SWIG_NewPointerObj((new std::vector< double >::allocator_type(static_cast< const std::vector< double >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_double_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_begin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_begin" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (arg1)->begin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_end",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_end" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (arg1)->end();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rbegin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rbegin" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (arg1)->rbegin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rend",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rend" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (arg1)->rend();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double >::size_type arg1 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleVector",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< double >::size_type >(val1);
--  result = (std::vector< double > *)new std::vector< double >(arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_pop_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop_back" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  (arg1)->pop_back();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_resize",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::size_type >(val2);
--  (arg1)->resize(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::iterator arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< double >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_erase",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::iterator arg2 ;
--  std::vector< double >::iterator arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  swig::SwigPyIterator *iter3 = 0 ;
--  int res3 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< double >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--    }
--  }
--  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res3) || !iter3) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector< double >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter3);
--    if (iter_t) {
--      arg3 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector< double >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2,arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_erase(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
--      if (_v) {
--        return _wrap_DoubleVector_erase__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
--      if (_v) {
--        swig::SwigPyIterator *iter = 0;
--        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
--        if (_v) {
--          return _wrap_DoubleVector_erase__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_erase'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::erase(std::vector< double >::iterator)\n"
--    "    std::vector< double >::erase(std::vector< double >::iterator,std::vector< double >::iterator)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double >::size_type arg1 ;
--  std::vector< double >::value_type *arg2 = 0 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  std::vector< double >::value_type temp2 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< double > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_DoubleVector",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< double >::size_type >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_DoubleVector" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< double >::value_type >(val2);
--  arg2 = &temp2;
--  result = (std::vector< double > *)new std::vector< double >(arg1,(std::vector< double >::value_type const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_DoubleVector(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_DoubleVector__SWIG_0(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      return _wrap_new_DoubleVector__SWIG_2(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_DoubleVector__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_new_DoubleVector__SWIG_3(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_DoubleVector'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::vector()\n"
--    "    std::vector< double >::vector(std::vector< double > const &)\n"
--    "    std::vector< double >::vector(std::vector< double >::size_type)\n"
--    "    std::vector< double >::vector(std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  std::vector< double >::value_type temp2 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_push_back",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_push_back" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_push_back" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp2 = static_cast< std::vector< double >::value_type >(val2);
--  arg2 = &temp2;
--  (arg1)->push_back((std::vector< double >::value_type const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_front",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_front" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (std::vector< double >::value_type *) &((std::vector< double > const *)arg1)->front();
--  resultobj = SWIG_From_double(static_cast< double >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_back" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = (std::vector< double >::value_type *) &((std::vector< double > const *)arg1)->back();
--  resultobj = SWIG_From_double(static_cast< double >(*result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::size_type arg2 ;
--  std::vector< double >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< double >::value_type temp3 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_assign" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_assign" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::size_type >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_assign" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< double >::value_type >(val3);
--  arg3 = &temp3;
--  (arg1)->assign(arg2,(std::vector< double >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::size_type arg2 ;
--  std::vector< double >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  std::vector< double >::value_type temp3 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::size_type >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_resize" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< double >::value_type >(val3);
--  arg3 = &temp3;
--  (arg1)->resize(arg2,(std::vector< double >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_resize(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_DoubleVector_resize__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_DoubleVector_resize__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_resize'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::resize(std::vector< double >::size_type)\n"
--    "    std::vector< double >::resize(std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::iterator arg2 ;
--  std::vector< double >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  std::vector< double >::value_type temp3 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< double >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--    }
--  }
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp3 = static_cast< std::vector< double >::value_type >(val3);
--  arg3 = &temp3;
--  result = (arg1)->insert(arg2,(std::vector< double >::value_type const &)*arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::iterator arg2 ;
--  std::vector< double >::size_type arg3 ;
--  std::vector< double >::value_type *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  size_t val3 ;
--  int ecode3 = 0 ;
--  std::vector< double >::value_type temp4 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
--    }
--  }
--  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg3 = static_cast< std::vector< double >::size_type >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "DoubleVector_insert" "', argument " "4"" of type '" "std::vector< double >::value_type""'");
--  } 
--  temp4 = static_cast< std::vector< double >::value_type >(val4);
--  arg4 = &temp4;
--  (arg1)->insert(arg2,arg3,(std::vector< double >::value_type const &)*arg4);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_insert(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_DoubleVector_insert__SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
--      if (_v) {
--        {
--          int res = SWIG_AsVal_size_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_double(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            return _wrap_DoubleVector_insert__SWIG_1(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_insert'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< double >::insert(std::vector< double >::iterator,std::vector< double >::value_type const &)\n"
--    "    std::vector< double >::insert(std::vector< double >::iterator,std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  std::vector< double >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_reserve",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_reserve" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_reserve" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< double >::size_type >(val2);
--  (arg1)->reserve(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_DoubleVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< double >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_capacity",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_capacity" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  result = ((std::vector< double > const *)arg1)->capacity();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_DoubleVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_DoubleVector",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_DoubleVector" "', argument " "1"" of type '" "std::vector< double > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *DoubleVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_ImageVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  PyObject **arg2 = (PyObject **) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  swig::SwigPyIterator *result = 0 ;
--  
--  arg2 = &obj0;
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_iterator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_iterator" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (swig::SwigPyIterator *)std_vector_Sl_vips_VImage_Sg__iterator(arg1,arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector___nonzero__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___nonzero__" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (bool)std_vector_Sl_vips_VImage_Sg____nonzero__((std::vector< vips::VImage > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector___bool__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___bool__" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (bool)std_vector_Sl_vips_VImage_Sg____bool__((std::vector< vips::VImage > const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector___len__",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___len__" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = std_vector_Sl_vips_VImage_Sg____len__((std::vector< vips::VImage > const *)arg1);
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::value_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_pop",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_pop" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  try {
--    result = std_vector_Sl_vips_VImage_Sg__pop(arg1);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj((new std::vector< vips::VImage >::value_type(static_cast< const std::vector< vips::VImage >::value_type& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  std::vector< vips::VImage >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___getslice__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___getslice__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ImageVector___getslice__" "', argument " "3"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< vips::VImage >::difference_type >(val3);
--  try {
--    result = (std::vector< vips::VImage,std::allocator< vips::VImage > > *)std_vector_Sl_vips_VImage_Sg____getslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  std::vector< vips::VImage >::difference_type arg3 ;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  int res4 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:ImageVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___setslice__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___setslice__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ImageVector___setslice__" "', argument " "3"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< vips::VImage >::difference_type >(val3);
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    res4 = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res4)) {
--      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "ImageVector___setslice__" "', argument " "4"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector___setslice__" "', argument " "4"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > > const &""'"); 
--    }
--    arg4 = ptr;
--  }
--  try {
--    std_vector_Sl_vips_VImage_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< vips::VImage,std::allocator< vips::VImage > > const &)*arg4);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res4)) delete arg4;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  std::vector< vips::VImage >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___setslice__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___setslice__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ImageVector___setslice__" "', argument " "3"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< vips::VImage >::difference_type >(val3);
--  try {
--    std_vector_Sl_vips_VImage_Sg____setslice____SWIG_0(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setslice__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_ImageVector___setslice____SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_ImageVector___setslice____SWIG_0(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector___setslice__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::__setslice__(std::vector< vips::VImage >::difference_type,std::vector< vips::VImage >::difference_type,std::vector< vips::VImage,std::allocator< vips::VImage > > const &)\n"
--    "    std::vector< vips::VImage >::__setslice__(std::vector< vips::VImage >::difference_type,std::vector< vips::VImage >::difference_type)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  std::vector< vips::VImage >::difference_type arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  ptrdiff_t val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___delslice__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___delslice__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ImageVector___delslice__" "', argument " "3"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg3 = static_cast< std::vector< vips::VImage >::difference_type >(val3);
--  try {
--    std_vector_Sl_vips_VImage_Sg____delslice__(arg1,arg2,arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___delitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___delitem__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  try {
--    std_vector_Sl_vips_VImage_Sg____delitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___getitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    result = (std::vector< vips::VImage,std::allocator< vips::VImage > > *)std_vector_Sl_vips_VImage_Sg____getitem____SWIG_0(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res3 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___setitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    res3 = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ImageVector___setitem__" "', argument " "3"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector___setitem__" "', argument " "3"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > > const &""'"); 
--    }
--    arg3 = ptr;
--  }
--  try {
--    std_vector_Sl_vips_VImage_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< vips::VImage,std::allocator< vips::VImage > > const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res3)) delete arg3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector___setitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___setitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_vips_VImage_Sg____setitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  PySliceObject *arg2 = (PySliceObject *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector___delitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___delitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  {
--    if (!PySlice_Check(obj1)) {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
--    }
--    arg2 = (PySliceObject *) obj1;
--  }
--  try {
--    std_vector_Sl_vips_VImage_Sg____delitem____SWIG_1(arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  catch(std::invalid_argument &_e) {
--    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___delitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_ImageVector___delitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_ImageVector___delitem____SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector___delitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::__delitem__(std::vector< vips::VImage >::difference_type)\n"
--    "    std::vector< vips::VImage >::__delitem__(PySliceObject *)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< vips::VImage >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector___getitem__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___getitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___getitem__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  try {
--    result = (std::vector< vips::VImage >::value_type *) &std_vector_Sl_vips_VImage_Sg____getitem____SWIG_1((std::vector< vips::VImage > const *)arg1,arg2);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___getitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_ImageVector___getitem____SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_ImageVector___getitem____SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector___getitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::__getitem__(PySliceObject *)\n"
--    "    std::vector< vips::VImage >::__getitem__(std::vector< vips::VImage >::difference_type) const\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::difference_type arg2 ;
--  std::vector< vips::VImage >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  ptrdiff_t val2 ;
--  int ecode2 = 0 ;
--  void *argp3 = 0 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector___setitem__" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector___setitem__" "', argument " "2"" of type '" "std::vector< vips::VImage >::difference_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::difference_type >(val2);
--  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ImageVector___setitem__" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp3) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector___setitem__" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg3 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp3);
--  try {
--    std_vector_Sl_vips_VImage_Sg____setitem____SWIG_2(arg1,arg2,(vips::VImage const &)*arg3);
--  }
--  catch(std::out_of_range &_e) {
--    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector___setitem__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        return _wrap_ImageVector___setitem____SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        _v = PySlice_Check(argv[1]);
--      }
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_ImageVector___setitem____SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_vips__VImage, 0);
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_ImageVector___setitem____SWIG_2(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector___setitem__'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::__setitem__(PySliceObject *,std::vector< vips::VImage,std::allocator< vips::VImage > > const &)\n"
--    "    std::vector< vips::VImage >::__setitem__(PySliceObject *)\n"
--    "    std::vector< vips::VImage >::__setitem__(std::vector< vips::VImage >::difference_type,std::vector< vips::VImage >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_append",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_append" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ImageVector_append" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_append" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp2);
--  std_vector_Sl_vips_VImage_Sg__append(arg1,(vips::VImage const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_ImageVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_ImageVector")) SWIG_fail;
--  result = (std::vector< vips::VImage > *)new std::vector< vips::VImage >();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_ImageVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = 0 ;
--  int res1 = SWIG_OLDOBJ ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_ImageVector",&obj0)) SWIG_fail;
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    res1 = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ImageVector" "', argument " "1"" of type '" "std::vector< vips::VImage > const &""'"); 
--    }
--    if (!ptr) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ImageVector" "', argument " "1"" of type '" "std::vector< vips::VImage > const &""'"); 
--    }
--    arg1 = ptr;
--  }
--  result = (std::vector< vips::VImage > *)new std::vector< vips::VImage >((std::vector< vips::VImage > const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_NEW |  0 );
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return resultobj;
--fail:
--  if (SWIG_IsNewObj(res1)) delete arg1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_empty",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_empty" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (bool)((std::vector< vips::VImage > const *)arg1)->empty();
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_size",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_size" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = ((std::vector< vips::VImage > const *)arg1)->size();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_clear",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_clear" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  (arg1)->clear();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage > *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_swap",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_swap" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ImageVector_swap" "', argument " "2"" of type '" "std::vector< vips::VImage > &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_swap" "', argument " "2"" of type '" "std::vector< vips::VImage > &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< vips::VImage > * >(argp2);
--  (arg1)->swap(*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  SwigValueWrapper< std::allocator< vips::VImage > > result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_get_allocator",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_get_allocator" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = ((std::vector< vips::VImage > const *)arg1)->get_allocator();
--  resultobj = SWIG_NewPointerObj((new std::vector< vips::VImage >::allocator_type(static_cast< const std::vector< vips::VImage >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_vips__VImage_t, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_begin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_begin" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (arg1)->begin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_end",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_end" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (arg1)->end();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_rbegin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_rbegin" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (arg1)->rbegin();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::reverse_iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_rend",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_rend" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (arg1)->rend();
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::reverse_iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_ImageVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage >::size_type arg1 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_ImageVector",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ImageVector" "', argument " "1"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< vips::VImage >::size_type >(val1);
--  result = (std::vector< vips::VImage > *)new std::vector< vips::VImage >(arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_pop_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_pop_back" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  (arg1)->pop_back();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_resize",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_resize" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector_resize" "', argument " "2"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::size_type >(val2);
--  (arg1)->resize(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::iterator arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< vips::VImage >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_erase",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_erase" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::iterator arg2 ;
--  std::vector< vips::VImage >::iterator arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  swig::SwigPyIterator *iter3 = 0 ;
--  int res3 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< vips::VImage >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_erase" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--    }
--  }
--  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res3) || !iter3) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "3"" of type '" "std::vector< vips::VImage >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter3);
--    if (iter_t) {
--      arg3 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_erase" "', argument " "3"" of type '" "std::vector< vips::VImage >::iterator""'");
--    }
--  }
--  result = (arg1)->erase(arg2,arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_erase(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter) != 0));
--      if (_v) {
--        return _wrap_ImageVector_erase__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter) != 0));
--      if (_v) {
--        swig::SwigPyIterator *iter = 0;
--        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter) != 0));
--        if (_v) {
--          return _wrap_ImageVector_erase__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector_erase'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::erase(std::vector< vips::VImage >::iterator)\n"
--    "    std::vector< vips::VImage >::erase(std::vector< vips::VImage >::iterator,std::vector< vips::VImage >::iterator)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_ImageVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage >::size_type arg1 ;
--  std::vector< vips::VImage >::value_type *arg2 = 0 ;
--  size_t val1 ;
--  int ecode1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::vector< vips::VImage > *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_ImageVector",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_ImageVector" "', argument " "1"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg1 = static_cast< std::vector< vips::VImage >::size_type >(val1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_ImageVector" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ImageVector" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp2);
--  result = (std::vector< vips::VImage > *)new std::vector< vips::VImage >(arg1,(std::vector< vips::VImage >::value_type const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_ImageVector(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_ImageVector__SWIG_0(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      return _wrap_new_ImageVector__SWIG_2(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_ImageVector__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    {
--      int res = SWIG_AsVal_size_t(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_new_ImageVector__SWIG_3(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_ImageVector'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::vector()\n"
--    "    std::vector< vips::VImage >::vector(std::vector< vips::VImage > const &)\n"
--    "    std::vector< vips::VImage >::vector(std::vector< vips::VImage >::size_type)\n"
--    "    std::vector< vips::VImage >::vector(std::vector< vips::VImage >::size_type,std::vector< vips::VImage >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::value_type *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_push_back",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_push_back" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ImageVector_push_back" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_push_back" "', argument " "2"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg2 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp2);
--  (arg1)->push_back((std::vector< vips::VImage >::value_type const &)*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_front",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_front" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (std::vector< vips::VImage >::value_type *) &((std::vector< vips::VImage > const *)arg1)->front();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::value_type *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_back",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_back" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = (std::vector< vips::VImage >::value_type *) &((std::vector< vips::VImage > const *)arg1)->back();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::size_type arg2 ;
--  std::vector< vips::VImage >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  void *argp3 = 0 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_assign" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector_assign" "', argument " "2"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::size_type >(val2);
--  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ImageVector_assign" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp3) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_assign" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg3 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp3);
--  (arg1)->assign(arg2,(std::vector< vips::VImage >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::size_type arg2 ;
--  std::vector< vips::VImage >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  void *argp3 = 0 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_resize" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector_resize" "', argument " "2"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::size_type >(val2);
--  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ImageVector_resize" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp3) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_resize" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg3 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp3);
--  (arg1)->resize(arg2,(std::vector< vips::VImage >::value_type const &)*arg3);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_resize(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_ImageVector_resize__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_size_t(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_vips__VImage, 0);
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_ImageVector_resize__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector_resize'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::resize(std::vector< vips::VImage >::size_type)\n"
--    "    std::vector< vips::VImage >::resize(std::vector< vips::VImage >::size_type,std::vector< vips::VImage >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::iterator arg2 ;
--  std::vector< vips::VImage >::value_type *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  void *argp3 = 0 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  std::vector< vips::VImage >::iterator result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:ImageVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_insert" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_insert" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_insert" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--    }
--  }
--  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ImageVector_insert" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp3) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_insert" "', argument " "3"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg3 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp3);
--  result = (arg1)->insert(arg2,(std::vector< vips::VImage >::value_type const &)*arg3);
--  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< vips::VImage >::iterator & >(result)),
--    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::iterator arg2 ;
--  std::vector< vips::VImage >::size_type arg3 ;
--  std::vector< vips::VImage >::value_type *arg4 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  swig::SwigPyIterator *iter2 = 0 ;
--  int res2 ;
--  size_t val3 ;
--  int ecode3 = 0 ;
--  void *argp4 = 0 ;
--  int res4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:ImageVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_insert" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
--  if (!SWIG_IsOK(res2) || !iter2) {
--    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_insert" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--  } else {
--    swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter2);
--    if (iter_t) {
--      arg2 = iter_t->get_current();
--    } else {
--      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageVector_insert" "', argument " "2"" of type '" "std::vector< vips::VImage >::iterator""'");
--    }
--  }
--  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ImageVector_insert" "', argument " "3"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg3 = static_cast< std::vector< vips::VImage >::size_type >(val3);
--  res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res4)) {
--    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "ImageVector_insert" "', argument " "4"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  if (!argp4) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ImageVector_insert" "', argument " "4"" of type '" "std::vector< vips::VImage >::value_type const &""'"); 
--  }
--  arg4 = reinterpret_cast< std::vector< vips::VImage >::value_type * >(argp4);
--  (arg1)->insert(arg2,arg3,(std::vector< vips::VImage >::value_type const &)*arg4);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_insert(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter) != 0));
--      if (_v) {
--        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_vips__VImage, 0);
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_ImageVector_insert__SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    int res = swig::asptr(argv[0], (std::vector<vips::VImage,std::allocator< vips::VImage > >**)(0));
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      swig::SwigPyIterator *iter = 0;
--      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
--      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< vips::VImage >::iterator > *>(iter) != 0));
--      if (_v) {
--        {
--          int res = SWIG_AsVal_size_t(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_vips__VImage, 0);
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_ImageVector_insert__SWIG_1(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ImageVector_insert'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    std::vector< vips::VImage >::insert(std::vector< vips::VImage >::iterator,std::vector< vips::VImage >::value_type const &)\n"
--    "    std::vector< vips::VImage >::insert(std::vector< vips::VImage >::iterator,std::vector< vips::VImage >::size_type,std::vector< vips::VImage >::value_type const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  std::vector< vips::VImage >::size_type arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  size_t val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:ImageVector_reserve",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_reserve" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ImageVector_reserve" "', argument " "2"" of type '" "std::vector< vips::VImage >::size_type""'");
--  } 
--  arg2 = static_cast< std::vector< vips::VImage >::size_type >(val2);
--  (arg1)->reserve(arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_ImageVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::vector< vips::VImage >::size_type result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:ImageVector_capacity",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ImageVector_capacity" "', argument " "1"" of type '" "std::vector< vips::VImage > const *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  result = ((std::vector< vips::VImage > const *)arg1)->capacity();
--  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_ImageVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage > *arg1 = (std::vector< vips::VImage > *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_ImageVector",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ImageVector" "', argument " "1"" of type '" "std::vector< vips::VImage > *""'"); 
--  }
--  arg1 = reinterpret_cast< std::vector< vips::VImage > * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *ImageVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_init__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:init",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "init" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  result = (bool)vips::init((char const *)arg1);
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_init__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  bool result;
--  
--  if (!PyArg_ParseTuple(args,(char *)":init")) SWIG_fail;
--  result = (bool)vips::init();
--  resultobj = SWIG_From_bool(static_cast< bool >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_init(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[2];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_init__SWIG_1(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_init__SWIG_0(self, args);
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'init'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::init(char const *)\n"
--    "    vips::init()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_shutdown(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  
--  if (!PyArg_ParseTuple(args,(char *)":shutdown")) SWIG_fail;
--  vips::shutdown();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_print_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  
--  if (!PyArg_ParseTuple(args,(char *)":VImage_print_all")) SWIG_fail;
--  vips::VImage::print_all();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  char *arg2 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_VImage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VImage" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_VImage" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (vips::VImage *)new vips::VImage((char const *)arg1,(char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VImage",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VImage" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = (vips::VImage *)new vips::VImage((char const *)arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  void *arg1 = (void *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  int res1 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:new_VImage",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VImage" "', argument " "1"" of type '" "void *""'"); 
--  }
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_VImage" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_VImage" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_VImage" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_VImage" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  try {
--    result = (vips::VImage *)new vips::VImage(arg1,arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  _VipsImage *arg1 = (_VipsImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VImage",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p__VipsImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VImage" "', argument " "1"" of type '" "_VipsImage *""'"); 
--  }
--  arg1 = reinterpret_cast< _VipsImage * >(argp1);
--  result = (vips::VImage *)new vips::VImage(arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VImage")) SWIG_fail;
--  try {
--    result = (vips::VImage *)new vips::VImage();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convert2disc(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  char *arg2 = (char *) 0 ;
--  char *arg3 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_convert2disc",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convert2disc" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convert2disc" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_convert2disc" "', argument " "3"" of type '" "char const *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  try {
--    result = vips::VImage::convert2disc((char const *)arg1,(char const *)arg2,(char const *)arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VImage",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VImage" "', argument " "1"" of type '" "vips::VImage const &""'"); 
--  }
--  if (!argp1) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VImage" "', argument " "1"" of type '" "vips::VImage const &""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (vips::VImage *)new vips::VImage((vips::VImage const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VImage(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[6];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VImage__SWIG_4(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p__VipsImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VImage__SWIG_3(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VImage__SWIG_5(self, args);
--    }
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VImage__SWIG_1(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_new_VImage__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 5) {
--    int _v;
--    void *ptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &ptr, 0, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              return _wrap_new_VImage__SWIG_2(self, args);
--            }
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VImage'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::VImage(char const *,char const *)\n"
--    "    vips::VImage::VImage(char const *)\n"
--    "    vips::VImage::VImage(void *,int,int,int,vips::VImage::TBandFmt)\n"
--    "    vips::VImage::VImage(_VipsImage *)\n"
--    "    vips::VImage::VImage()\n"
--    "    vips::VImage::VImage(vips::VImage const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage___assign__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage___assign__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage___assign__" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage___assign__" "', argument " "2"" of type '" "vips::VImage const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage___assign__" "', argument " "2"" of type '" "vips::VImage const &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VImage * >(argp2);
--  try {
--    result = (vips::VImage *) &(arg1)->operator =((vips::VImage const &)*arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VImage, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VImage(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VImage",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VImage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_image(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  _VipsImage *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_image",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_image" "', argument " "1"" of type '" "vips::VImage const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (_VipsImage *)((vips::VImage const *)arg1)->image();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p__VipsImage, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_data(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  void *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_data",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_data" "', argument " "1"" of type '" "vips::VImage const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (void *)((vips::VImage const *)arg1)->data();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_write__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_write",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_write" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_write" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_write" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->write(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_write__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_write",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_write" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_write" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (arg1)->write((char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_write__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_write",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_write" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->write();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_write(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 1) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_VImage_write__SWIG_2(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_write__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_write__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_write'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::write(vips::VImage)\n"
--    "    vips::VImage::write(char const *)\n"
--    "    vips::VImage::write()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_debug_print(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_debug_print",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_debug_print" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  (arg1)->debug_print();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Xsize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Xsize",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Xsize" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Xsize();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Ysize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Ysize",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Ysize" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Ysize();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Bands(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Bands",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Bands" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Bands();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_BandFmt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage::TBandFmt result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_BandFmt",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_BandFmt" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (vips::VImage::TBandFmt)(arg1)->BandFmt();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Coding(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage::TCoding result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Coding",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Coding" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (vips::VImage::TCoding)(arg1)->Coding();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Type(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage::TType result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Type",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Type" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (vips::VImage::TType)(arg1)->Type();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Xres(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  float result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Xres",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Xres" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (float)(arg1)->Xres();
--  resultobj = SWIG_From_float(static_cast< float >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Yres(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  float result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Yres",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Yres" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (float)(arg1)->Yres();
--  resultobj = SWIG_From_float(static_cast< float >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Length(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Length",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Length" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Length();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Compression(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage::TCompression result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Compression",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Compression" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (vips::VImage::TCompression)(arg1)->Compression();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Level(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  short result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Level",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Level" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (short)(arg1)->Level();
--  resultobj = SWIG_From_short(static_cast< short >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Xoffset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Xoffset",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Xoffset" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Xoffset();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Yoffset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Yoffset",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Yoffset" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (int)(arg1)->Yoffset();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_filename(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_filename",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_filename" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (char *)(arg1)->filename();
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Hist(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Hist",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Hist" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  result = (char *)(arg1)->Hist();
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_remove(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  gboolean result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_remove",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_remove" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_remove" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  result = (arg1)->meta_remove((char const *)arg2);
--  resultobj = SWIG_NewPointerObj((new gboolean(static_cast< const gboolean& >(result))), SWIGTYPE_p_gboolean, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_typeof(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  GType result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_get_typeof",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_typeof" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_typeof" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  result = (arg1)->meta_get_typeof((char const *)arg2);
--  resultobj = SWIG_NewPointerObj((new GType(static_cast< const GType& >(result))), SWIGTYPE_p_GType, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_int(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_get_int",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_int" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_int" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (int)(arg1)->meta_get_int((char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_double(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_get_double",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_double" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_double" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (double)(arg1)->meta_get_double((char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_string(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_get_string",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_string" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_string" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (char *)(arg1)->meta_get_string((char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_area(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  void *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_meta_get_area",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_area" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_area" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (void *)(arg1)->meta_get_area((char const *)arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_get_blob(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  size_t *arg3 = (size_t *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  void *argp3 = 0 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  void *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_meta_get_blob",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_get_blob" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_get_blob" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_size_t, 0 |  0 );
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_meta_get_blob" "', argument " "3"" of type '" "size_t *""'"); 
--  }
--  arg3 = reinterpret_cast< size_t * >(argp3);
--  try {
--    result = (void *)(arg1)->meta_get_blob((char const *)arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_set__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_meta_set",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_set" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_set" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_meta_set" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    (arg1)->meta_set((char const *)arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_set__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  double arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_meta_set",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_set" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_set" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_meta_set" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    (arg1)->meta_set((char const *)arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_set__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  char *arg3 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_meta_set",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_meta_set" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_meta_set" "', argument " "2"" of type '" "char const *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_meta_set" "', argument " "3"" of type '" "char const *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  try {
--    (arg1)->meta_set((char const *)arg2,(char const *)arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_meta_set(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_VImage_meta_set__SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_VImage_meta_set__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        int res = SWIG_AsCharPtrAndSize(argv[2], 0, NULL, 0);
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_VImage_meta_set__SWIG_2(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_meta_set'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::meta_set(char const *,int)\n"
--    "    vips::VImage::meta_set(char const *,double)\n"
--    "    vips::VImage::meta_set(char const *,char const *)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  vips::VImage::TCoding arg6 ;
--  vips::VImage::TType arg7 ;
--  float arg8 ;
--  float arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  float val8 ;
--  int ecode8 = 0 ;
--  float val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_initdesc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_initdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_initdesc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_initdesc" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_initdesc" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_initdesc" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_initdesc" "', argument " "6"" of type '" "vips::VImage::TCoding""'");
--  } 
--  arg6 = static_cast< vips::VImage::TCoding >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_initdesc" "', argument " "7"" of type '" "vips::VImage::TType""'");
--  } 
--  arg7 = static_cast< vips::VImage::TType >(val7);
--  ecode8 = SWIG_AsVal_float(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_initdesc" "', argument " "8"" of type '" "float""'");
--  } 
--  arg8 = static_cast< float >(val8);
--  ecode9 = SWIG_AsVal_float(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_initdesc" "', argument " "9"" of type '" "float""'");
--  } 
--  arg9 = static_cast< float >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_initdesc" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_initdesc" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    (arg1)->initdesc(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  vips::VImage::TCoding arg6 ;
--  vips::VImage::TType arg7 ;
--  float arg8 ;
--  float arg9 ;
--  int arg10 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  float val8 ;
--  int ecode8 = 0 ;
--  float val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:VImage_initdesc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_initdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_initdesc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_initdesc" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_initdesc" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_initdesc" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_initdesc" "', argument " "6"" of type '" "vips::VImage::TCoding""'");
--  } 
--  arg6 = static_cast< vips::VImage::TCoding >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_initdesc" "', argument " "7"" of type '" "vips::VImage::TType""'");
--  } 
--  arg7 = static_cast< vips::VImage::TType >(val7);
--  ecode8 = SWIG_AsVal_float(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_initdesc" "', argument " "8"" of type '" "float""'");
--  } 
--  arg8 = static_cast< float >(val8);
--  ecode9 = SWIG_AsVal_float(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_initdesc" "', argument " "9"" of type '" "float""'");
--  } 
--  arg9 = static_cast< float >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_initdesc" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  try {
--    (arg1)->initdesc(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  vips::VImage::TCoding arg6 ;
--  vips::VImage::TType arg7 ;
--  float arg8 ;
--  float arg9 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  float val8 ;
--  int ecode8 = 0 ;
--  float val9 ;
--  int ecode9 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:VImage_initdesc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_initdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_initdesc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_initdesc" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_initdesc" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_initdesc" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_initdesc" "', argument " "6"" of type '" "vips::VImage::TCoding""'");
--  } 
--  arg6 = static_cast< vips::VImage::TCoding >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_initdesc" "', argument " "7"" of type '" "vips::VImage::TType""'");
--  } 
--  arg7 = static_cast< vips::VImage::TType >(val7);
--  ecode8 = SWIG_AsVal_float(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_initdesc" "', argument " "8"" of type '" "float""'");
--  } 
--  arg8 = static_cast< float >(val8);
--  ecode9 = SWIG_AsVal_float(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_initdesc" "', argument " "9"" of type '" "float""'");
--  } 
--  arg9 = static_cast< float >(val9);
--  try {
--    (arg1)->initdesc(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  vips::VImage::TCoding arg6 ;
--  vips::VImage::TType arg7 ;
--  float arg8 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  float val8 ;
--  int ecode8 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOO:VImage_initdesc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_initdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_initdesc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_initdesc" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_initdesc" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_initdesc" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_initdesc" "', argument " "6"" of type '" "vips::VImage::TCoding""'");
--  } 
--  arg6 = static_cast< vips::VImage::TCoding >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_initdesc" "', argument " "7"" of type '" "vips::VImage::TType""'");
--  } 
--  arg7 = static_cast< vips::VImage::TType >(val7);
--  ecode8 = SWIG_AsVal_float(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_initdesc" "', argument " "8"" of type '" "float""'");
--  } 
--  arg8 = static_cast< float >(val8);
--  try {
--    (arg1)->initdesc(arg2,arg3,arg4,arg5,arg6,arg7,arg8);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  vips::VImage::TCoding arg6 ;
--  vips::VImage::TType arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_initdesc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_initdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_initdesc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_initdesc" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_initdesc" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_initdesc" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_initdesc" "', argument " "6"" of type '" "vips::VImage::TCoding""'");
--  } 
--  arg6 = static_cast< vips::VImage::TCoding >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_initdesc" "', argument " "7"" of type '" "vips::VImage::TType""'");
--  } 
--  arg7 = static_cast< vips::VImage::TType >(val7);
--  try {
--    (arg1)->initdesc(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_initdesc(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[12];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 11) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 7) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                {
--                  int res = SWIG_AsVal_int(argv[6], NULL);
--                  _v = SWIG_CheckState(res);
--                }
--                if (_v) {
--                  return _wrap_VImage_initdesc__SWIG_4(self, args);
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  if (argc == 8) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                {
--                  int res = SWIG_AsVal_int(argv[6], NULL);
--                  _v = SWIG_CheckState(res);
--                }
--                if (_v) {
--                  {
--                    int res = SWIG_AsVal_float(argv[7], NULL);
--                    _v = SWIG_CheckState(res);
--                  }
--                  if (_v) {
--                    return _wrap_VImage_initdesc__SWIG_3(self, args);
--                  }
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  if (argc == 9) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                {
--                  int res = SWIG_AsVal_int(argv[6], NULL);
--                  _v = SWIG_CheckState(res);
--                }
--                if (_v) {
--                  {
--                    int res = SWIG_AsVal_float(argv[7], NULL);
--                    _v = SWIG_CheckState(res);
--                  }
--                  if (_v) {
--                    {
--                      int res = SWIG_AsVal_float(argv[8], NULL);
--                      _v = SWIG_CheckState(res);
--                    }
--                    if (_v) {
--                      return _wrap_VImage_initdesc__SWIG_2(self, args);
--                    }
--                  }
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  if (argc == 10) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                {
--                  int res = SWIG_AsVal_int(argv[6], NULL);
--                  _v = SWIG_CheckState(res);
--                }
--                if (_v) {
--                  {
--                    int res = SWIG_AsVal_float(argv[7], NULL);
--                    _v = SWIG_CheckState(res);
--                  }
--                  if (_v) {
--                    {
--                      int res = SWIG_AsVal_float(argv[8], NULL);
--                      _v = SWIG_CheckState(res);
--                    }
--                    if (_v) {
--                      {
--                        int res = SWIG_AsVal_int(argv[9], NULL);
--                        _v = SWIG_CheckState(res);
--                      }
--                      if (_v) {
--                        return _wrap_VImage_initdesc__SWIG_1(self, args);
--                      }
--                    }
--                  }
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  if (argc == 11) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                {
--                  int res = SWIG_AsVal_int(argv[6], NULL);
--                  _v = SWIG_CheckState(res);
--                }
--                if (_v) {
--                  {
--                    int res = SWIG_AsVal_float(argv[7], NULL);
--                    _v = SWIG_CheckState(res);
--                  }
--                  if (_v) {
--                    {
--                      int res = SWIG_AsVal_float(argv[8], NULL);
--                      _v = SWIG_CheckState(res);
--                    }
--                    if (_v) {
--                      {
--                        int res = SWIG_AsVal_int(argv[9], NULL);
--                        _v = SWIG_CheckState(res);
--                      }
--                      if (_v) {
--                        {
--                          int res = SWIG_AsVal_int(argv[10], NULL);
--                          _v = SWIG_CheckState(res);
--                        }
--                        if (_v) {
--                          return _wrap_VImage_initdesc__SWIG_0(self, args);
--                        }
--                      }
--                    }
--                  }
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_initdesc'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::initdesc(int,int,int,vips::VImage::TBandFmt,vips::VImage::TCoding,vips::VImage::TType,float,float,int,int)\n"
--    "    vips::VImage::initdesc(int,int,int,vips::VImage::TBandFmt,vips::VImage::TCoding,vips::VImage::TType,float,float,int)\n"
--    "    vips::VImage::initdesc(int,int,int,vips::VImage::TBandFmt,vips::VImage::TCoding,vips::VImage::TType,float,float)\n"
--    "    vips::VImage::initdesc(int,int,int,vips::VImage::TBandFmt,vips::VImage::TCoding,vips::VImage::TType,float)\n"
--    "    vips::VImage::initdesc(int,int,int,vips::VImage::TBandFmt,vips::VImage::TCoding,vips::VImage::TType)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_abs(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_abs",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_abs" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->abs();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_acos(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_acos",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_acos" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->acos();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_add",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_add" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_add" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_add" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->add(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_asin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_asin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_asin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->asin();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_atan(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_atan",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_atan" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->atan();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_avg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_avg",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_avg" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->avg();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_point(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  double arg3 ;
--  double arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_point",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_point" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_point" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_point" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_point" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_point" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = (double)(arg1)->point(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_point_bilinear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_point_bilinear",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_point_bilinear" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_point_bilinear" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_point_bilinear" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_point_bilinear" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (double)(arg1)->point_bilinear(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_bandmean(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_bandmean",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_bandmean" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->bandmean();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_ceil(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_ceil",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_ceil" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->ceil();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_cos(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_cos",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_cos" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->cos();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_cross_phase(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_cross_phase",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_cross_phase" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_cross_phase" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_cross_phase" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->cross_phase(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_deviate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_deviate",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_deviate" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->deviate();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_divide(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_divide",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_divide" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_divide" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_divide" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->divide(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_exp10(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_exp10",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_exp10" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->exp10();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_expn__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_expn",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_expn" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_expn" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->expn(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_expn__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_expn",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_expn" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_expn" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->expn(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_expn(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_expn__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_expn__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_expn'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::expn(double)\n"
--    "    vips::VImage::expn(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_exp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_exp",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_exp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->exp();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_floor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_floor",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_floor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->floor();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_invert(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_invert",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_invert" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->invert();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_lin",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_lin" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lin" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = (arg1)->lin(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_linreg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > arg1 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_linreg",&obj0,&obj1)) SWIG_fail;
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    int res = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_linreg" "', argument " "1"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > >""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_linreg" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = vips::VImage::linreg(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  std::vector< double,std::allocator< double > > arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_lin",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_lin" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_lin" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg3 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->lin(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lin(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[4];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 3) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          return _wrap_VImage_lin__SWIG_0(self, args);
--        }
--      }
--    }
--  }
--  if (argc == 3) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          return _wrap_VImage_lin__SWIG_1(self, args);
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_lin'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::lin(double,double)\n"
--    "    vips::VImage::lin(std::vector< double,std::allocator< double > >,std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_log10(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_log10",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_log10" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->log10();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_log(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_log",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_log" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->log();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_max(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_max",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_max" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->max();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_maxpos(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::complex< double > result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_maxpos",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_maxpos" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->maxpos();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_maxpos_avg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double *arg2 = 0 ;
--  double *arg3 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double temp2 ;
--  int res2 = SWIG_TMPOBJ ;
--  double temp3 ;
--  int res3 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  arg2 = &temp2;
--  arg3 = &temp3;
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_maxpos_avg",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_maxpos_avg" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->maxpos_avg(*arg2,*arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (SWIG_IsTmpObj(res2)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg2)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res2) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg2), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res3)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg3)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res3) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg3), SWIGTYPE_p_double, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_measure(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_measure",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_measure" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_measure" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_measure" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_measure" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_measure" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_measure" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_measure" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  try {
--    result = (arg1)->measure(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_min(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_min",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_min" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->min();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_minpos(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  std::complex< double > result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_minpos",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_minpos" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->minpos();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_multiply(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_multiply",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_multiply" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_multiply" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_multiply" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->multiply(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_pow__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_pow",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_pow" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_pow" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->pow(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_pow__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_pow",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_pow" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_pow" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->pow(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_pow(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_pow__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_pow__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_pow'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::pow(double)\n"
--    "    vips::VImage::pow(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_recomb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_recomb",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_recomb" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_recomb" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_recomb" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->recomb(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_remainder__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_remainder",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_remainder" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_remainder" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_remainder" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->remainder(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_remainder__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_remainder",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_remainder" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_remainder" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->remainder(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_remainder__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_remainder",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_remainder" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_remainder" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->remainder(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_remainder(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_remainder__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_remainder__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_remainder__SWIG_2(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_remainder'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::remainder(vips::VImage)\n"
--    "    vips::VImage::remainder(double)\n"
--    "    vips::VImage::remainder(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rint(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rint",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rint" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rint();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_sign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_sign",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_sign" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->sign();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_sin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_sin",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_sin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->sin();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_stats(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_stats",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_stats" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->stats();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_subtract(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_subtract",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_subtract" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_subtract" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_subtract" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->subtract(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tan(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_tan",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tan" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->tan();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_greyc(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  double arg9 ;
--  double arg10 ;
--  int arg11 ;
--  int arg12 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  double val9 ;
--  int ecode9 = 0 ;
--  double val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOO:VImage_greyc",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_greyc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_greyc" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_greyc" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_greyc" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_greyc" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_greyc" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_greyc" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_greyc" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  ecode9 = SWIG_AsVal_double(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_greyc" "', argument " "9"" of type '" "double""'");
--  } 
--  arg9 = static_cast< double >(val9);
--  ecode10 = SWIG_AsVal_double(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_greyc" "', argument " "10"" of type '" "double""'");
--  } 
--  arg10 = static_cast< double >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_greyc" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_greyc" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  try {
--    result = (arg1)->greyc(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_greyc_mask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  double arg9 ;
--  double arg10 ;
--  double arg11 ;
--  int arg12 ;
--  int arg13 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  double val9 ;
--  int ecode9 = 0 ;
--  double val10 ;
--  int ecode10 = 0 ;
--  double val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  int val13 ;
--  int ecode13 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  PyObject * obj12 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOOO:VImage_greyc_mask",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11,&obj12)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_greyc_mask" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_greyc_mask" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_greyc_mask" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_greyc_mask" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_greyc_mask" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_greyc_mask" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_greyc_mask" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_greyc_mask" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_greyc_mask" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  ecode9 = SWIG_AsVal_double(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_greyc_mask" "', argument " "9"" of type '" "double""'");
--  } 
--  arg9 = static_cast< double >(val9);
--  ecode10 = SWIG_AsVal_double(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_greyc_mask" "', argument " "10"" of type '" "double""'");
--  } 
--  arg10 = static_cast< double >(val10);
--  ecode11 = SWIG_AsVal_double(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_greyc_mask" "', argument " "11"" of type '" "double""'");
--  } 
--  arg11 = static_cast< double >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_greyc_mask" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  ecode13 = SWIG_AsVal_int(obj12, &val13);
--  if (!SWIG_IsOK(ecode13)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode13), "in method '" "VImage_greyc_mask" "', argument " "13"" of type '" "int""'");
--  } 
--  arg13 = static_cast< int >(val13);
--  try {
--    result = (arg1)->greyc_mask(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LCh2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LCh2Lab",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LCh2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LCh2Lab();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LCh2UCS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LCh2UCS",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LCh2UCS" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LCh2UCS();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2LCh(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Lab2LCh",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2LCh" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Lab2LCh();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2LabQ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Lab2LabQ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2LabQ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Lab2LabQ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2LabS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Lab2LabS",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2LabS" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Lab2LabS();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2UCS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Lab2UCS",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2UCS" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Lab2UCS();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Lab2XYZ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Lab2XYZ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2XYZ_temp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_Lab2XYZ_temp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2XYZ_temp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_Lab2XYZ_temp" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_Lab2XYZ_temp" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_Lab2XYZ_temp" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  try {
--    result = (arg1)->Lab2XYZ_temp(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Lab2disp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDisplay arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_Lab2disp",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Lab2disp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_Lab2disp" "', argument " "2"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_Lab2disp" "', argument " "2"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->Lab2disp(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabQ2LabS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LabQ2LabS",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabQ2LabS" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LabQ2LabS();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabQ2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LabQ2Lab",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabQ2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LabQ2Lab();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabQ2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LabQ2XYZ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabQ2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LabQ2XYZ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabQ2disp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDisplay arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_LabQ2disp",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabQ2disp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_LabQ2disp" "', argument " "2"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_LabQ2disp" "', argument " "2"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->LabQ2disp(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabS2LabQ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LabS2LabQ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabS2LabQ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LabS2LabQ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_LabS2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_LabS2Lab",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_LabS2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->LabS2Lab();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_UCS2LCh(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_UCS2LCh",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_UCS2LCh" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->UCS2LCh();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_UCS2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_UCS2Lab",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_UCS2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->UCS2Lab();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_UCS2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_UCS2XYZ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_UCS2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->UCS2XYZ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_XYZ2Lab",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->XYZ2Lab();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2Lab_temp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_XYZ2Lab_temp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2Lab_temp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_XYZ2Lab_temp" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_XYZ2Lab_temp" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_XYZ2Lab_temp" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  try {
--    result = (arg1)->XYZ2Lab_temp(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2UCS(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_XYZ2UCS",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2UCS" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->XYZ2UCS();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2Yxy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_XYZ2Yxy",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2Yxy" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->XYZ2Yxy();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2disp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDisplay arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_XYZ2disp",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2disp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_XYZ2disp" "', argument " "2"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_XYZ2disp" "', argument " "2"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->XYZ2disp(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_XYZ2sRGB(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_XYZ2sRGB",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_XYZ2sRGB" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->XYZ2sRGB();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_Yxy2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_Yxy2XYZ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_Yxy2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->Yxy2XYZ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dE00_fromLab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dE00_fromLab",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dE00_fromLab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dE00_fromLab" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dE00_fromLab" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dE00_fromLab(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dECMC_fromLab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dECMC_fromLab",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dECMC_fromLab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dECMC_fromLab" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dECMC_fromLab" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dECMC_fromLab(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dECMC_fromdisp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VDisplay arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_dECMC_fromdisp",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dECMC_fromdisp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dECMC_fromdisp" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dECMC_fromdisp" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_dECMC_fromdisp" "', argument " "3"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dECMC_fromdisp" "', argument " "3"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dECMC_fromdisp(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dE_fromLab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dE_fromLab",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dE_fromLab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dE_fromLab" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dE_fromLab" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dE_fromLab(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dE_fromXYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dE_fromXYZ",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dE_fromXYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dE_fromXYZ" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dE_fromXYZ" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dE_fromXYZ(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dE_fromdisp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VDisplay arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_dE_fromdisp",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dE_fromdisp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dE_fromdisp" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dE_fromdisp" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_dE_fromdisp" "', argument " "3"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dE_fromdisp" "', argument " "3"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dE_fromdisp(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_disp2Lab(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDisplay arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_disp2Lab",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_disp2Lab" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_disp2Lab" "', argument " "2"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_disp2Lab" "', argument " "2"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->disp2Lab(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_disp2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDisplay arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_disp2XYZ",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_disp2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDisplay,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_disp2XYZ" "', argument " "2"" of type '" "vips::VDisplay""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_disp2XYZ" "', argument " "2"" of type '" "vips::VDisplay""'");
--    } else {
--      vips::VDisplay * temp = reinterpret_cast< vips::VDisplay * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->disp2XYZ(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_float2rad(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_float2rad",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_float2rad" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->float2rad();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_ac2rc(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_icc_ac2rc",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_ac2rc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_icc_ac2rc" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (arg1)->icc_ac2rc(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_export_depth(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  char *arg3 = (char *) 0 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_icc_export_depth",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_export_depth" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_icc_export_depth" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_icc_export_depth" "', argument " "3"" of type '" "char *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_icc_export_depth" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->icc_export_depth(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return resultobj;
--fail:
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_import(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_icc_import",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_import" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_icc_import" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_icc_import" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->icc_import(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_import_embedded(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_icc_import_embedded",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_import_embedded" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_icc_import_embedded" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->icc_import_embedded(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_transform(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  char *arg3 = (char *) 0 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_icc_transform",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_transform" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_icc_transform" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_icc_transform" "', argument " "3"" of type '" "char *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_icc_transform" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->icc_transform(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lab_morph(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_lab_morph",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lab_morph" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lab_morph" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lab_morph" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lab_morph" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_lab_morph" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_lab_morph" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_lab_morph" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  try {
--    result = (arg1)->lab_morph(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rad2float(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rad2float",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rad2float" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rad2float();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_sRGB2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_sRGB2XYZ",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_sRGB2XYZ" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->sRGB2XYZ();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gaussnoise(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_gaussnoise",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_gaussnoise" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_gaussnoise" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_gaussnoise" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_gaussnoise" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  try {
--    result = vips::VImage::gaussnoise(arg1,arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_bandjoin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_bandjoin",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_bandjoin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_bandjoin" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_bandjoin" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->bandjoin(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_black(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int arg3 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_black",&obj0,&obj1,&obj2)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_black" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_black" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_black" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = vips::VImage::black(arg1,arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_c2amph(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_c2amph",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_c2amph" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->c2amph();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_c2imag(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_c2imag",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_c2imag" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->c2imag();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_c2real(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_c2real",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_c2real" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->c2real();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_c2rect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_c2rect",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_c2rect" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->c2rect();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2fmt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_clip2fmt",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2fmt" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_clip2fmt" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->clip2fmt(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_copy",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_copy" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->copy();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_copy_file(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_copy_file",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_copy_file" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->copy_file();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_copy_morph(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_copy_morph",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_copy_morph" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_copy_morph" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_copy_morph" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_copy_morph" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->copy_morph(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_copy_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_copy_swap",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_copy_swap" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->copy_swap();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_copy_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  int arg5 ;
--  int arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_copy_set",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_copy_set" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_copy_set" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_copy_set" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_copy_set" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_copy_set" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_copy_set" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  try {
--    result = (arg1)->copy_set(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_extract_area(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_extract_area",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_extract_area" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_extract_area" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_extract_area" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_extract_area" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_extract_area" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = (arg1)->extract_area(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_extract_areabands(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_extract_areabands",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_extract_areabands" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_extract_areabands" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_extract_areabands" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_extract_areabands" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_extract_areabands" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_extract_areabands" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_extract_areabands" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  try {
--    result = (arg1)->extract_areabands(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_extract_band(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_extract_band",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_extract_band" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_extract_band" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->extract_band(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_extract_bands(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_extract_bands",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_extract_bands" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_extract_bands" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_extract_bands" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->extract_bands(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_extract(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_extract",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_extract" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_extract" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_extract" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_extract" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_extract" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_extract" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  try {
--    result = (arg1)->extract(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_falsecolour(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_falsecolour",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_falsecolour" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->falsecolour();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fliphor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_fliphor",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fliphor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->fliphor();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_flipver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_flipver",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_flipver" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->flipver();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gbandjoin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > arg1 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_gbandjoin",&obj0)) SWIG_fail;
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    int res = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_gbandjoin" "', argument " "1"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > >""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = vips::VImage::gbandjoin(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_grid(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_grid",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_grid" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_grid" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_grid" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_grid" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->grid(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_insert" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_insert" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_insert" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_insert" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_insert" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->insert(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  std::vector< int,std::allocator< int > > arg3 ;
--  std::vector< int,std::allocator< int > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_insert" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_insert" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_insert" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_insert" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg3 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_insert" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->insert(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insert(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 4) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            return _wrap_VImage_insert__SWIG_0(self, args);
--          }
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<int,std::allocator< int > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<int,std::allocator< int > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_VImage_insert__SWIG_1(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_insert'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::insert(vips::VImage,int,int)\n"
--    "    vips::VImage::insert(vips::VImage,std::vector< int,std::allocator< int > >,std::vector< int,std::allocator< int > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insert_noexpand(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_insert_noexpand",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_insert_noexpand" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_insert_noexpand" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_insert_noexpand" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_insert_noexpand" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_insert_noexpand" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->insert_noexpand(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_embed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_embed",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_embed" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_embed" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_embed" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_embed" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_embed" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_embed" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  try {
--    result = (arg1)->embed(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lrjoin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_lrjoin",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lrjoin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lrjoin" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lrjoin" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->lrjoin(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_msb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_msb",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_msb" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->msb();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_msb_band(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_msb_band",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_msb_band" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_msb_band" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->msb_band(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_replicate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_replicate",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_replicate" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_replicate" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_replicate" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->replicate(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_ri2c(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_ri2c",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_ri2c" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_ri2c" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_ri2c" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->ri2c(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rot180(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rot180",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rot180" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rot180();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rot270(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rot270",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rot270" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rot270();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rot90(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rot90",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rot90" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rot90();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_scale(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_scale",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_scale" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->scale();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_scaleps(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_scaleps",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_scaleps" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->scaleps();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_subsample(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_subsample",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_subsample" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_subsample" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_subsample" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->subsample(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_system(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_system",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_system" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_system" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (char *)(arg1)->system(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_system_image(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  char *arg3 = (char *) 0 ;
--  char *arg4 = (char *) 0 ;
--  char **arg5 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  int res4 ;
--  char *buf4 = 0 ;
--  int alloc4 = 0 ;
--  void *argp5 = 0 ;
--  int res5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_system_image",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_system_image" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_system_image" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_system_image" "', argument " "3"" of type '" "char *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
--  if (!SWIG_IsOK(res4)) {
--    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VImage_system_image" "', argument " "4"" of type '" "char *""'");
--  }
--  arg4 = reinterpret_cast< char * >(buf4);
--  res5 = SWIG_ConvertPtr(obj4, &argp5, SWIGTYPE_p_p_char,  0 );
--  if (!SWIG_IsOK(res5)) {
--    SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "VImage_system_image" "', argument " "5"" of type '" "char *&""'"); 
--  }
--  if (!argp5) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_system_image" "', argument " "5"" of type '" "char *&""'"); 
--  }
--  arg5 = reinterpret_cast< char ** >(argp5);
--  try {
--    result = (arg1)->system_image(arg2,arg3,arg4,*arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  if (alloc4 == SWIG_NEWOBJ) delete[] buf4;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tbjoin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_tbjoin",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tbjoin" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tbjoin" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tbjoin" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->tbjoin(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_text(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  char *arg2 = (char *) 0 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_text",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_text" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_text" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_text" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_text" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_text" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = vips::VImage::text(arg1,arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_wrap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_wrap",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_wrap" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_wrap" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_wrap" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->wrap(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_zoom(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_zoom",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_zoom" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_zoom" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_zoom" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->zoom(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_aconvsep(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_aconvsep",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_aconvsep" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_aconvsep" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_aconvsep" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_aconvsep" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->aconvsep(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_aconv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_aconv",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_aconv" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_aconv" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_aconv" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_aconv" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_aconv" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->aconv(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_addgnoise(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_addgnoise",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_addgnoise" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_addgnoise" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->addgnoise(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_compass(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_compass",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_compass" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_compass" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_compass" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->compass(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_contrast_surface(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_contrast_surface",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_contrast_surface" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_contrast_surface" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_contrast_surface" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->contrast_surface(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_conv__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_conv",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_conv" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_conv" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_conv" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->conv(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_conv__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_conv",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_conv" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_conv" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_conv" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->conv(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_conv(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VIMask, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_conv__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VDMask, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_conv__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_conv'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::conv(vips::VIMask)\n"
--    "    vips::VImage::conv(vips::VDMask)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsep__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convsep",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsep" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsep" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsep" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convsep(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsep__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convsep",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsep" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsep" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsep" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convsep(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsep(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VIMask, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_convsep__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VDMask, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_convsep__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_convsep'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::convsep(vips::VIMask)\n"
--    "    vips::VImage::convsep(vips::VDMask)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fastcor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_fastcor",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fastcor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_fastcor" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_fastcor" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->fastcor(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gradcor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_gradcor",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_gradcor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_gradcor" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_gradcor" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->gradcor(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gradient(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_gradient",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_gradient" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_gradient" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_gradient" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->gradient(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_grad_x(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_grad_x",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_grad_x" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->grad_x();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_grad_y(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_grad_y",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_grad_y" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->grad_y();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lindetect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_lindetect",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lindetect" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lindetect" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lindetect" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->lindetect(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_sharpen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_sharpen",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_sharpen" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_sharpen" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_sharpen" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_sharpen" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_sharpen" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_sharpen" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_sharpen" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  try {
--    result = (arg1)->sharpen(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_spcor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_spcor",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_spcor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_spcor" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_spcor" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->spcor(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_argb2rgba(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_argb2rgba",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_argb2rgba" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->argb2rgba();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_flood_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  std::vector< double,std::allocator< double > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_flood_copy",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_flood_copy" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_flood_copy" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_flood_copy" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_flood_copy" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->flood_copy(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_flood_blob_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  std::vector< double,std::allocator< double > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_flood_blob_copy",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_flood_blob_copy" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_flood_blob_copy" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_flood_blob_copy" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_flood_blob_copy" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->flood_blob_copy(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_flood_other_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_flood_other_copy",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_flood_other_copy" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_flood_other_copy" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_flood_other_copy" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_flood_other_copy" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_flood_other_copy" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_flood_other_copy" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = (arg1)->flood_other_copy(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_c2ps(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_c2ps",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_c2ps" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->c2ps();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_resize_linear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_resize_linear",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_resize_linear" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_resize_linear" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_resize_linear" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->resize_linear(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_cmulnorm(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_cmulnorm",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_cmulnorm" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_cmulnorm" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_cmulnorm" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->cmulnorm(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fav4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VImage arg3 ;
--  vips::VImage arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  void *argp4 ;
--  int res4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_fav4",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fav4" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_fav4" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_fav4" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_fav4" "', argument " "3"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_fav4" "', argument " "3"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  {
--    res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res4)) {
--      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VImage_fav4" "', argument " "4"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp4) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_fav4" "', argument " "4"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp4);
--      arg4 = *temp;
--      if (SWIG_IsNewObj(res4)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->fav4(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gadd(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  vips::VImage arg4 ;
--  double arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  void *argp4 ;
--  int res4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_gadd",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_gadd" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_gadd" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_gadd" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  {
--    res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res4)) {
--      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VImage_gadd" "', argument " "4"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp4) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_gadd" "', argument " "4"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp4);
--      arg4 = *temp;
--      if (SWIG_IsNewObj(res4)) delete temp;
--    }
--  }
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_gadd" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  try {
--    result = (arg1)->gadd(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_icc_export(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_icc_export",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_icc_export" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_icc_export" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_icc_export" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->icc_export(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_litecor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  double arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_litecor",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_litecor" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_litecor" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_litecor" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_litecor" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_litecor" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  try {
--    result = (arg1)->litecor(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_affine(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_affine",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_affine" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_affine" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_affine" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_affine" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_affine" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_affine" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_affine" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_affine" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_affine" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_affine" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_affine" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    result = (arg1)->affine(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2c(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2c",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2c" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2c();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2cm(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2cm",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2cm" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2cm();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2d(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2d",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2d" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2d();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2dcm(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2dcm",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2dcm" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2dcm();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2f(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2f",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2f" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2f();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2i(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2i",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2i" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2i();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsub(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_convsub",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsub" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsub" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsub" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_convsub" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_convsub" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->convsub(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convf(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convf",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convf" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convf" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convf" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convf(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsepf(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convsepf",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsepf" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsepf" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsepf" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convsepf(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2s(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2s",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2s" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2s();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2ui(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2ui",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2ui" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2ui();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insertplace__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  std::vector< int,std::allocator< int > > arg3 ;
--  std::vector< int,std::allocator< int > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_insertplace",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_insertplace" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_insertplace" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_insertplace" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj2, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_insertplace" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg3 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_insertplace" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->insertplace(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_clip2us(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_clip2us",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_clip2us" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->clip2us();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_slice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_slice",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_slice" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_slice" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_slice" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = (arg1)->slice(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_segment(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int temp2 ;
--  int res2 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  arg2 = &temp2;
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_segment",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_segment" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->segment(*arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (SWIG_IsTmpObj(res2)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg2)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res2) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg2), SWIGTYPE_p_int, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_line__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_line",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_line" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_line" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_line" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_line" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_line" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_line" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  try {
--    (arg1)->line(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_thresh(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_thresh",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_thresh" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_thresh" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->thresh(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convf_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convf_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convf_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convf_raw" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convf_raw" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convf_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_conv_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_conv_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_conv_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_conv_raw" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_conv_raw" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->conv_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_contrast_surface_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_contrast_surface_raw",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_contrast_surface_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_contrast_surface_raw" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_contrast_surface_raw" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->contrast_surface_raw(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsepf_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convsepf_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsepf_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsepf_raw" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsepf_raw" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convsepf_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_convsep_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_convsep_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_convsep_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_convsep_raw" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_convsep_raw" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->convsep_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fastcor_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_fastcor_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fastcor_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_fastcor_raw" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_fastcor_raw" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->fastcor_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gradcor_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_gradcor_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_gradcor_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_gradcor_raw" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_gradcor_raw" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->gradcor_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_spcor_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_spcor_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_spcor_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_spcor_raw" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_spcor_raw" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->spcor_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lhisteq_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_lhisteq_raw",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lhisteq_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_lhisteq_raw" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lhisteq_raw" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->lhisteq_raw(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_stdif_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  int arg6 ;
--  int arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_stdif_raw",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_stdif_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_stdif_raw" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_stdif_raw" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_stdif_raw" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_stdif_raw" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_stdif_raw" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_stdif_raw" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  try {
--    result = (arg1)->stdif_raw(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rank_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_rank_raw",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rank_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_rank_raw" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_rank_raw" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_rank_raw" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->rank_raw(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dilate_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dilate_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dilate_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dilate_raw" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dilate_raw" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dilate_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_erode_raw(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_erode_raw",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_erode_raw" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_erode_raw" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_erode_raw" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->erode_raw(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_similarity_area(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:VImage_similarity_area",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_similarity_area" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_similarity_area" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_similarity_area" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_similarity_area" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_similarity_area" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_similarity_area" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_similarity_area" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_similarity_area" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_similarity_area" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  try {
--    result = (arg1)->similarity_area(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_similarity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_similarity",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_similarity" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_similarity" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_similarity" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_similarity" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_similarity" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  try {
--    result = (arg1)->similarity(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_mask2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask arg1 ;
--  void *argp1 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_mask2vips",&obj0)) SWIG_fail;
--  {
--    res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_mask2vips" "', argument " "1"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp1) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_mask2vips" "', argument " "1"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp1);
--      arg1 = *temp;
--      if (SWIG_IsNewObj(res1)) delete temp;
--    }
--  }
--  try {
--    result = vips::VImage::mask2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2mask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_vips2mask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2mask" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->vips2mask();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insertplace__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_insertplace",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_insertplace" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_insertplace" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_insertplace" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_insertplace" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_insertplace" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    (arg1)->insertplace(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_insertplace(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[5];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 4) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            return _wrap_VImage_insertplace__SWIG_1(self, args);
--          }
--        }
--      }
--    }
--  }
--  if (argc == 4) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        int res = swig::asptr(argv[2], (std::vector<int,std::allocator< int > >**)(0));
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<int,std::allocator< int > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            return _wrap_VImage_insertplace__SWIG_0(self, args);
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_insertplace'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::insertplace(vips::VImage,std::vector< int,std::allocator< int > >,std::vector< int,std::allocator< int > >)\n"
--    "    vips::VImage::insertplace(vips::VImage,int,int)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_circle(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_circle",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_circle" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_circle" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_circle" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_circle" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_circle" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    (arg1)->circle(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_andimage__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_andimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_andimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_andimage" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_andimage" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->andimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_andimage__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_andimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_andimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_andimage" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->andimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_andimage__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_andimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_andimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_andimage" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->andimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_andimage(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_andimage__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_andimage__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_andimage__SWIG_2(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_andimage'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::andimage(vips::VImage)\n"
--    "    vips::VImage::andimage(int)\n"
--    "    vips::VImage::andimage(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_orimage__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_orimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_orimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_orimage" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_orimage" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->orimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_orimage__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_orimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_orimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_orimage" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->orimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_orimage__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_orimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_orimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_orimage" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->orimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_orimage(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_orimage__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_orimage__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_orimage__SWIG_2(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_orimage'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::orimage(vips::VImage)\n"
--    "    vips::VImage::orimage(int)\n"
--    "    vips::VImage::orimage(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_eorimage__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_eorimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_eorimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_eorimage" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_eorimage" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->eorimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_eorimage__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_eorimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_eorimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_eorimage" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->eorimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_eorimage__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_eorimage",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_eorimage" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_eorimage" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->eorimage(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_eorimage(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_eorimage__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_eorimage__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_eorimage__SWIG_2(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_eorimage'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::eorimage(vips::VImage)\n"
--    "    vips::VImage::eorimage(int)\n"
--    "    vips::VImage::eorimage(std::vector< double,std::allocator< double > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftleft__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_shiftleft",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_shiftleft" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_shiftleft" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->shiftleft(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftleft__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_shiftleft",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_shiftleft" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_shiftleft" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->shiftleft(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftleft(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_shiftleft__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_shiftleft__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_shiftleft'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::shiftleft(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::shiftleft(int)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftright__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_shiftright",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_shiftright" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_shiftright" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->shiftright(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftright__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_shiftright",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_shiftright" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_shiftright" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->shiftright(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shiftright(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_shiftright__SWIG_1(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_shiftright__SWIG_0(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_shiftright'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::shiftright(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::shiftright(int)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_blend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VImage arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_blend",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_blend" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_blend" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_blend" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_blend" "', argument " "3"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_blend" "', argument " "3"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->blend(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_equal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_equal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_equal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_equal" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_equal" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->equal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_equal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_equal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_equal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_equal" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->equal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_equal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_equal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_equal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_equal" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->equal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_equal(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_equal__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_equal__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_equal__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_equal'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::equal(vips::VImage)\n"
--    "    vips::VImage::equal(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::equal(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_ifthenelse(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VImage arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_ifthenelse",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_ifthenelse" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_ifthenelse" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_ifthenelse" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_ifthenelse" "', argument " "3"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_ifthenelse" "', argument " "3"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->ifthenelse(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_less__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_less",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_less" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_less" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_less" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->less(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_less__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_less",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_less" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_less" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->less(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_less__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_less",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_less" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_less" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->less(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_less(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_less__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_less__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_less__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_less'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::less(vips::VImage)\n"
--    "    vips::VImage::less(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::less(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lesseq__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_lesseq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lesseq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lesseq" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lesseq" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->lesseq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lesseq__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_lesseq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lesseq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_lesseq" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->lesseq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lesseq__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_lesseq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lesseq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_lesseq" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->lesseq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lesseq(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_lesseq__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_lesseq__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_lesseq__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_lesseq'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::lesseq(vips::VImage)\n"
--    "    vips::VImage::lesseq(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::lesseq(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_more__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_more",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_more" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_more" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_more" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->more(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_more__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_more",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_more" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_more" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->more(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_more__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_more",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_more" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_more" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->more(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_more(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_more__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_more__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_more__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_more'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::more(vips::VImage)\n"
--    "    vips::VImage::more(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::more(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_moreeq__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_moreeq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_moreeq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_moreeq" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_moreeq" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->moreeq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_moreeq__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_moreeq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_moreeq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_moreeq" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->moreeq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_moreeq__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_moreeq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_moreeq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_moreeq" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->moreeq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_moreeq(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_moreeq__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_moreeq__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_moreeq__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_moreeq'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::moreeq(vips::VImage)\n"
--    "    vips::VImage::moreeq(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::moreeq(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_notequal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_notequal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_notequal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_notequal" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_notequal" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->notequal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_notequal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  std::vector< double,std::allocator< double > > arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_notequal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_notequal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj1, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_notequal" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg2 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->notequal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_notequal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_notequal",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_notequal" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_notequal" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->notequal(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_notequal(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_notequal__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_double(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_VImage_notequal__SWIG_2(self, args);
--      }
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap_VImage_notequal__SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_notequal'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::notequal(vips::VImage)\n"
--    "    vips::VImage::notequal(std::vector< double,std::allocator< double > >)\n"
--    "    vips::VImage::notequal(double)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_quadratic(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_quadratic",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_quadratic" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_quadratic" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_quadratic" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->quadratic(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_csv2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_csv2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_csv2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::csv2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fits2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_fits2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fits2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::fits2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_jpeg2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_jpeg2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_jpeg2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::jpeg2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_magick2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_magick2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_magick2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::magick2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_png2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_png2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_png2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::png2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_exr2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_exr2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_exr2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::exr2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_ppm2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_ppm2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_ppm2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::ppm2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_analyze2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_analyze2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_analyze2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::analyze2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tiff2vips(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_tiff2vips",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tiff2vips" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  try {
--    result = vips::VImage::tiff2vips(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2csv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2csv",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2csv" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2csv" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2csv(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2dz(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2dz",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2dz" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2dz" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2dz(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2jpeg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2jpeg",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2jpeg" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2jpeg" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2jpeg(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2mimejpeg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2mimejpeg",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2mimejpeg" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_vips2mimejpeg" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    (arg1)->vips2mimejpeg(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2png(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2png",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2png" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2png" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2png(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2ppm(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2ppm",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2ppm" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2ppm" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2ppm(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_vips2tiff(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_vips2tiff",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_vips2tiff" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_vips2tiff" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    (arg1)->vips2tiff(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_create_fmask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOO:VImage_create_fmask",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_create_fmask" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_create_fmask" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_create_fmask" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_create_fmask" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_create_fmask" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_create_fmask" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_create_fmask" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_create_fmask" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  try {
--    result = vips::VImage::create_fmask(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_disp_ps(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_disp_ps",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_disp_ps" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->disp_ps();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_flt_image_freq(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_flt_image_freq",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_flt_image_freq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_flt_image_freq" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_flt_image_freq" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_flt_image_freq" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_flt_image_freq" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_flt_image_freq" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_flt_image_freq" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  try {
--    result = (arg1)->flt_image_freq(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fractsurf(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  double arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_fractsurf",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_fractsurf" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_fractsurf" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VImage::fractsurf(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_freqflt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_freqflt",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_freqflt" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_freqflt" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_freqflt" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->freqflt(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fwfft(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_fwfft",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_fwfft" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->fwfft();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rotquad(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_rotquad",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rotquad" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->rotquad();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_invfft(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_invfft",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_invfft" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->invfft();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_phasecor_fft(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_phasecor_fft",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_phasecor_fft" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_phasecor_fft" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_phasecor_fft" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->phasecor_fft(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_invfftr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_invfftr",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_invfftr" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->invfftr();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_gammacorrect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_gammacorrect",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_gammacorrect" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_gammacorrect" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->gammacorrect(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_heq(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_heq",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_heq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_heq" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->heq(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_hist(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_hist",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_hist" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_hist" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->hist(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histcum(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_histcum",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histcum" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->histcum();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histeq(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_histeq",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histeq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->histeq();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_hist_indexed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_hist_indexed",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_hist_indexed" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_hist_indexed" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_hist_indexed" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->hist_indexed(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histgr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_histgr",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histgr" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_histgr" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->histgr(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histnD(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_histnD",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histnD" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_histnD" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->histnD(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histnorm(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_histnorm",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histnorm" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->histnorm();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histplot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_histplot",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histplot" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->histplot();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_histspec(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_histspec",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_histspec" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_histspec" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_histspec" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->histspec(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_hsp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_hsp",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_hsp" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_hsp" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_hsp" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->hsp(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_identity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_identity",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_identity" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  try {
--    result = vips::VImage::identity(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_identity_ushort(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_identity_ushort",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_identity_ushort" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_identity_ushort" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::identity_ushort(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_ismonotonic(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_ismonotonic",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_ismonotonic" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (int)(arg1)->ismonotonic();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lhisteq(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_lhisteq",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lhisteq" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_lhisteq" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lhisteq" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (arg1)->lhisteq(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_mpercent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_mpercent",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_mpercent" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_mpercent" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (int)(arg1)->mpercent(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_invertlut(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask arg1 ;
--  int arg2 ;
--  void *argp1 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_invertlut",&obj0,&obj1)) SWIG_fail;
--  {
--    res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_invertlut" "', argument " "1"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp1) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_invertlut" "', argument " "1"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp1);
--      arg1 = *temp;
--      if (SWIG_IsNewObj(res1)) delete temp;
--    }
--  }
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_invertlut" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::invertlut(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_buildlut(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask arg1 ;
--  void *argp1 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_buildlut",&obj0)) SWIG_fail;
--  {
--    res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res1)) {
--      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_buildlut" "', argument " "1"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp1) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_buildlut" "', argument " "1"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp1);
--      arg1 = *temp;
--      if (SWIG_IsNewObj(res1)) delete temp;
--    }
--  }
--  try {
--    result = vips::VImage::buildlut(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_maplut(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_maplut",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_maplut" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_maplut" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_maplut" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->maplut(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_project(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_project",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_project" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_project" "', argument " "2"" of type '" "vips::VImage &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_project" "', argument " "2"" of type '" "vips::VImage &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VImage * >(argp2);
--  try {
--    result = (arg1)->project(*arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_stdif(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  int arg6 ;
--  int arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_stdif",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_stdif" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_stdif" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_stdif" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_stdif" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_stdif" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_stdif" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_stdif" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  try {
--    result = (arg1)->stdif(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tone_analyse(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_tone_analyse",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tone_analyse" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_tone_analyse" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tone_analyse" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tone_analyse" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tone_analyse" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tone_analyse" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tone_analyse" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  try {
--    result = (arg1)->tone_analyse(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tone_build(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOO:VImage_tone_build",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_tone_build" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_tone_build" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tone_build" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tone_build" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tone_build" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tone_build" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tone_build" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_tone_build" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  try {
--    result = vips::VImage::tone_build(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tone_build_range(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  double arg9 ;
--  double arg10 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  double val9 ;
--  int ecode9 = 0 ;
--  double val10 ;
--  int ecode10 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:VImage_tone_build_range",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_tone_build_range" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_tone_build_range" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tone_build_range" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tone_build_range" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tone_build_range" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tone_build_range" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tone_build_range" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_tone_build_range" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  ecode9 = SWIG_AsVal_double(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_tone_build_range" "', argument " "9"" of type '" "double""'");
--  } 
--  arg9 = static_cast< double >(val9);
--  ecode10 = SWIG_AsVal_double(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_tone_build_range" "', argument " "10"" of type '" "double""'");
--  } 
--  arg10 = static_cast< double >(val10);
--  try {
--    result = vips::VImage::tone_build_range(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tone_map(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_tone_map",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tone_map" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tone_map" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tone_map" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->tone_map(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_circle(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  std::vector< double,std::allocator< double > > arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_draw_circle",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_circle" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_circle" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_circle" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_circle" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_draw_circle" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj5, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_circle" "', argument " "6"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg6 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_circle(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_rect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  std::vector< double,std::allocator< double > > arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_draw_rect",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_rect" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_rect" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_rect" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_rect" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_draw_rect" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_draw_rect" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj6, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_rect" "', argument " "7"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg7 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_rect(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_line(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  std::vector< double,std::allocator< double > > arg6 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:VImage_draw_line",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_line" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_line" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_line" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_line" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_draw_line" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj5, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_line" "', argument " "6"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg6 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_line(arg2,arg3,arg4,arg5,arg6);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_point(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  std::vector< double,std::allocator< double > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_draw_point",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_point" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_point" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_point" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_point" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_point(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_smudge(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_draw_smudge",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_smudge" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_smudge" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_smudge" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_smudge" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_draw_smudge" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    (arg1)->draw_smudge(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_flood(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  std::vector< double,std::allocator< double > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_draw_flood",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_flood" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_flood" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_flood" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_flood" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_flood(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_flood_blob(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  std::vector< double,std::allocator< double > > arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_draw_flood_blob",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_flood_blob" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_draw_flood_blob" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_flood_blob" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_flood_blob" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_flood_blob(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_flood_other(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_draw_flood_other",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_flood_other" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_draw_flood_other" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_draw_flood_other" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_flood_other" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_flood_other" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_draw_flood_other" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    (arg1)->draw_flood_other(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_image(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_draw_image",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_image" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_draw_image" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_draw_image" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_image" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_image" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    (arg1)->draw_image(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_draw_mask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  std::vector< double,std::allocator< double > > arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_draw_mask",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_draw_mask" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_draw_mask" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_draw_mask" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_draw_mask" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_draw_mask" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj4, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_draw_mask" "', argument " "5"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg5 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    (arg1)->draw_mask(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_line__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  vips::VImage arg3 ;
--  std::vector< int,std::allocator< int > > arg4 ;
--  std::vector< int,std::allocator< int > > arg5 ;
--  std::vector< int,std::allocator< int > > arg6 ;
--  std::vector< int,std::allocator< int > > arg7 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  void *argp3 ;
--  int res3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_line",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_line" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_line" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_line" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  {
--    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res3)) {
--      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_line" "', argument " "3"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp3) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_line" "', argument " "3"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp3);
--      arg3 = *temp;
--      if (SWIG_IsNewObj(res3)) delete temp;
--    }
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj3, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_line" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg4 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj4, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_line" "', argument " "5"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg5 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj5, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_line" "', argument " "6"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg6 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj6, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_line" "', argument " "7"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg7 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = (arg1)->line(arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_line(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[8];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 7) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 6) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            {
--              int res = SWIG_AsVal_int(argv[4], NULL);
--              _v = SWIG_CheckState(res);
--            }
--            if (_v) {
--              {
--                int res = SWIG_AsVal_int(argv[5], NULL);
--                _v = SWIG_CheckState(res);
--              }
--              if (_v) {
--                return _wrap_VImage_line__SWIG_0(self, args);
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  if (argc == 7) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_vips__VImage, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VImage, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_vips__VImage, 0);
--        _v = SWIG_CheckState(res);
--        if (_v) {
--          int res = swig::asptr(argv[3], (std::vector<int,std::allocator< int > >**)(0));
--          _v = SWIG_CheckState(res);
--          if (_v) {
--            int res = swig::asptr(argv[4], (std::vector<int,std::allocator< int > >**)(0));
--            _v = SWIG_CheckState(res);
--            if (_v) {
--              int res = swig::asptr(argv[5], (std::vector<int,std::allocator< int > >**)(0));
--              _v = SWIG_CheckState(res);
--              if (_v) {
--                int res = swig::asptr(argv[6], (std::vector<int,std::allocator< int > >**)(0));
--                _v = SWIG_CheckState(res);
--                if (_v) {
--                  return _wrap_VImage_line__SWIG_1(self, args);
--                }
--              }
--            }
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VImage_line'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VImage::line(int,int,int,int,int)\n"
--    "    vips::VImage::line(vips::VImage,vips::VImage,std::vector< int,std::allocator< int > >,std::vector< int,std::allocator< int > >,std::vector< int,std::allocator< int > >,std::vector< int,std::allocator< int > >)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_binfile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_binfile",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_binfile" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_binfile" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_binfile" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_binfile" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_binfile" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = vips::VImage::binfile(arg1,arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_cache(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_cache",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_cache" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_cache" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_cache" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_cache" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->cache(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_getext(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_getext",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_getext" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (char *)(arg1)->getext();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_header_get_typeof(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_header_get_typeof",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_header_get_typeof" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_header_get_typeof" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (int)(arg1)->header_get_typeof(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_header_int(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_header_int",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_header_int" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_header_int" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (int)(arg1)->header_int(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_header_double(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_header_double",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_header_double" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_header_double" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (double)(arg1)->header_double(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_header_string(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_header_string",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_header_string" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_header_string" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  try {
--    result = (char *)(arg1)->header_string(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_history_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_history_get",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_history_get" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (char *)(arg1)->history_get();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_printdesc(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_printdesc",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_printdesc" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    (arg1)->printdesc();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_cntlines(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_cntlines",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_cntlines" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_cntlines" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (double)(arg1)->cntlines(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_dilate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_dilate",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_dilate" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_dilate" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_dilate" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->dilate(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rank(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_rank",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rank" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_rank" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_rank" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_rank" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->rank(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rank_image(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > arg1 ;
--  int arg2 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_rank_image",&obj0,&obj1)) SWIG_fail;
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    int res = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_rank_image" "', argument " "1"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > >""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_rank_image" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::rank_image(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_maxvalue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::vector< vips::VImage,std::allocator< vips::VImage > > arg1 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_maxvalue",&obj0)) SWIG_fail;
--  {
--    std::vector<vips::VImage,std::allocator< vips::VImage > > *ptr = (std::vector<vips::VImage,std::allocator< vips::VImage > > *)0;
--    int res = swig::asptr(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_maxvalue" "', argument " "1"" of type '" "std::vector< vips::VImage,std::allocator< vips::VImage > >""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  try {
--    result = vips::VImage::maxvalue(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_label_regions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int temp2 ;
--  int res2 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  arg2 = &temp2;
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_label_regions",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_label_regions" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->label_regions(*arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (SWIG_IsTmpObj(res2)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg2)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res2) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg2), SWIGTYPE_p_int, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_zerox(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_zerox",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_zerox" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_zerox" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->zerox(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_erode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VIMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_erode",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_erode" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VIMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_erode" "', argument " "2"" of type '" "vips::VIMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_erode" "', argument " "2"" of type '" "vips::VIMask""'");
--    } else {
--      vips::VIMask * temp = reinterpret_cast< vips::VIMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->erode(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_profile(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_profile",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_profile" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_profile" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->profile(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_align_bands(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_align_bands",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_align_bands" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->align_bands();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_correl(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int *arg9 = 0 ;
--  int *arg10 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int temp9 ;
--  int res9 = SWIG_TMPOBJ ;
--  int temp10 ;
--  int res10 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  double result;
--  
--  arg9 = &temp9;
--  arg10 = &temp10;
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOO:VImage_correl",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_correl" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_correl" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_correl" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_correl" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_correl" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_correl" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_correl" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_correl" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_correl" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  try {
--    result = (double)(arg1)->correl(arg2,arg3,arg4,arg5,arg6,arg7,arg8,*arg9,*arg10);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (SWIG_IsTmpObj(res9)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg9)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res9) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg9), SWIGTYPE_p_int, new_flags));
--  }
--  if (SWIG_IsTmpObj(res10)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg10)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res10) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg10), SWIGTYPE_p_int, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage__find_lroverlap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int *arg10 = 0 ;
--  double *arg11 = 0 ;
--  double *arg12 = 0 ;
--  double *arg13 = 0 ;
--  double *arg14 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int temp10 ;
--  int res10 = SWIG_TMPOBJ ;
--  double temp11 ;
--  int res11 = SWIG_TMPOBJ ;
--  double temp12 ;
--  int res12 = SWIG_TMPOBJ ;
--  double temp13 ;
--  int res13 = SWIG_TMPOBJ ;
--  double temp14 ;
--  int res14 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  int result;
--  
--  arg10 = &temp10;
--  arg11 = &temp11;
--  arg12 = &temp12;
--  arg13 = &temp13;
--  arg14 = &temp14;
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:VImage__find_lroverlap",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage__find_lroverlap" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage__find_lroverlap" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage__find_lroverlap" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage__find_lroverlap" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage__find_lroverlap" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage__find_lroverlap" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage__find_lroverlap" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage__find_lroverlap" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage__find_lroverlap" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage__find_lroverlap" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  try {
--    result = (int)(arg1)->_find_lroverlap(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,*arg10,*arg11,*arg12,*arg13,*arg14);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (SWIG_IsTmpObj(res10)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg10)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res10) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg10), SWIGTYPE_p_int, new_flags));
--  }
--  if (SWIG_IsTmpObj(res11)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg11)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res11) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg11), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res12)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg12)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res12) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg12), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res13)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg13)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res13) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg13), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res14)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg14)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res14) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg14), SWIGTYPE_p_double, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage__find_tboverlap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int *arg10 = 0 ;
--  double *arg11 = 0 ;
--  double *arg12 = 0 ;
--  double *arg13 = 0 ;
--  double *arg14 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int temp10 ;
--  int res10 = SWIG_TMPOBJ ;
--  double temp11 ;
--  int res11 = SWIG_TMPOBJ ;
--  double temp12 ;
--  int res12 = SWIG_TMPOBJ ;
--  double temp13 ;
--  int res13 = SWIG_TMPOBJ ;
--  double temp14 ;
--  int res14 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  int result;
--  
--  arg10 = &temp10;
--  arg11 = &temp11;
--  arg12 = &temp12;
--  arg13 = &temp13;
--  arg14 = &temp14;
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:VImage__find_tboverlap",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage__find_tboverlap" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage__find_tboverlap" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage__find_tboverlap" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage__find_tboverlap" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage__find_tboverlap" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage__find_tboverlap" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage__find_tboverlap" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage__find_tboverlap" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage__find_tboverlap" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage__find_tboverlap" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  try {
--    result = (int)(arg1)->_find_tboverlap(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,*arg10,*arg11,*arg12,*arg13,*arg14);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (SWIG_IsTmpObj(res10)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_int((*arg10)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res10) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg10), SWIGTYPE_p_int, new_flags));
--  }
--  if (SWIG_IsTmpObj(res11)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg11)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res11) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg11), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res12)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg12)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res12) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg12), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res13)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg13)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res13) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg13), SWIGTYPE_p_double, new_flags));
--  }
--  if (SWIG_IsTmpObj(res14)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg14)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res14) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg14), SWIGTYPE_p_double, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_global_balance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_global_balance",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_global_balance" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_global_balance" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->global_balance(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_global_balancef(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_global_balancef",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_global_balancef" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_global_balancef" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = (arg1)->global_balancef(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lrmerge(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_lrmerge",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lrmerge" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lrmerge" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lrmerge" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lrmerge" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_lrmerge" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_lrmerge" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = (arg1)->lrmerge(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lrmerge1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_lrmerge1",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lrmerge1" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lrmerge1" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lrmerge1" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lrmerge1" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_lrmerge1" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_lrmerge1" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_lrmerge1" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_lrmerge1" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_lrmerge1" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_lrmerge1" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_lrmerge1" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_lrmerge1" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    result = (arg1)->lrmerge1(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lrmosaic(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_lrmosaic",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lrmosaic" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lrmosaic" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lrmosaic" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lrmosaic" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_lrmosaic" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_lrmosaic" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_lrmosaic" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_lrmosaic" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_lrmosaic" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_lrmosaic" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_lrmosaic" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_lrmosaic" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    result = (arg1)->lrmosaic(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_lrmosaic1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  int arg12 ;
--  int arg13 ;
--  int arg14 ;
--  int arg15 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  int val13 ;
--  int ecode13 = 0 ;
--  int val14 ;
--  int ecode14 = 0 ;
--  int val15 ;
--  int ecode15 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  PyObject * obj12 = 0 ;
--  PyObject * obj13 = 0 ;
--  PyObject * obj14 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOOOOO:VImage_lrmosaic1",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11,&obj12,&obj13,&obj14)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_lrmosaic1" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_lrmosaic1" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_lrmosaic1" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_lrmosaic1" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_lrmosaic1" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_lrmosaic1" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_lrmosaic1" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_lrmosaic1" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_lrmosaic1" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_lrmosaic1" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_lrmosaic1" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_lrmosaic1" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_lrmosaic1" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  ecode13 = SWIG_AsVal_int(obj12, &val13);
--  if (!SWIG_IsOK(ecode13)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode13), "in method '" "VImage_lrmosaic1" "', argument " "13"" of type '" "int""'");
--  } 
--  arg13 = static_cast< int >(val13);
--  ecode14 = SWIG_AsVal_int(obj13, &val14);
--  if (!SWIG_IsOK(ecode14)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode14), "in method '" "VImage_lrmosaic1" "', argument " "14"" of type '" "int""'");
--  } 
--  arg14 = static_cast< int >(val14);
--  ecode15 = SWIG_AsVal_int(obj14, &val15);
--  if (!SWIG_IsOK(ecode15)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode15), "in method '" "VImage_lrmosaic1" "', argument " "15"" of type '" "int""'");
--  } 
--  arg15 = static_cast< int >(val15);
--  try {
--    result = (arg1)->lrmosaic1(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_match_linear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:VImage_match_linear",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_match_linear" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_match_linear" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_match_linear" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_match_linear" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_match_linear" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_match_linear" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_match_linear" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_match_linear" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_match_linear" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_match_linear" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_match_linear" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  try {
--    result = (arg1)->match_linear(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_match_linear_search(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  int arg12 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOO:VImage_match_linear_search",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_match_linear_search" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_match_linear_search" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_match_linear_search" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_match_linear_search" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_match_linear_search" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_match_linear_search" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_match_linear_search" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_match_linear_search" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_match_linear_search" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_match_linear_search" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_match_linear_search" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_match_linear_search" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_match_linear_search" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  try {
--    result = (arg1)->match_linear_search(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_maxpos_subpel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double temp2 ;
--  int res2 = SWIG_TMPOBJ ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  arg2 = &temp2;
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_maxpos_subpel",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_maxpos_subpel" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->maxpos_subpel(*arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  if (SWIG_IsTmpObj(res2)) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_From_double((*arg2)));
--  } else {
--    int new_flags = SWIG_IsNewObj(res2) ? (SWIG_POINTER_OWN |  0 ) :  0 ;
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_NewPointerObj((void*)(arg2), SWIGTYPE_p_double, new_flags));
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_remosaic(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  char *arg3 = (char *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  int res3 ;
--  char *buf3 = 0 ;
--  int alloc3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_remosaic",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_remosaic" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_remosaic" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
--  if (!SWIG_IsOK(res3)) {
--    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VImage_remosaic" "', argument " "3"" of type '" "char *""'");
--  }
--  arg3 = reinterpret_cast< char * >(buf3);
--  try {
--    result = (arg1)->remosaic(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tbmerge(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_tbmerge",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tbmerge" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tbmerge" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tbmerge" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tbmerge" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tbmerge" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tbmerge" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  try {
--    result = (arg1)->tbmerge(arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tbmerge1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_tbmerge1",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tbmerge1" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tbmerge1" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tbmerge1" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tbmerge1" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tbmerge1" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tbmerge1" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tbmerge1" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tbmerge1" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_tbmerge1" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_tbmerge1" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_tbmerge1" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_tbmerge1" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    result = (arg1)->tbmerge1(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tbmosaic(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:VImage_tbmosaic",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tbmosaic" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tbmosaic" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tbmosaic" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tbmosaic" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tbmosaic" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tbmosaic" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tbmosaic" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tbmosaic" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_tbmosaic" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_tbmosaic" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_tbmosaic" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_tbmosaic" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  try {
--    result = (arg1)->tbmosaic(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tbmosaic1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  vips::VImage arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  int arg12 ;
--  int arg13 ;
--  int arg14 ;
--  int arg15 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  int val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  int val13 ;
--  int ecode13 = 0 ;
--  int val14 ;
--  int ecode14 = 0 ;
--  int val15 ;
--  int ecode15 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  PyObject * obj12 = 0 ;
--  PyObject * obj13 = 0 ;
--  PyObject * obj14 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOOOOO:VImage_tbmosaic1",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11,&obj12,&obj13,&obj14)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tbmosaic1" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VImage,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_tbmosaic1" "', argument " "2"" of type '" "vips::VImage""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VImage_tbmosaic1" "', argument " "2"" of type '" "vips::VImage""'");
--    } else {
--      vips::VImage * temp = reinterpret_cast< vips::VImage * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_tbmosaic1" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_tbmosaic1" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_tbmosaic1" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_tbmosaic1" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_tbmosaic1" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  ecode8 = SWIG_AsVal_int(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_tbmosaic1" "', argument " "8"" of type '" "int""'");
--  } 
--  arg8 = static_cast< int >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_tbmosaic1" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_tbmosaic1" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_tbmosaic1" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_tbmosaic1" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  ecode13 = SWIG_AsVal_int(obj12, &val13);
--  if (!SWIG_IsOK(ecode13)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode13), "in method '" "VImage_tbmosaic1" "', argument " "13"" of type '" "int""'");
--  } 
--  arg13 = static_cast< int >(val13);
--  ecode14 = SWIG_AsVal_int(obj13, &val14);
--  if (!SWIG_IsOK(ecode14)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode14), "in method '" "VImage_tbmosaic1" "', argument " "14"" of type '" "int""'");
--  } 
--  arg14 = static_cast< int >(val14);
--  ecode15 = SWIG_AsVal_int(obj14, &val15);
--  if (!SWIG_IsOK(ecode15)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode15), "in method '" "VImage_tbmosaic1" "', argument " "15"" of type '" "int""'");
--  } 
--  arg15 = static_cast< int >(val15);
--  try {
--    result = (arg1)->tbmosaic1(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_benchmark(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_benchmark",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_benchmark" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (arg1)->benchmark();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_benchmark2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_benchmark2",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_benchmark2" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = (double)(arg1)->benchmark2();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_benchmarkn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_benchmarkn",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_benchmarkn" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_benchmarkn" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (arg1)->benchmarkn(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_eye(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_eye",&obj0,&obj1,&obj2)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_eye" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_eye" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_eye" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = vips::VImage::eye(arg1,arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_grey(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_grey",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_grey" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_grey" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::grey(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_feye(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_feye",&obj0,&obj1,&obj2)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_feye" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_feye" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_feye" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = vips::VImage::feye(arg1,arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fgrey(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_fgrey",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_fgrey" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_fgrey" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::fgrey(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fzone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_fzone",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_fzone" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  try {
--    result = vips::VImage::fzone(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_make_xy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_make_xy",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_make_xy" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_make_xy" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::make_xy(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_sines(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_sines",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_sines" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_sines" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_sines" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_sines" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  try {
--    result = vips::VImage::sines(arg1,arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_zone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_zone",&obj0)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_zone" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  try {
--    result = vips::VImage::zone(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_rightshift_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOO:VImage_rightshift_size",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_rightshift_size" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_rightshift_size" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_rightshift_size" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_rightshift_size" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  try {
--    result = (arg1)->rightshift_size(arg2,arg3,arg4);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_shrink(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_shrink",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_shrink" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_shrink" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_shrink" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = (arg1)->shrink(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_stretch3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  double arg2 ;
--  double arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VImage_stretch3",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_stretch3" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_stretch3" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_stretch3" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  try {
--    result = (arg1)->stretch3(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_affinei(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  int arg9 ;
--  int arg10 ;
--  int arg11 ;
--  int arg12 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  int val9 ;
--  int ecode9 = 0 ;
--  int val10 ;
--  int ecode10 = 0 ;
--  int val11 ;
--  int ecode11 = 0 ;
--  int val12 ;
--  int ecode12 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  PyObject * obj8 = 0 ;
--  PyObject * obj9 = 0 ;
--  PyObject * obj10 = 0 ;
--  PyObject * obj11 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOOO:VImage_affinei",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10,&obj11)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_affinei" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_affinei" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_affinei" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_affinei" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_affinei" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_affinei" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_affinei" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_affinei" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  ecode9 = SWIG_AsVal_int(obj8, &val9);
--  if (!SWIG_IsOK(ecode9)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "VImage_affinei" "', argument " "9"" of type '" "int""'");
--  } 
--  arg9 = static_cast< int >(val9);
--  ecode10 = SWIG_AsVal_int(obj9, &val10);
--  if (!SWIG_IsOK(ecode10)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "VImage_affinei" "', argument " "10"" of type '" "int""'");
--  } 
--  arg10 = static_cast< int >(val10);
--  ecode11 = SWIG_AsVal_int(obj10, &val11);
--  if (!SWIG_IsOK(ecode11)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "VImage_affinei" "', argument " "11"" of type '" "int""'");
--  } 
--  arg11 = static_cast< int >(val11);
--  ecode12 = SWIG_AsVal_int(obj11, &val12);
--  if (!SWIG_IsOK(ecode12)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode12), "in method '" "VImage_affinei" "', argument " "12"" of type '" "int""'");
--  } 
--  arg12 = static_cast< int >(val12);
--  try {
--    result = (arg1)->affinei(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_affinei_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char *arg2 = (char *) 0 ;
--  double arg3 ;
--  double arg4 ;
--  double arg5 ;
--  double arg6 ;
--  double arg7 ;
--  double arg8 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int res2 ;
--  char *buf2 = 0 ;
--  int alloc2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  double val5 ;
--  int ecode5 = 0 ;
--  double val6 ;
--  int ecode6 = 0 ;
--  double val7 ;
--  int ecode7 = 0 ;
--  double val8 ;
--  int ecode8 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  PyObject * obj7 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOO:VImage_affinei_all",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_affinei_all" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VImage_affinei_all" "', argument " "2"" of type '" "char *""'");
--  }
--  arg2 = reinterpret_cast< char * >(buf2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_affinei_all" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_affinei_all" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  ecode5 = SWIG_AsVal_double(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_affinei_all" "', argument " "5"" of type '" "double""'");
--  } 
--  arg5 = static_cast< double >(val5);
--  ecode6 = SWIG_AsVal_double(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_affinei_all" "', argument " "6"" of type '" "double""'");
--  } 
--  arg6 = static_cast< double >(val6);
--  ecode7 = SWIG_AsVal_double(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_affinei_all" "', argument " "7"" of type '" "double""'");
--  } 
--  arg7 = static_cast< double >(val7);
--  ecode8 = SWIG_AsVal_double(obj7, &val8);
--  if (!SWIG_IsOK(ecode8)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "VImage_affinei_all" "', argument " "8"" of type '" "double""'");
--  } 
--  arg8 = static_cast< double >(val8);
--  try {
--    result = (arg1)->affinei_all(arg2,arg3,arg4,arg5,arg6,arg7,arg8);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return resultobj;
--fail:
--  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_video_test(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VImage_video_test",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VImage_video_test" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_video_test" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = vips::VImage::video_test(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_video_v4l1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  int arg5 ;
--  int arg6 ;
--  int arg7 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  int val6 ;
--  int ecode6 = 0 ;
--  int val7 ;
--  int ecode7 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  PyObject * obj6 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:VImage_video_v4l1",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_video_v4l1" "', argument " "1"" of type '" "char *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_video_v4l1" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_video_v4l1" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_video_v4l1" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_video_v4l1" "', argument " "5"" of type '" "int""'");
--  } 
--  arg5 = static_cast< int >(val5);
--  ecode6 = SWIG_AsVal_int(obj5, &val6);
--  if (!SWIG_IsOK(ecode6)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "VImage_video_v4l1" "', argument " "6"" of type '" "int""'");
--  } 
--  arg6 = static_cast< int >(val6);
--  ecode7 = SWIG_AsVal_int(obj6, &val7);
--  if (!SWIG_IsOK(ecode7)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "VImage_video_v4l1" "', argument " "7"" of type '" "int""'");
--  } 
--  arg7 = static_cast< int >(val7);
--  try {
--    result = vips::VImage::video_v4l1(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tobuffer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  VBuffer result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_tobuffer",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tobuffer" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    result = vips_VImage_tobuffer(arg1);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  {
--    resultobj = PyBuffer_FromMemory ((&result)->data, (&result)->size);
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_frombuffer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  VBuffer arg1 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_frombuffer",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  {
--    const char *buffer;
--    Py_ssize_t buffer_len;
--    
--    if (PyObject_AsCharBuffer (obj0, &buffer, &buffer_len) == -1) {
--      PyErr_SetString (PyExc_TypeError,"Type error. Unable to get char pointer from buffer");
--      return NULL;
--    }
--    
--    (&arg1)->data = (void *) buffer;
--    (&arg1)->size = buffer_len;
--  }
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_frombuffer" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_frombuffer" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_frombuffer" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_frombuffer" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  try {
--    result = vips_VImage_frombuffer(arg1,arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_tostring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VImage *arg1 = (vips::VImage *) 0 ;
--  char **arg2 = (char **) 0 ;
--  int *arg3 = (int *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  char *temp2 = 0 ;
--  int tempn2 ;
--  PyObject * obj0 = 0 ;
--  
--  arg2 = &temp2; arg3 = &tempn2;
--  if (!PyArg_ParseTuple(args,(char *)"O:VImage_tostring",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VImage, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VImage_tostring" "', argument " "1"" of type '" "vips::VImage *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VImage * >(argp1);
--  try {
--    vips_VImage_tostring(arg1,arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  if (*arg2) {
--    resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg2,*arg3));
--    im_free (*arg2);
--  }
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VImage_fromstring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::string arg1 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  vips::VImage::TBandFmt arg5 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  int val5 ;
--  int ecode5 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VImage result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:VImage_fromstring",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  {
--    std::string *ptr = (std::string *)0;
--    int res = SWIG_AsPtr_std_string(obj0, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "VImage_fromstring" "', argument " "1"" of type '" "std::string""'"); 
--    }
--    arg1 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VImage_fromstring" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VImage_fromstring" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "VImage_fromstring" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  ecode5 = SWIG_AsVal_int(obj4, &val5);
--  if (!SWIG_IsOK(ecode5)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "VImage_fromstring" "', argument " "5"" of type '" "vips::VImage::TBandFmt""'");
--  } 
--  arg5 = static_cast< vips::VImage::TBandFmt >(val5);
--  try {
--    result = vips_VImage_fromstring(arg1,arg2,arg3,arg4,arg5);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VImage(static_cast< const vips::VImage& >(result))), SWIGTYPE_p_vips__VImage, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VImage_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VImage, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_im_init_world(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:im_init_world",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "im_init_world" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  result = (int)im_init_world((char const *)arg1);
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_im__print_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  
--  if (!PyArg_ParseTuple(args,(char *)":im__print_all")) SWIG_fail;
--  im__print_all();
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_im_col_Lab2XYZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  float arg1 ;
--  float arg2 ;
--  float arg3 ;
--  float *arg4 = (float *) 0 ;
--  float *arg5 = (float *) 0 ;
--  float *arg6 = (float *) 0 ;
--  float val1 ;
--  int ecode1 = 0 ;
--  float val2 ;
--  int ecode2 = 0 ;
--  float val3 ;
--  int ecode3 = 0 ;
--  void *argp4 = 0 ;
--  int res4 = 0 ;
--  void *argp5 = 0 ;
--  int res5 = 0 ;
--  void *argp6 = 0 ;
--  int res6 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  PyObject * obj5 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:im_col_Lab2XYZ",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
--  ecode1 = SWIG_AsVal_float(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "im_col_Lab2XYZ" "', argument " "1"" of type '" "float""'");
--  } 
--  arg1 = static_cast< float >(val1);
--  ecode2 = SWIG_AsVal_float(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "im_col_Lab2XYZ" "', argument " "2"" of type '" "float""'");
--  } 
--  arg2 = static_cast< float >(val2);
--  ecode3 = SWIG_AsVal_float(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "im_col_Lab2XYZ" "', argument " "3"" of type '" "float""'");
--  } 
--  arg3 = static_cast< float >(val3);
--  res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_float, 0 |  0 );
--  if (!SWIG_IsOK(res4)) {
--    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "im_col_Lab2XYZ" "', argument " "4"" of type '" "float *""'"); 
--  }
--  arg4 = reinterpret_cast< float * >(argp4);
--  res5 = SWIG_ConvertPtr(obj4, &argp5,SWIGTYPE_p_float, 0 |  0 );
--  if (!SWIG_IsOK(res5)) {
--    SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "im_col_Lab2XYZ" "', argument " "5"" of type '" "float *""'"); 
--  }
--  arg5 = reinterpret_cast< float * >(argp5);
--  res6 = SWIG_ConvertPtr(obj5, &argp6,SWIGTYPE_p_float, 0 |  0 );
--  if (!SWIG_IsOK(res6)) {
--    SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "im_col_Lab2XYZ" "', argument " "6"" of type '" "float *""'"); 
--  }
--  arg6 = reinterpret_cast< float * >(argp6);
--  im_col_Lab2XYZ(arg1,arg2,arg3,arg4,arg5,arg6);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--static PyMethodDef SwigMethods[] = {
--       { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
--       { (char *)"delete_SwigPyIterator", _wrap_delete_SwigPyIterator, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_value", _wrap_SwigPyIterator_value, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_incr", _wrap_SwigPyIterator_incr, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_decr", _wrap_SwigPyIterator_decr, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_distance", _wrap_SwigPyIterator_distance, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_equal", _wrap_SwigPyIterator_equal, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_copy", _wrap_SwigPyIterator_copy, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_next", _wrap_SwigPyIterator_next, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___next__", _wrap_SwigPyIterator___next__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_previous", _wrap_SwigPyIterator_previous, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_advance", _wrap_SwigPyIterator_advance, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___eq__", _wrap_SwigPyIterator___eq__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___ne__", _wrap_SwigPyIterator___ne__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___iadd__", _wrap_SwigPyIterator___iadd__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___isub__", _wrap_SwigPyIterator___isub__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___add__", _wrap_SwigPyIterator___add__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator___sub__", _wrap_SwigPyIterator___sub__, METH_VARARGS, NULL},
--       { (char *)"SwigPyIterator_swigregister", SwigPyIterator_swigregister, METH_VARARGS, NULL},
--       { (char *)"IntVector_iterator", _wrap_IntVector_iterator, METH_VARARGS, NULL},
--       { (char *)"IntVector___nonzero__", _wrap_IntVector___nonzero__, METH_VARARGS, NULL},
--       { (char *)"IntVector___bool__", _wrap_IntVector___bool__, METH_VARARGS, NULL},
--       { (char *)"IntVector___len__", _wrap_IntVector___len__, METH_VARARGS, NULL},
--       { (char *)"IntVector_pop", _wrap_IntVector_pop, METH_VARARGS, NULL},
--       { (char *)"IntVector___getslice__", _wrap_IntVector___getslice__, METH_VARARGS, NULL},
--       { (char *)"IntVector___setslice__", _wrap_IntVector___setslice__, METH_VARARGS, NULL},
--       { (char *)"IntVector___delslice__", _wrap_IntVector___delslice__, METH_VARARGS, NULL},
--       { (char *)"IntVector___delitem__", _wrap_IntVector___delitem__, METH_VARARGS, NULL},
--       { (char *)"IntVector___getitem__", _wrap_IntVector___getitem__, METH_VARARGS, NULL},
--       { (char *)"IntVector___setitem__", _wrap_IntVector___setitem__, METH_VARARGS, NULL},
--       { (char *)"IntVector_append", _wrap_IntVector_append, METH_VARARGS, NULL},
--       { (char *)"IntVector_empty", _wrap_IntVector_empty, METH_VARARGS, NULL},
--       { (char *)"IntVector_size", _wrap_IntVector_size, METH_VARARGS, NULL},
--       { (char *)"IntVector_clear", _wrap_IntVector_clear, METH_VARARGS, NULL},
--       { (char *)"IntVector_swap", _wrap_IntVector_swap, METH_VARARGS, NULL},
--       { (char *)"IntVector_get_allocator", _wrap_IntVector_get_allocator, METH_VARARGS, NULL},
--       { (char *)"IntVector_begin", _wrap_IntVector_begin, METH_VARARGS, NULL},
--       { (char *)"IntVector_end", _wrap_IntVector_end, METH_VARARGS, NULL},
--       { (char *)"IntVector_rbegin", _wrap_IntVector_rbegin, METH_VARARGS, NULL},
--       { (char *)"IntVector_rend", _wrap_IntVector_rend, METH_VARARGS, NULL},
--       { (char *)"IntVector_pop_back", _wrap_IntVector_pop_back, METH_VARARGS, NULL},
--       { (char *)"IntVector_erase", _wrap_IntVector_erase, METH_VARARGS, NULL},
--       { (char *)"new_IntVector", _wrap_new_IntVector, METH_VARARGS, NULL},
--       { (char *)"IntVector_push_back", _wrap_IntVector_push_back, METH_VARARGS, NULL},
--       { (char *)"IntVector_front", _wrap_IntVector_front, METH_VARARGS, NULL},
--       { (char *)"IntVector_back", _wrap_IntVector_back, METH_VARARGS, NULL},
--       { (char *)"IntVector_assign", _wrap_IntVector_assign, METH_VARARGS, NULL},
--       { (char *)"IntVector_resize", _wrap_IntVector_resize, METH_VARARGS, NULL},
--       { (char *)"IntVector_insert", _wrap_IntVector_insert, METH_VARARGS, NULL},
--       { (char *)"IntVector_reserve", _wrap_IntVector_reserve, METH_VARARGS, NULL},
--       { (char *)"IntVector_capacity", _wrap_IntVector_capacity, METH_VARARGS, NULL},
--       { (char *)"delete_IntVector", _wrap_delete_IntVector, METH_VARARGS, NULL},
--       { (char *)"IntVector_swigregister", IntVector_swigregister, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_iterator", _wrap_DoubleVector_iterator, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___nonzero__", _wrap_DoubleVector___nonzero__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___bool__", _wrap_DoubleVector___bool__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___len__", _wrap_DoubleVector___len__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_pop", _wrap_DoubleVector_pop, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___getslice__", _wrap_DoubleVector___getslice__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___setslice__", _wrap_DoubleVector___setslice__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___delslice__", _wrap_DoubleVector___delslice__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___delitem__", _wrap_DoubleVector___delitem__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___getitem__", _wrap_DoubleVector___getitem__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector___setitem__", _wrap_DoubleVector___setitem__, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_append", _wrap_DoubleVector_append, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_empty", _wrap_DoubleVector_empty, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_size", _wrap_DoubleVector_size, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_clear", _wrap_DoubleVector_clear, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_swap", _wrap_DoubleVector_swap, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_get_allocator", _wrap_DoubleVector_get_allocator, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_begin", _wrap_DoubleVector_begin, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_end", _wrap_DoubleVector_end, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_rbegin", _wrap_DoubleVector_rbegin, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_rend", _wrap_DoubleVector_rend, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_pop_back", _wrap_DoubleVector_pop_back, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_erase", _wrap_DoubleVector_erase, METH_VARARGS, NULL},
--       { (char *)"new_DoubleVector", _wrap_new_DoubleVector, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_push_back", _wrap_DoubleVector_push_back, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_front", _wrap_DoubleVector_front, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_back", _wrap_DoubleVector_back, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_assign", _wrap_DoubleVector_assign, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_resize", _wrap_DoubleVector_resize, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_insert", _wrap_DoubleVector_insert, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_reserve", _wrap_DoubleVector_reserve, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_capacity", _wrap_DoubleVector_capacity, METH_VARARGS, NULL},
--       { (char *)"delete_DoubleVector", _wrap_delete_DoubleVector, METH_VARARGS, NULL},
--       { (char *)"DoubleVector_swigregister", DoubleVector_swigregister, METH_VARARGS, NULL},
--       { (char *)"ImageVector_iterator", _wrap_ImageVector_iterator, METH_VARARGS, NULL},
--       { (char *)"ImageVector___nonzero__", _wrap_ImageVector___nonzero__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___bool__", _wrap_ImageVector___bool__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___len__", _wrap_ImageVector___len__, METH_VARARGS, NULL},
--       { (char *)"ImageVector_pop", _wrap_ImageVector_pop, METH_VARARGS, NULL},
--       { (char *)"ImageVector___getslice__", _wrap_ImageVector___getslice__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___setslice__", _wrap_ImageVector___setslice__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___delslice__", _wrap_ImageVector___delslice__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___delitem__", _wrap_ImageVector___delitem__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___getitem__", _wrap_ImageVector___getitem__, METH_VARARGS, NULL},
--       { (char *)"ImageVector___setitem__", _wrap_ImageVector___setitem__, METH_VARARGS, NULL},
--       { (char *)"ImageVector_append", _wrap_ImageVector_append, METH_VARARGS, NULL},
--       { (char *)"ImageVector_empty", _wrap_ImageVector_empty, METH_VARARGS, NULL},
--       { (char *)"ImageVector_size", _wrap_ImageVector_size, METH_VARARGS, NULL},
--       { (char *)"ImageVector_clear", _wrap_ImageVector_clear, METH_VARARGS, NULL},
--       { (char *)"ImageVector_swap", _wrap_ImageVector_swap, METH_VARARGS, NULL},
--       { (char *)"ImageVector_get_allocator", _wrap_ImageVector_get_allocator, METH_VARARGS, NULL},
--       { (char *)"ImageVector_begin", _wrap_ImageVector_begin, METH_VARARGS, NULL},
--       { (char *)"ImageVector_end", _wrap_ImageVector_end, METH_VARARGS, NULL},
--       { (char *)"ImageVector_rbegin", _wrap_ImageVector_rbegin, METH_VARARGS, NULL},
--       { (char *)"ImageVector_rend", _wrap_ImageVector_rend, METH_VARARGS, NULL},
--       { (char *)"ImageVector_pop_back", _wrap_ImageVector_pop_back, METH_VARARGS, NULL},
--       { (char *)"ImageVector_erase", _wrap_ImageVector_erase, METH_VARARGS, NULL},
--       { (char *)"new_ImageVector", _wrap_new_ImageVector, METH_VARARGS, NULL},
--       { (char *)"ImageVector_push_back", _wrap_ImageVector_push_back, METH_VARARGS, NULL},
--       { (char *)"ImageVector_front", _wrap_ImageVector_front, METH_VARARGS, NULL},
--       { (char *)"ImageVector_back", _wrap_ImageVector_back, METH_VARARGS, NULL},
--       { (char *)"ImageVector_assign", _wrap_ImageVector_assign, METH_VARARGS, NULL},
--       { (char *)"ImageVector_resize", _wrap_ImageVector_resize, METH_VARARGS, NULL},
--       { (char *)"ImageVector_insert", _wrap_ImageVector_insert, METH_VARARGS, NULL},
--       { (char *)"ImageVector_reserve", _wrap_ImageVector_reserve, METH_VARARGS, NULL},
--       { (char *)"ImageVector_capacity", _wrap_ImageVector_capacity, METH_VARARGS, NULL},
--       { (char *)"delete_ImageVector", _wrap_delete_ImageVector, METH_VARARGS, NULL},
--       { (char *)"ImageVector_swigregister", ImageVector_swigregister, METH_VARARGS, NULL},
--       { (char *)"init", _wrap_init, METH_VARARGS, NULL},
--       { (char *)"shutdown", _wrap_shutdown, METH_VARARGS, NULL},
--       { (char *)"VImage_print_all", _wrap_VImage_print_all, METH_VARARGS, NULL},
--       { (char *)"VImage_convert2disc", _wrap_VImage_convert2disc, METH_VARARGS, NULL},
--       { (char *)"new_VImage", _wrap_new_VImage, METH_VARARGS, NULL},
--       { (char *)"VImage___assign__", _wrap_VImage___assign__, METH_VARARGS, NULL},
--       { (char *)"delete_VImage", _wrap_delete_VImage, METH_VARARGS, NULL},
--       { (char *)"VImage_image", _wrap_VImage_image, METH_VARARGS, NULL},
--       { (char *)"VImage_data", _wrap_VImage_data, METH_VARARGS, NULL},
--       { (char *)"VImage_write", _wrap_VImage_write, METH_VARARGS, NULL},
--       { (char *)"VImage_debug_print", _wrap_VImage_debug_print, METH_VARARGS, NULL},
--       { (char *)"VImage_Xsize", _wrap_VImage_Xsize, METH_VARARGS, NULL},
--       { (char *)"VImage_Ysize", _wrap_VImage_Ysize, METH_VARARGS, NULL},
--       { (char *)"VImage_Bands", _wrap_VImage_Bands, METH_VARARGS, NULL},
--       { (char *)"VImage_BandFmt", _wrap_VImage_BandFmt, METH_VARARGS, NULL},
--       { (char *)"VImage_Coding", _wrap_VImage_Coding, METH_VARARGS, NULL},
--       { (char *)"VImage_Type", _wrap_VImage_Type, METH_VARARGS, NULL},
--       { (char *)"VImage_Xres", _wrap_VImage_Xres, METH_VARARGS, NULL},
--       { (char *)"VImage_Yres", _wrap_VImage_Yres, METH_VARARGS, NULL},
--       { (char *)"VImage_Length", _wrap_VImage_Length, METH_VARARGS, NULL},
--       { (char *)"VImage_Compression", _wrap_VImage_Compression, METH_VARARGS, NULL},
--       { (char *)"VImage_Level", _wrap_VImage_Level, METH_VARARGS, NULL},
--       { (char *)"VImage_Xoffset", _wrap_VImage_Xoffset, METH_VARARGS, NULL},
--       { (char *)"VImage_Yoffset", _wrap_VImage_Yoffset, METH_VARARGS, NULL},
--       { (char *)"VImage_filename", _wrap_VImage_filename, METH_VARARGS, NULL},
--       { (char *)"VImage_Hist", _wrap_VImage_Hist, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_remove", _wrap_VImage_meta_remove, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_typeof", _wrap_VImage_meta_get_typeof, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_int", _wrap_VImage_meta_get_int, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_double", _wrap_VImage_meta_get_double, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_string", _wrap_VImage_meta_get_string, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_area", _wrap_VImage_meta_get_area, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_get_blob", _wrap_VImage_meta_get_blob, METH_VARARGS, NULL},
--       { (char *)"VImage_meta_set", _wrap_VImage_meta_set, METH_VARARGS, NULL},
--       { (char *)"VImage_initdesc", _wrap_VImage_initdesc, METH_VARARGS, NULL},
--       { (char *)"VImage_abs", _wrap_VImage_abs, METH_VARARGS, NULL},
--       { (char *)"VImage_acos", _wrap_VImage_acos, METH_VARARGS, NULL},
--       { (char *)"VImage_add", _wrap_VImage_add, METH_VARARGS, NULL},
--       { (char *)"VImage_asin", _wrap_VImage_asin, METH_VARARGS, NULL},
--       { (char *)"VImage_atan", _wrap_VImage_atan, METH_VARARGS, NULL},
--       { (char *)"VImage_avg", _wrap_VImage_avg, METH_VARARGS, NULL},
--       { (char *)"VImage_point", _wrap_VImage_point, METH_VARARGS, NULL},
--       { (char *)"VImage_point_bilinear", _wrap_VImage_point_bilinear, METH_VARARGS, NULL},
--       { (char *)"VImage_bandmean", _wrap_VImage_bandmean, METH_VARARGS, NULL},
--       { (char *)"VImage_ceil", _wrap_VImage_ceil, METH_VARARGS, NULL},
--       { (char *)"VImage_cos", _wrap_VImage_cos, METH_VARARGS, NULL},
--       { (char *)"VImage_cross_phase", _wrap_VImage_cross_phase, METH_VARARGS, NULL},
--       { (char *)"VImage_deviate", _wrap_VImage_deviate, METH_VARARGS, NULL},
--       { (char *)"VImage_divide", _wrap_VImage_divide, METH_VARARGS, NULL},
--       { (char *)"VImage_exp10", _wrap_VImage_exp10, METH_VARARGS, NULL},
--       { (char *)"VImage_expn", _wrap_VImage_expn, METH_VARARGS, NULL},
--       { (char *)"VImage_exp", _wrap_VImage_exp, METH_VARARGS, NULL},
--       { (char *)"VImage_floor", _wrap_VImage_floor, METH_VARARGS, NULL},
--       { (char *)"VImage_invert", _wrap_VImage_invert, METH_VARARGS, NULL},
--       { (char *)"VImage_linreg", _wrap_VImage_linreg, METH_VARARGS, NULL},
--       { (char *)"VImage_lin", _wrap_VImage_lin, METH_VARARGS, NULL},
--       { (char *)"VImage_log10", _wrap_VImage_log10, METH_VARARGS, NULL},
--       { (char *)"VImage_log", _wrap_VImage_log, METH_VARARGS, NULL},
--       { (char *)"VImage_max", _wrap_VImage_max, METH_VARARGS, NULL},
--       { (char *)"VImage_maxpos", _wrap_VImage_maxpos, METH_VARARGS, NULL},
--       { (char *)"VImage_maxpos_avg", _wrap_VImage_maxpos_avg, METH_VARARGS, NULL},
--       { (char *)"VImage_measure", _wrap_VImage_measure, METH_VARARGS, NULL},
--       { (char *)"VImage_min", _wrap_VImage_min, METH_VARARGS, NULL},
--       { (char *)"VImage_minpos", _wrap_VImage_minpos, METH_VARARGS, NULL},
--       { (char *)"VImage_multiply", _wrap_VImage_multiply, METH_VARARGS, NULL},
--       { (char *)"VImage_pow", _wrap_VImage_pow, METH_VARARGS, NULL},
--       { (char *)"VImage_recomb", _wrap_VImage_recomb, METH_VARARGS, NULL},
--       { (char *)"VImage_remainder", _wrap_VImage_remainder, METH_VARARGS, NULL},
--       { (char *)"VImage_rint", _wrap_VImage_rint, METH_VARARGS, NULL},
--       { (char *)"VImage_sign", _wrap_VImage_sign, METH_VARARGS, NULL},
--       { (char *)"VImage_sin", _wrap_VImage_sin, METH_VARARGS, NULL},
--       { (char *)"VImage_stats", _wrap_VImage_stats, METH_VARARGS, NULL},
--       { (char *)"VImage_subtract", _wrap_VImage_subtract, METH_VARARGS, NULL},
--       { (char *)"VImage_tan", _wrap_VImage_tan, METH_VARARGS, NULL},
--       { (char *)"VImage_greyc", _wrap_VImage_greyc, METH_VARARGS, NULL},
--       { (char *)"VImage_greyc_mask", _wrap_VImage_greyc_mask, METH_VARARGS, NULL},
--       { (char *)"VImage_LCh2Lab", _wrap_VImage_LCh2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_LCh2UCS", _wrap_VImage_LCh2UCS, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2LCh", _wrap_VImage_Lab2LCh, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2LabQ", _wrap_VImage_Lab2LabQ, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2LabS", _wrap_VImage_Lab2LabS, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2UCS", _wrap_VImage_Lab2UCS, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2XYZ", _wrap_VImage_Lab2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2XYZ_temp", _wrap_VImage_Lab2XYZ_temp, METH_VARARGS, NULL},
--       { (char *)"VImage_Lab2disp", _wrap_VImage_Lab2disp, METH_VARARGS, NULL},
--       { (char *)"VImage_LabQ2LabS", _wrap_VImage_LabQ2LabS, METH_VARARGS, NULL},
--       { (char *)"VImage_LabQ2Lab", _wrap_VImage_LabQ2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_LabQ2XYZ", _wrap_VImage_LabQ2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_LabQ2disp", _wrap_VImage_LabQ2disp, METH_VARARGS, NULL},
--       { (char *)"VImage_LabS2LabQ", _wrap_VImage_LabS2LabQ, METH_VARARGS, NULL},
--       { (char *)"VImage_LabS2Lab", _wrap_VImage_LabS2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_UCS2LCh", _wrap_VImage_UCS2LCh, METH_VARARGS, NULL},
--       { (char *)"VImage_UCS2Lab", _wrap_VImage_UCS2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_UCS2XYZ", _wrap_VImage_UCS2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2Lab", _wrap_VImage_XYZ2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2Lab_temp", _wrap_VImage_XYZ2Lab_temp, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2UCS", _wrap_VImage_XYZ2UCS, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2Yxy", _wrap_VImage_XYZ2Yxy, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2disp", _wrap_VImage_XYZ2disp, METH_VARARGS, NULL},
--       { (char *)"VImage_XYZ2sRGB", _wrap_VImage_XYZ2sRGB, METH_VARARGS, NULL},
--       { (char *)"VImage_Yxy2XYZ", _wrap_VImage_Yxy2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_dE00_fromLab", _wrap_VImage_dE00_fromLab, METH_VARARGS, NULL},
--       { (char *)"VImage_dECMC_fromLab", _wrap_VImage_dECMC_fromLab, METH_VARARGS, NULL},
--       { (char *)"VImage_dECMC_fromdisp", _wrap_VImage_dECMC_fromdisp, METH_VARARGS, NULL},
--       { (char *)"VImage_dE_fromLab", _wrap_VImage_dE_fromLab, METH_VARARGS, NULL},
--       { (char *)"VImage_dE_fromXYZ", _wrap_VImage_dE_fromXYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_dE_fromdisp", _wrap_VImage_dE_fromdisp, METH_VARARGS, NULL},
--       { (char *)"VImage_disp2Lab", _wrap_VImage_disp2Lab, METH_VARARGS, NULL},
--       { (char *)"VImage_disp2XYZ", _wrap_VImage_disp2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_float2rad", _wrap_VImage_float2rad, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_ac2rc", _wrap_VImage_icc_ac2rc, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_export_depth", _wrap_VImage_icc_export_depth, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_import", _wrap_VImage_icc_import, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_import_embedded", _wrap_VImage_icc_import_embedded, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_transform", _wrap_VImage_icc_transform, METH_VARARGS, NULL},
--       { (char *)"VImage_lab_morph", _wrap_VImage_lab_morph, METH_VARARGS, NULL},
--       { (char *)"VImage_rad2float", _wrap_VImage_rad2float, METH_VARARGS, NULL},
--       { (char *)"VImage_sRGB2XYZ", _wrap_VImage_sRGB2XYZ, METH_VARARGS, NULL},
--       { (char *)"VImage_gaussnoise", _wrap_VImage_gaussnoise, METH_VARARGS, NULL},
--       { (char *)"VImage_bandjoin", _wrap_VImage_bandjoin, METH_VARARGS, NULL},
--       { (char *)"VImage_black", _wrap_VImage_black, METH_VARARGS, NULL},
--       { (char *)"VImage_c2amph", _wrap_VImage_c2amph, METH_VARARGS, NULL},
--       { (char *)"VImage_c2imag", _wrap_VImage_c2imag, METH_VARARGS, NULL},
--       { (char *)"VImage_c2real", _wrap_VImage_c2real, METH_VARARGS, NULL},
--       { (char *)"VImage_c2rect", _wrap_VImage_c2rect, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2fmt", _wrap_VImage_clip2fmt, METH_VARARGS, NULL},
--       { (char *)"VImage_copy", _wrap_VImage_copy, METH_VARARGS, NULL},
--       { (char *)"VImage_copy_file", _wrap_VImage_copy_file, METH_VARARGS, NULL},
--       { (char *)"VImage_copy_morph", _wrap_VImage_copy_morph, METH_VARARGS, NULL},
--       { (char *)"VImage_copy_swap", _wrap_VImage_copy_swap, METH_VARARGS, NULL},
--       { (char *)"VImage_copy_set", _wrap_VImage_copy_set, METH_VARARGS, NULL},
--       { (char *)"VImage_extract_area", _wrap_VImage_extract_area, METH_VARARGS, NULL},
--       { (char *)"VImage_extract_areabands", _wrap_VImage_extract_areabands, METH_VARARGS, NULL},
--       { (char *)"VImage_extract_band", _wrap_VImage_extract_band, METH_VARARGS, NULL},
--       { (char *)"VImage_extract_bands", _wrap_VImage_extract_bands, METH_VARARGS, NULL},
--       { (char *)"VImage_extract", _wrap_VImage_extract, METH_VARARGS, NULL},
--       { (char *)"VImage_falsecolour", _wrap_VImage_falsecolour, METH_VARARGS, NULL},
--       { (char *)"VImage_fliphor", _wrap_VImage_fliphor, METH_VARARGS, NULL},
--       { (char *)"VImage_flipver", _wrap_VImage_flipver, METH_VARARGS, NULL},
--       { (char *)"VImage_gbandjoin", _wrap_VImage_gbandjoin, METH_VARARGS, NULL},
--       { (char *)"VImage_grid", _wrap_VImage_grid, METH_VARARGS, NULL},
--       { (char *)"VImage_insert", _wrap_VImage_insert, METH_VARARGS, NULL},
--       { (char *)"VImage_insert_noexpand", _wrap_VImage_insert_noexpand, METH_VARARGS, NULL},
--       { (char *)"VImage_embed", _wrap_VImage_embed, METH_VARARGS, NULL},
--       { (char *)"VImage_lrjoin", _wrap_VImage_lrjoin, METH_VARARGS, NULL},
--       { (char *)"VImage_msb", _wrap_VImage_msb, METH_VARARGS, NULL},
--       { (char *)"VImage_msb_band", _wrap_VImage_msb_band, METH_VARARGS, NULL},
--       { (char *)"VImage_replicate", _wrap_VImage_replicate, METH_VARARGS, NULL},
--       { (char *)"VImage_ri2c", _wrap_VImage_ri2c, METH_VARARGS, NULL},
--       { (char *)"VImage_rot180", _wrap_VImage_rot180, METH_VARARGS, NULL},
--       { (char *)"VImage_rot270", _wrap_VImage_rot270, METH_VARARGS, NULL},
--       { (char *)"VImage_rot90", _wrap_VImage_rot90, METH_VARARGS, NULL},
--       { (char *)"VImage_scale", _wrap_VImage_scale, METH_VARARGS, NULL},
--       { (char *)"VImage_scaleps", _wrap_VImage_scaleps, METH_VARARGS, NULL},
--       { (char *)"VImage_subsample", _wrap_VImage_subsample, METH_VARARGS, NULL},
--       { (char *)"VImage_system", _wrap_VImage_system, METH_VARARGS, NULL},
--       { (char *)"VImage_system_image", _wrap_VImage_system_image, METH_VARARGS, NULL},
--       { (char *)"VImage_tbjoin", _wrap_VImage_tbjoin, METH_VARARGS, NULL},
--       { (char *)"VImage_text", _wrap_VImage_text, METH_VARARGS, NULL},
--       { (char *)"VImage_wrap", _wrap_VImage_wrap, METH_VARARGS, NULL},
--       { (char *)"VImage_zoom", _wrap_VImage_zoom, METH_VARARGS, NULL},
--       { (char *)"VImage_aconvsep", _wrap_VImage_aconvsep, METH_VARARGS, NULL},
--       { (char *)"VImage_aconv", _wrap_VImage_aconv, METH_VARARGS, NULL},
--       { (char *)"VImage_addgnoise", _wrap_VImage_addgnoise, METH_VARARGS, NULL},
--       { (char *)"VImage_compass", _wrap_VImage_compass, METH_VARARGS, NULL},
--       { (char *)"VImage_contrast_surface", _wrap_VImage_contrast_surface, METH_VARARGS, NULL},
--       { (char *)"VImage_conv", _wrap_VImage_conv, METH_VARARGS, NULL},
--       { (char *)"VImage_convsep", _wrap_VImage_convsep, METH_VARARGS, NULL},
--       { (char *)"VImage_fastcor", _wrap_VImage_fastcor, METH_VARARGS, NULL},
--       { (char *)"VImage_gradcor", _wrap_VImage_gradcor, METH_VARARGS, NULL},
--       { (char *)"VImage_gradient", _wrap_VImage_gradient, METH_VARARGS, NULL},
--       { (char *)"VImage_grad_x", _wrap_VImage_grad_x, METH_VARARGS, NULL},
--       { (char *)"VImage_grad_y", _wrap_VImage_grad_y, METH_VARARGS, NULL},
--       { (char *)"VImage_lindetect", _wrap_VImage_lindetect, METH_VARARGS, NULL},
--       { (char *)"VImage_sharpen", _wrap_VImage_sharpen, METH_VARARGS, NULL},
--       { (char *)"VImage_spcor", _wrap_VImage_spcor, METH_VARARGS, NULL},
--       { (char *)"VImage_argb2rgba", _wrap_VImage_argb2rgba, METH_VARARGS, NULL},
--       { (char *)"VImage_flood_copy", _wrap_VImage_flood_copy, METH_VARARGS, NULL},
--       { (char *)"VImage_flood_blob_copy", _wrap_VImage_flood_blob_copy, METH_VARARGS, NULL},
--       { (char *)"VImage_flood_other_copy", _wrap_VImage_flood_other_copy, METH_VARARGS, NULL},
--       { (char *)"VImage_clip", _wrap_VImage_clip, METH_VARARGS, NULL},
--       { (char *)"VImage_c2ps", _wrap_VImage_c2ps, METH_VARARGS, NULL},
--       { (char *)"VImage_resize_linear", _wrap_VImage_resize_linear, METH_VARARGS, NULL},
--       { (char *)"VImage_cmulnorm", _wrap_VImage_cmulnorm, METH_VARARGS, NULL},
--       { (char *)"VImage_fav4", _wrap_VImage_fav4, METH_VARARGS, NULL},
--       { (char *)"VImage_gadd", _wrap_VImage_gadd, METH_VARARGS, NULL},
--       { (char *)"VImage_icc_export", _wrap_VImage_icc_export, METH_VARARGS, NULL},
--       { (char *)"VImage_litecor", _wrap_VImage_litecor, METH_VARARGS, NULL},
--       { (char *)"VImage_affine", _wrap_VImage_affine, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2c", _wrap_VImage_clip2c, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2cm", _wrap_VImage_clip2cm, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2d", _wrap_VImage_clip2d, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2dcm", _wrap_VImage_clip2dcm, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2f", _wrap_VImage_clip2f, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2i", _wrap_VImage_clip2i, METH_VARARGS, NULL},
--       { (char *)"VImage_convsub", _wrap_VImage_convsub, METH_VARARGS, NULL},
--       { (char *)"VImage_convf", _wrap_VImage_convf, METH_VARARGS, NULL},
--       { (char *)"VImage_convsepf", _wrap_VImage_convsepf, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2s", _wrap_VImage_clip2s, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2ui", _wrap_VImage_clip2ui, METH_VARARGS, NULL},
--       { (char *)"VImage_clip2us", _wrap_VImage_clip2us, METH_VARARGS, NULL},
--       { (char *)"VImage_slice", _wrap_VImage_slice, METH_VARARGS, NULL},
--       { (char *)"VImage_segment", _wrap_VImage_segment, METH_VARARGS, NULL},
--       { (char *)"VImage_thresh", _wrap_VImage_thresh, METH_VARARGS, NULL},
--       { (char *)"VImage_convf_raw", _wrap_VImage_convf_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_conv_raw", _wrap_VImage_conv_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_contrast_surface_raw", _wrap_VImage_contrast_surface_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_convsepf_raw", _wrap_VImage_convsepf_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_convsep_raw", _wrap_VImage_convsep_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_fastcor_raw", _wrap_VImage_fastcor_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_gradcor_raw", _wrap_VImage_gradcor_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_spcor_raw", _wrap_VImage_spcor_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_lhisteq_raw", _wrap_VImage_lhisteq_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_stdif_raw", _wrap_VImage_stdif_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_rank_raw", _wrap_VImage_rank_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_dilate_raw", _wrap_VImage_dilate_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_erode_raw", _wrap_VImage_erode_raw, METH_VARARGS, NULL},
--       { (char *)"VImage_similarity_area", _wrap_VImage_similarity_area, METH_VARARGS, NULL},
--       { (char *)"VImage_similarity", _wrap_VImage_similarity, METH_VARARGS, NULL},
--       { (char *)"VImage_mask2vips", _wrap_VImage_mask2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2mask", _wrap_VImage_vips2mask, METH_VARARGS, NULL},
--       { (char *)"VImage_insertplace", _wrap_VImage_insertplace, METH_VARARGS, NULL},
--       { (char *)"VImage_circle", _wrap_VImage_circle, METH_VARARGS, NULL},
--       { (char *)"VImage_andimage", _wrap_VImage_andimage, METH_VARARGS, NULL},
--       { (char *)"VImage_orimage", _wrap_VImage_orimage, METH_VARARGS, NULL},
--       { (char *)"VImage_eorimage", _wrap_VImage_eorimage, METH_VARARGS, NULL},
--       { (char *)"VImage_shiftleft", _wrap_VImage_shiftleft, METH_VARARGS, NULL},
--       { (char *)"VImage_shiftright", _wrap_VImage_shiftright, METH_VARARGS, NULL},
--       { (char *)"VImage_blend", _wrap_VImage_blend, METH_VARARGS, NULL},
--       { (char *)"VImage_equal", _wrap_VImage_equal, METH_VARARGS, NULL},
--       { (char *)"VImage_ifthenelse", _wrap_VImage_ifthenelse, METH_VARARGS, NULL},
--       { (char *)"VImage_less", _wrap_VImage_less, METH_VARARGS, NULL},
--       { (char *)"VImage_lesseq", _wrap_VImage_lesseq, METH_VARARGS, NULL},
--       { (char *)"VImage_more", _wrap_VImage_more, METH_VARARGS, NULL},
--       { (char *)"VImage_moreeq", _wrap_VImage_moreeq, METH_VARARGS, NULL},
--       { (char *)"VImage_notequal", _wrap_VImage_notequal, METH_VARARGS, NULL},
--       { (char *)"VImage_quadratic", _wrap_VImage_quadratic, METH_VARARGS, NULL},
--       { (char *)"VImage_csv2vips", _wrap_VImage_csv2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_fits2vips", _wrap_VImage_fits2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_jpeg2vips", _wrap_VImage_jpeg2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_magick2vips", _wrap_VImage_magick2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_png2vips", _wrap_VImage_png2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_exr2vips", _wrap_VImage_exr2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_ppm2vips", _wrap_VImage_ppm2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_analyze2vips", _wrap_VImage_analyze2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_tiff2vips", _wrap_VImage_tiff2vips, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2csv", _wrap_VImage_vips2csv, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2dz", _wrap_VImage_vips2dz, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2jpeg", _wrap_VImage_vips2jpeg, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2mimejpeg", _wrap_VImage_vips2mimejpeg, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2png", _wrap_VImage_vips2png, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2ppm", _wrap_VImage_vips2ppm, METH_VARARGS, NULL},
--       { (char *)"VImage_vips2tiff", _wrap_VImage_vips2tiff, METH_VARARGS, NULL},
--       { (char *)"VImage_create_fmask", _wrap_VImage_create_fmask, METH_VARARGS, NULL},
--       { (char *)"VImage_disp_ps", _wrap_VImage_disp_ps, METH_VARARGS, NULL},
--       { (char *)"VImage_flt_image_freq", _wrap_VImage_flt_image_freq, METH_VARARGS, NULL},
--       { (char *)"VImage_fractsurf", _wrap_VImage_fractsurf, METH_VARARGS, NULL},
--       { (char *)"VImage_freqflt", _wrap_VImage_freqflt, METH_VARARGS, NULL},
--       { (char *)"VImage_fwfft", _wrap_VImage_fwfft, METH_VARARGS, NULL},
--       { (char *)"VImage_rotquad", _wrap_VImage_rotquad, METH_VARARGS, NULL},
--       { (char *)"VImage_invfft", _wrap_VImage_invfft, METH_VARARGS, NULL},
--       { (char *)"VImage_phasecor_fft", _wrap_VImage_phasecor_fft, METH_VARARGS, NULL},
--       { (char *)"VImage_invfftr", _wrap_VImage_invfftr, METH_VARARGS, NULL},
--       { (char *)"VImage_gammacorrect", _wrap_VImage_gammacorrect, METH_VARARGS, NULL},
--       { (char *)"VImage_heq", _wrap_VImage_heq, METH_VARARGS, NULL},
--       { (char *)"VImage_hist", _wrap_VImage_hist, METH_VARARGS, NULL},
--       { (char *)"VImage_histcum", _wrap_VImage_histcum, METH_VARARGS, NULL},
--       { (char *)"VImage_histeq", _wrap_VImage_histeq, METH_VARARGS, NULL},
--       { (char *)"VImage_hist_indexed", _wrap_VImage_hist_indexed, METH_VARARGS, NULL},
--       { (char *)"VImage_histgr", _wrap_VImage_histgr, METH_VARARGS, NULL},
--       { (char *)"VImage_histnD", _wrap_VImage_histnD, METH_VARARGS, NULL},
--       { (char *)"VImage_histnorm", _wrap_VImage_histnorm, METH_VARARGS, NULL},
--       { (char *)"VImage_histplot", _wrap_VImage_histplot, METH_VARARGS, NULL},
--       { (char *)"VImage_histspec", _wrap_VImage_histspec, METH_VARARGS, NULL},
--       { (char *)"VImage_hsp", _wrap_VImage_hsp, METH_VARARGS, NULL},
--       { (char *)"VImage_identity", _wrap_VImage_identity, METH_VARARGS, NULL},
--       { (char *)"VImage_identity_ushort", _wrap_VImage_identity_ushort, METH_VARARGS, NULL},
--       { (char *)"VImage_ismonotonic", _wrap_VImage_ismonotonic, METH_VARARGS, NULL},
--       { (char *)"VImage_lhisteq", _wrap_VImage_lhisteq, METH_VARARGS, NULL},
--       { (char *)"VImage_mpercent", _wrap_VImage_mpercent, METH_VARARGS, NULL},
--       { (char *)"VImage_invertlut", _wrap_VImage_invertlut, METH_VARARGS, NULL},
--       { (char *)"VImage_buildlut", _wrap_VImage_buildlut, METH_VARARGS, NULL},
--       { (char *)"VImage_maplut", _wrap_VImage_maplut, METH_VARARGS, NULL},
--       { (char *)"VImage_project", _wrap_VImage_project, METH_VARARGS, NULL},
--       { (char *)"VImage_stdif", _wrap_VImage_stdif, METH_VARARGS, NULL},
--       { (char *)"VImage_tone_analyse", _wrap_VImage_tone_analyse, METH_VARARGS, NULL},
--       { (char *)"VImage_tone_build", _wrap_VImage_tone_build, METH_VARARGS, NULL},
--       { (char *)"VImage_tone_build_range", _wrap_VImage_tone_build_range, METH_VARARGS, NULL},
--       { (char *)"VImage_tone_map", _wrap_VImage_tone_map, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_circle", _wrap_VImage_draw_circle, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_rect", _wrap_VImage_draw_rect, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_line", _wrap_VImage_draw_line, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_point", _wrap_VImage_draw_point, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_smudge", _wrap_VImage_draw_smudge, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_flood", _wrap_VImage_draw_flood, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_flood_blob", _wrap_VImage_draw_flood_blob, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_flood_other", _wrap_VImage_draw_flood_other, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_image", _wrap_VImage_draw_image, METH_VARARGS, NULL},
--       { (char *)"VImage_draw_mask", _wrap_VImage_draw_mask, METH_VARARGS, NULL},
--       { (char *)"VImage_line", _wrap_VImage_line, METH_VARARGS, NULL},
--       { (char *)"VImage_binfile", _wrap_VImage_binfile, METH_VARARGS, NULL},
--       { (char *)"VImage_cache", _wrap_VImage_cache, METH_VARARGS, NULL},
--       { (char *)"VImage_getext", _wrap_VImage_getext, METH_VARARGS, NULL},
--       { (char *)"VImage_header_get_typeof", _wrap_VImage_header_get_typeof, METH_VARARGS, NULL},
--       { (char *)"VImage_header_int", _wrap_VImage_header_int, METH_VARARGS, NULL},
--       { (char *)"VImage_header_double", _wrap_VImage_header_double, METH_VARARGS, NULL},
--       { (char *)"VImage_header_string", _wrap_VImage_header_string, METH_VARARGS, NULL},
--       { (char *)"VImage_history_get", _wrap_VImage_history_get, METH_VARARGS, NULL},
--       { (char *)"VImage_printdesc", _wrap_VImage_printdesc, METH_VARARGS, NULL},
--       { (char *)"VImage_cntlines", _wrap_VImage_cntlines, METH_VARARGS, NULL},
--       { (char *)"VImage_dilate", _wrap_VImage_dilate, METH_VARARGS, NULL},
--       { (char *)"VImage_rank", _wrap_VImage_rank, METH_VARARGS, NULL},
--       { (char *)"VImage_rank_image", _wrap_VImage_rank_image, METH_VARARGS, NULL},
--       { (char *)"VImage_maxvalue", _wrap_VImage_maxvalue, METH_VARARGS, NULL},
--       { (char *)"VImage_label_regions", _wrap_VImage_label_regions, METH_VARARGS, NULL},
--       { (char *)"VImage_zerox", _wrap_VImage_zerox, METH_VARARGS, NULL},
--       { (char *)"VImage_erode", _wrap_VImage_erode, METH_VARARGS, NULL},
--       { (char *)"VImage_profile", _wrap_VImage_profile, METH_VARARGS, NULL},
--       { (char *)"VImage_align_bands", _wrap_VImage_align_bands, METH_VARARGS, NULL},
--       { (char *)"VImage_correl", _wrap_VImage_correl, METH_VARARGS, NULL},
--       { (char *)"VImage__find_lroverlap", _wrap_VImage__find_lroverlap, METH_VARARGS, NULL},
--       { (char *)"VImage__find_tboverlap", _wrap_VImage__find_tboverlap, METH_VARARGS, NULL},
--       { (char *)"VImage_global_balance", _wrap_VImage_global_balance, METH_VARARGS, NULL},
--       { (char *)"VImage_global_balancef", _wrap_VImage_global_balancef, METH_VARARGS, NULL},
--       { (char *)"VImage_lrmerge", _wrap_VImage_lrmerge, METH_VARARGS, NULL},
--       { (char *)"VImage_lrmerge1", _wrap_VImage_lrmerge1, METH_VARARGS, NULL},
--       { (char *)"VImage_lrmosaic", _wrap_VImage_lrmosaic, METH_VARARGS, NULL},
--       { (char *)"VImage_lrmosaic1", _wrap_VImage_lrmosaic1, METH_VARARGS, NULL},
--       { (char *)"VImage_match_linear", _wrap_VImage_match_linear, METH_VARARGS, NULL},
--       { (char *)"VImage_match_linear_search", _wrap_VImage_match_linear_search, METH_VARARGS, NULL},
--       { (char *)"VImage_maxpos_subpel", _wrap_VImage_maxpos_subpel, METH_VARARGS, NULL},
--       { (char *)"VImage_remosaic", _wrap_VImage_remosaic, METH_VARARGS, NULL},
--       { (char *)"VImage_tbmerge", _wrap_VImage_tbmerge, METH_VARARGS, NULL},
--       { (char *)"VImage_tbmerge1", _wrap_VImage_tbmerge1, METH_VARARGS, NULL},
--       { (char *)"VImage_tbmosaic", _wrap_VImage_tbmosaic, METH_VARARGS, NULL},
--       { (char *)"VImage_tbmosaic1", _wrap_VImage_tbmosaic1, METH_VARARGS, NULL},
--       { (char *)"VImage_benchmark", _wrap_VImage_benchmark, METH_VARARGS, NULL},
--       { (char *)"VImage_benchmark2", _wrap_VImage_benchmark2, METH_VARARGS, NULL},
--       { (char *)"VImage_benchmarkn", _wrap_VImage_benchmarkn, METH_VARARGS, NULL},
--       { (char *)"VImage_eye", _wrap_VImage_eye, METH_VARARGS, NULL},
--       { (char *)"VImage_grey", _wrap_VImage_grey, METH_VARARGS, NULL},
--       { (char *)"VImage_feye", _wrap_VImage_feye, METH_VARARGS, NULL},
--       { (char *)"VImage_fgrey", _wrap_VImage_fgrey, METH_VARARGS, NULL},
--       { (char *)"VImage_fzone", _wrap_VImage_fzone, METH_VARARGS, NULL},
--       { (char *)"VImage_make_xy", _wrap_VImage_make_xy, METH_VARARGS, NULL},
--       { (char *)"VImage_sines", _wrap_VImage_sines, METH_VARARGS, NULL},
--       { (char *)"VImage_zone", _wrap_VImage_zone, METH_VARARGS, NULL},
--       { (char *)"VImage_rightshift_size", _wrap_VImage_rightshift_size, METH_VARARGS, NULL},
--       { (char *)"VImage_shrink", _wrap_VImage_shrink, METH_VARARGS, NULL},
--       { (char *)"VImage_stretch3", _wrap_VImage_stretch3, METH_VARARGS, NULL},
--       { (char *)"VImage_affinei", _wrap_VImage_affinei, METH_VARARGS, NULL},
--       { (char *)"VImage_affinei_all", _wrap_VImage_affinei_all, METH_VARARGS, NULL},
--       { (char *)"VImage_video_test", _wrap_VImage_video_test, METH_VARARGS, NULL},
--       { (char *)"VImage_video_v4l1", _wrap_VImage_video_v4l1, METH_VARARGS, NULL},
--       { (char *)"VImage_tobuffer", _wrap_VImage_tobuffer, METH_VARARGS, NULL},
--       { (char *)"VImage_frombuffer", _wrap_VImage_frombuffer, METH_VARARGS, NULL},
--       { (char *)"VImage_tostring", _wrap_VImage_tostring, METH_VARARGS, NULL},
--       { (char *)"VImage_fromstring", _wrap_VImage_fromstring, METH_VARARGS, NULL},
--       { (char *)"VImage_swigregister", VImage_swigregister, METH_VARARGS, NULL},
--       { (char *)"im_init_world", _wrap_im_init_world, METH_VARARGS, NULL},
--       { (char *)"im__print_all", _wrap_im__print_all, METH_VARARGS, NULL},
--       { (char *)"im_col_Lab2XYZ", _wrap_im_col_Lab2XYZ, METH_VARARGS, NULL},
--       { NULL, NULL, 0, NULL }
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
--
--static swig_type_info _swigt__p_GType = {"_p_GType", "GType *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_VBuffer = {"_p_VBuffer", "VBuffer *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p__VipsImage = {"_p__VipsImage", "_VipsImage *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_allocator_type = {"_p_allocator_type", "allocator_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_double = {"_p_double", "double *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_float = {"_p_float", "float *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_gboolean = {"_p_gboolean", "gboolean *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_matrix = {"_p_matrix", "matrix *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_p_PyObject = {"_p_p_PyObject", "PyObject **", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_size_t = {"_p_size_t", "size_t *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_size_type = {"_p_size_type", "size_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__allocatorT_double_t = {"_p_std__allocatorT_double_t", "std::vector< double >::allocator_type *|std::allocator< double > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__allocatorT_int_t = {"_p_std__allocatorT_int_t", "std::vector< int >::allocator_type *|std::allocator< int > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__allocatorT_vips__VImage_t = {"_p_std__allocatorT_vips__VImage_t", "std::vector< vips::VImage >::allocator_type *|std::allocator< vips::VImage > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__vectorT__Tp__Alloc_t = {"_p_std__vectorT__Tp__Alloc_t", "std::vector< _Tp,_Alloc > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__vectorT_double_std__allocatorT_double_t_t = {"_p_std__vectorT_double_std__allocatorT_double_t_t", "std::vector< double,std::allocator< double > > *|std::vector< double > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__vectorT_int_std__allocatorT_int_t_t = {"_p_std__vectorT_int_std__allocatorT_int_t_t", "std::vector< int,std::allocator< int > > *|std::vector< int > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t = {"_p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t", "std::vector< vips::VImage > *|std::vector< vips::VImage,std::allocator< vips::VImage > > *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_swig__SwigPyIterator = {"_p_swig__SwigPyIterator", "swig::SwigPyIterator *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VDMask = {"_p_vips__VDMask", "vips::VDMask *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VDisplay = {"_p_vips__VDisplay", "vips::VDisplay *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VError = {"_p_vips__VError", "vips::VError *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VIMask = {"_p_vips__VIMask", "vips::VIMask *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VImage = {"_p_vips__VImage", "vips::VImage *|std::vector< vips::VImage >::value_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0};
--
--static swig_type_info *swig_type_initial[] = {
--  &_swigt__p_GType,
--  &_swigt__p_VBuffer,
--  &_swigt__p__VipsImage,
--  &_swigt__p_allocator_type,
--  &_swigt__p_char,
--  &_swigt__p_difference_type,
--  &_swigt__p_double,
--  &_swigt__p_float,
--  &_swigt__p_gboolean,
--  &_swigt__p_int,
--  &_swigt__p_matrix,
--  &_swigt__p_p_PyObject,
--  &_swigt__p_p_char,
--  &_swigt__p_size_t,
--  &_swigt__p_size_type,
--  &_swigt__p_std__allocatorT_double_t,
--  &_swigt__p_std__allocatorT_int_t,
--  &_swigt__p_std__allocatorT_vips__VImage_t,
--  &_swigt__p_std__invalid_argument,
--  &_swigt__p_std__vectorT__Tp__Alloc_t,
--  &_swigt__p_std__vectorT_double_std__allocatorT_double_t_t,
--  &_swigt__p_std__vectorT_int_std__allocatorT_int_t_t,
--  &_swigt__p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t,
--  &_swigt__p_swig__SwigPyIterator,
--  &_swigt__p_value_type,
--  &_swigt__p_vips__VDMask,
--  &_swigt__p_vips__VDisplay,
--  &_swigt__p_vips__VError,
--  &_swigt__p_vips__VIMask,
--  &_swigt__p_vips__VImage,
--  &_swigt__p_void,
--};
--
--static swig_cast_info _swigc__p_GType[] = {  {&_swigt__p_GType, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_VBuffer[] = {  {&_swigt__p_VBuffer, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p__VipsImage[] = {  {&_swigt__p__VipsImage, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_allocator_type[] = {  {&_swigt__p_allocator_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_difference_type[] = {  {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_double[] = {  {&_swigt__p_double, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_float[] = {  {&_swigt__p_float, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_gboolean[] = {  {&_swigt__p_gboolean, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_int[] = {  {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_matrix[] = {  {&_swigt__p_matrix, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_p_PyObject[] = {  {&_swigt__p_p_PyObject, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_p_char[] = {  {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_size_t[] = {  {&_swigt__p_size_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_size_type[] = {  {&_swigt__p_size_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__allocatorT_double_t[] = {  {&_swigt__p_std__allocatorT_double_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__allocatorT_int_t[] = {  {&_swigt__p_std__allocatorT_int_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__allocatorT_vips__VImage_t[] = {  {&_swigt__p_std__allocatorT_vips__VImage_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__vectorT__Tp__Alloc_t[] = {  {&_swigt__p_std__vectorT__Tp__Alloc_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__vectorT_double_std__allocatorT_double_t_t[] = {  {&_swigt__p_std__vectorT_double_std__allocatorT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__vectorT_int_std__allocatorT_int_t_t[] = {  {&_swigt__p_std__vectorT_int_std__allocatorT_int_t_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t[] = {  {&_swigt__p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_swig__SwigPyIterator[] = {  {&_swigt__p_swig__SwigPyIterator, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_value_type[] = {  {&_swigt__p_value_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VDMask[] = {  {&_swigt__p_vips__VDMask, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VDisplay[] = {  {&_swigt__p_vips__VDisplay, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VError[] = {  {&_swigt__p_vips__VError, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VIMask[] = {  {&_swigt__p_vips__VIMask, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VImage[] = {  {&_swigt__p_vips__VImage, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_void[] = {  {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
--
--static swig_cast_info *swig_cast_initial[] = {
--  _swigc__p_GType,
--  _swigc__p_VBuffer,
--  _swigc__p__VipsImage,
--  _swigc__p_allocator_type,
--  _swigc__p_char,
--  _swigc__p_difference_type,
--  _swigc__p_double,
--  _swigc__p_float,
--  _swigc__p_gboolean,
--  _swigc__p_int,
--  _swigc__p_matrix,
--  _swigc__p_p_PyObject,
--  _swigc__p_p_char,
--  _swigc__p_size_t,
--  _swigc__p_size_type,
--  _swigc__p_std__allocatorT_double_t,
--  _swigc__p_std__allocatorT_int_t,
--  _swigc__p_std__allocatorT_vips__VImage_t,
--  _swigc__p_std__invalid_argument,
--  _swigc__p_std__vectorT__Tp__Alloc_t,
--  _swigc__p_std__vectorT_double_std__allocatorT_double_t_t,
--  _swigc__p_std__vectorT_int_std__allocatorT_int_t_t,
--  _swigc__p_std__vectorT_vips__VImage_std__allocatorT_vips__VImage_t_t,
--  _swigc__p_swig__SwigPyIterator,
--  _swigc__p_value_type,
--  _swigc__p_vips__VDMask,
--  _swigc__p_vips__VDisplay,
--  _swigc__p_vips__VError,
--  _swigc__p_vips__VIMask,
--  _swigc__p_vips__VImage,
--  _swigc__p_void,
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
--
--static swig_const_info swig_const_table[] = {
--{0, 0, 0, 0.0, 0, 0}};
--
--#ifdef __cplusplus
--}
--#endif
--/* -----------------------------------------------------------------------------
-- * Type initialization:
-- * This problem is tough by the requirement that no dynamic 
-- * memory is used. Also, since swig_type_info structures store pointers to 
-- * swig_cast_info structures and swig_cast_info structures store pointers back
-- * to swig_type_info structures, we need some lookup code at initialization. 
-- * The idea is that swig generates all the structures that are needed. 
-- * The runtime then collects these partially filled structures. 
-- * The SWIG_InitializeModule function takes these initial arrays out of 
-- * swig_module, and does all the lookup, filling in the swig_module.types
-- * array with the correct data and linking the correct swig_cast_info
-- * structures together.
-- *
-- * The generated swig_type_info structures are assigned staticly to an initial 
-- * array. We just loop through that array, and handle each type individually.
-- * First we lookup if this type has been already loaded, and if so, use the
-- * loaded structure instead of the generated one. Then we have to fill in the
-- * cast linked list. The cast data is initially stored in something like a
-- * two-dimensional array. Each row corresponds to a type (there are the same
-- * number of rows as there are in the swig_type_initial array). Each entry in
-- * a column is one of the swig_cast_info structures for that type.
-- * The cast_initial array is actually an array of arrays, because each row has
-- * a variable number of columns. So to actually build the cast linked list,
-- * we find the array of casts associated with the type, and loop through it 
-- * adding the casts to the list. The one last trick we need to do is making
-- * sure the type pointer in the swig_cast_info struct is correct.
-- *
-- * First off, we lookup the cast->type name to see if it is already loaded. 
-- * There are three cases to handle:
-- *  1) If the cast->type has already been loaded AND the type we are adding
-- *     casting info to has not been loaded (it is in this module), THEN we
-- *     replace the cast->type pointer with the type pointer that has already
-- *     been loaded.
-- *  2) If BOTH types (the one we are adding casting info to, and the 
-- *     cast->type) are loaded, THEN the cast info has already been loaded by
-- *     the previous module so we just ignore it.
-- *  3) Finally, if cast->type has not already been loaded, then we add that
-- *     swig_cast_info to the linked list (because the cast->type) pointer will
-- *     be correct.
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#if 0
--} /* c-mode */
--#endif
--#endif
--
--#if 0
--#define SWIGRUNTIME_DEBUG
--#endif
--
--
--SWIGRUNTIME void
--SWIG_InitializeModule(void *clientdata) {
--  size_t i;
--  swig_module_info *module_head, *iter;
--  int found, init;
--  
--  /* check to see if the circular list has been setup, if not, set it up */
--  if (swig_module.next==0) {
--    /* Initialize the swig_module */
--    swig_module.type_initial = swig_type_initial;
--    swig_module.cast_initial = swig_cast_initial;
--    swig_module.next = &swig_module;
--    init = 1;
--  } else {
--    init = 0;
--  }
--  
--  /* Try and load any already created modules */
--  module_head = SWIG_GetModule(clientdata);
--  if (!module_head) {
--    /* This is the first module loaded for this interpreter */
--    /* so set the swig module into the interpreter */
--    SWIG_SetModule(clientdata, &swig_module);
--    module_head = &swig_module;
--  } else {
--    /* the interpreter has loaded a SWIG module, but has it loaded this one? */
--    found=0;
--    iter=module_head;
--    do {
--      if (iter==&swig_module) {
--        found=1;
--        break;
--      }
--      iter=iter->next;
--    } while (iter!= module_head);
--    
--    /* if the is found in the list, then all is done and we may leave */
--    if (found) return;
--    /* otherwise we must add out module into the list */
--    swig_module.next = module_head->next;
--    module_head->next = &swig_module;
--  }
--  
--  /* When multiple interpeters are used, a module could have already been initialized in
--       a different interpreter, but not yet have a pointer in this interpreter.
--       In this case, we do not want to continue adding types... everything should be
--       set up already */
--  if (init == 0) return;
--  
--  /* Now work on filling in swig_module.types */
--#ifdef SWIGRUNTIME_DEBUG
--  printf("SWIG_InitializeModule: size %d\n", swig_module.size);
--#endif
--  for (i = 0; i < swig_module.size; ++i) {
--    swig_type_info *type = 0;
--    swig_type_info *ret;
--    swig_cast_info *cast;
--    
--#ifdef SWIGRUNTIME_DEBUG
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--#endif
--    
--    /* if there is another module already loaded */
--    if (swig_module.next != &swig_module) {
--      type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
--    }
--    if (type) {
--      /* Overwrite clientdata field */
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: found type %s\n", type->name);
--#endif
--      if (swig_module.type_initial[i]->clientdata) {
--        type->clientdata = swig_module.type_initial[i]->clientdata;
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
--#endif
--      }
--    } else {
--      type = swig_module.type_initial[i];
--    }
--    
--    /* Insert casting types */
--    cast = swig_module.cast_initial[i];
--    while (cast->type) {
--      /* Don't need to add information already in the list */
--      ret = 0;
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
--#endif
--      if (swig_module.next != &swig_module) {
--        ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
--#ifdef SWIGRUNTIME_DEBUG
--        if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
--#endif
--      }
--      if (ret) {
--        if (type == swig_module.type_initial[i]) {
--#ifdef SWIGRUNTIME_DEBUG
--          printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
--#endif
--          cast->type = ret;
--          ret = 0;
--        } else {
--          /* Check for casting already in the list */
--          swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
--#ifdef SWIGRUNTIME_DEBUG
--          if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
--#endif
--          if (!ocast) ret = 0;
--        }
--      }
--      
--      if (!ret) {
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
--#endif
--        if (type->cast) {
--          type->cast->prev = cast;
--          cast->next = type->cast;
--        }
--        type->cast = cast;
--      }
--      cast++;
--    }
--    /* Set entry in modules->types array equal to the type */
--    swig_module.types[i] = type;
--  }
--  swig_module.types[i] = 0;
--  
--#ifdef SWIGRUNTIME_DEBUG
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--  for (i = 0; i < swig_module.size; ++i) {
--    int j = 0;
--    swig_cast_info *cast = swig_module.cast_initial[i];
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--    while (cast->type) {
--      printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
--      cast++;
--      ++j;
--    }
--    printf("---- Total casts: %d\n",j);
--  }
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--#endif
--}
--
--/* This function will propagate the clientdata field of type to
--* any new swig_type_info structures that have been added into the list
--* of equivalent types.  It is like calling
--* SWIG_TypeClientData(type, clientdata) a second time.
--*/
--SWIGRUNTIME void
--SWIG_PropagateClientData(void) {
--  size_t i;
--  swig_cast_info *equiv;
--  static int init_run = 0;
--  
--  if (init_run) return;
--  init_run = 1;
--  
--  for (i = 0; i < swig_module.size; i++) {
--    if (swig_module.types[i]->clientdata) {
--      equiv = swig_module.types[i]->cast;
--      while (equiv) {
--        if (!equiv->converter) {
--          if (equiv->type && !equiv->type->clientdata)
--          SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
--        }
--        equiv = equiv->next;
--      }
--    }
--  }
--}
--
--#ifdef __cplusplus
--#if 0
--{
--  /* c-mode */
--#endif
--}
--#endif
--
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--  
--  /* Python-specific SWIG API */
--#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
--#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
--#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
--  
--  /* -----------------------------------------------------------------------------
--   * global variable support code.
--   * ----------------------------------------------------------------------------- */
--  
--  typedef struct swig_globalvar {
--    char       *name;                  /* Name of global variable */
--    PyObject *(*get_attr)(void);       /* Return the current value */
--    int       (*set_attr)(PyObject *); /* Set the value */
--    struct swig_globalvar *next;
--  } swig_globalvar;
--  
--  typedef struct swig_varlinkobject {
--    PyObject_HEAD
--    swig_globalvar *vars;
--  } swig_varlinkobject;
--  
--  SWIGINTERN PyObject *
--  swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
--#if PY_VERSION_HEX >= 0x03000000
--    return PyUnicode_InternFromString("<Swig global variables>");
--#else
--    return PyString_FromString("<Swig global variables>");
--#endif
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_str(swig_varlinkobject *v) {
--#if PY_VERSION_HEX >= 0x03000000
--    PyObject *str = PyUnicode_InternFromString("(");
--    PyObject *tail;
--    PyObject *joined;
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      tail = PyUnicode_FromString(var->name);
--      joined = PyUnicode_Concat(str, tail);
--      Py_DecRef(str);
--      Py_DecRef(tail);
--      str = joined;
--      if (var->next) {
--        tail = PyUnicode_InternFromString(", ");
--        joined = PyUnicode_Concat(str, tail);
--        Py_DecRef(str);
--        Py_DecRef(tail);
--        str = joined;
--      }
--    }
--    tail = PyUnicode_InternFromString(")");
--    joined = PyUnicode_Concat(str, tail);
--    Py_DecRef(str);
--    Py_DecRef(tail);
--    str = joined;
--#else
--    PyObject *str = PyString_FromString("(");
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      PyString_ConcatAndDel(&str,PyString_FromString(var->name));
--      if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
--    }
--    PyString_ConcatAndDel(&str,PyString_FromString(")"));
--#endif
--    return str;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
--    char *tmp;
--    PyObject *str = swig_varlink_str(v);
--    fprintf(fp,"Swig global variables ");
--    fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(str);
--    return 0;
--  }
--  
--  SWIGINTERN void
--  swig_varlink_dealloc(swig_varlinkobject *v) {
--    swig_globalvar *var = v->vars;
--    while (var) {
--      swig_globalvar *n = var->next;
--      free(var->name);
--      free(var);
--      var = n;
--    }
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_getattr(swig_varlinkobject *v, char *n) {
--    PyObject *res = NULL;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->get_attr)();
--        break;
--      }
--      var = var->next;
--    }
--    if (res == NULL && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
--    int res = 1;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->set_attr)(p);
--        break;
--      }
--      var = var->next;
--    }
--    if (res == 1 && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN PyTypeObject*
--  swig_varlink_type(void) {
--    static char varlink__doc__[] = "Swig var link object";
--    static PyTypeObject varlink_type;
--    static int type_init = 0;
--    if (!type_init) {
--      const PyTypeObject tmp = {
--        /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--        PyVarObject_HEAD_INIT(NULL, 0)
--#else
--        PyObject_HEAD_INIT(NULL)
--        0,                                  /* ob_size */
--#endif
--        (char *)"swigvarlink",              /* tp_name */
--        sizeof(swig_varlinkobject),         /* tp_basicsize */
--        0,                                  /* tp_itemsize */
--        (destructor) swig_varlink_dealloc,  /* tp_dealloc */
--        (printfunc) swig_varlink_print,     /* tp_print */
--        (getattrfunc) swig_varlink_getattr, /* tp_getattr */
--        (setattrfunc) swig_varlink_setattr, /* tp_setattr */
--        0,                                  /* tp_compare */
--        (reprfunc) swig_varlink_repr,       /* tp_repr */
--        0,                                  /* tp_as_number */
--        0,                                  /* tp_as_sequence */
--        0,                                  /* tp_as_mapping */
--        0,                                  /* tp_hash */
--        0,                                  /* tp_call */
--        (reprfunc) swig_varlink_str,        /* tp_str */
--        0,                                  /* tp_getattro */
--        0,                                  /* tp_setattro */
--        0,                                  /* tp_as_buffer */
--        0,                                  /* tp_flags */
--        varlink__doc__,                     /* tp_doc */
--        0,                                  /* tp_traverse */
--        0,                                  /* tp_clear */
--        0,                                  /* tp_richcompare */
--        0,                                  /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--        0,                                  /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--        0,                                  /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--        0,0,0,0                             /* tp_alloc -> tp_next */
--#endif
--      };
--      varlink_type = tmp;
--      type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--      varlink_type.ob_type = &PyType_Type;
--#else
--      if (PyType_Ready(&varlink_type) < 0)
--      return NULL;
--#endif
--    }
--    return &varlink_type;
--  }
--  
--  /* Create a variable linking object for use later */
--  SWIGINTERN PyObject *
--  SWIG_Python_newvarlink(void) {
--    swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
--    if (result) {
--      result->vars = 0;
--    }
--    return ((PyObject*) result);
--  }
--  
--  SWIGINTERN void 
--  SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
--    swig_varlinkobject *v = (swig_varlinkobject *) p;
--    swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
--    if (gv) {
--      size_t size = strlen(name)+1;
--      gv->name = (char *)malloc(size);
--      if (gv->name) {
--        strncpy(gv->name,name,size);
--        gv->get_attr = get_attr;
--        gv->set_attr = set_attr;
--        gv->next = v->vars;
--      }
--    }
--    v->vars = gv;
--  }
--  
--  SWIGINTERN PyObject *
--  SWIG_globals(void) {
--    static PyObject *_SWIG_globals = 0; 
--    if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();  
--    return _SWIG_globals;
--  }
--  
--  /* -----------------------------------------------------------------------------
--   * constants/methods manipulation
--   * ----------------------------------------------------------------------------- */
--  
--  /* Install Constants */
--  SWIGINTERN void
--  SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
--    PyObject *obj = 0;
--    size_t i;
--    for (i = 0; constants[i].type; ++i) {
--      switch(constants[i].type) {
--      case SWIG_PY_POINTER:
--        obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
--        break;
--      case SWIG_PY_BINARY:
--        obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
--        break;
--      default:
--        obj = 0;
--        break;
--      }
--      if (obj) {
--        PyDict_SetItemString(d, constants[i].name, obj);
--        Py_DECREF(obj);
--      }
--    }
--  }
--  
--  /* -----------------------------------------------------------------------------*/
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  /* -----------------------------------------------------------------------------*/
--  
--  SWIGINTERN void
--  SWIG_Python_FixMethods(PyMethodDef *methods,
--    swig_const_info *const_table,
--    swig_type_info **types,
--    swig_type_info **types_initial) {
--    size_t i;
--    for (i = 0; methods[i].ml_name; ++i) {
--      const char *c = methods[i].ml_doc;
--      if (c && (c = strstr(c, "swig_ptr: "))) {
--        int j;
--        swig_const_info *ci = 0;
--        const char *name = c + 10;
--        for (j = 0; const_table[j].type; ++j) {
--          if (strncmp(const_table[j].name, name, 
--              strlen(const_table[j].name)) == 0) {
--            ci = &(const_table[j]);
--            break;
--          }
--        }
--        if (ci) {
--          void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
--          if (ptr) {
--            size_t shift = (ci->ptype) - types;
--            swig_type_info *ty = types_initial[shift];
--            size_t ldoc = (c - methods[i].ml_doc);
--            size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
--            char *ndoc = (char*)malloc(ldoc + lptr + 10);
--            if (ndoc) {
--              char *buff = ndoc;
--              strncpy(buff, methods[i].ml_doc, ldoc);
--              buff += ldoc;
--              strncpy(buff, "swig_ptr: ", 10);
--              buff += 10;
--              SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
--              methods[i].ml_doc = ndoc;
--            }
--          }
--        }
--      }
--    }
--  } 
--  
--#ifdef __cplusplus
--}
--#endif
--
--/* -----------------------------------------------------------------------------*
-- *  Partial Init method
-- * -----------------------------------------------------------------------------*/
--
--#ifdef __cplusplus
--extern "C"
--#endif
--
--SWIGEXPORT 
--#if PY_VERSION_HEX >= 0x03000000
--PyObject*
--#else
--void
--#endif
--SWIG_init(void) {
--  PyObject *m, *d, *md;
--#if PY_VERSION_HEX >= 0x03000000
--  static struct PyModuleDef SWIG_module = {
--# if PY_VERSION_HEX >= 0x03020000
--    PyModuleDef_HEAD_INIT,
--# else
--    {
--      PyObject_HEAD_INIT(NULL)
--      NULL, /* m_init */
--      0,    /* m_index */
--      NULL, /* m_copy */
--    },
--# endif
--    (char *) SWIG_name,
--    NULL,
--    -1,
--    SwigMethods,
--    NULL,
--    NULL,
--    NULL,
--    NULL
--  };
--#endif
--  
--#if defined(SWIGPYTHON_BUILTIN)
--  static SwigPyClientData SwigPyObject_clientdata = {
--    0, 0, 0, 0, 0, 0, 0
--  };
--  static PyGetSetDef this_getset_def = {
--    (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
--  };
--  static SwigPyGetSet thisown_getset_closure = {
--    (PyCFunction) SwigPyObject_own,
--    (PyCFunction) SwigPyObject_own
--  };
--  static PyGetSetDef thisown_getset_def = {
--    (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
--  };
--  PyObject *metatype_args;
--  PyTypeObject *builtin_pytype;
--  int builtin_base_count;
--  swig_type_info *builtin_basetype;
--  PyObject *tuple;
--  PyGetSetDescrObject *static_getset;
--  PyTypeObject *metatype;
--  SwigPyClientData *cd;
--  PyObject *public_interface, *public_symbol;
--  PyObject *this_descr;
--  PyObject *thisown_descr;
--  int i;
--  
--  (void)builtin_pytype;
--  (void)builtin_base_count;
--  (void)builtin_basetype;
--  (void)tuple;
--  (void)static_getset;
--  
--  /* metatype is used to implement static member variables. */
--  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
--  assert(metatype_args);
--  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
--  assert(metatype);
--  Py_DECREF(metatype_args);
--  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
--  assert(PyType_Ready(metatype) >= 0);
--#endif
--  
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  m = PyModule_Create(&SWIG_module);
--#else
--  m = Py_InitModule((char *) SWIG_name, SwigMethods);
--#endif
--  md = d = PyModule_GetDict(m);
--  (void)md;
--  
--  SWIG_InitializeModule(0);
--  
--#ifdef SWIGPYTHON_BUILTIN
--  SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
--  assert(SwigPyObject_stype);
--  cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--  if (!cd) {
--    SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
--    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
--  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
--    PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
--# if PY_VERSION_HEX >= 0x03000000
--    return NULL;
--# else
--    return;
--# endif
--  }
--  
--  /* All objects have a 'this' attribute */
--  this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
--  (void)this_descr;
--  
--  /* All objects have a 'thisown' attribute */
--  thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
--  (void)thisown_descr;
--  
--  public_interface = PyList_New(0);
--  public_symbol = 0;
--  (void)public_symbol;
--  
--  PyDict_SetItemString(md, "__all__", public_interface);
--  Py_DECREF(public_interface);
--  for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
--  for (i = 0; swig_const_table[i].name != 0; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
--#endif
--  
--  SWIG_InstallConstants(d,swig_const_table);
--  
--  SWIG_Python_SetConstant(d, "VImage_MULTIBAND",SWIG_From_int(static_cast< int >(vips::VImage::MULTIBAND)));
--  SWIG_Python_SetConstant(d, "VImage_B_W",SWIG_From_int(static_cast< int >(vips::VImage::B_W)));
--  SWIG_Python_SetConstant(d, "VImage_LUMINACE",SWIG_From_int(static_cast< int >(vips::VImage::LUMINACE)));
--  SWIG_Python_SetConstant(d, "VImage_XRAY",SWIG_From_int(static_cast< int >(vips::VImage::XRAY)));
--  SWIG_Python_SetConstant(d, "VImage_IR",SWIG_From_int(static_cast< int >(vips::VImage::IR)));
--  SWIG_Python_SetConstant(d, "VImage_YUV",SWIG_From_int(static_cast< int >(vips::VImage::YUV)));
--  SWIG_Python_SetConstant(d, "VImage_RED_ONLY",SWIG_From_int(static_cast< int >(vips::VImage::RED_ONLY)));
--  SWIG_Python_SetConstant(d, "VImage_GREEN_ONLY",SWIG_From_int(static_cast< int >(vips::VImage::GREEN_ONLY)));
--  SWIG_Python_SetConstant(d, "VImage_BLUE_ONLY",SWIG_From_int(static_cast< int >(vips::VImage::BLUE_ONLY)));
--  SWIG_Python_SetConstant(d, "VImage_POWER_SPECTRUM",SWIG_From_int(static_cast< int >(vips::VImage::POWER_SPECTRUM)));
--  SWIG_Python_SetConstant(d, "VImage_HISTOGRAM",SWIG_From_int(static_cast< int >(vips::VImage::HISTOGRAM)));
--  SWIG_Python_SetConstant(d, "VImage_LUT",SWIG_From_int(static_cast< int >(vips::VImage::LUT)));
--  SWIG_Python_SetConstant(d, "VImage_XYZ",SWIG_From_int(static_cast< int >(vips::VImage::XYZ)));
--  SWIG_Python_SetConstant(d, "VImage_LAB",SWIG_From_int(static_cast< int >(vips::VImage::LAB)));
--  SWIG_Python_SetConstant(d, "VImage_CMC",SWIG_From_int(static_cast< int >(vips::VImage::CMC)));
--  SWIG_Python_SetConstant(d, "VImage_CMYK",SWIG_From_int(static_cast< int >(vips::VImage::CMYK)));
--  SWIG_Python_SetConstant(d, "VImage_LABQ",SWIG_From_int(static_cast< int >(vips::VImage::LABQ)));
--  SWIG_Python_SetConstant(d, "VImage_RGB",SWIG_From_int(static_cast< int >(vips::VImage::RGB)));
--  SWIG_Python_SetConstant(d, "VImage_UCS",SWIG_From_int(static_cast< int >(vips::VImage::UCS)));
--  SWIG_Python_SetConstant(d, "VImage_LCH",SWIG_From_int(static_cast< int >(vips::VImage::LCH)));
--  SWIG_Python_SetConstant(d, "VImage_LABS",SWIG_From_int(static_cast< int >(vips::VImage::LABS)));
--  SWIG_Python_SetConstant(d, "VImage_sRGB",SWIG_From_int(static_cast< int >(vips::VImage::sRGB)));
--  SWIG_Python_SetConstant(d, "VImage_YXY",SWIG_From_int(static_cast< int >(vips::VImage::YXY)));
--  SWIG_Python_SetConstant(d, "VImage_FOURIER",SWIG_From_int(static_cast< int >(vips::VImage::FOURIER)));
--  SWIG_Python_SetConstant(d, "VImage_RGB16",SWIG_From_int(static_cast< int >(vips::VImage::RGB16)));
--  SWIG_Python_SetConstant(d, "VImage_GREY16",SWIG_From_int(static_cast< int >(vips::VImage::GREY16)));
--  SWIG_Python_SetConstant(d, "VImage_FMTNOTSET",SWIG_From_int(static_cast< int >(vips::VImage::FMTNOTSET)));
--  SWIG_Python_SetConstant(d, "VImage_FMTUCHAR",SWIG_From_int(static_cast< int >(vips::VImage::FMTUCHAR)));
--  SWIG_Python_SetConstant(d, "VImage_FMTCHAR",SWIG_From_int(static_cast< int >(vips::VImage::FMTCHAR)));
--  SWIG_Python_SetConstant(d, "VImage_FMTUSHORT",SWIG_From_int(static_cast< int >(vips::VImage::FMTUSHORT)));
--  SWIG_Python_SetConstant(d, "VImage_FMTSHORT",SWIG_From_int(static_cast< int >(vips::VImage::FMTSHORT)));
--  SWIG_Python_SetConstant(d, "VImage_FMTUINT",SWIG_From_int(static_cast< int >(vips::VImage::FMTUINT)));
--  SWIG_Python_SetConstant(d, "VImage_FMTINT",SWIG_From_int(static_cast< int >(vips::VImage::FMTINT)));
--  SWIG_Python_SetConstant(d, "VImage_FMTFLOAT",SWIG_From_int(static_cast< int >(vips::VImage::FMTFLOAT)));
--  SWIG_Python_SetConstant(d, "VImage_FMTCOMPLEX",SWIG_From_int(static_cast< int >(vips::VImage::FMTCOMPLEX)));
--  SWIG_Python_SetConstant(d, "VImage_FMTDOUBLE",SWIG_From_int(static_cast< int >(vips::VImage::FMTDOUBLE)));
--  SWIG_Python_SetConstant(d, "VImage_FMTDPCOMPLEX",SWIG_From_int(static_cast< int >(vips::VImage::FMTDPCOMPLEX)));
--  SWIG_Python_SetConstant(d, "VImage_NOCODING",SWIG_From_int(static_cast< int >(vips::VImage::NOCODING)));
--  SWIG_Python_SetConstant(d, "VImage_COLQUANT",SWIG_From_int(static_cast< int >(vips::VImage::COLQUANT)));
--  SWIG_Python_SetConstant(d, "VImage_LABPACK",SWIG_From_int(static_cast< int >(vips::VImage::LABPACK)));
--  SWIG_Python_SetConstant(d, "VImage_LABPACK_COMPRESSED",SWIG_From_int(static_cast< int >(vips::VImage::LABPACK_COMPRESSED)));
--  SWIG_Python_SetConstant(d, "VImage_RGB_COMPRESSED",SWIG_From_int(static_cast< int >(vips::VImage::RGB_COMPRESSED)));
--  SWIG_Python_SetConstant(d, "VImage_LUM_COMPRESSED",SWIG_From_int(static_cast< int >(vips::VImage::LUM_COMPRESSED)));
--  SWIG_Python_SetConstant(d, "VImage_RAD",SWIG_From_int(static_cast< int >(vips::VImage::RAD)));
--  SWIG_Python_SetConstant(d, "VImage_NO_COMPRESSION",SWIG_From_int(static_cast< int >(vips::VImage::NO_COMPRESSION)));
--  SWIG_Python_SetConstant(d, "VImage_TCSF_COMPRESSION",SWIG_From_int(static_cast< int >(vips::VImage::TCSF_COMPRESSION)));
--  SWIG_Python_SetConstant(d, "VImage_JPEG_COMPRESSION",SWIG_From_int(static_cast< int >(vips::VImage::JPEG_COMPRESSION)));
--  
--  {
--    Args *args;
--    
--    args = args_new ();
--    
--#ifdef DEBUG
--    printf ("on startup:\n");
--    args_print (args);
--#endif /*DEBUG*/
--    
--    if (im_init_world (args->argv[0])) {
--      args_free (args);
--      vips_fatal ("can't initialise module vips");
--    }
--    
--    /* Now parse any GOptions. 
--       */
--    GError *error = NULL;
--    GOptionContext *context;
--    
--    context = g_option_context_new ("- vips");
--    g_option_context_add_group (context, im_get_option_group());
--    
--    g_option_context_set_ignore_unknown_options (context, TRUE);
--    if (!g_option_context_parse (context, 
--        &args->argc, &args->argv, &error)) {
--      g_option_context_free (context);
--      args_free (args);
--      im_error ("vipsmodule", "%s", error->message);
--      g_error_free (error);
--      vips_fatal ("can't initialise module vips");
--    }
--    g_option_context_free (context);
--    
--#ifdef DEBUG
--    printf ("after parse:\n");
--    args_print (args);
--#endif /*DEBUG*/
--    
--    // Write (possibly) modified argc/argv back again.
--    if (args->argv) 
--    PySys_SetArgv (args->argc, args->argv);
--    
--    args_free (args);
--  }
--  
--#if PY_VERSION_HEX >= 0x03000000
--  return m;
--#else
--  return;
--#endif
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VImage.py vips-7.38.5/swig/vipsCC/VImage.py
---- vips-7.38.5-vanilla/swig/vipsCC/VImage.py  2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VImage.py  1969-12-31 19:00:00.000000000 -0500
-@@ -1,919 +0,0 @@
--# This file was automatically generated by SWIG (http://www.swig.org).
--# Version 2.0.10
--#
--# Do not make changes to this file unless you know what you are doing--modify
--# the SWIG interface file instead.
--
--
--
--from sys import version_info
--if version_info >= (2,6,0):
--    def swig_import_helper():
--        from os.path import dirname
--        import imp
--        fp = None
--        try:
--            fp, pathname, description = imp.find_module('vimagemodule', [dirname(__file__)])
--        except ImportError:
--            import vimagemodule
--            return vimagemodule
--        if fp is not None:
--            try:
--                _mod = imp.load_module('vimagemodule', fp, pathname, description)
--            finally:
--                fp.close()
--            return _mod
--    vimagemodule = swig_import_helper()
--    del swig_import_helper
--else:
--    import vimagemodule
--del version_info
--try:
--    _swig_property = property
--except NameError:
--    pass # Python < 2.2 doesn't have 'property'.
--def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
--    if (name == "thisown"): return self.this.own(value)
--    if (name == "this"):
--        if type(value).__name__ == 'SwigPyObject':
--            self.__dict__[name] = value
--            return
--    method = class_type.__swig_setmethods__.get(name,None)
--    if method: return method(self,value)
--    if (not static):
--        self.__dict__[name] = value
--    else:
--        raise AttributeError("You cannot add attributes to %s" % self)
--
--def _swig_setattr(self,class_type,name,value):
--    return _swig_setattr_nondynamic(self,class_type,name,value,0)
--
--def _swig_getattr(self,class_type,name):
--    if (name == "thisown"): return self.this.own()
--    method = class_type.__swig_getmethods__.get(name,None)
--    if method: return method(self)
--    raise AttributeError(name)
--
--def _swig_repr(self):
--    try: strthis = "proxy of " + self.this.__repr__()
--    except: strthis = ""
--    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
--
--try:
--    _object = object
--    _newclass = 1
--except AttributeError:
--    class _object : pass
--    _newclass = 0
--
--
--class SwigPyIterator(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, SwigPyIterator, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, SwigPyIterator, name)
--    def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract")
--    __repr__ = _swig_repr
--    __swig_destroy__ = vimagemodule.delete_SwigPyIterator
--    __del__ = lambda self : None;
--    def value(self): return vimagemodule.SwigPyIterator_value(self)
--    def incr(self, n=1): return vimagemodule.SwigPyIterator_incr(self, n)
--    def decr(self, n=1): return vimagemodule.SwigPyIterator_decr(self, n)
--    def distance(self, *args): return vimagemodule.SwigPyIterator_distance(self, *args)
--    def equal(self, *args): return vimagemodule.SwigPyIterator_equal(self, *args)
--    def copy(self): return vimagemodule.SwigPyIterator_copy(self)
--    def next(self): return vimagemodule.SwigPyIterator_next(self)
--    def __next__(self): return vimagemodule.SwigPyIterator___next__(self)
--    def previous(self): return vimagemodule.SwigPyIterator_previous(self)
--    def advance(self, *args): return vimagemodule.SwigPyIterator_advance(self, *args)
--    def __eq__(self, *args): return vimagemodule.SwigPyIterator___eq__(self, *args)
--    def __ne__(self, *args): return vimagemodule.SwigPyIterator___ne__(self, *args)
--    def __iadd__(self, *args): return vimagemodule.SwigPyIterator___iadd__(self, *args)
--    def __isub__(self, *args): return vimagemodule.SwigPyIterator___isub__(self, *args)
--    def __add__(self, *args): return vimagemodule.SwigPyIterator___add__(self, *args)
--    def __sub__(self, *args): return vimagemodule.SwigPyIterator___sub__(self, *args)
--    def __iter__(self): return self
--SwigPyIterator_swigregister = vimagemodule.SwigPyIterator_swigregister
--SwigPyIterator_swigregister(SwigPyIterator)
--
--import VError
--import VMask
--import VDisplay
--class IntVector(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, IntVector, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, IntVector, name)
--    __repr__ = _swig_repr
--    def iterator(self): return vimagemodule.IntVector_iterator(self)
--    def __iter__(self): return self.iterator()
--    def __nonzero__(self): return vimagemodule.IntVector___nonzero__(self)
--    def __bool__(self): return vimagemodule.IntVector___bool__(self)
--    def __len__(self): return vimagemodule.IntVector___len__(self)
--    def pop(self): return vimagemodule.IntVector_pop(self)
--    def __getslice__(self, *args): return vimagemodule.IntVector___getslice__(self, *args)
--    def __setslice__(self, *args): return vimagemodule.IntVector___setslice__(self, *args)
--    def __delslice__(self, *args): return vimagemodule.IntVector___delslice__(self, *args)
--    def __delitem__(self, *args): return vimagemodule.IntVector___delitem__(self, *args)
--    def __getitem__(self, *args): return vimagemodule.IntVector___getitem__(self, *args)
--    def __setitem__(self, *args): return vimagemodule.IntVector___setitem__(self, *args)
--    def append(self, *args): return vimagemodule.IntVector_append(self, *args)
--    def empty(self): return vimagemodule.IntVector_empty(self)
--    def size(self): return vimagemodule.IntVector_size(self)
--    def clear(self): return vimagemodule.IntVector_clear(self)
--    def swap(self, *args): return vimagemodule.IntVector_swap(self, *args)
--    def get_allocator(self): return vimagemodule.IntVector_get_allocator(self)
--    def begin(self): return vimagemodule.IntVector_begin(self)
--    def end(self): return vimagemodule.IntVector_end(self)
--    def rbegin(self): return vimagemodule.IntVector_rbegin(self)
--    def rend(self): return vimagemodule.IntVector_rend(self)
--    def pop_back(self): return vimagemodule.IntVector_pop_back(self)
--    def erase(self, *args): return vimagemodule.IntVector_erase(self, *args)
--    def __init__(self, *args): 
--        this = vimagemodule.new_IntVector(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def push_back(self, *args): return vimagemodule.IntVector_push_back(self, *args)
--    def front(self): return vimagemodule.IntVector_front(self)
--    def back(self): return vimagemodule.IntVector_back(self)
--    def assign(self, *args): return vimagemodule.IntVector_assign(self, *args)
--    def resize(self, *args): return vimagemodule.IntVector_resize(self, *args)
--    def insert(self, *args): return vimagemodule.IntVector_insert(self, *args)
--    def reserve(self, *args): return vimagemodule.IntVector_reserve(self, *args)
--    def capacity(self): return vimagemodule.IntVector_capacity(self)
--    __swig_destroy__ = vimagemodule.delete_IntVector
--    __del__ = lambda self : None;
--IntVector_swigregister = vimagemodule.IntVector_swigregister
--IntVector_swigregister(IntVector)
--
--class DoubleVector(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, DoubleVector, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, DoubleVector, name)
--    __repr__ = _swig_repr
--    def iterator(self): return vimagemodule.DoubleVector_iterator(self)
--    def __iter__(self): return self.iterator()
--    def __nonzero__(self): return vimagemodule.DoubleVector___nonzero__(self)
--    def __bool__(self): return vimagemodule.DoubleVector___bool__(self)
--    def __len__(self): return vimagemodule.DoubleVector___len__(self)
--    def pop(self): return vimagemodule.DoubleVector_pop(self)
--    def __getslice__(self, *args): return vimagemodule.DoubleVector___getslice__(self, *args)
--    def __setslice__(self, *args): return vimagemodule.DoubleVector___setslice__(self, *args)
--    def __delslice__(self, *args): return vimagemodule.DoubleVector___delslice__(self, *args)
--    def __delitem__(self, *args): return vimagemodule.DoubleVector___delitem__(self, *args)
--    def __getitem__(self, *args): return vimagemodule.DoubleVector___getitem__(self, *args)
--    def __setitem__(self, *args): return vimagemodule.DoubleVector___setitem__(self, *args)
--    def append(self, *args): return vimagemodule.DoubleVector_append(self, *args)
--    def empty(self): return vimagemodule.DoubleVector_empty(self)
--    def size(self): return vimagemodule.DoubleVector_size(self)
--    def clear(self): return vimagemodule.DoubleVector_clear(self)
--    def swap(self, *args): return vimagemodule.DoubleVector_swap(self, *args)
--    def get_allocator(self): return vimagemodule.DoubleVector_get_allocator(self)
--    def begin(self): return vimagemodule.DoubleVector_begin(self)
--    def end(self): return vimagemodule.DoubleVector_end(self)
--    def rbegin(self): return vimagemodule.DoubleVector_rbegin(self)
--    def rend(self): return vimagemodule.DoubleVector_rend(self)
--    def pop_back(self): return vimagemodule.DoubleVector_pop_back(self)
--    def erase(self, *args): return vimagemodule.DoubleVector_erase(self, *args)
--    def __init__(self, *args): 
--        this = vimagemodule.new_DoubleVector(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def push_back(self, *args): return vimagemodule.DoubleVector_push_back(self, *args)
--    def front(self): return vimagemodule.DoubleVector_front(self)
--    def back(self): return vimagemodule.DoubleVector_back(self)
--    def assign(self, *args): return vimagemodule.DoubleVector_assign(self, *args)
--    def resize(self, *args): return vimagemodule.DoubleVector_resize(self, *args)
--    def insert(self, *args): return vimagemodule.DoubleVector_insert(self, *args)
--    def reserve(self, *args): return vimagemodule.DoubleVector_reserve(self, *args)
--    def capacity(self): return vimagemodule.DoubleVector_capacity(self)
--    __swig_destroy__ = vimagemodule.delete_DoubleVector
--    __del__ = lambda self : None;
--DoubleVector_swigregister = vimagemodule.DoubleVector_swigregister
--DoubleVector_swigregister(DoubleVector)
--
--class ImageVector(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, ImageVector, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, ImageVector, name)
--    __repr__ = _swig_repr
--    def iterator(self): return vimagemodule.ImageVector_iterator(self)
--    def __iter__(self): return self.iterator()
--    def __nonzero__(self): return vimagemodule.ImageVector___nonzero__(self)
--    def __bool__(self): return vimagemodule.ImageVector___bool__(self)
--    def __len__(self): return vimagemodule.ImageVector___len__(self)
--    def pop(self): return vimagemodule.ImageVector_pop(self)
--    def __getslice__(self, *args): return vimagemodule.ImageVector___getslice__(self, *args)
--    def __setslice__(self, *args): return vimagemodule.ImageVector___setslice__(self, *args)
--    def __delslice__(self, *args): return vimagemodule.ImageVector___delslice__(self, *args)
--    def __delitem__(self, *args): return vimagemodule.ImageVector___delitem__(self, *args)
--    def __getitem__(self, *args): return vimagemodule.ImageVector___getitem__(self, *args)
--    def __setitem__(self, *args): return vimagemodule.ImageVector___setitem__(self, *args)
--    def append(self, *args): return vimagemodule.ImageVector_append(self, *args)
--    def empty(self): return vimagemodule.ImageVector_empty(self)
--    def size(self): return vimagemodule.ImageVector_size(self)
--    def clear(self): return vimagemodule.ImageVector_clear(self)
--    def swap(self, *args): return vimagemodule.ImageVector_swap(self, *args)
--    def get_allocator(self): return vimagemodule.ImageVector_get_allocator(self)
--    def begin(self): return vimagemodule.ImageVector_begin(self)
--    def end(self): return vimagemodule.ImageVector_end(self)
--    def rbegin(self): return vimagemodule.ImageVector_rbegin(self)
--    def rend(self): return vimagemodule.ImageVector_rend(self)
--    def pop_back(self): return vimagemodule.ImageVector_pop_back(self)
--    def erase(self, *args): return vimagemodule.ImageVector_erase(self, *args)
--    def __init__(self, *args): 
--        this = vimagemodule.new_ImageVector(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def push_back(self, *args): return vimagemodule.ImageVector_push_back(self, *args)
--    def front(self): return vimagemodule.ImageVector_front(self)
--    def back(self): return vimagemodule.ImageVector_back(self)
--    def assign(self, *args): return vimagemodule.ImageVector_assign(self, *args)
--    def resize(self, *args): return vimagemodule.ImageVector_resize(self, *args)
--    def insert(self, *args): return vimagemodule.ImageVector_insert(self, *args)
--    def reserve(self, *args): return vimagemodule.ImageVector_reserve(self, *args)
--    def capacity(self): return vimagemodule.ImageVector_capacity(self)
--    __swig_destroy__ = vimagemodule.delete_ImageVector
--    __del__ = lambda self : None;
--ImageVector_swigregister = vimagemodule.ImageVector_swigregister
--ImageVector_swigregister(ImageVector)
--
--
--def init(argv0="nothing"):
--  return vimagemodule.init(argv0)
--init = vimagemodule.init
--
--def shutdown():
--  return vimagemodule.shutdown()
--shutdown = vimagemodule.shutdown
--class VImage(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VImage, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, VImage, name)
--    __repr__ = _swig_repr
--    __swig_getmethods__["print_all"] = lambda x: vimagemodule.VImage_print_all
--    if _newclass:print_all = staticmethod(vimagemodule.VImage_print_all)
--    MULTIBAND = vimagemodule.VImage_MULTIBAND
--    B_W = vimagemodule.VImage_B_W
--    LUMINACE = vimagemodule.VImage_LUMINACE
--    XRAY = vimagemodule.VImage_XRAY
--    IR = vimagemodule.VImage_IR
--    YUV = vimagemodule.VImage_YUV
--    RED_ONLY = vimagemodule.VImage_RED_ONLY
--    GREEN_ONLY = vimagemodule.VImage_GREEN_ONLY
--    BLUE_ONLY = vimagemodule.VImage_BLUE_ONLY
--    POWER_SPECTRUM = vimagemodule.VImage_POWER_SPECTRUM
--    HISTOGRAM = vimagemodule.VImage_HISTOGRAM
--    LUT = vimagemodule.VImage_LUT
--    XYZ = vimagemodule.VImage_XYZ
--    LAB = vimagemodule.VImage_LAB
--    CMC = vimagemodule.VImage_CMC
--    CMYK = vimagemodule.VImage_CMYK
--    LABQ = vimagemodule.VImage_LABQ
--    RGB = vimagemodule.VImage_RGB
--    UCS = vimagemodule.VImage_UCS
--    LCH = vimagemodule.VImage_LCH
--    LABS = vimagemodule.VImage_LABS
--    sRGB = vimagemodule.VImage_sRGB
--    YXY = vimagemodule.VImage_YXY
--    FOURIER = vimagemodule.VImage_FOURIER
--    RGB16 = vimagemodule.VImage_RGB16
--    GREY16 = vimagemodule.VImage_GREY16
--    FMTNOTSET = vimagemodule.VImage_FMTNOTSET
--    FMTUCHAR = vimagemodule.VImage_FMTUCHAR
--    FMTCHAR = vimagemodule.VImage_FMTCHAR
--    FMTUSHORT = vimagemodule.VImage_FMTUSHORT
--    FMTSHORT = vimagemodule.VImage_FMTSHORT
--    FMTUINT = vimagemodule.VImage_FMTUINT
--    FMTINT = vimagemodule.VImage_FMTINT
--    FMTFLOAT = vimagemodule.VImage_FMTFLOAT
--    FMTCOMPLEX = vimagemodule.VImage_FMTCOMPLEX
--    FMTDOUBLE = vimagemodule.VImage_FMTDOUBLE
--    FMTDPCOMPLEX = vimagemodule.VImage_FMTDPCOMPLEX
--    NOCODING = vimagemodule.VImage_NOCODING
--    COLQUANT = vimagemodule.VImage_COLQUANT
--    LABPACK = vimagemodule.VImage_LABPACK
--    LABPACK_COMPRESSED = vimagemodule.VImage_LABPACK_COMPRESSED
--    RGB_COMPRESSED = vimagemodule.VImage_RGB_COMPRESSED
--    LUM_COMPRESSED = vimagemodule.VImage_LUM_COMPRESSED
--    RAD = vimagemodule.VImage_RAD
--    NO_COMPRESSION = vimagemodule.VImage_NO_COMPRESSION
--    TCSF_COMPRESSION = vimagemodule.VImage_TCSF_COMPRESSION
--    JPEG_COMPRESSION = vimagemodule.VImage_JPEG_COMPRESSION
--    __swig_getmethods__["convert2disc"] = lambda x: vimagemodule.VImage_convert2disc
--    if _newclass:convert2disc = staticmethod(vimagemodule.VImage_convert2disc)
--    def __init__(self, *args): 
--        this = vimagemodule.new_VImage(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def __assign__(self, *args): return vimagemodule.VImage___assign__(self, *args)
--    __swig_destroy__ = vimagemodule.delete_VImage
--    __del__ = lambda self : None;
--    def image(self): return vimagemodule.VImage_image(self)
--    def data(self): return vimagemodule.VImage_data(self)
--    def write(self, *args): return vimagemodule.VImage_write(self, *args)
--    def debug_print(self): return vimagemodule.VImage_debug_print(self)
--    def Xsize(self): return vimagemodule.VImage_Xsize(self)
--    def Ysize(self): return vimagemodule.VImage_Ysize(self)
--    def Bands(self): return vimagemodule.VImage_Bands(self)
--    def BandFmt(self): return vimagemodule.VImage_BandFmt(self)
--    def Coding(self): return vimagemodule.VImage_Coding(self)
--    def Type(self): return vimagemodule.VImage_Type(self)
--    def Xres(self): return vimagemodule.VImage_Xres(self)
--    def Yres(self): return vimagemodule.VImage_Yres(self)
--    def Length(self): return vimagemodule.VImage_Length(self)
--    def Compression(self): return vimagemodule.VImage_Compression(self)
--    def Level(self): return vimagemodule.VImage_Level(self)
--    def Xoffset(self): return vimagemodule.VImage_Xoffset(self)
--    def Yoffset(self): return vimagemodule.VImage_Yoffset(self)
--    def filename(self): return vimagemodule.VImage_filename(self)
--    def Hist(self): return vimagemodule.VImage_Hist(self)
--    def meta_remove(self, *args): return vimagemodule.VImage_meta_remove(self, *args)
--    def meta_get_typeof(self, *args): return vimagemodule.VImage_meta_get_typeof(self, *args)
--    def meta_get_int(self, *args): return vimagemodule.VImage_meta_get_int(self, *args)
--    def meta_get_double(self, *args): return vimagemodule.VImage_meta_get_double(self, *args)
--    def meta_get_string(self, *args): return vimagemodule.VImage_meta_get_string(self, *args)
--    def meta_get_area(self, *args): return vimagemodule.VImage_meta_get_area(self, *args)
--    def meta_get_blob(self, *args): return vimagemodule.VImage_meta_get_blob(self, *args)
--    def meta_set(self, *args): return vimagemodule.VImage_meta_set(self, *args)
--    def initdesc(self, *args): return vimagemodule.VImage_initdesc(self, *args)
--    def abs(self): return vimagemodule.VImage_abs(self)
--    def acos(self): return vimagemodule.VImage_acos(self)
--    def add(self, *args): return vimagemodule.VImage_add(self, *args)
--    def asin(self): return vimagemodule.VImage_asin(self)
--    def atan(self): return vimagemodule.VImage_atan(self)
--    def avg(self): return vimagemodule.VImage_avg(self)
--    def point(self, *args): return vimagemodule.VImage_point(self, *args)
--    def point_bilinear(self, *args): return vimagemodule.VImage_point_bilinear(self, *args)
--    def bandmean(self): return vimagemodule.VImage_bandmean(self)
--    def ceil(self): return vimagemodule.VImage_ceil(self)
--    def cos(self): return vimagemodule.VImage_cos(self)
--    def cross_phase(self, *args): return vimagemodule.VImage_cross_phase(self, *args)
--    def deviate(self): return vimagemodule.VImage_deviate(self)
--    def divide(self, *args): return vimagemodule.VImage_divide(self, *args)
--    def exp10(self): return vimagemodule.VImage_exp10(self)
--    def expn(self, *args): return vimagemodule.VImage_expn(self, *args)
--    def exp(self): return vimagemodule.VImage_exp(self)
--    def floor(self): return vimagemodule.VImage_floor(self)
--    def invert(self): return vimagemodule.VImage_invert(self)
--    __swig_getmethods__["linreg"] = lambda x: vimagemodule.VImage_linreg
--    if _newclass:linreg = staticmethod(vimagemodule.VImage_linreg)
--    def lin(self, *args): return vimagemodule.VImage_lin(self, *args)
--    def log10(self): return vimagemodule.VImage_log10(self)
--    def log(self): return vimagemodule.VImage_log(self)
--    def max(self): return vimagemodule.VImage_max(self)
--    def maxpos(self): return vimagemodule.VImage_maxpos(self)
--    def maxpos_avg(self): return vimagemodule.VImage_maxpos_avg(self)
--    def measure(self, *args): return vimagemodule.VImage_measure(self, *args)
--    def min(self): return vimagemodule.VImage_min(self)
--    def minpos(self): return vimagemodule.VImage_minpos(self)
--    def multiply(self, *args): return vimagemodule.VImage_multiply(self, *args)
--    def pow(self, *args): return vimagemodule.VImage_pow(self, *args)
--    def recomb(self, *args): return vimagemodule.VImage_recomb(self, *args)
--    def remainder(self, *args): return vimagemodule.VImage_remainder(self, *args)
--    def rint(self): return vimagemodule.VImage_rint(self)
--    def sign(self): return vimagemodule.VImage_sign(self)
--    def sin(self): return vimagemodule.VImage_sin(self)
--    def stats(self): return vimagemodule.VImage_stats(self)
--    def subtract(self, *args): return vimagemodule.VImage_subtract(self, *args)
--    def tan(self): return vimagemodule.VImage_tan(self)
--    def greyc(self, *args): return vimagemodule.VImage_greyc(self, *args)
--    def greyc_mask(self, *args): return vimagemodule.VImage_greyc_mask(self, *args)
--    def LCh2Lab(self): return vimagemodule.VImage_LCh2Lab(self)
--    def LCh2UCS(self): return vimagemodule.VImage_LCh2UCS(self)
--    def Lab2LCh(self): return vimagemodule.VImage_Lab2LCh(self)
--    def Lab2LabQ(self): return vimagemodule.VImage_Lab2LabQ(self)
--    def Lab2LabS(self): return vimagemodule.VImage_Lab2LabS(self)
--    def Lab2UCS(self): return vimagemodule.VImage_Lab2UCS(self)
--    def Lab2XYZ(self): return vimagemodule.VImage_Lab2XYZ(self)
--    def Lab2XYZ_temp(self, *args): return vimagemodule.VImage_Lab2XYZ_temp(self, *args)
--    def Lab2disp(self, *args): return vimagemodule.VImage_Lab2disp(self, *args)
--    def LabQ2LabS(self): return vimagemodule.VImage_LabQ2LabS(self)
--    def LabQ2Lab(self): return vimagemodule.VImage_LabQ2Lab(self)
--    def LabQ2XYZ(self): return vimagemodule.VImage_LabQ2XYZ(self)
--    def LabQ2disp(self, *args): return vimagemodule.VImage_LabQ2disp(self, *args)
--    def LabS2LabQ(self): return vimagemodule.VImage_LabS2LabQ(self)
--    def LabS2Lab(self): return vimagemodule.VImage_LabS2Lab(self)
--    def UCS2LCh(self): return vimagemodule.VImage_UCS2LCh(self)
--    def UCS2Lab(self): return vimagemodule.VImage_UCS2Lab(self)
--    def UCS2XYZ(self): return vimagemodule.VImage_UCS2XYZ(self)
--    def XYZ2Lab(self): return vimagemodule.VImage_XYZ2Lab(self)
--    def XYZ2Lab_temp(self, *args): return vimagemodule.VImage_XYZ2Lab_temp(self, *args)
--    def XYZ2UCS(self): return vimagemodule.VImage_XYZ2UCS(self)
--    def XYZ2Yxy(self): return vimagemodule.VImage_XYZ2Yxy(self)
--    def XYZ2disp(self, *args): return vimagemodule.VImage_XYZ2disp(self, *args)
--    def XYZ2sRGB(self): return vimagemodule.VImage_XYZ2sRGB(self)
--    def Yxy2XYZ(self): return vimagemodule.VImage_Yxy2XYZ(self)
--    def dE00_fromLab(self, *args): return vimagemodule.VImage_dE00_fromLab(self, *args)
--    def dECMC_fromLab(self, *args): return vimagemodule.VImage_dECMC_fromLab(self, *args)
--    def dECMC_fromdisp(self, *args): return vimagemodule.VImage_dECMC_fromdisp(self, *args)
--    def dE_fromLab(self, *args): return vimagemodule.VImage_dE_fromLab(self, *args)
--    def dE_fromXYZ(self, *args): return vimagemodule.VImage_dE_fromXYZ(self, *args)
--    def dE_fromdisp(self, *args): return vimagemodule.VImage_dE_fromdisp(self, *args)
--    def disp2Lab(self, *args): return vimagemodule.VImage_disp2Lab(self, *args)
--    def disp2XYZ(self, *args): return vimagemodule.VImage_disp2XYZ(self, *args)
--    def float2rad(self): return vimagemodule.VImage_float2rad(self)
--    def icc_ac2rc(self, *args): return vimagemodule.VImage_icc_ac2rc(self, *args)
--    def icc_export_depth(self, *args): return vimagemodule.VImage_icc_export_depth(self, *args)
--    def icc_import(self, *args): return vimagemodule.VImage_icc_import(self, *args)
--    def icc_import_embedded(self, *args): return vimagemodule.VImage_icc_import_embedded(self, *args)
--    def icc_transform(self, *args): return vimagemodule.VImage_icc_transform(self, *args)
--    def lab_morph(self, *args): return vimagemodule.VImage_lab_morph(self, *args)
--    def rad2float(self): return vimagemodule.VImage_rad2float(self)
--    def sRGB2XYZ(self): return vimagemodule.VImage_sRGB2XYZ(self)
--    __swig_getmethods__["gaussnoise"] = lambda x: vimagemodule.VImage_gaussnoise
--    if _newclass:gaussnoise = staticmethod(vimagemodule.VImage_gaussnoise)
--    def bandjoin(self, *args): return vimagemodule.VImage_bandjoin(self, *args)
--    __swig_getmethods__["black"] = lambda x: vimagemodule.VImage_black
--    if _newclass:black = staticmethod(vimagemodule.VImage_black)
--    def c2amph(self): return vimagemodule.VImage_c2amph(self)
--    def c2imag(self): return vimagemodule.VImage_c2imag(self)
--    def c2real(self): return vimagemodule.VImage_c2real(self)
--    def c2rect(self): return vimagemodule.VImage_c2rect(self)
--    def clip2fmt(self, *args): return vimagemodule.VImage_clip2fmt(self, *args)
--    def copy(self): return vimagemodule.VImage_copy(self)
--    def copy_file(self): return vimagemodule.VImage_copy_file(self)
--    def copy_morph(self, *args): return vimagemodule.VImage_copy_morph(self, *args)
--    def copy_swap(self): return vimagemodule.VImage_copy_swap(self)
--    def copy_set(self, *args): return vimagemodule.VImage_copy_set(self, *args)
--    def extract_area(self, *args): return vimagemodule.VImage_extract_area(self, *args)
--    def extract_areabands(self, *args): return vimagemodule.VImage_extract_areabands(self, *args)
--    def extract_band(self, *args): return vimagemodule.VImage_extract_band(self, *args)
--    def extract_bands(self, *args): return vimagemodule.VImage_extract_bands(self, *args)
--    def extract(self, *args): return vimagemodule.VImage_extract(self, *args)
--    def falsecolour(self): return vimagemodule.VImage_falsecolour(self)
--    def fliphor(self): return vimagemodule.VImage_fliphor(self)
--    def flipver(self): return vimagemodule.VImage_flipver(self)
--    __swig_getmethods__["gbandjoin"] = lambda x: vimagemodule.VImage_gbandjoin
--    if _newclass:gbandjoin = staticmethod(vimagemodule.VImage_gbandjoin)
--    def grid(self, *args): return vimagemodule.VImage_grid(self, *args)
--    def insert(self, *args): return vimagemodule.VImage_insert(self, *args)
--    def insert_noexpand(self, *args): return vimagemodule.VImage_insert_noexpand(self, *args)
--    def embed(self, *args): return vimagemodule.VImage_embed(self, *args)
--    def lrjoin(self, *args): return vimagemodule.VImage_lrjoin(self, *args)
--    def msb(self): return vimagemodule.VImage_msb(self)
--    def msb_band(self, *args): return vimagemodule.VImage_msb_band(self, *args)
--    def replicate(self, *args): return vimagemodule.VImage_replicate(self, *args)
--    def ri2c(self, *args): return vimagemodule.VImage_ri2c(self, *args)
--    def rot180(self): return vimagemodule.VImage_rot180(self)
--    def rot270(self): return vimagemodule.VImage_rot270(self)
--    def rot90(self): return vimagemodule.VImage_rot90(self)
--    def scale(self): return vimagemodule.VImage_scale(self)
--    def scaleps(self): return vimagemodule.VImage_scaleps(self)
--    def subsample(self, *args): return vimagemodule.VImage_subsample(self, *args)
--    def system(self, *args): return vimagemodule.VImage_system(self, *args)
--    def system_image(self, *args): return vimagemodule.VImage_system_image(self, *args)
--    def tbjoin(self, *args): return vimagemodule.VImage_tbjoin(self, *args)
--    __swig_getmethods__["text"] = lambda x: vimagemodule.VImage_text
--    if _newclass:text = staticmethod(vimagemodule.VImage_text)
--    def wrap(self, *args): return vimagemodule.VImage_wrap(self, *args)
--    def zoom(self, *args): return vimagemodule.VImage_zoom(self, *args)
--    def aconvsep(self, *args): return vimagemodule.VImage_aconvsep(self, *args)
--    def aconv(self, *args): return vimagemodule.VImage_aconv(self, *args)
--    def addgnoise(self, *args): return vimagemodule.VImage_addgnoise(self, *args)
--    def compass(self, *args): return vimagemodule.VImage_compass(self, *args)
--    def contrast_surface(self, *args): return vimagemodule.VImage_contrast_surface(self, *args)
--    def conv(self, *args): return vimagemodule.VImage_conv(self, *args)
--    def convsep(self, *args): return vimagemodule.VImage_convsep(self, *args)
--    def fastcor(self, *args): return vimagemodule.VImage_fastcor(self, *args)
--    def gradcor(self, *args): return vimagemodule.VImage_gradcor(self, *args)
--    def gradient(self, *args): return vimagemodule.VImage_gradient(self, *args)
--    def grad_x(self): return vimagemodule.VImage_grad_x(self)
--    def grad_y(self): return vimagemodule.VImage_grad_y(self)
--    def lindetect(self, *args): return vimagemodule.VImage_lindetect(self, *args)
--    def sharpen(self, *args): return vimagemodule.VImage_sharpen(self, *args)
--    def spcor(self, *args): return vimagemodule.VImage_spcor(self, *args)
--    def argb2rgba(self): return vimagemodule.VImage_argb2rgba(self)
--    def flood_copy(self, *args): return vimagemodule.VImage_flood_copy(self, *args)
--    def flood_blob_copy(self, *args): return vimagemodule.VImage_flood_blob_copy(self, *args)
--    def flood_other_copy(self, *args): return vimagemodule.VImage_flood_other_copy(self, *args)
--    def clip(self): return vimagemodule.VImage_clip(self)
--    def c2ps(self): return vimagemodule.VImage_c2ps(self)
--    def resize_linear(self, *args): return vimagemodule.VImage_resize_linear(self, *args)
--    def cmulnorm(self, *args): return vimagemodule.VImage_cmulnorm(self, *args)
--    def fav4(self, *args): return vimagemodule.VImage_fav4(self, *args)
--    def gadd(self, *args): return vimagemodule.VImage_gadd(self, *args)
--    def icc_export(self, *args): return vimagemodule.VImage_icc_export(self, *args)
--    def litecor(self, *args): return vimagemodule.VImage_litecor(self, *args)
--    def affine(self, *args): return vimagemodule.VImage_affine(self, *args)
--    def clip2c(self): return vimagemodule.VImage_clip2c(self)
--    def clip2cm(self): return vimagemodule.VImage_clip2cm(self)
--    def clip2d(self): return vimagemodule.VImage_clip2d(self)
--    def clip2dcm(self): return vimagemodule.VImage_clip2dcm(self)
--    def clip2f(self): return vimagemodule.VImage_clip2f(self)
--    def clip2i(self): return vimagemodule.VImage_clip2i(self)
--    def convsub(self, *args): return vimagemodule.VImage_convsub(self, *args)
--    def convf(self, *args): return vimagemodule.VImage_convf(self, *args)
--    def convsepf(self, *args): return vimagemodule.VImage_convsepf(self, *args)
--    def clip2s(self): return vimagemodule.VImage_clip2s(self)
--    def clip2ui(self): return vimagemodule.VImage_clip2ui(self)
--    def clip2us(self): return vimagemodule.VImage_clip2us(self)
--    def slice(self, *args): return vimagemodule.VImage_slice(self, *args)
--    def segment(self): return vimagemodule.VImage_segment(self)
--    def thresh(self, *args): return vimagemodule.VImage_thresh(self, *args)
--    def convf_raw(self, *args): return vimagemodule.VImage_convf_raw(self, *args)
--    def conv_raw(self, *args): return vimagemodule.VImage_conv_raw(self, *args)
--    def contrast_surface_raw(self, *args): return vimagemodule.VImage_contrast_surface_raw(self, *args)
--    def convsepf_raw(self, *args): return vimagemodule.VImage_convsepf_raw(self, *args)
--    def convsep_raw(self, *args): return vimagemodule.VImage_convsep_raw(self, *args)
--    def fastcor_raw(self, *args): return vimagemodule.VImage_fastcor_raw(self, *args)
--    def gradcor_raw(self, *args): return vimagemodule.VImage_gradcor_raw(self, *args)
--    def spcor_raw(self, *args): return vimagemodule.VImage_spcor_raw(self, *args)
--    def lhisteq_raw(self, *args): return vimagemodule.VImage_lhisteq_raw(self, *args)
--    def stdif_raw(self, *args): return vimagemodule.VImage_stdif_raw(self, *args)
--    def rank_raw(self, *args): return vimagemodule.VImage_rank_raw(self, *args)
--    def dilate_raw(self, *args): return vimagemodule.VImage_dilate_raw(self, *args)
--    def erode_raw(self, *args): return vimagemodule.VImage_erode_raw(self, *args)
--    def similarity_area(self, *args): return vimagemodule.VImage_similarity_area(self, *args)
--    def similarity(self, *args): return vimagemodule.VImage_similarity(self, *args)
--    __swig_getmethods__["mask2vips"] = lambda x: vimagemodule.VImage_mask2vips
--    if _newclass:mask2vips = staticmethod(vimagemodule.VImage_mask2vips)
--    def vips2mask(self): return vimagemodule.VImage_vips2mask(self)
--    def insertplace(self, *args): return vimagemodule.VImage_insertplace(self, *args)
--    def circle(self, *args): return vimagemodule.VImage_circle(self, *args)
--    def andimage(self, *args): return vimagemodule.VImage_andimage(self, *args)
--    def orimage(self, *args): return vimagemodule.VImage_orimage(self, *args)
--    def eorimage(self, *args): return vimagemodule.VImage_eorimage(self, *args)
--    def shiftleft(self, *args): return vimagemodule.VImage_shiftleft(self, *args)
--    def shiftright(self, *args): return vimagemodule.VImage_shiftright(self, *args)
--    def blend(self, *args): return vimagemodule.VImage_blend(self, *args)
--    def equal(self, *args): return vimagemodule.VImage_equal(self, *args)
--    def ifthenelse(self, *args): return vimagemodule.VImage_ifthenelse(self, *args)
--    def less(self, *args): return vimagemodule.VImage_less(self, *args)
--    def lesseq(self, *args): return vimagemodule.VImage_lesseq(self, *args)
--    def more(self, *args): return vimagemodule.VImage_more(self, *args)
--    def moreeq(self, *args): return vimagemodule.VImage_moreeq(self, *args)
--    def notequal(self, *args): return vimagemodule.VImage_notequal(self, *args)
--    def quadratic(self, *args): return vimagemodule.VImage_quadratic(self, *args)
--    __swig_getmethods__["csv2vips"] = lambda x: vimagemodule.VImage_csv2vips
--    if _newclass:csv2vips = staticmethod(vimagemodule.VImage_csv2vips)
--    __swig_getmethods__["fits2vips"] = lambda x: vimagemodule.VImage_fits2vips
--    if _newclass:fits2vips = staticmethod(vimagemodule.VImage_fits2vips)
--    __swig_getmethods__["jpeg2vips"] = lambda x: vimagemodule.VImage_jpeg2vips
--    if _newclass:jpeg2vips = staticmethod(vimagemodule.VImage_jpeg2vips)
--    __swig_getmethods__["magick2vips"] = lambda x: vimagemodule.VImage_magick2vips
--    if _newclass:magick2vips = staticmethod(vimagemodule.VImage_magick2vips)
--    __swig_getmethods__["png2vips"] = lambda x: vimagemodule.VImage_png2vips
--    if _newclass:png2vips = staticmethod(vimagemodule.VImage_png2vips)
--    __swig_getmethods__["exr2vips"] = lambda x: vimagemodule.VImage_exr2vips
--    if _newclass:exr2vips = staticmethod(vimagemodule.VImage_exr2vips)
--    __swig_getmethods__["ppm2vips"] = lambda x: vimagemodule.VImage_ppm2vips
--    if _newclass:ppm2vips = staticmethod(vimagemodule.VImage_ppm2vips)
--    __swig_getmethods__["analyze2vips"] = lambda x: vimagemodule.VImage_analyze2vips
--    if _newclass:analyze2vips = staticmethod(vimagemodule.VImage_analyze2vips)
--    __swig_getmethods__["tiff2vips"] = lambda x: vimagemodule.VImage_tiff2vips
--    if _newclass:tiff2vips = staticmethod(vimagemodule.VImage_tiff2vips)
--    def vips2csv(self, *args): return vimagemodule.VImage_vips2csv(self, *args)
--    def vips2dz(self, *args): return vimagemodule.VImage_vips2dz(self, *args)
--    def vips2jpeg(self, *args): return vimagemodule.VImage_vips2jpeg(self, *args)
--    def vips2mimejpeg(self, *args): return vimagemodule.VImage_vips2mimejpeg(self, *args)
--    def vips2png(self, *args): return vimagemodule.VImage_vips2png(self, *args)
--    def vips2ppm(self, *args): return vimagemodule.VImage_vips2ppm(self, *args)
--    def vips2tiff(self, *args): return vimagemodule.VImage_vips2tiff(self, *args)
--    __swig_getmethods__["create_fmask"] = lambda x: vimagemodule.VImage_create_fmask
--    if _newclass:create_fmask = staticmethod(vimagemodule.VImage_create_fmask)
--    def disp_ps(self): return vimagemodule.VImage_disp_ps(self)
--    def flt_image_freq(self, *args): return vimagemodule.VImage_flt_image_freq(self, *args)
--    __swig_getmethods__["fractsurf"] = lambda x: vimagemodule.VImage_fractsurf
--    if _newclass:fractsurf = staticmethod(vimagemodule.VImage_fractsurf)
--    def freqflt(self, *args): return vimagemodule.VImage_freqflt(self, *args)
--    def fwfft(self): return vimagemodule.VImage_fwfft(self)
--    def rotquad(self): return vimagemodule.VImage_rotquad(self)
--    def invfft(self): return vimagemodule.VImage_invfft(self)
--    def phasecor_fft(self, *args): return vimagemodule.VImage_phasecor_fft(self, *args)
--    def invfftr(self): return vimagemodule.VImage_invfftr(self)
--    def gammacorrect(self, *args): return vimagemodule.VImage_gammacorrect(self, *args)
--    def heq(self, *args): return vimagemodule.VImage_heq(self, *args)
--    def hist(self, *args): return vimagemodule.VImage_hist(self, *args)
--    def histcum(self): return vimagemodule.VImage_histcum(self)
--    def histeq(self): return vimagemodule.VImage_histeq(self)
--    def hist_indexed(self, *args): return vimagemodule.VImage_hist_indexed(self, *args)
--    def histgr(self, *args): return vimagemodule.VImage_histgr(self, *args)
--    def histnD(self, *args): return vimagemodule.VImage_histnD(self, *args)
--    def histnorm(self): return vimagemodule.VImage_histnorm(self)
--    def histplot(self): return vimagemodule.VImage_histplot(self)
--    def histspec(self, *args): return vimagemodule.VImage_histspec(self, *args)
--    def hsp(self, *args): return vimagemodule.VImage_hsp(self, *args)
--    __swig_getmethods__["identity"] = lambda x: vimagemodule.VImage_identity
--    if _newclass:identity = staticmethod(vimagemodule.VImage_identity)
--    __swig_getmethods__["identity_ushort"] = lambda x: vimagemodule.VImage_identity_ushort
--    if _newclass:identity_ushort = staticmethod(vimagemodule.VImage_identity_ushort)
--    def ismonotonic(self): return vimagemodule.VImage_ismonotonic(self)
--    def lhisteq(self, *args): return vimagemodule.VImage_lhisteq(self, *args)
--    def mpercent(self, *args): return vimagemodule.VImage_mpercent(self, *args)
--    __swig_getmethods__["invertlut"] = lambda x: vimagemodule.VImage_invertlut
--    if _newclass:invertlut = staticmethod(vimagemodule.VImage_invertlut)
--    __swig_getmethods__["buildlut"] = lambda x: vimagemodule.VImage_buildlut
--    if _newclass:buildlut = staticmethod(vimagemodule.VImage_buildlut)
--    def maplut(self, *args): return vimagemodule.VImage_maplut(self, *args)
--    def project(self, *args): return vimagemodule.VImage_project(self, *args)
--    def stdif(self, *args): return vimagemodule.VImage_stdif(self, *args)
--    def tone_analyse(self, *args): return vimagemodule.VImage_tone_analyse(self, *args)
--    __swig_getmethods__["tone_build"] = lambda x: vimagemodule.VImage_tone_build
--    if _newclass:tone_build = staticmethod(vimagemodule.VImage_tone_build)
--    __swig_getmethods__["tone_build_range"] = lambda x: vimagemodule.VImage_tone_build_range
--    if _newclass:tone_build_range = staticmethod(vimagemodule.VImage_tone_build_range)
--    def tone_map(self, *args): return vimagemodule.VImage_tone_map(self, *args)
--    def draw_circle(self, *args): return vimagemodule.VImage_draw_circle(self, *args)
--    def draw_rect(self, *args): return vimagemodule.VImage_draw_rect(self, *args)
--    def draw_line(self, *args): return vimagemodule.VImage_draw_line(self, *args)
--    def draw_point(self, *args): return vimagemodule.VImage_draw_point(self, *args)
--    def draw_smudge(self, *args): return vimagemodule.VImage_draw_smudge(self, *args)
--    def draw_flood(self, *args): return vimagemodule.VImage_draw_flood(self, *args)
--    def draw_flood_blob(self, *args): return vimagemodule.VImage_draw_flood_blob(self, *args)
--    def draw_flood_other(self, *args): return vimagemodule.VImage_draw_flood_other(self, *args)
--    def draw_image(self, *args): return vimagemodule.VImage_draw_image(self, *args)
--    def draw_mask(self, *args): return vimagemodule.VImage_draw_mask(self, *args)
--    def line(self, *args): return vimagemodule.VImage_line(self, *args)
--    __swig_getmethods__["binfile"] = lambda x: vimagemodule.VImage_binfile
--    if _newclass:binfile = staticmethod(vimagemodule.VImage_binfile)
--    def cache(self, *args): return vimagemodule.VImage_cache(self, *args)
--    def getext(self): return vimagemodule.VImage_getext(self)
--    def header_get_typeof(self, *args): return vimagemodule.VImage_header_get_typeof(self, *args)
--    def header_int(self, *args): return vimagemodule.VImage_header_int(self, *args)
--    def header_double(self, *args): return vimagemodule.VImage_header_double(self, *args)
--    def header_string(self, *args): return vimagemodule.VImage_header_string(self, *args)
--    def history_get(self): return vimagemodule.VImage_history_get(self)
--    def printdesc(self): return vimagemodule.VImage_printdesc(self)
--    def cntlines(self, *args): return vimagemodule.VImage_cntlines(self, *args)
--    def dilate(self, *args): return vimagemodule.VImage_dilate(self, *args)
--    def rank(self, *args): return vimagemodule.VImage_rank(self, *args)
--    __swig_getmethods__["rank_image"] = lambda x: vimagemodule.VImage_rank_image
--    if _newclass:rank_image = staticmethod(vimagemodule.VImage_rank_image)
--    __swig_getmethods__["maxvalue"] = lambda x: vimagemodule.VImage_maxvalue
--    if _newclass:maxvalue = staticmethod(vimagemodule.VImage_maxvalue)
--    def label_regions(self): return vimagemodule.VImage_label_regions(self)
--    def zerox(self, *args): return vimagemodule.VImage_zerox(self, *args)
--    def erode(self, *args): return vimagemodule.VImage_erode(self, *args)
--    def profile(self, *args): return vimagemodule.VImage_profile(self, *args)
--    def align_bands(self): return vimagemodule.VImage_align_bands(self)
--    def correl(self, *args): return vimagemodule.VImage_correl(self, *args)
--    def _find_lroverlap(self, *args): return vimagemodule.VImage__find_lroverlap(self, *args)
--    def _find_tboverlap(self, *args): return vimagemodule.VImage__find_tboverlap(self, *args)
--    def global_balance(self, *args): return vimagemodule.VImage_global_balance(self, *args)
--    def global_balancef(self, *args): return vimagemodule.VImage_global_balancef(self, *args)
--    def lrmerge(self, *args): return vimagemodule.VImage_lrmerge(self, *args)
--    def lrmerge1(self, *args): return vimagemodule.VImage_lrmerge1(self, *args)
--    def lrmosaic(self, *args): return vimagemodule.VImage_lrmosaic(self, *args)
--    def lrmosaic1(self, *args): return vimagemodule.VImage_lrmosaic1(self, *args)
--    def match_linear(self, *args): return vimagemodule.VImage_match_linear(self, *args)
--    def match_linear_search(self, *args): return vimagemodule.VImage_match_linear_search(self, *args)
--    def maxpos_subpel(self): return vimagemodule.VImage_maxpos_subpel(self)
--    def remosaic(self, *args): return vimagemodule.VImage_remosaic(self, *args)
--    def tbmerge(self, *args): return vimagemodule.VImage_tbmerge(self, *args)
--    def tbmerge1(self, *args): return vimagemodule.VImage_tbmerge1(self, *args)
--    def tbmosaic(self, *args): return vimagemodule.VImage_tbmosaic(self, *args)
--    def tbmosaic1(self, *args): return vimagemodule.VImage_tbmosaic1(self, *args)
--    def benchmark(self): return vimagemodule.VImage_benchmark(self)
--    def benchmark2(self): return vimagemodule.VImage_benchmark2(self)
--    def benchmarkn(self, *args): return vimagemodule.VImage_benchmarkn(self, *args)
--    __swig_getmethods__["eye"] = lambda x: vimagemodule.VImage_eye
--    if _newclass:eye = staticmethod(vimagemodule.VImage_eye)
--    __swig_getmethods__["grey"] = lambda x: vimagemodule.VImage_grey
--    if _newclass:grey = staticmethod(vimagemodule.VImage_grey)
--    __swig_getmethods__["feye"] = lambda x: vimagemodule.VImage_feye
--    if _newclass:feye = staticmethod(vimagemodule.VImage_feye)
--    __swig_getmethods__["fgrey"] = lambda x: vimagemodule.VImage_fgrey
--    if _newclass:fgrey = staticmethod(vimagemodule.VImage_fgrey)
--    __swig_getmethods__["fzone"] = lambda x: vimagemodule.VImage_fzone
--    if _newclass:fzone = staticmethod(vimagemodule.VImage_fzone)
--    __swig_getmethods__["make_xy"] = lambda x: vimagemodule.VImage_make_xy
--    if _newclass:make_xy = staticmethod(vimagemodule.VImage_make_xy)
--    __swig_getmethods__["sines"] = lambda x: vimagemodule.VImage_sines
--    if _newclass:sines = staticmethod(vimagemodule.VImage_sines)
--    __swig_getmethods__["zone"] = lambda x: vimagemodule.VImage_zone
--    if _newclass:zone = staticmethod(vimagemodule.VImage_zone)
--    def rightshift_size(self, *args): return vimagemodule.VImage_rightshift_size(self, *args)
--    def shrink(self, *args): return vimagemodule.VImage_shrink(self, *args)
--    def stretch3(self, *args): return vimagemodule.VImage_stretch3(self, *args)
--    def affinei(self, *args): return vimagemodule.VImage_affinei(self, *args)
--    def affinei_all(self, *args): return vimagemodule.VImage_affinei_all(self, *args)
--    __swig_getmethods__["video_test"] = lambda x: vimagemodule.VImage_video_test
--    if _newclass:video_test = staticmethod(vimagemodule.VImage_video_test)
--    __swig_getmethods__["video_v4l1"] = lambda x: vimagemodule.VImage_video_v4l1
--    if _newclass:video_v4l1 = staticmethod(vimagemodule.VImage_video_v4l1)
--    def tobuffer(self): return vimagemodule.VImage_tobuffer(self)
--    __swig_getmethods__["frombuffer"] = lambda x: vimagemodule.VImage_frombuffer
--    if _newclass:frombuffer = staticmethod(vimagemodule.VImage_frombuffer)
--    def tostring(self): return vimagemodule.VImage_tostring(self)
--    __swig_getmethods__["fromstring"] = lambda x: vimagemodule.VImage_fromstring
--    if _newclass:fromstring = staticmethod(vimagemodule.VImage_fromstring)
--VImage_swigregister = vimagemodule.VImage_swigregister
--VImage_swigregister(VImage)
--
--def VImage_print_all():
--  return vimagemodule.VImage_print_all()
--VImage_print_all = vimagemodule.VImage_print_all
--
--def VImage_convert2disc(*args):
--  return vimagemodule.VImage_convert2disc(*args)
--VImage_convert2disc = vimagemodule.VImage_convert2disc
--
--def VImage_linreg(*args):
--  return vimagemodule.VImage_linreg(*args)
--VImage_linreg = vimagemodule.VImage_linreg
--
--def VImage_gaussnoise(*args):
--  return vimagemodule.VImage_gaussnoise(*args)
--VImage_gaussnoise = vimagemodule.VImage_gaussnoise
--
--def VImage_black(*args):
--  return vimagemodule.VImage_black(*args)
--VImage_black = vimagemodule.VImage_black
--
--def VImage_gbandjoin(*args):
--  return vimagemodule.VImage_gbandjoin(*args)
--VImage_gbandjoin = vimagemodule.VImage_gbandjoin
--
--def VImage_text(*args):
--  return vimagemodule.VImage_text(*args)
--VImage_text = vimagemodule.VImage_text
--
--def VImage_mask2vips(*args):
--  return vimagemodule.VImage_mask2vips(*args)
--VImage_mask2vips = vimagemodule.VImage_mask2vips
--
--def VImage_csv2vips(*args):
--  return vimagemodule.VImage_csv2vips(*args)
--VImage_csv2vips = vimagemodule.VImage_csv2vips
--
--def VImage_fits2vips(*args):
--  return vimagemodule.VImage_fits2vips(*args)
--VImage_fits2vips = vimagemodule.VImage_fits2vips
--
--def VImage_jpeg2vips(*args):
--  return vimagemodule.VImage_jpeg2vips(*args)
--VImage_jpeg2vips = vimagemodule.VImage_jpeg2vips
--
--def VImage_magick2vips(*args):
--  return vimagemodule.VImage_magick2vips(*args)
--VImage_magick2vips = vimagemodule.VImage_magick2vips
--
--def VImage_png2vips(*args):
--  return vimagemodule.VImage_png2vips(*args)
--VImage_png2vips = vimagemodule.VImage_png2vips
--
--def VImage_exr2vips(*args):
--  return vimagemodule.VImage_exr2vips(*args)
--VImage_exr2vips = vimagemodule.VImage_exr2vips
--
--def VImage_ppm2vips(*args):
--  return vimagemodule.VImage_ppm2vips(*args)
--VImage_ppm2vips = vimagemodule.VImage_ppm2vips
--
--def VImage_analyze2vips(*args):
--  return vimagemodule.VImage_analyze2vips(*args)
--VImage_analyze2vips = vimagemodule.VImage_analyze2vips
--
--def VImage_tiff2vips(*args):
--  return vimagemodule.VImage_tiff2vips(*args)
--VImage_tiff2vips = vimagemodule.VImage_tiff2vips
--
--def VImage_create_fmask(*args):
--  return vimagemodule.VImage_create_fmask(*args)
--VImage_create_fmask = vimagemodule.VImage_create_fmask
--
--def VImage_fractsurf(*args):
--  return vimagemodule.VImage_fractsurf(*args)
--VImage_fractsurf = vimagemodule.VImage_fractsurf
--
--def VImage_identity(*args):
--  return vimagemodule.VImage_identity(*args)
--VImage_identity = vimagemodule.VImage_identity
--
--def VImage_identity_ushort(*args):
--  return vimagemodule.VImage_identity_ushort(*args)
--VImage_identity_ushort = vimagemodule.VImage_identity_ushort
--
--def VImage_invertlut(*args):
--  return vimagemodule.VImage_invertlut(*args)
--VImage_invertlut = vimagemodule.VImage_invertlut
--
--def VImage_buildlut(*args):
--  return vimagemodule.VImage_buildlut(*args)
--VImage_buildlut = vimagemodule.VImage_buildlut
--
--def VImage_tone_build(*args):
--  return vimagemodule.VImage_tone_build(*args)
--VImage_tone_build = vimagemodule.VImage_tone_build
--
--def VImage_tone_build_range(*args):
--  return vimagemodule.VImage_tone_build_range(*args)
--VImage_tone_build_range = vimagemodule.VImage_tone_build_range
--
--def VImage_binfile(*args):
--  return vimagemodule.VImage_binfile(*args)
--VImage_binfile = vimagemodule.VImage_binfile
--
--def VImage_rank_image(*args):
--  return vimagemodule.VImage_rank_image(*args)
--VImage_rank_image = vimagemodule.VImage_rank_image
--
--def VImage_maxvalue(*args):
--  return vimagemodule.VImage_maxvalue(*args)
--VImage_maxvalue = vimagemodule.VImage_maxvalue
--
--def VImage_eye(*args):
--  return vimagemodule.VImage_eye(*args)
--VImage_eye = vimagemodule.VImage_eye
--
--def VImage_grey(*args):
--  return vimagemodule.VImage_grey(*args)
--VImage_grey = vimagemodule.VImage_grey
--
--def VImage_feye(*args):
--  return vimagemodule.VImage_feye(*args)
--VImage_feye = vimagemodule.VImage_feye
--
--def VImage_fgrey(*args):
--  return vimagemodule.VImage_fgrey(*args)
--VImage_fgrey = vimagemodule.VImage_fgrey
--
--def VImage_fzone(*args):
--  return vimagemodule.VImage_fzone(*args)
--VImage_fzone = vimagemodule.VImage_fzone
--
--def VImage_make_xy(*args):
--  return vimagemodule.VImage_make_xy(*args)
--VImage_make_xy = vimagemodule.VImage_make_xy
--
--def VImage_sines(*args):
--  return vimagemodule.VImage_sines(*args)
--VImage_sines = vimagemodule.VImage_sines
--
--def VImage_zone(*args):
--  return vimagemodule.VImage_zone(*args)
--VImage_zone = vimagemodule.VImage_zone
--
--def VImage_video_test(*args):
--  return vimagemodule.VImage_video_test(*args)
--VImage_video_test = vimagemodule.VImage_video_test
--
--def VImage_video_v4l1(*args):
--  return vimagemodule.VImage_video_v4l1(*args)
--VImage_video_v4l1 = vimagemodule.VImage_video_v4l1
--
--def VImage_frombuffer(*args):
--  return vimagemodule.VImage_frombuffer(*args)
--VImage_frombuffer = vimagemodule.VImage_frombuffer
--
--def VImage_fromstring(*args):
--  return vimagemodule.VImage_fromstring(*args)
--VImage_fromstring = vimagemodule.VImage_fromstring
--
--
--def im_init_world(*args):
--  return vimagemodule.im_init_world(*args)
--im_init_world = vimagemodule.im_init_world
--
--def im__print_all():
--  return vimagemodule.im__print_all()
--im__print_all = vimagemodule.im__print_all
--
--def im_col_Lab2XYZ(*args):
--  return vimagemodule.im_col_Lab2XYZ(*args)
--im_col_Lab2XYZ = vimagemodule.im_col_Lab2XYZ
--# try to guess a PIL mode string from a VIPS image
--def PIL_mode_from_vips (vim):
--  if vim.Bands () == 3 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'RGB'
--  elif vim.Bands () == 4 and vim.BandFmt () == VImage.FMTUCHAR and vim.Type () == VImage.RGB:
--    return 'RGBA'
--  elif vim.Bands () == 4 and vim.BandFmt () == VImage.FMTUCHAR and vim.Type () == VImage.CMYK:
--    return 'CMYK'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'L'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTINT:
--    return 'I'
--  elif vim.Bands () == 1 and vim.BandFmt () == VImage.FMTFLOAT:
--    return 'F'
--  elif vim.Bands () == 2 and vim.BandFmt () == VImage.FMTUCHAR:
--    return 'LA'
--  else:
--    raise ValueError ('unsupported vips -> pil image')
--
--# return vips (bands, format, type) for a PIL mode
--def vips_from_PIL_mode (mode):
--  if mode == 'RGB':
--    return (3, VImage.FMTUCHAR, VImage.RGB)
--  elif mode == 'RGBA':
--    return (4, VImage.FMTUCHAR, VImage.RGB)
--  elif mode == 'CMYK':
--    return (4, VImage.FMTUCHAR, VImage.CMYK)
--  elif mode == 'L':
--    return (1, VImage.FMTUCHAR, VImage.B_W)
--  elif mode == 'I':
--    return (1, VImage.FMTINT, VImage.B_W)
--  elif mode == 'F':
--    return (1, VImage.FMTFLOAT, VImage.B_W)
--  elif mode == 'LA':
--    return (2, VImage.FMTUCHAR, VImage.B_W)
--  else:
--    raise ValueError ('unsupported pil -> vips image')
--
--# This file is compatible with both classic and new-style classes.
--
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VMask.i vips-7.38.5/swig/vipsCC/VMask.i
---- vips-7.38.5-vanilla/swig/vipsCC/VMask.i    2014-07-17 23:48:36.207794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VMask.i    1969-12-31 19:00:00.000000000 -0500
-@@ -1,35 +0,0 @@
--/* SWIG interface file for VMask.
-- */
--
--%module VMask
--%{
--#include <stdexcept>
--#include <vips/vipscpp.h>
--%}
--
--%import "VError.i"
--%import "VImage.i"
--
--/* Need to override assignment to get refcounting working.
-- */
--%rename(__assign__) *::operator=;
--
--/* [] is array subscript, as you'd expect.
-- */
--%rename(__index__) vips::VIMask::operator[];
--%rename(__index__) vips::VDMask::operator[];
--
--/* () is 2d array subscript, how odd!
-- */
--%rename(__call__) vips::VIMask::operator();
--%rename(__call__) vips::VDMask::operator();
--
--/* Type conversion operators renamed as functions.
-- */
--%rename(convert_VImage) vips::VIMask::operator vips::VImage;
--%rename(convert_VImage) vips::VDMask::operator vips::VImage;
--
--%rename(convert_VIMask) vips::VDMask::operator vips::VIMask;
--%rename(convert_VDMask) vips::VIMask::operator vips::VDMask;
--
--%include vips/VMask.h
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/vmaskmodule.cxx vips-7.38.5/swig/vipsCC/vmaskmodule.cxx
---- vips-7.38.5-vanilla/swig/vipsCC/vmaskmodule.cxx    2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/vmaskmodule.cxx    1969-12-31 19:00:00.000000000 -0500
-@@ -1,7363 +0,0 @@
--/* ----------------------------------------------------------------------------
-- * This file was automatically generated by SWIG (http://www.swig.org).
-- * Version 2.0.10
-- * 
-- * This file is not intended to be easily readable and contains a number of 
-- * coding conventions designed to improve portability and efficiency. Do not make
-- * changes to this file unless you know what you are doing--modify the SWIG 
-- * interface file instead. 
-- * ----------------------------------------------------------------------------- */
--
--#define SWIGPYTHON
--#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
--
--
--#ifdef __cplusplus
--/* SwigValueWrapper is described in swig.swg */
--template<typename T> class SwigValueWrapper {
--  struct SwigMovePointer {
--    T *ptr;
--    SwigMovePointer(T *p) : ptr(p) { }
--    ~SwigMovePointer() { delete ptr; }
--    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
--  } pointer;
--  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
--  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
--public:
--  SwigValueWrapper() : pointer(0) { }
--  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
--  operator T&() const { return *pointer.ptr; }
--  T *operator&() { return pointer.ptr; }
--};
--
--template <typename T> T SwigValueInit() {
--  return T();
--}
--#endif
--
--/* -----------------------------------------------------------------------------
-- *  This section contains generic SWIG labels for method/variable
-- *  declarations/attributes, and other compiler dependent labels.
-- * ----------------------------------------------------------------------------- */
--
--/* template workaround for compilers that cannot correctly implement the C++ standard */
--#ifndef SWIGTEMPLATEDISAMBIGUATOR
--# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# elif defined(__HP_aCC)
--/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
--/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
--#  define SWIGTEMPLATEDISAMBIGUATOR template
--# else
--#  define SWIGTEMPLATEDISAMBIGUATOR
--# endif
--#endif
--
--/* inline attribute */
--#ifndef SWIGINLINE
--# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
--#   define SWIGINLINE inline
--# else
--#   define SWIGINLINE
--# endif
--#endif
--
--/* attribute recognised by some compilers to avoid 'unused' warnings */
--#ifndef SWIGUNUSED
--# if defined(__GNUC__)
--#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
--#     define SWIGUNUSED __attribute__ ((__unused__)) 
--#   else
--#     define SWIGUNUSED
--#   endif
--# elif defined(__ICC)
--#   define SWIGUNUSED __attribute__ ((__unused__)) 
--# else
--#   define SWIGUNUSED 
--# endif
--#endif
--
--#ifndef SWIG_MSC_UNSUPPRESS_4505
--# if defined(_MSC_VER)
--#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
--# endif 
--#endif
--
--#ifndef SWIGUNUSEDPARM
--# ifdef __cplusplus
--#   define SWIGUNUSEDPARM(p)
--# else
--#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
--# endif
--#endif
--
--/* internal SWIG method */
--#ifndef SWIGINTERN
--# define SWIGINTERN static SWIGUNUSED
--#endif
--
--/* internal inline SWIG method */
--#ifndef SWIGINTERNINLINE
--# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
--#endif
--
--/* exporting methods */
--#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
--#  ifndef GCC_HASCLASSVISIBILITY
--#    define GCC_HASCLASSVISIBILITY
--#  endif
--#endif
--
--#ifndef SWIGEXPORT
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   if defined(STATIC_LINKED)
--#     define SWIGEXPORT
--#   else
--#     define SWIGEXPORT __declspec(dllexport)
--#   endif
--# else
--#   if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
--#     define SWIGEXPORT __attribute__ ((visibility("default")))
--#   else
--#     define SWIGEXPORT
--#   endif
--# endif
--#endif
--
--/* calling conventions for Windows */
--#ifndef SWIGSTDCALL
--# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#   define SWIGSTDCALL __stdcall
--# else
--#   define SWIGSTDCALL
--# endif 
--#endif
--
--/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
--#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
--# define _CRT_SECURE_NO_DEPRECATE
--#endif
--
--/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
--#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
--# define _SCL_SECURE_NO_DEPRECATE
--#endif
--
--
--
--/* Python.h has to appear first */
--#include <Python.h>
--
--/* -----------------------------------------------------------------------------
-- * swigrun.swg
-- *
-- * This file contains generic C API SWIG runtime support for pointer
-- * type checking.
-- * ----------------------------------------------------------------------------- */
--
--/* This should only be incremented when either the layout of swig_type_info changes,
--   or for whatever reason, the runtime changes incompatibly */
--#define SWIG_RUNTIME_VERSION "4"
--
--/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
--#ifdef SWIG_TYPE_TABLE
--# define SWIG_QUOTE_STRING(x) #x
--# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
--# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
--#else
--# define SWIG_TYPE_TABLE_NAME
--#endif
--
--/*
--  You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
--  creating a static or dynamic library from the SWIG runtime code.
--  In 99.9% of the cases, SWIG just needs to declare them as 'static'.
--  
--  But only do this if strictly necessary, ie, if you have problems
--  with your compiler or suchlike.
--*/
--
--#ifndef SWIGRUNTIME
--# define SWIGRUNTIME SWIGINTERN
--#endif
--
--#ifndef SWIGRUNTIMEINLINE
--# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
--#endif
--
--/*  Generic buffer size */
--#ifndef SWIG_BUFFER_SIZE
--# define SWIG_BUFFER_SIZE 1024
--#endif
--
--/* Flags for pointer conversions */
--#define SWIG_POINTER_DISOWN        0x1
--#define SWIG_CAST_NEW_MEMORY       0x2
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_OWN           0x1
--
--
--/* 
--   Flags/methods for returning states.
--   
--   The SWIG conversion methods, as ConvertPtr, return an integer 
--   that tells if the conversion was successful or not. And if not,
--   an error code can be returned (see swigerrors.swg for the codes).
--   
--   Use the following macros/flags to set or process the returning
--   states.
--   
--   In old versions of SWIG, code such as the following was usually written:
--
--     if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
--       // success code
--     } else {
--       //fail code
--     }
--
--   Now you can be more explicit:
--
--    int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--    } else {
--      // fail code
--    }
--
--   which is the same really, but now you can also do
--
--    Type *ptr;
--    int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
--    if (SWIG_IsOK(res)) {
--      // success code
--      if (SWIG_IsNewObj(res) {
--        ...
--      delete *ptr;
--      } else {
--        ...
--      }
--    } else {
--      // fail code
--    }
--    
--   I.e., now SWIG_ConvertPtr can return new objects and you can
--   identify the case and take care of the deallocation. Of course that
--   also requires SWIG_ConvertPtr to return new result values, such as
--
--      int SWIG_ConvertPtr(obj, ptr,...) {         
--        if (<obj is ok>) {                           
--          if (<need new object>) {                   
--            *ptr = <ptr to new allocated object>; 
--            return SWIG_NEWOBJ;                      
--          } else {                                   
--            *ptr = <ptr to old object>;              
--            return SWIG_OLDOBJ;                      
--          }                                  
--        } else {                                     
--          return SWIG_BADOBJ;                
--        }                                            
--      }
--
--   Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
--   more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
--   SWIG errors code.
--
--   Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
--   allows to return the 'cast rank', for example, if you have this
--
--       int food(double)
--       int fooi(int);
--
--   and you call
-- 
--      food(1)   // cast rank '1'  (1 -> 1.0)
--      fooi(1)   // cast rank '0'
--
--   just use the SWIG_AddCast()/SWIG_CheckState()
--*/
--
--#define SWIG_OK                    (0) 
--#define SWIG_ERROR                 (-1)
--#define SWIG_IsOK(r)               (r >= 0)
--#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
--
--/* The CastRankLimit says how many bits are used for the cast rank */
--#define SWIG_CASTRANKLIMIT         (1 << 8)
--/* The NewMask denotes the object was created (using new/malloc) */
--#define SWIG_NEWOBJMASK            (SWIG_CASTRANKLIMIT  << 1)
--/* The TmpMask is for in/out typemaps that use temporal objects */
--#define SWIG_TMPOBJMASK            (SWIG_NEWOBJMASK << 1)
--/* Simple returning values */
--#define SWIG_BADOBJ                (SWIG_ERROR)
--#define SWIG_OLDOBJ                (SWIG_OK)
--#define SWIG_NEWOBJ                (SWIG_OK | SWIG_NEWOBJMASK)
--#define SWIG_TMPOBJ                (SWIG_OK | SWIG_TMPOBJMASK)
--/* Check, add and del mask methods */
--#define SWIG_AddNewMask(r)         (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
--#define SWIG_DelNewMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
--#define SWIG_IsNewObj(r)           (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
--#define SWIG_AddTmpMask(r)         (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
--#define SWIG_DelTmpMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
--#define SWIG_IsTmpObj(r)           (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
--
--/* Cast-Rank Mode */
--#if defined(SWIG_CASTRANK_MODE)
--#  ifndef SWIG_TypeRank
--#    define SWIG_TypeRank             unsigned long
--#  endif
--#  ifndef SWIG_MAXCASTRANK            /* Default cast allowed */
--#    define SWIG_MAXCASTRANK          (2)
--#  endif
--#  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
--#  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
--SWIGINTERNINLINE int SWIG_AddCast(int r) { 
--  return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
--}
--SWIGINTERNINLINE int SWIG_CheckState(int r) { 
--  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
--}
--#else /* no cast-rank mode */
--#  define SWIG_AddCast(r) (r)
--#  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
--#endif
--
--
--#include <string.h>
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--typedef void *(*swig_converter_func)(void *, int *);
--typedef struct swig_type_info *(*swig_dycast_func)(void **);
--
--/* Structure to store information on one type */
--typedef struct swig_type_info {
--  const char             *name;                       /* mangled name of this type */
--  const char             *str;                        /* human readable name of this type */
--  swig_dycast_func        dcast;              /* dynamic cast function down a hierarchy */
--  struct swig_cast_info  *cast;                       /* linked list of types that can cast into this type */
--  void                   *clientdata;         /* language specific type data */
--  int                    owndata;             /* flag if the structure owns the clientdata */
--} swig_type_info;
--
--/* Structure to store a type and conversion function used for casting */
--typedef struct swig_cast_info {
--  swig_type_info         *type;                       /* pointer to type that is equivalent to this type */
--  swig_converter_func     converter;          /* function to cast the void pointers */
--  struct swig_cast_info  *next;                       /* pointer to next cast in linked list */
--  struct swig_cast_info  *prev;                       /* pointer to the previous cast */
--} swig_cast_info;
--
--/* Structure used to store module information
-- * Each module generates one structure like this, and the runtime collects
-- * all of these structures and stores them in a circularly linked list.*/
--typedef struct swig_module_info {
--  swig_type_info         **types;             /* Array of pointers to swig_type_info structures that are in this module */
--  size_t                 size;                        /* Number of types in this module */
--  struct swig_module_info *next;              /* Pointer to next element in circularly linked list */
--  swig_type_info         **type_initial;      /* Array of initially generated type structures */
--  swig_cast_info         **cast_initial;      /* Array of initially generated casting structures */
--  void                    *clientdata;                /* Language specific module data */
--} swig_module_info;
--
--/* 
--  Compare two type names skipping the space characters, therefore
--  "char*" == "char *" and "Class<int>" == "Class<int >", etc.
--
--  Return 0 when the two name types are equivalent, as in
--  strncmp, but skipping ' '.
--*/
--SWIGRUNTIME int
--SWIG_TypeNameComp(const char *f1, const char *l1,
--                const char *f2, const char *l2) {
--  for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
--    while ((*f1 == ' ') && (f1 != l1)) ++f1;
--    while ((*f2 == ' ') && (f2 != l2)) ++f2;
--    if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
--  }
--  return (int)((l1 - f1) - (l2 - f2));
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
--*/
--SWIGRUNTIME int
--SWIG_TypeCmp(const char *nb, const char *tb) {
--  int equiv = 1;
--  const char* te = tb + strlen(tb);
--  const char* ne = nb;
--  while (equiv != 0 && *ne) {
--    for (nb = ne; *ne; ++ne) {
--      if (*ne == '|') break;
--    }
--    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
--    if (*ne) ++ne;
--  }
--  return equiv;
--}
--
--/*
--  Check type equivalence in a name list like <name1>|<name2>|...
--  Return 0 if not equal, 1 if equal
--*/
--SWIGRUNTIME int
--SWIG_TypeEquiv(const char *nb, const char *tb) {
--  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
--}
--
--/*
--  Check the typename
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheck(const char *c, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (strcmp(iter->type->name, c) == 0) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/* 
--  Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
--*/
--SWIGRUNTIME swig_cast_info *
--SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
--  if (ty) {
--    swig_cast_info *iter = ty->cast;
--    while (iter) {
--      if (iter->type == from) {
--        if (iter == ty->cast)
--          return iter;
--        /* Move iter to the top of the linked list */
--        iter->prev->next = iter->next;
--        if (iter->next)
--          iter->next->prev = iter->prev;
--        iter->next = ty->cast;
--        iter->prev = 0;
--        if (ty->cast) ty->cast->prev = iter;
--        ty->cast = iter;
--        return iter;
--      }
--      iter = iter->next;
--    }
--  }
--  return 0;
--}
--
--/*
--  Cast a pointer up an inheritance hierarchy
--*/
--SWIGRUNTIMEINLINE void *
--SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
--  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
--}
--
--/* 
--   Dynamic pointer casting. Down an inheritance hierarchy
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
--  swig_type_info *lastty = ty;
--  if (!ty || !ty->dcast) return ty;
--  while (ty && (ty->dcast)) {
--    ty = (*ty->dcast)(ptr);
--    if (ty) lastty = ty;
--  }
--  return lastty;
--}
--
--/*
--  Return the name associated with this type
--*/
--SWIGRUNTIMEINLINE const char *
--SWIG_TypeName(const swig_type_info *ty) {
--  return ty->name;
--}
--
--/*
--  Return the pretty name associated with this type,
--  that is an unmangled type name in a form presentable to the user.
--*/
--SWIGRUNTIME const char *
--SWIG_TypePrettyName(const swig_type_info *type) {
--  /* The "str" field contains the equivalent pretty names of the
--     type, separated by vertical-bar characters.  We choose
--     to print the last name, as it is often (?) the most
--     specific. */
--  if (!type) return NULL;
--  if (type->str != NULL) {
--    const char *last_name = type->str;
--    const char *s;
--    for (s = type->str; *s; s++)
--      if (*s == '|') last_name = s+1;
--    return last_name;
--  }
--  else
--    return type->name;
--}
--
--/* 
--   Set the clientdata field for a type
--*/
--SWIGRUNTIME void
--SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
--  swig_cast_info *cast = ti->cast;
--  /* if (ti->clientdata == clientdata) return; */
--  ti->clientdata = clientdata;
--  
--  while (cast) {
--    if (!cast->converter) {
--      swig_type_info *tc = cast->type;
--      if (!tc->clientdata) {
--      SWIG_TypeClientData(tc, clientdata);
--      }
--    }    
--    cast = cast->next;
--  }
--}
--SWIGRUNTIME void
--SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
--  SWIG_TypeClientData(ti, clientdata);
--  ti->owndata = 1;
--}
--  
--/*
--  Search for a swig_type_info structure only by mangled name
--  Search is a O(log #types)
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_MangledTypeQueryModule(swig_module_info *start, 
--                            swig_module_info *end, 
--                          const char *name) {
--  swig_module_info *iter = start;
--  do {
--    if (iter->size) {
--      register size_t l = 0;
--      register size_t r = iter->size - 1;
--      do {
--      /* since l+r >= 0, we can (>> 1) instead (/ 2) */
--      register size_t i = (l + r) >> 1; 
--      const char *iname = iter->types[i]->name;
--      if (iname) {
--        register int compare = strcmp(name, iname);
--        if (compare == 0) {       
--          return iter->types[i];
--        } else if (compare < 0) {
--          if (i) {
--            r = i - 1;
--          } else {
--            break;
--          }
--        } else if (compare > 0) {
--          l = i + 1;
--        }
--      } else {
--        break; /* should never happen */
--      }
--      } while (l <= r);
--    }
--    iter = iter->next;
--  } while (iter != end);
--  return 0;
--}
--
--/*
--  Search for a swig_type_info structure for either a mangled name or a human readable name.
--  It first searches the mangled names of the types, which is a O(log #types)
--  If a type is not found it then searches the human readable names, which is O(#types).
--  
--  We start searching at module start, and finish searching when start == end.  
--  Note: if start == end at the beginning of the function, we go all the way around
--  the circular list.
--*/
--SWIGRUNTIME swig_type_info *
--SWIG_TypeQueryModule(swig_module_info *start, 
--                     swig_module_info *end, 
--                   const char *name) {
--  /* STEP 1: Search the name field using binary search */
--  swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
--  if (ret) {
--    return ret;
--  } else {
--    /* STEP 2: If the type hasn't been found, do a complete search
--       of the str field (the human readable name) */
--    swig_module_info *iter = start;
--    do {
--      register size_t i = 0;
--      for (; i < iter->size; ++i) {
--      if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
--        return iter->types[i];
--      }
--      iter = iter->next;
--    } while (iter != end);
--  }
--  
--  /* neither found a match */
--  return 0;
--}
--
--/* 
--   Pack binary data into a string
--*/
--SWIGRUNTIME char *
--SWIG_PackData(char *c, void *ptr, size_t sz) {
--  static const char hex[17] = "0123456789abcdef";
--  register const unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu =  u + sz;
--  for (; u != eu; ++u) {
--    register unsigned char uu = *u;
--    *(c++) = hex[(uu & 0xf0) >> 4];
--    *(c++) = hex[uu & 0xf];
--  }
--  return c;
--}
--
--/* 
--   Unpack binary data from a string
--*/
--SWIGRUNTIME const char *
--SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
--  register unsigned char *u = (unsigned char *) ptr;
--  register const unsigned char *eu = u + sz;
--  for (; u != eu; ++u) {
--    register char d = *(c++);
--    register unsigned char uu;
--    if ((d >= '0') && (d <= '9'))
--      uu = ((d - '0') << 4);
--    else if ((d >= 'a') && (d <= 'f'))
--      uu = ((d - ('a'-10)) << 4);
--    else 
--      return (char *) 0;
--    d = *(c++);
--    if ((d >= '0') && (d <= '9'))
--      uu |= (d - '0');
--    else if ((d >= 'a') && (d <= 'f'))
--      uu |= (d - ('a'-10));
--    else 
--      return (char *) 0;
--    *u = uu;
--  }
--  return c;
--}
--
--/* 
--   Pack 'void *' into a string buffer.
--*/
--SWIGRUNTIME char *
--SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
--  char *r = buff;
--  if ((2*sizeof(void *) + 2) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,&ptr,sizeof(void *));
--  if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
--  strcpy(r,name);
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      *ptr = (void *) 0;
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sizeof(void *));
--}
--
--SWIGRUNTIME char *
--SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
--  char *r = buff;
--  size_t lname = (name ? strlen(name) : 0);
--  if ((2*sz + 2 + lname) > bsz) return 0;
--  *(r++) = '_';
--  r = SWIG_PackData(r,ptr,sz);
--  if (lname) {
--    strncpy(r,name,lname+1);
--  } else {
--    *r = 0;
--  }
--  return buff;
--}
--
--SWIGRUNTIME const char *
--SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
--  if (*c != '_') {
--    if (strcmp(c,"NULL") == 0) {
--      memset(ptr,0,sz);
--      return name;
--    } else {
--      return 0;
--    }
--  }
--  return SWIG_UnpackData(++c,ptr,sz);
--}
--
--#ifdef __cplusplus
--}
--#endif
--
--/*  Errors in SWIG */
--#define  SWIG_UnknownError               -1 
--#define  SWIG_IOError            -2 
--#define  SWIG_RuntimeError       -3 
--#define  SWIG_IndexError         -4 
--#define  SWIG_TypeError          -5 
--#define  SWIG_DivisionByZero     -6 
--#define  SWIG_OverflowError      -7 
--#define  SWIG_SyntaxError        -8 
--#define  SWIG_ValueError         -9 
--#define  SWIG_SystemError        -10
--#define  SWIG_AttributeError     -11
--#define  SWIG_MemoryError        -12 
--#define  SWIG_NullReferenceError   -13
--
--
--
--/* Compatibility macros for Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--
--#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
--#define PyInt_Check(x) PyLong_Check(x)
--#define PyInt_AsLong(x) PyLong_AsLong(x)
--#define PyInt_FromLong(x) PyLong_FromLong(x)
--#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
--#define PyString_Check(name) PyBytes_Check(name)
--#define PyString_FromString(x) PyUnicode_FromString(x)
--#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
--#define PyString_AsString(str) PyBytes_AsString(str)
--#define PyString_Size(str) PyBytes_Size(str)  
--#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
--#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
--#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
--#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
--
--#endif
--
--#ifndef Py_TYPE
--#  define Py_TYPE(op) ((op)->ob_type)
--#endif
--
--/* SWIG APIs for compatibility of both Python 2 & 3 */
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_FromFormat PyUnicode_FromFormat
--#else
--#  define SWIG_Python_str_FromFormat PyString_FromFormat
--#endif
--
--
--/* Warning: This function will allocate a new string in Python 3,
-- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
-- */
--SWIGINTERN char*
--SWIG_Python_str_AsChar(PyObject *str)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  char *cstr;
--  char *newstr;
--  Py_ssize_t len;
--  str = PyUnicode_AsUTF8String(str);
--  PyBytes_AsStringAndSize(str, &cstr, &len);
--  newstr = (char *) malloc(len+1);
--  memcpy(newstr, cstr, len+1);
--  Py_XDECREF(str);
--  return newstr;
--#else
--  return PyString_AsString(str);
--#endif
--}
--
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
--#else
--#  define SWIG_Python_str_DelForPy3(x) 
--#endif
--
--
--SWIGINTERN PyObject*
--SWIG_Python_str_FromChar(const char *c)
--{
--#if PY_VERSION_HEX >= 0x03000000
--  return PyUnicode_FromString(c); 
--#else
--  return PyString_FromString(c);
--#endif
--}
--
--/* Add PyOS_snprintf for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
--#  define PyOS_snprintf _snprintf
--# else
--#  define PyOS_snprintf snprintf
--# endif
--#endif
--
--/* A crude PyString_FromFormat implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--
--#ifndef SWIG_PYBUFFER_SIZE
--# define SWIG_PYBUFFER_SIZE 1024
--#endif
--
--static PyObject *
--PyString_FromFormat(const char *fmt, ...) {
--  va_list ap;
--  char buf[SWIG_PYBUFFER_SIZE * 2];
--  int res;
--  va_start(ap, fmt);
--  res = vsnprintf(buf, sizeof(buf), fmt, ap);
--  va_end(ap);
--  return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
--}
--#endif
--
--/* Add PyObject_Del for old Pythons */
--#if PY_VERSION_HEX < 0x01060000
--# define PyObject_Del(op) PyMem_DEL((op))
--#endif
--#ifndef PyObject_DEL
--# define PyObject_DEL PyObject_Del
--#endif
--
--/* A crude PyExc_StopIteration exception for old Pythons */
--#if PY_VERSION_HEX < 0x02020000
--# ifndef PyExc_StopIteration
--#  define PyExc_StopIteration PyExc_RuntimeError
--# endif
--# ifndef PyObject_GenericGetAttr
--#  define PyObject_GenericGetAttr 0
--# endif
--#endif
--
--/* Py_NotImplemented is defined in 2.1 and up. */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef Py_NotImplemented
--#  define Py_NotImplemented PyExc_RuntimeError
--# endif
--#endif
--
--/* A crude PyString_AsStringAndSize implementation for old Pythons */
--#if PY_VERSION_HEX < 0x02010000
--# ifndef PyString_AsStringAndSize
--#  define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
--# endif
--#endif
--
--/* PySequence_Size for old Pythons */
--#if PY_VERSION_HEX < 0x02000000
--# ifndef PySequence_Size
--#  define PySequence_Size PySequence_Length
--# endif
--#endif
--
--/* PyBool_FromLong for old Pythons */
--#if PY_VERSION_HEX < 0x02030000
--static
--PyObject *PyBool_FromLong(long ok)
--{
--  PyObject *result = ok ? Py_True : Py_False;
--  Py_INCREF(result);
--  return result;
--}
--#endif
--
--/* Py_ssize_t for old Pythons */
--/* This code is as recommended by: */
--/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
--#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
--typedef int Py_ssize_t;
--# define PY_SSIZE_T_MAX INT_MAX
--# define PY_SSIZE_T_MIN INT_MIN
--typedef inquiry lenfunc;
--typedef intargfunc ssizeargfunc;
--typedef intintargfunc ssizessizeargfunc;
--typedef intobjargproc ssizeobjargproc;
--typedef intintobjargproc ssizessizeobjargproc;
--typedef getreadbufferproc readbufferproc;
--typedef getwritebufferproc writebufferproc;
--typedef getsegcountproc segcountproc;
--typedef getcharbufferproc charbufferproc;
--static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
--{
--  long result = 0;
--  PyObject *i = PyNumber_Int(x);
--  if (i) {
--    result = PyInt_AsLong(i);
--    Py_DECREF(i);
--  }
--  return result;
--}
--#endif
--
--#if PY_VERSION_HEX < 0x02050000
--#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
--#endif
--
--#if PY_VERSION_HEX < 0x02040000
--#define Py_VISIT(op)                          \
--  do {                                                \
--    if (op) {                                 \
--      int vret = visit((op), arg);            \
--      if (vret)                                       \
--        return vret;                          \
--    }                                         \
--  } while (0)
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef struct {
--  PyTypeObject type;
--  PyNumberMethods as_number;
--  PyMappingMethods as_mapping;
--  PySequenceMethods as_sequence;
--  PyBufferProcs as_buffer;
--  PyObject *name, *slots;
--} PyHeapTypeObject;
--#endif
--
--#if PY_VERSION_HEX < 0x02030000
--typedef destructor freefunc;
--#endif
--
--#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
--     (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
--     (PY_MAJOR_VERSION > 3))
--# define SWIGPY_USE_CAPSULE
--# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
--#endif
--
--#if PY_VERSION_HEX < 0x03020000
--#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
--#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
--#endif
--
--/* -----------------------------------------------------------------------------
-- * error manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIME PyObject*
--SWIG_Python_ErrorType(int code) {
--  PyObject* type = 0;
--  switch(code) {
--  case SWIG_MemoryError:
--    type = PyExc_MemoryError;
--    break;
--  case SWIG_IOError:
--    type = PyExc_IOError;
--    break;
--  case SWIG_RuntimeError:
--    type = PyExc_RuntimeError;
--    break;
--  case SWIG_IndexError:
--    type = PyExc_IndexError;
--    break;
--  case SWIG_TypeError:
--    type = PyExc_TypeError;
--    break;
--  case SWIG_DivisionByZero:
--    type = PyExc_ZeroDivisionError;
--    break;
--  case SWIG_OverflowError:
--    type = PyExc_OverflowError;
--    break;
--  case SWIG_SyntaxError:
--    type = PyExc_SyntaxError;
--    break;
--  case SWIG_ValueError:
--    type = PyExc_ValueError;
--    break;
--  case SWIG_SystemError:
--    type = PyExc_SystemError;
--    break;
--  case SWIG_AttributeError:
--    type = PyExc_AttributeError;
--    break;
--  default:
--    type = PyExc_RuntimeError;
--  }
--  return type;
--}
--
--
--SWIGRUNTIME void
--SWIG_Python_AddErrorMsg(const char* mesg)
--{
--  PyObject *type = 0;
--  PyObject *value = 0;
--  PyObject *traceback = 0;
--
--  if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
--  if (value) {
--    char *tmp;
--    PyObject *old_str = PyObject_Str(value);
--    PyErr_Clear();
--    Py_XINCREF(type);
--
--    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(old_str);
--    Py_DECREF(value);
--  } else {
--    PyErr_SetString(PyExc_RuntimeError, mesg);
--  }
--}
--
--#if defined(SWIG_PYTHON_NO_THREADS)
--#  if defined(SWIG_PYTHON_THREADS)
--#    undef SWIG_PYTHON_THREADS
--#  endif
--#endif
--#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
--#  if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
--#    if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
--#      define SWIG_PYTHON_USE_GIL
--#    endif
--#  endif
--#  if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
--#    ifndef SWIG_PYTHON_INITIALIZE_THREADS
--#     define SWIG_PYTHON_INITIALIZE_THREADS  PyEval_InitThreads() 
--#    endif
--#    ifdef __cplusplus /* C++ code */
--       class SWIG_Python_Thread_Block {
--         bool status;
--         PyGILState_STATE state;
--       public:
--         void end() { if (status) { PyGILState_Release(state); status = false;} }
--         SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
--         ~SWIG_Python_Thread_Block() { end(); }
--       };
--       class SWIG_Python_Thread_Allow {
--         bool status;
--         PyThreadState *save;
--       public:
--         void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
--         SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
--         ~SWIG_Python_Thread_Allow() { end(); }
--       };
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   SWIG_Python_Thread_Block _swig_thread_block
--#      define SWIG_PYTHON_THREAD_END_BLOCK     _swig_thread_block.end()
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   SWIG_Python_Thread_Allow _swig_thread_allow
--#      define SWIG_PYTHON_THREAD_END_ALLOW     _swig_thread_allow.end()
--#    else /* C code */
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK   PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
--#      define SWIG_PYTHON_THREAD_END_BLOCK     PyGILState_Release(_swig_thread_block)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW   PyThreadState *_swig_thread_allow = PyEval_SaveThread()
--#      define SWIG_PYTHON_THREAD_END_ALLOW     PyEval_RestoreThread(_swig_thread_allow)
--#    endif
--#  else /* Old thread way, not implemented, user must provide it */
--#    if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
--#      define SWIG_PYTHON_INITIALIZE_THREADS
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
--#      define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
--#      define SWIG_PYTHON_THREAD_END_BLOCK
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
--#      define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#    endif
--#    if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
--#      define SWIG_PYTHON_THREAD_END_ALLOW
--#    endif
--#  endif
--#else /* No thread support */
--#  define SWIG_PYTHON_INITIALIZE_THREADS
--#  define SWIG_PYTHON_THREAD_BEGIN_BLOCK
--#  define SWIG_PYTHON_THREAD_END_BLOCK
--#  define SWIG_PYTHON_THREAD_BEGIN_ALLOW
--#  define SWIG_PYTHON_THREAD_END_ALLOW
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Python API portion that goes into the runtime
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Constant declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Constant Types */
--#define SWIG_PY_POINTER 4
--#define SWIG_PY_BINARY  5
--
--/* Constant information structure */
--typedef struct swig_const_info {
--  int type;
--  char *name;
--  long lvalue;
--  double dvalue;
--  void   *pvalue;
--  swig_type_info **ptype;
--} swig_const_info;
--
--
--/* -----------------------------------------------------------------------------
-- * Wrapper of PyInstanceMethod_New() used in Python 3
-- * It is exported to the generated module, used for -fastproxy
-- * ----------------------------------------------------------------------------- */
--#if PY_VERSION_HEX >= 0x03000000
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
--{
--  return PyInstanceMethod_New(func);
--}
--#else
--SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
--{
--  return NULL;
--}
--#endif
--
--#ifdef __cplusplus
--}
--#endif
--
--
--/* -----------------------------------------------------------------------------
-- * pyrun.swg
-- *
-- * This file contains the runtime support for Python modules
-- * and includes code for managing global variables and pointer
-- * type checking.
-- *
-- * ----------------------------------------------------------------------------- */
--
--/* Common SWIG API */
--
--/* for raw pointers */
--#define SWIG_Python_ConvertPtr(obj, pptr, type, flags)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
--#define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Python_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
--
--#ifdef SWIGPYTHON_BUILTIN
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(self, ptr, type, flags)
--#else
--#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--#endif
--
--#define SWIG_InternalNewPointerObj(ptr, type, flags)  SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
--
--#define SWIG_CheckImplicit(ty)                          SWIG_Python_CheckImplicit(ty) 
--#define SWIG_AcquirePtr(ptr, src)                       SWIG_Python_AcquirePtr(ptr, src)
--#define swig_owntype                                    int
--
--/* for raw packed data */
--#define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--/* for class or struct pointers */
--#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_ConvertPtr(obj, pptr, type, flags)
--#define SWIG_NewInstanceObj(ptr, type, flags)           SWIG_NewPointerObj(ptr, type, flags)
--
--/* for C or C++ function pointers */
--#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
--#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
--
--/* for C++ member pointers, ie, member methods */
--#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
--#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Python_NewPackedObj(ptr, sz, type)
--
--
--/* Runtime API */
--
--#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
--#define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
--#define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
--
--#define SWIG_SetErrorObj                                SWIG_Python_SetErrorObj                            
--#define SWIG_SetErrorMsg                              SWIG_Python_SetErrorMsg                            
--#define SWIG_ErrorType(code)                          SWIG_Python_ErrorType(code)                        
--#define SWIG_Error(code, msg)                         SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) 
--#define SWIG_fail                                     goto fail                                          
--
--
--/* Runtime API implementation */
--
--/* Error manipulation */
--
--SWIGINTERN void 
--SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK; 
--  PyErr_SetObject(errtype, obj);
--  Py_DECREF(obj);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--SWIGINTERN void 
--SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
--  SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--  PyErr_SetString(errtype, msg);
--  SWIG_PYTHON_THREAD_END_BLOCK;
--}
--
--#define SWIG_Python_Raise(obj, type, desc)  SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
--
--/* Set a constant value */
--
--#if defined(SWIGPYTHON_BUILTIN)
--
--SWIGINTERN void
--SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
--  PyObject *s = PyString_InternFromString(key);
--  PyList_Append(seq, s);
--  Py_DECREF(s);
--}
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);
--  if (public_interface)
--    SwigPyBuiltin_AddPublicSymbol(public_interface, name);
--}
--
--#else
--
--SWIGINTERN void
--SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
--#if PY_VERSION_HEX < 0x02030000
--  PyDict_SetItemString(d, (char *)name, obj);
--#else
--  PyDict_SetItemString(d, name, obj);
--#endif
--  Py_DECREF(obj);                            
--}
--
--#endif
--
--/* Append a value to the result obj */
--
--SWIGINTERN PyObject*
--SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
--#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyList_Check(result)) {
--      PyObject *o2 = result;
--      result = PyList_New(1);
--      PyList_SetItem(result, 0, o2);
--    }
--    PyList_Append(result,obj);
--    Py_DECREF(obj);
--  }
--  return result;
--#else
--  PyObject*   o2;
--  PyObject*   o3;
--  if (!result) {
--    result = obj;
--  } else if (result == Py_None) {
--    Py_DECREF(result);
--    result = obj;
--  } else {
--    if (!PyTuple_Check(result)) {
--      o2 = result;
--      result = PyTuple_New(1);
--      PyTuple_SET_ITEM(result, 0, o2);
--    }
--    o3 = PyTuple_New(1);
--    PyTuple_SET_ITEM(o3, 0, obj);
--    o2 = result;
--    result = PySequence_Concat(o2, o3);
--    Py_DECREF(o2);
--    Py_DECREF(o3);
--  }
--  return result;
--#endif
--}
--
--/* Unpack the argument tuple */
--
--SWIGINTERN int
--SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
--{
--  if (!args) {
--    if (!min && !max) {
--      return 1;
--    } else {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", 
--                 name, (min == max ? "" : "at least "), (int)min);
--      return 0;
--    }
--  }  
--  if (!PyTuple_Check(args)) {
--    if (min <= 1 && max >= 1) {
--      register int i;
--      objs[0] = args;
--      for (i = 1; i < max; ++i) {
--      objs[i] = 0;
--      }
--      return 2;
--    }
--    PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
--    return 0;
--  } else {
--    register Py_ssize_t l = PyTuple_GET_SIZE(args);
--    if (l < min) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at least "), (int)min, (int)l);
--      return 0;
--    } else if (l > max) {
--      PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
--                 name, (min == max ? "" : "at most "), (int)max, (int)l);
--      return 0;
--    } else {
--      register int i;
--      for (i = 0; i < l; ++i) {
--      objs[i] = PyTuple_GET_ITEM(args, i);
--      }
--      for (; l < max; ++l) {
--      objs[l] = 0;
--      }
--      return i + 1;
--    }    
--  }
--}
--
--/* A functor is a function object with one single object argument */
--#if PY_VERSION_HEX >= 0x02020000
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunctionObjArgs(functor, obj, NULL);
--#else
--#define SWIG_Python_CallFunctor(functor, obj)         PyObject_CallFunction(functor, "O", obj);
--#endif
--
--/*
--  Helper for static pointer initialization for both C and C++ code, for example
--  static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
--*/
--#ifdef __cplusplus
--#define SWIG_STATIC_POINTER(var)  var
--#else
--#define SWIG_STATIC_POINTER(var)  var = 0; if (!var) var
--#endif
--
--/* -----------------------------------------------------------------------------
-- * Pointer declarations
-- * ----------------------------------------------------------------------------- */
--
--/* Flags for new pointer objects */
--#define SWIG_POINTER_NOSHADOW       (SWIG_POINTER_OWN      << 1)
--#define SWIG_POINTER_NEW            (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
--
--#define SWIG_POINTER_IMPLICIT_CONV  (SWIG_POINTER_DISOWN   << 1)
--
--#define SWIG_BUILTIN_TP_INIT      (SWIG_POINTER_OWN << 2)
--#define SWIG_BUILTIN_INIT         (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--/*  How to access Py_None */
--#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
--#  ifndef SWIG_PYTHON_NO_BUILD_NONE
--#    ifndef SWIG_PYTHON_BUILD_NONE
--#      define SWIG_PYTHON_BUILD_NONE
--#    endif
--#  endif
--#endif
--
--#ifdef SWIG_PYTHON_BUILD_NONE
--#  ifdef Py_None
--#   undef Py_None
--#   define Py_None SWIG_Py_None()
--#  endif
--SWIGRUNTIMEINLINE PyObject * 
--_SWIG_Py_None(void)
--{
--  PyObject *none = Py_BuildValue((char*)"");
--  Py_DECREF(none);
--  return none;
--}
--SWIGRUNTIME PyObject * 
--SWIG_Py_None(void)
--{
--  static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
--  return none;
--}
--#endif
--
--/* The python void return value */
--
--SWIGRUNTIMEINLINE PyObject * 
--SWIG_Py_Void(void)
--{
--  PyObject *none = Py_None;
--  Py_INCREF(none);
--  return none;
--}
--
--/* SwigPyClientData */
--
--typedef struct {
--  PyObject *klass;
--  PyObject *newraw;
--  PyObject *newargs;
--  PyObject *destroy;
--  int delargs;
--  int implicitconv;
--  PyTypeObject *pytype;
--} SwigPyClientData;
--
--SWIGRUNTIMEINLINE int 
--SWIG_Python_CheckImplicit(swig_type_info *ty)
--{
--  SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
--  return data ? data->implicitconv : 0;
--}
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_ExceptionType(swig_type_info *desc) {
--  SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
--  PyObject *klass = data ? data->klass : 0;
--  return (klass ? klass : PyExc_RuntimeError);
--}
--
--
--SWIGRUNTIME SwigPyClientData * 
--SwigPyClientData_New(PyObject* obj)
--{
--  if (!obj) {
--    return 0;
--  } else {
--    SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
--    /* the klass element */
--    data->klass = obj;
--    Py_INCREF(data->klass);
--    /* the newraw method and newargs arguments used to create a new raw instance */
--    if (PyClass_Check(obj)) {
--      data->newraw = 0;
--      data->newargs = obj;
--      Py_INCREF(obj);
--    } else {
--#if (PY_VERSION_HEX < 0x02020000)
--      data->newraw = 0;
--#else
--      data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
--#endif
--      if (data->newraw) {
--      Py_INCREF(data->newraw);
--      data->newargs = PyTuple_New(1);
--      PyTuple_SetItem(data->newargs, 0, obj);
--      } else {
--      data->newargs = obj;
--      }
--      Py_INCREF(data->newargs);
--    }
--    /* the destroy method, aka as the C++ delete method */
--    data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      data->destroy = 0;
--    }
--    if (data->destroy) {
--      int flags;
--      Py_INCREF(data->destroy);
--      flags = PyCFunction_GET_FLAGS(data->destroy);
--#ifdef METH_O
--      data->delargs = !(flags & (METH_O));
--#else
--      data->delargs = 0;
--#endif
--    } else {
--      data->delargs = 0;
--    }
--    data->implicitconv = 0;
--    data->pytype = 0;
--    return data;
--  }
--}
--
--SWIGRUNTIME void 
--SwigPyClientData_Del(SwigPyClientData *data) {
--  Py_XDECREF(data->newraw);
--  Py_XDECREF(data->newargs);
--  Py_XDECREF(data->destroy);
--}
--
--/* =============== SwigPyObject =====================*/
--
--typedef struct {
--  PyObject_HEAD
--  void *ptr;
--  swig_type_info *ty;
--  int own;
--  PyObject *next;
--#ifdef SWIGPYTHON_BUILTIN
--  PyObject *dict;
--#endif
--} SwigPyObject;
--
--SWIGRUNTIME PyObject *
--SwigPyObject_long(SwigPyObject *v)
--{
--  return PyLong_FromVoidPtr(v->ptr);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_format(const char* fmt, SwigPyObject *v)
--{
--  PyObject *res = NULL;
--  PyObject *args = PyTuple_New(1);
--  if (args) {
--    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
--      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
--      if (ofmt) {
--#if PY_VERSION_HEX >= 0x03000000
--      res = PyUnicode_Format(ofmt,args);
--#else
--      res = PyString_Format(ofmt,args);
--#endif
--      Py_DECREF(ofmt);
--      }
--      Py_DECREF(args);
--    }
--  }
--  return res;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_oct(SwigPyObject *v)
--{
--  return SwigPyObject_format("%o",v);
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_hex(SwigPyObject *v)
--{
--  return SwigPyObject_format("%x",v);
--}
--
--SWIGRUNTIME PyObject *
--#ifdef METH_NOARGS
--SwigPyObject_repr(SwigPyObject *v)
--#else
--SwigPyObject_repr(SwigPyObject *v, PyObject *args)
--#endif
--{
--  const char *name = SWIG_TypePrettyName(v->ty);
--  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
--  if (v->next) {
--# ifdef METH_NOARGS
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
--# else
--    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
--# endif
--# if PY_VERSION_HEX >= 0x03000000
--    PyObject *joined = PyUnicode_Concat(repr, nrep);
--    Py_DecRef(repr);
--    Py_DecRef(nrep);
--    repr = joined;
--# else
--    PyString_ConcatAndDel(&repr,nrep);
--# endif
--  }
--  return repr;  
--}
--
--SWIGRUNTIME int
--SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char *str;
--#ifdef METH_NOARGS
--  PyObject *repr = SwigPyObject_repr(v);
--#else
--  PyObject *repr = SwigPyObject_repr(v, NULL);
--#endif
--  if (repr) {
--    str = SWIG_Python_str_AsChar(repr); 
--    fputs(str, fp);
--    SWIG_Python_str_DelForPy3(str);
--    Py_DECREF(repr);
--    return 0; 
--  } else {
--    return 1; 
--  }
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_str(SwigPyObject *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
--    SWIG_Python_str_FromChar(result) : 0;
--}
--
--SWIGRUNTIME int
--SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
--{
--  void *i = v->ptr;
--  void *j = w->ptr;
--  return (i < j) ? -1 : ((i > j) ? 1 : 0);
--}
--
--/* Added for Python 3.x, would it also be useful for Python 2.x? */
--SWIGRUNTIME PyObject*
--SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
--{
--  PyObject* res;
--  if( op != Py_EQ && op != Py_NE ) {
--    Py_INCREF(Py_NotImplemented);
--    return Py_NotImplemented;
--  }
--  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
--  return res;  
--}
--
--
--SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
--
--#ifdef SWIGPYTHON_BUILTIN
--static swig_type_info *SwigPyObject_stype = 0;
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--    SwigPyClientData *cd;
--    assert(SwigPyObject_stype);
--    cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--    assert(cd);
--    assert(cd->pytype);
--    return cd->pytype;
--}
--#else
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
--  return type;
--}
--#endif
--
--SWIGRUNTIMEINLINE int
--SwigPyObject_Check(PyObject *op) {
--#ifdef SWIGPYTHON_BUILTIN
--  PyTypeObject *target_tp = SwigPyObject_type();
--  if (PyType_IsSubtype(op->ob_type, target_tp))
--    return 1;
--  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
--#else
--  return (Py_TYPE(op) == SwigPyObject_type())
--    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
--#endif
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
--
--SWIGRUNTIME void
--SwigPyObject_dealloc(PyObject *v)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  PyObject *next = sobj->next;
--  if (sobj->own == SWIG_POINTER_OWN) {
--    swig_type_info *ty = sobj->ty;
--    SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--    PyObject *destroy = data ? data->destroy : 0;
--    if (destroy) {
--      /* destroy is always a VARARGS method */
--      PyObject *res;
--      if (data->delargs) {
--      /* we need to create a temporary object to carry the destroy operation */
--      PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
--      res = SWIG_Python_CallFunctor(destroy, tmp);
--      Py_DECREF(tmp);
--      } else {
--      PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
--      PyObject *mself = PyCFunction_GET_SELF(destroy);
--      res = ((*meth)(mself, v));
--      }
--      Py_XDECREF(res);
--    } 
--#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
--    else {
--      const char *name = SWIG_TypePrettyName(ty);
--      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
--    }
--#endif
--  } 
--  Py_XDECREF(next);
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyObject* 
--SwigPyObject_append(PyObject* v, PyObject* next)
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--#ifndef METH_O
--  PyObject *tmp = 0;
--  if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
--  next = tmp;
--#endif
--  if (!SwigPyObject_Check(next)) {
--    return NULL;
--  }
--  sobj->next = next;
--  Py_INCREF(next);
--  return SWIG_Py_Void();
--}
--
--SWIGRUNTIME PyObject* 
--#ifdef METH_NOARGS
--SwigPyObject_next(PyObject* v)
--#else
--SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *) v;
--  if (sobj->next) {    
--    Py_INCREF(sobj->next);
--    return sobj->next;
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_disown(PyObject *v)
--#else
--SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = 0;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--#ifdef METH_NOARGS
--SwigPyObject_acquire(PyObject *v)
--#else
--SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
--#endif
--{
--  SwigPyObject *sobj = (SwigPyObject *)v;
--  sobj->own = SWIG_POINTER_OWN;
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject*
--SwigPyObject_own(PyObject *v, PyObject *args)
--{
--  PyObject *val = 0;
--#if (PY_VERSION_HEX < 0x02020000)
--  if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
--#elif (PY_VERSION_HEX < 0x02050000)
--  if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
--#else
--  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
--#endif
--    {
--      return NULL;
--    } 
--  else
--    {
--      SwigPyObject *sobj = (SwigPyObject *)v;
--      PyObject *obj = PyBool_FromLong(sobj->own);
--      if (val) {
--#ifdef METH_NOARGS
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v);
--      } else {
--        SwigPyObject_disown(v);
--      }
--#else
--      if (PyObject_IsTrue(val)) {
--        SwigPyObject_acquire(v,args);
--      } else {
--        SwigPyObject_disown(v,args);
--      }
--#endif
--      } 
--      return obj;
--    }
--}
--
--#ifdef METH_O
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#else
--static PyMethodDef
--swigobject_methods[] = {
--  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
--  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
--  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
--  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
--  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
--  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
--  {0, 0, 0, 0}  
--};
--#endif
--
--#if PY_VERSION_HEX < 0x02020000
--SWIGINTERN PyObject *
--SwigPyObject_getattr(SwigPyObject *sobj,char *name)
--{
--  return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
--}
--#endif
--
--SWIGRUNTIME PyTypeObject*
--SwigPyObject_TypeOnce(void) {
--  static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
--
--  static PyNumberMethods SwigPyObject_as_number = {
--    (binaryfunc)0, /*nb_add*/
--    (binaryfunc)0, /*nb_subtract*/
--    (binaryfunc)0, /*nb_multiply*/
--    /* nb_divide removed in Python 3 */
--#if PY_VERSION_HEX < 0x03000000
--    (binaryfunc)0, /*nb_divide*/
--#endif
--    (binaryfunc)0, /*nb_remainder*/
--    (binaryfunc)0, /*nb_divmod*/
--    (ternaryfunc)0,/*nb_power*/
--    (unaryfunc)0,  /*nb_negative*/
--    (unaryfunc)0,  /*nb_positive*/
--    (unaryfunc)0,  /*nb_absolute*/
--    (inquiry)0,    /*nb_nonzero*/
--    0,                   /*nb_invert*/
--    0,                   /*nb_lshift*/
--    0,                   /*nb_rshift*/
--    0,                   /*nb_and*/
--    0,                   /*nb_xor*/
--    0,                   /*nb_or*/
--#if PY_VERSION_HEX < 0x03000000
--    0,   /*nb_coerce*/
--#endif
--    (unaryfunc)SwigPyObject_long, /*nb_int*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_long, /*nb_long*/
--#else
--    0, /*nb_reserved*/
--#endif
--    (unaryfunc)0,                 /*nb_float*/
--#if PY_VERSION_HEX < 0x03000000
--    (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
--    (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
--#endif
--#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
--#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
--#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
--    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
--#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
--    0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
--#endif
--  };
--
--  static PyTypeObject swigpyobject_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyObject",               /* tp_name */
--      sizeof(SwigPyObject),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyObject_print,        /* tp_print */
--#if PY_VERSION_HEX < 0x02020000
--      (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
--#else
--      (getattrfunc)0,                       /* tp_getattr */
--#endif
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX >= 0x03000000
--    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
--#else
--      (cmpfunc)SwigPyObject_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyObject_repr,          /* tp_repr */
--      &SwigPyObject_as_number,              /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyObject_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigobject_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      swigobject_methods,                   /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpyobject_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpyobject_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpyobject_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpyobject_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
--{
--  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
--  if (sobj) {
--    sobj->ptr  = ptr;
--    sobj->ty   = ty;
--    sobj->own  = own;
--    sobj->next = 0;
--  }
--  return (PyObject *)sobj;
--}
--
--/* -----------------------------------------------------------------------------
-- * Implements a simple Swig Packed type, and use it instead of string
-- * ----------------------------------------------------------------------------- */
--
--typedef struct {
--  PyObject_HEAD
--  void *pack;
--  swig_type_info *ty;
--  size_t size;
--} SwigPyPacked;
--
--SWIGRUNTIME int
--SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
--{
--  char result[SWIG_BUFFER_SIZE];
--  fputs("<Swig Packed ", fp); 
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    fputs("at ", fp); 
--    fputs(result, fp); 
--  }
--  fputs(v->ty->name,fp); 
--  fputs(">", fp);
--  return 0; 
--}
--  
--SWIGRUNTIME PyObject *
--SwigPyPacked_repr(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
--    return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
--  }  
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_str(SwigPyPacked *v)
--{
--  char result[SWIG_BUFFER_SIZE];
--  if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
--    return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
--  } else {
--    return SWIG_Python_str_FromChar(v->ty->name);
--  }  
--}
--
--SWIGRUNTIME int
--SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
--{
--  size_t i = v->size;
--  size_t j = w->size;
--  int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
--  return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
--}
--
--SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_type(void) {
--  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
--  return type;
--}
--
--SWIGRUNTIMEINLINE int
--SwigPyPacked_Check(PyObject *op) {
--  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
--    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
--}
--
--SWIGRUNTIME void
--SwigPyPacked_dealloc(PyObject *v)
--{
--  if (SwigPyPacked_Check(v)) {
--    SwigPyPacked *sobj = (SwigPyPacked *) v;
--    free(sobj->pack);
--  }
--  PyObject_DEL(v);
--}
--
--SWIGRUNTIME PyTypeObject*
--SwigPyPacked_TypeOnce(void) {
--  static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
--  static PyTypeObject swigpypacked_type;
--  static int type_init = 0;
--  if (!type_init) {
--    const PyTypeObject tmp = {
--      /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX>=0x03000000
--      PyVarObject_HEAD_INIT(NULL, 0)
--#else
--      PyObject_HEAD_INIT(NULL)
--      0,                                    /* ob_size */
--#endif
--      (char *)"SwigPyPacked",               /* tp_name */
--      sizeof(SwigPyPacked),                 /* tp_basicsize */
--      0,                                    /* tp_itemsize */
--      (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
--      (printfunc)SwigPyPacked_print,        /* tp_print */
--      (getattrfunc)0,                       /* tp_getattr */
--      (setattrfunc)0,                       /* tp_setattr */
--#if PY_VERSION_HEX>=0x03000000
--      0, /* tp_reserved in 3.0.1 */
--#else
--      (cmpfunc)SwigPyPacked_compare,        /* tp_compare */
--#endif
--      (reprfunc)SwigPyPacked_repr,          /* tp_repr */
--      0,                                    /* tp_as_number */
--      0,                                    /* tp_as_sequence */
--      0,                                    /* tp_as_mapping */
--      (hashfunc)0,                          /* tp_hash */
--      (ternaryfunc)0,                       /* tp_call */
--      (reprfunc)SwigPyPacked_str,           /* tp_str */
--      PyObject_GenericGetAttr,              /* tp_getattro */
--      0,                                    /* tp_setattro */
--      0,                                    /* tp_as_buffer */
--      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
--      swigpacked_doc,                       /* tp_doc */
--      0,                                    /* tp_traverse */
--      0,                                    /* tp_clear */
--      0,                                    /* tp_richcompare */
--      0,                                    /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--      0,                                    /* tp_iter */
--      0,                                    /* tp_iternext */
--      0,                                    /* tp_methods */
--      0,                                    /* tp_members */
--      0,                                    /* tp_getset */
--      0,                                    /* tp_base */
--      0,                                    /* tp_dict */
--      0,                                    /* tp_descr_get */
--      0,                                    /* tp_descr_set */
--      0,                                    /* tp_dictoffset */
--      0,                                    /* tp_init */
--      0,                                    /* tp_alloc */
--      0,                                    /* tp_new */
--      0,                                    /* tp_free */
--      0,                                    /* tp_is_gc */
--      0,                                    /* tp_bases */
--      0,                                    /* tp_mro */
--      0,                                    /* tp_cache */
--      0,                                    /* tp_subclasses */
--      0,                                    /* tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--      0,                                    /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--      0,                                    /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--      0,0,0,0                               /* tp_alloc -> tp_next */
--#endif
--    };
--    swigpypacked_type = tmp;
--    type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--    swigpypacked_type.ob_type = &PyType_Type;
--#else
--    if (PyType_Ready(&swigpypacked_type) < 0)
--      return NULL;
--#endif
--  }
--  return &swigpypacked_type;
--}
--
--SWIGRUNTIME PyObject *
--SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
--{
--  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
--  if (sobj) {
--    void *pack = malloc(size);
--    if (pack) {
--      memcpy(pack, ptr, size);
--      sobj->pack = pack;
--      sobj->ty   = ty;
--      sobj->size = size;
--    } else {
--      PyObject_DEL((PyObject *) sobj);
--      sobj = 0;
--    }
--  }
--  return (PyObject *) sobj;
--}
--
--SWIGRUNTIME swig_type_info *
--SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
--{
--  if (SwigPyPacked_Check(obj)) {
--    SwigPyPacked *sobj = (SwigPyPacked *)obj;
--    if (sobj->size != size) return 0;
--    memcpy(ptr, sobj->pack, size);
--    return sobj->ty;
--  } else {
--    return 0;
--  }
--}
--
--/* -----------------------------------------------------------------------------
-- * pointers/data manipulation
-- * ----------------------------------------------------------------------------- */
--
--SWIGRUNTIMEINLINE PyObject *
--_SWIG_This(void)
--{
--    return SWIG_Python_str_FromChar("this");
--}
--
--static PyObject *swig_this = NULL;
--
--SWIGRUNTIME PyObject *
--SWIG_This(void)
--{
--  if (swig_this == NULL)
--    swig_this = _SWIG_This();
--  return swig_this;
--}
--
--/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
--
--/* TODO: I don't know how to implement the fast getset in Python 3 right now */
--#if PY_VERSION_HEX>=0x03000000
--#define SWIG_PYTHON_SLOW_GETSET_THIS 
--#endif
--
--SWIGRUNTIME SwigPyObject *
--SWIG_Python_GetSwigThis(PyObject *pyobj) 
--{
--  PyObject *obj;
--
--  if (SwigPyObject_Check(pyobj))
--    return (SwigPyObject *) pyobj;
--
--#ifdef SWIGPYTHON_BUILTIN
--  (void)obj;
--# ifdef PyWeakref_CheckProxy
--  if (PyWeakref_CheckProxy(pyobj)) {
--    pyobj = PyWeakref_GET_OBJECT(pyobj);
--    if (pyobj && SwigPyObject_Check(pyobj))
--      return (SwigPyObject*) pyobj;
--  }
--# endif
--  return NULL;
--#else
--
--  obj = 0;
--
--#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
--  if (PyInstance_Check(pyobj)) {
--    obj = _PyInstance_Lookup(pyobj, SWIG_This());      
--  } else {
--    PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
--    if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
--    } else {
--#ifdef PyWeakref_CheckProxy
--      if (PyWeakref_CheckProxy(pyobj)) {
--      PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
--      return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
--      }
--#endif
--      obj = PyObject_GetAttr(pyobj,SWIG_This());
--      if (obj) {
--      Py_DECREF(obj);
--      } else {
--      if (PyErr_Occurred()) PyErr_Clear();
--      return 0;
--      }
--    }
--  }
--#else
--  obj = PyObject_GetAttr(pyobj,SWIG_This());
--  if (obj) {
--    Py_DECREF(obj);
--  } else {
--    if (PyErr_Occurred()) PyErr_Clear();
--    return 0;
--  }
--#endif
--  if (obj && !SwigPyObject_Check(obj)) {
--    /* a PyObject is called 'this', try to get the 'real this'
--       SwigPyObject from it */ 
--    return SWIG_Python_GetSwigThis(obj);
--  }
--  return (SwigPyObject *)obj;
--#endif
--}
--
--/* Acquire a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_AcquirePtr(PyObject *obj, int own) {
--  if (own == SWIG_POINTER_OWN) {
--    SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
--    if (sobj) {
--      int oldown = sobj->own;
--      sobj->own = own;
--      return oldown;
--    }
--  }
--  return 0;
--}
--
--/* Convert a pointer value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
--  int res;
--  SwigPyObject *sobj;
--
--  if (!obj)
--    return SWIG_ERROR;
--  if (obj == Py_None) {
--    if (ptr)
--      *ptr = 0;
--    return SWIG_OK;
--  }
--
--  res = SWIG_ERROR;
--
--  sobj = SWIG_Python_GetSwigThis(obj);
--  if (own)
--    *own = 0;
--  while (sobj) {
--    void *vptr = sobj->ptr;
--    if (ty) {
--      swig_type_info *to = sobj->ty;
--      if (to == ty) {
--        /* no type cast needed */
--        if (ptr) *ptr = vptr;
--        break;
--      } else {
--        swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--        if (!tc) {
--          sobj = (SwigPyObject *)sobj->next;
--        } else {
--          if (ptr) {
--            int newmemory = 0;
--            *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--            if (newmemory == SWIG_CAST_NEW_MEMORY) {
--              assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
--              if (own)
--                *own = *own | SWIG_CAST_NEW_MEMORY;
--            }
--          }
--          break;
--        }
--      }
--    } else {
--      if (ptr) *ptr = vptr;
--      break;
--    }
--  }
--  if (sobj) {
--    if (own)
--      *own = *own | sobj->own;
--    if (flags & SWIG_POINTER_DISOWN) {
--      sobj->own = 0;
--    }
--    res = SWIG_OK;
--  } else {
--    if (flags & SWIG_POINTER_IMPLICIT_CONV) {
--      SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
--      if (data && !data->implicitconv) {
--        PyObject *klass = data->klass;
--        if (klass) {
--          PyObject *impconv;
--          data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
--          impconv = SWIG_Python_CallFunctor(klass, obj);
--          data->implicitconv = 0;
--          if (PyErr_Occurred()) {
--            PyErr_Clear();
--            impconv = 0;
--          }
--          if (impconv) {
--            SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
--            if (iobj) {
--              void *vptr;
--              res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
--              if (SWIG_IsOK(res)) {
--                if (ptr) {
--                  *ptr = vptr;
--                  /* transfer the ownership to 'ptr' */
--                  iobj->own = 0;
--                  res = SWIG_AddCast(res);
--                  res = SWIG_AddNewMask(res);
--                } else {
--                  res = SWIG_AddCast(res);                
--                }
--              }
--            }
--            Py_DECREF(impconv);
--          }
--        }
--      }
--    }
--  }
--  return res;
--}
--
--/* Convert a function ptr value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
--  if (!PyCFunction_Check(obj)) {
--    return SWIG_ConvertPtr(obj, ptr, ty, 0);
--  } else {
--    void *vptr = 0;
--    
--    /* here we get the method pointer for callbacks */
--    const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
--    const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
--    if (desc)
--      desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
--    if (!desc) 
--      return SWIG_ERROR;
--    if (ty) {
--      swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
--      if (tc) {
--        int newmemory = 0;
--        *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
--        assert(!newmemory); /* newmemory handling not yet implemented */
--      } else {
--        return SWIG_ERROR;
--      }
--    } else {
--      *ptr = vptr;
--    }
--    return SWIG_OK;
--  }
--}
--
--/* Convert a packed value value */
--
--SWIGRUNTIME int
--SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
--  swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
--  if (!to) return SWIG_ERROR;
--  if (ty) {
--    if (to != ty) {
--      /* check type cast? */
--      swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
--      if (!tc) return SWIG_ERROR;
--    }
--  }
--  return SWIG_OK;
--}  
--
--/* -----------------------------------------------------------------------------
-- * Create a new pointer object
-- * ----------------------------------------------------------------------------- */
--
--/*
--  Create a new instance object, without calling __init__, and set the
--  'this' attribute.
--*/
--
--SWIGRUNTIME PyObject* 
--SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
--{
--#if (PY_VERSION_HEX >= 0x02020000)
--  PyObject *inst = 0;
--  PyObject *newraw = data->newraw;
--  if (newraw) {
--    inst = PyObject_Call(newraw, data->newargs, NULL);
--    if (inst) {
--#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
--      PyObject **dictptr = _PyObject_GetDictPtr(inst);
--      if (dictptr != NULL) {
--      PyObject *dict = *dictptr;
--      if (dict == NULL) {
--        dict = PyDict_New();
--        *dictptr = dict;
--        PyDict_SetItem(dict, SWIG_This(), swig_this);
--      }
--      }
--#else
--      PyObject *key = SWIG_This();
--      PyObject_SetAttr(inst, key, swig_this);
--#endif
--    }
--  } else {
--#if PY_VERSION_HEX >= 0x03000000
--    inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
--    if (inst) {
--      PyObject_SetAttr(inst, SWIG_This(), swig_this);
--      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
--    }
--#else
--    PyObject *dict = PyDict_New();
--    if (dict) {
--      PyDict_SetItem(dict, SWIG_This(), swig_this);
--      inst = PyInstance_NewRaw(data->newargs, dict);
--      Py_DECREF(dict);
--    }
--#endif
--  }
--  return inst;
--#else
--#if (PY_VERSION_HEX >= 0x02010000)
--  PyObject *inst = 0;
--  PyObject *dict = PyDict_New();
--  if (dict) {
--    PyDict_SetItem(dict, SWIG_This(), swig_this);
--    inst = PyInstance_NewRaw(data->newargs, dict);
--    Py_DECREF(dict);
--  }
--  return (PyObject *) inst;
--#else
--  PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
--  if (inst == NULL) {
--    return NULL;
--  }
--  inst->in_class = (PyClassObject *)data->newargs;
--  Py_INCREF(inst->in_class);
--  inst->in_dict = PyDict_New();
--  if (inst->in_dict == NULL) {
--    Py_DECREF(inst);
--    return NULL;
--  }
--#ifdef Py_TPFLAGS_HAVE_WEAKREFS
--  inst->in_weakreflist = NULL;
--#endif
--#ifdef Py_TPFLAGS_GC
--  PyObject_GC_Init(inst);
--#endif
--  PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
--  return (PyObject *) inst;
--#endif
--#endif
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
--{
-- PyObject *dict;
--#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
-- PyObject **dictptr = _PyObject_GetDictPtr(inst);
-- if (dictptr != NULL) {
--   dict = *dictptr;
--   if (dict == NULL) {
--     dict = PyDict_New();
--     *dictptr = dict;
--   }
--   PyDict_SetItem(dict, SWIG_This(), swig_this);
--   return;
-- }
--#endif
-- dict = PyObject_GetAttrString(inst, (char*)"__dict__");
-- PyDict_SetItem(dict, SWIG_This(), swig_this);
-- Py_DECREF(dict);
--} 
--
--
--SWIGINTERN PyObject *
--SWIG_Python_InitShadowInstance(PyObject *args) {
--  PyObject *obj[2];
--  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
--    return NULL;
--  } else {
--    SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
--    if (sthis) {
--      SwigPyObject_append((PyObject*) sthis, obj[1]);
--    } else {
--      SWIG_Python_SetSwigThis(obj[0], obj[1]);
--    }
--    return SWIG_Py_Void();
--  }
--}
--
--/* Create a new pointer object */
--
--SWIGRUNTIME PyObject *
--SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
--  SwigPyClientData *clientdata;
--  PyObject * robj;
--  int own;
--
--  if (!ptr)
--    return SWIG_Py_Void();
--
--  clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
--  own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
--  if (clientdata && clientdata->pytype) {
--    SwigPyObject *newobj;
--    if (flags & SWIG_BUILTIN_TP_INIT) {
--      newobj = (SwigPyObject*) self;
--      if (newobj->ptr) {
--        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
--        while (newobj->next)
--        newobj = (SwigPyObject *) newobj->next;
--        newobj->next = next_self;
--        newobj = (SwigPyObject *)next_self;
--      }
--    } else {
--      newobj = PyObject_New(SwigPyObject, clientdata->pytype);
--    }
--    if (newobj) {
--      newobj->ptr = ptr;
--      newobj->ty = type;
--      newobj->own = own;
--      newobj->next = 0;
--#ifdef SWIGPYTHON_BUILTIN
--      newobj->dict = 0;
--#endif
--      return (PyObject*) newobj;
--    }
--    return SWIG_Py_Void();
--  }
--
--  assert(!(flags & SWIG_BUILTIN_TP_INIT));
--
--  robj = SwigPyObject_New(ptr, type, own);
--  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
--    PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
--    Py_DECREF(robj);
--    robj = inst;
--  }
--  return robj;
--}
--
--/* Create a new packed object */
--
--SWIGRUNTIMEINLINE PyObject *
--SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
--  return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
--}
--
--/* -----------------------------------------------------------------------------*
-- *  Get type list 
-- * -----------------------------------------------------------------------------*/
--
--#ifdef SWIG_LINK_RUNTIME
--void *SWIG_ReturnGlobalTypeList(void *);
--#endif
--
--SWIGRUNTIME swig_module_info *
--SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
--  static void *type_pointer = (void *)0;
--  /* first check if module already created */
--  if (!type_pointer) {
--#ifdef SWIG_LINK_RUNTIME
--    type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
--#else
--# ifdef SWIGPY_USE_CAPSULE
--    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
--# else
--    type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
--                                  (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
--# endif
--    if (PyErr_Occurred()) {
--      PyErr_Clear();
--      type_pointer = (void *)0;
--    }
--#endif
--  }
--  return (swig_module_info *) type_pointer;
--}
--
--#if PY_MAJOR_VERSION < 2
--/* PyModule_AddObject function was introduced in Python 2.0.  The following function
--   is copied out of Python/modsupport.c in python version 2.3.4 */
--SWIGINTERN int
--PyModule_AddObject(PyObject *m, char *name, PyObject *o)
--{
--  PyObject *dict;
--  if (!PyModule_Check(m)) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs module as first arg");
--    return SWIG_ERROR;
--  }
--  if (!o) {
--    PyErr_SetString(PyExc_TypeError,
--                  "PyModule_AddObject() needs non-NULL value");
--    return SWIG_ERROR;
--  }
--  
--  dict = PyModule_GetDict(m);
--  if (dict == NULL) {
--    /* Internal error -- modules must have a dict! */
--    PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
--               PyModule_GetName(m));
--    return SWIG_ERROR;
--  }
--  if (PyDict_SetItemString(dict, name, o))
--    return SWIG_ERROR;
--  Py_DECREF(o);
--  return SWIG_OK;
--}
--#endif
--
--SWIGRUNTIME void
--#ifdef SWIGPY_USE_CAPSULE
--SWIG_Python_DestroyModule(PyObject *obj)
--#else
--SWIG_Python_DestroyModule(void *vptr)
--#endif
--{
--#ifdef SWIGPY_USE_CAPSULE
--  swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
--#else
--  swig_module_info *swig_module = (swig_module_info *) vptr;
--#endif
--  swig_type_info **types = swig_module->types;
--  size_t i;
--  for (i =0; i < swig_module->size; ++i) {
--    swig_type_info *ty = types[i];
--    if (ty->owndata) {
--      SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
--      if (data) SwigPyClientData_Del(data);
--    }
--  }
--  Py_DECREF(SWIG_This());
--  swig_this = NULL;
--}
--
--SWIGRUNTIME void
--SWIG_Python_SetModule(swig_module_info *swig_module) {
--#if PY_VERSION_HEX >= 0x03000000
-- /* Add a dummy module object into sys.modules */
--  PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
--#else
--  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
--  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
--#endif
--#ifdef SWIGPY_USE_CAPSULE
--  PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#else
--  PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
--  if (pointer && module) {
--    PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
--  } else {
--    Py_XDECREF(pointer);
--  }
--#endif
--}
--
--/* The python cached type query */
--SWIGRUNTIME PyObject *
--SWIG_Python_TypeCache(void) {
--  static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
--  return cache;
--}
--
--SWIGRUNTIME swig_type_info *
--SWIG_Python_TypeQuery(const char *type)
--{
--  PyObject *cache = SWIG_Python_TypeCache();
--  PyObject *key = SWIG_Python_str_FromChar(type); 
--  PyObject *obj = PyDict_GetItem(cache, key);
--  swig_type_info *descriptor;
--  if (obj) {
--#ifdef SWIGPY_USE_CAPSULE
--    descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
--#else
--    descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
--#endif
--  } else {
--    swig_module_info *swig_module = SWIG_GetModule(0);
--    descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
--    if (descriptor) {
--#ifdef SWIGPY_USE_CAPSULE
--      obj = PyCapsule_New((void*) descriptor, NULL, NULL);
--#else
--      obj = PyCObject_FromVoidPtr(descriptor, NULL);
--#endif
--      PyDict_SetItem(cache, key, obj);
--      Py_DECREF(obj);
--    }
--  }
--  Py_DECREF(key);
--  return descriptor;
--}
--
--/* 
--   For backward compatibility only
--*/
--#define SWIG_POINTER_EXCEPTION  0
--#define SWIG_arg_fail(arg)      SWIG_Python_ArgFail(arg)
--#define SWIG_MustGetPtr(p, type, argnum, flags)  SWIG_Python_MustGetPtr(p, type, argnum, flags)
--
--SWIGRUNTIME int
--SWIG_Python_AddErrMesg(const char* mesg, int infront)
--{  
--  if (PyErr_Occurred()) {
--    PyObject *type = 0;
--    PyObject *value = 0;
--    PyObject *traceback = 0;
--    PyErr_Fetch(&type, &value, &traceback);
--    if (value) {
--      char *tmp;
--      PyObject *old_str = PyObject_Str(value);
--      Py_XINCREF(type);
--      PyErr_Clear();
--      if (infront) {
--      PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
--      } else {
--      PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
--      }
--      SWIG_Python_str_DelForPy3(tmp);
--      Py_DECREF(old_str);
--    }
--    return 1;
--  } else {
--    return 0;
--  }
--}
--  
--SWIGRUNTIME int
--SWIG_Python_ArgFail(int argnum)
--{
--  if (PyErr_Occurred()) {
--    /* add information about failing argument */
--    char mesg[256];
--    PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
--    return SWIG_Python_AddErrMesg(mesg, 1);
--  } else {
--    return 0;
--  }
--}
--
--SWIGRUNTIMEINLINE const char *
--SwigPyObject_GetDesc(PyObject *self)
--{
--  SwigPyObject *v = (SwigPyObject *)self;
--  swig_type_info *ty = v ? v->ty : 0;
--  return ty ? ty->str : "";
--}
--
--SWIGRUNTIME void
--SWIG_Python_TypeError(const char *type, PyObject *obj)
--{
--  if (type) {
--#if defined(SWIG_COBJECT_TYPES)
--    if (obj && SwigPyObject_Check(obj)) {
--      const char *otype = (const char *) SwigPyObject_GetDesc(obj);
--      if (otype) {
--      PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
--                   type, otype);
--      return;
--      }
--    } else 
--#endif      
--    {
--      const char *otype = (obj ? obj->ob_type->tp_name : 0); 
--      if (otype) {
--      PyObject *str = PyObject_Str(obj);
--      const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
--      if (cstr) {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
--                     type, otype, cstr);
--          SWIG_Python_str_DelForPy3(cstr);
--      } else {
--        PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
--                     type, otype);
--      }
--      Py_XDECREF(str);
--      return;
--      }
--    }   
--    PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
--  } else {
--    PyErr_Format(PyExc_TypeError, "unexpected type is received");
--  }
--}
--
--
--/* Convert a pointer value, signal an exception on a type mismatch */
--SWIGRUNTIME void *
--SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
--  void *result;
--  if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
--    PyErr_Clear();
--#if SWIG_POINTER_EXCEPTION
--    if (flags) {
--      SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
--      SWIG_Python_ArgFail(argnum);
--    }
--#endif
--  }
--  return result;
--}
--
--#ifdef SWIGPYTHON_BUILTIN
--SWIGRUNTIME int
--SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
--  PyTypeObject *tp = obj->ob_type;
--  PyObject *descr;
--  PyObject *encoded_name;
--  descrsetfunc f;
--  int res;
--
--# ifdef Py_USING_UNICODE
--  if (PyString_Check(name)) {
--    name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
--    if (!name)
--      return -1;
--  } else if (!PyUnicode_Check(name))
--# else
--  if (!PyString_Check(name))
--# endif
--  {
--    PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
--    return -1;
--  } else {
--    Py_INCREF(name);
--  }
--
--  if (!tp->tp_dict) {
--    if (PyType_Ready(tp) < 0)
--      goto done;
--  }
--
--  res = -1;
--  descr = _PyType_Lookup(tp, name);
--  f = NULL;
--  if (descr != NULL)
--    f = descr->ob_type->tp_descr_set;
--  if (!f) {
--    if (PyString_Check(name)) {
--      encoded_name = name;
--      Py_INCREF(name);
--    } else {
--      encoded_name = PyUnicode_AsUTF8String(name);
--    }
--    PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
--    Py_DECREF(encoded_name);
--  } else {
--    res = f(descr, obj, value);
--  }
--  
--  done:
--  Py_DECREF(name);
--  return res;
--}
--#endif
--
--
--#ifdef __cplusplus
--}
--#endif
--
--
--
--#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) 
--
--#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else 
--
--
--
--/* -------- TYPES TABLE (BEGIN) -------- */
--
--#define SWIGTYPE_p__private_detail__MASKUNION swig_types[0]
--#define SWIGTYPE_p__private_detail__VPMask__VMaskType swig_types[1]
--#define SWIGTYPE_p_allocator_type swig_types[2]
--#define SWIGTYPE_p_char swig_types[3]
--#define SWIGTYPE_p_difference_type swig_types[4]
--#define SWIGTYPE_p_double swig_types[5]
--#define SWIGTYPE_p_im__DOUBLEMASK swig_types[6]
--#define SWIGTYPE_p_im__INTMASK swig_types[7]
--#define SWIGTYPE_p_int swig_types[8]
--#define SWIGTYPE_p_matrix swig_types[9]
--#define SWIGTYPE_p_size_type swig_types[10]
--#define SWIGTYPE_p_std__ostream swig_types[11]
--#define SWIGTYPE_p_value_type swig_types[12]
--#define SWIGTYPE_p_vips__VDMask swig_types[13]
--#define SWIGTYPE_p_vips__VError swig_types[14]
--#define SWIGTYPE_p_vips__VIMask swig_types[15]
--#define SWIGTYPE_p_vips__VMask swig_types[16]
--static swig_type_info *swig_types[18];
--static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0};
--#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
--#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
--
--/* -------- TYPES TABLE (END) -------- */
--
--#if (PY_VERSION_HEX <= 0x02000000)
--# if !defined(SWIG_PYTHON_CLASSIC)
--#  error "This python version requires swig to be run with the '-classic' option"
--# endif
--#endif
--
--/*-----------------------------------------------
--              @(target):= vmaskmodule.so
--  ------------------------------------------------*/
--#if PY_VERSION_HEX >= 0x03000000
--#  define SWIG_init    PyInit_vmaskmodule
--
--#else
--#  define SWIG_init    initvmaskmodule
--
--#endif
--#define SWIG_name    "vmaskmodule"
--
--#define SWIGVERSION 0x020010 
--#define SWIG_VERSION SWIGVERSION
--
--
--#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) 
--#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a)) 
--
--
--#include <stdexcept>
--
--
--namespace swig {
--  class SwigPtr_PyObject {
--  protected:
--    PyObject *_obj;
--
--  public:
--    SwigPtr_PyObject() :_obj(0)
--    {
--    }
--
--    SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
--    {
--      Py_XINCREF(_obj);      
--    }
--    
--    SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
--    {
--      if (initial_ref) {
--        Py_XINCREF(_obj);
--      }
--    }
--    
--    SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) 
--    {
--      Py_XINCREF(item._obj);
--      Py_XDECREF(_obj);
--      _obj = item._obj;
--      return *this;      
--    }
--    
--    ~SwigPtr_PyObject() 
--    {
--      Py_XDECREF(_obj);
--    }
--    
--    operator PyObject *() const
--    {
--      return _obj;
--    }
--
--    PyObject *operator->() const
--    {
--      return _obj;
--    }
--  };
--}
--
--
--namespace swig {
--  struct SwigVar_PyObject : SwigPtr_PyObject {
--    SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
--    
--    SwigVar_PyObject & operator = (PyObject* obj)
--    {
--      Py_XDECREF(_obj);
--      _obj = obj;
--      return *this;      
--    }
--  };
--}
--
--
--#include <stdexcept>
--#include <vips/vipscpp.h>
--
--
--  #include <stddef.h>
--
--
--namespace swig {
--  struct stop_iteration {
--  };
--
--  struct SwigPyIterator {
--  private:
--    SwigPtr_PyObject _seq;
--
--  protected:
--    SwigPyIterator(PyObject *seq) : _seq(seq)
--    {
--    }
--      
--  public:
--    virtual ~SwigPyIterator() {}
--
--    // Access iterator method, required by Python
--    virtual PyObject *value() const = 0;
--
--    // Forward iterator method, required by Python
--    virtual SwigPyIterator *incr(size_t n = 1) = 0;
--    
--    // Backward iterator method, very common in C++, but not required in Python
--    virtual SwigPyIterator *decr(size_t /*n*/ = 1)
--    {
--      throw stop_iteration();
--    }
--
--    // Random access iterator methods, but not required in Python
--    virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const
--    {
--      throw std::invalid_argument("operation not supported");
--    }
--
--    virtual bool equal (const SwigPyIterator &/*x*/) const
--    {
--      throw std::invalid_argument("operation not supported");
--    }
--    
--    // C++ common/needed methods
--    virtual SwigPyIterator *copy() const = 0;
--
--    PyObject *next()     
--    {
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
--      PyObject *obj = value();
--      incr();       
--      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
--      return obj;     
--    }
--
--    /* Make an alias for Python 3.x */
--    PyObject *__next__()
--    {
--      return next();
--    }
--
--    PyObject *previous()
--    {
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
--      decr();
--      PyObject *obj = value();
--      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads       
--      return obj;
--    }
--
--    SwigPyIterator *advance(ptrdiff_t n)
--    {
--      return  (n > 0) ?  incr(n) : decr(-n);
--    }
--      
--    bool operator == (const SwigPyIterator& x)  const
--    {
--      return equal(x);
--    }
--      
--    bool operator != (const SwigPyIterator& x) const
--    {
--      return ! operator==(x);
--    }
--      
--    SwigPyIterator& operator += (ptrdiff_t n)
--    {
--      return *advance(n);
--    }
--
--    SwigPyIterator& operator -= (ptrdiff_t n)
--    {
--      return *advance(-n);
--    }
--      
--    SwigPyIterator* operator + (ptrdiff_t n) const
--    {
--      return copy()->advance(n);
--    }
--
--    SwigPyIterator* operator - (ptrdiff_t n) const
--    {
--      return copy()->advance(-n);
--    }
--      
--    ptrdiff_t operator - (const SwigPyIterator& x) const
--    {
--      return x.distance(*this);
--    }
--      
--    static swig_type_info* descriptor() {
--      static int init = 0;
--      static swig_type_info* desc = 0;
--      if (!init) {
--      desc = SWIG_TypeQuery("swig::SwigPyIterator *");
--      init = 1;
--      }       
--      return desc;
--    }    
--  };
--
--#if defined(SWIGPYTHON_BUILTIN)
--  inline PyObject* make_output_iterator_builtin (PyObject *pyself)
--  {
--    Py_INCREF(pyself);
--    return pyself;
--  }
--#endif
--}
--
--
--namespace swig {  
--  template <class Type>
--  struct noconst_traits {
--    typedef Type noconst_type;
--  };
--
--  template <class Type>
--  struct noconst_traits<const Type> {
--    typedef Type noconst_type;
--  };
--
--  /*
--    type categories
--  */
--  struct pointer_category { };  
--  struct value_category { };
--
--  /*
--    General traits that provides type_name and type_info
--  */
--  template <class Type> struct traits { };
--
--  template <class Type>
--  inline const char* type_name() {
--    return traits<typename noconst_traits<Type >::noconst_type >::type_name();
--  }
--
--  template <class Type> 
--  struct traits_info {
--    static swig_type_info *type_query(std::string name) {
--      name += " *";
--      return SWIG_TypeQuery(name.c_str());
--    }    
--    static swig_type_info *type_info() {
--      static swig_type_info *info = type_query(type_name<Type>());
--      return info;
--    }
--  };
--
--  template <class Type>
--  inline swig_type_info *type_info() {
--    return traits_info<Type>::type_info();
--  }
--
--  /*
--    Partial specialization for pointers
--  */
--  template <class Type> struct traits <Type *> {
--    typedef pointer_category category;
--    static std::string make_ptr_name(const char* name) {
--      std::string ptrname = name;
--      ptrname += " *";
--      return ptrname;
--    }    
--    static const char* type_name() {
--      static std::string name = make_ptr_name(swig::type_name<Type>());
--      return name.c_str();
--    }
--  };
--
--  template <class Type, class Category> 
--  struct traits_as { };
-- 
--  template <class Type, class Category> 
--  struct traits_check { };
--
--}
--
--
--namespace swig {  
--  /*
--    Traits that provides the from method
--  */
--  template <class Type> struct traits_from_ptr {
--    static PyObject *from(Type *val, int owner = 0) {
--      return SWIG_InternalNewPointerObj(val, type_info<Type>(), owner);
--    }
--  };
--
--  template <class Type> struct traits_from {
--    static PyObject *from(const Type& val) {
--      return traits_from_ptr<Type>::from(new Type(val), 1);
--    }
--  };
--
--  template <class Type> struct traits_from<Type *> {
--    static PyObject *from(Type* val) {
--      return traits_from_ptr<Type>::from(val, 0);
--    }
--  };
--
--  template <class Type> struct traits_from<const Type *> {
--    static PyObject *from(const Type* val) {
--      return traits_from_ptr<Type>::from(const_cast<Type*>(val), 0);
--    }
--  };
--
--
--  template <class Type>
--  inline PyObject *from(const Type& val) {
--    return traits_from<Type>::from(val);
--  }
--
--  template <class Type>
--  inline PyObject *from_ptr(Type* val, int owner) {
--    return traits_from_ptr<Type>::from(val, owner);
--  }
--
--  /*
--    Traits that provides the asval/as/check method
--  */
--  template <class Type>
--  struct traits_asptr {   
--    static int asptr(PyObject *obj, Type **val) {
--      Type *p;
--      int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
--      if (SWIG_IsOK(res)) {
--      if (val) *val = p;
--      }
--      return res;
--    }
--  }; 
--
--  template <class Type>
--  inline int asptr(PyObject *obj, Type **vptr) {
--    return traits_asptr<Type>::asptr(obj, vptr);
--  }
--
--  template <class Type> 
--  struct traits_asval {
--    static int asval(PyObject *obj, Type *val) {
--      if (val) {
--      Type *p = 0;
--      int res = traits_asptr<Type>::asptr(obj, &p);
--      if (!SWIG_IsOK(res)) return res;        
--      if (p) {
--        typedef typename noconst_traits<Type>::noconst_type noconst_type;
--        *(const_cast<noconst_type*>(val)) = *p;
--        if (SWIG_IsNewObj(res)){
--          delete p;
--          res = SWIG_DelNewMask(res);
--        }
--        return res;
--      } else {
--        return SWIG_ERROR;
--      }
--      } else {
--      return traits_asptr<Type>::asptr(obj, (Type **)(0));
--      }
--    }
--  };
--
--  template <class Type> struct traits_asval<Type*> {
--    static int asval(PyObject *obj, Type **val) {
--      if (val) {
--        typedef typename noconst_traits<Type>::noconst_type noconst_type;
--        noconst_type *p = 0;
--        int res = traits_asptr<noconst_type>::asptr(obj,  &p);
--        if (SWIG_IsOK(res)) {
--          *(const_cast<noconst_type**>(val)) = p;
--      }
--      return res;
--      } else {
--      return traits_asptr<Type>::asptr(obj, (Type **)(0));
--      }
--    }
--  };
--  
--  template <class Type>
--  inline int asval(PyObject *obj, Type *val) {
--    return traits_asval<Type>::asval(obj, val);
--  }
--
--  template <class Type> 
--  struct traits_as<Type, value_category> {
--    static Type as(PyObject *obj, bool throw_error) {
--      Type v;
--      int res = asval(obj, &v);
--      if (!obj || !SWIG_IsOK(res)) {
--      if (!PyErr_Occurred()) {
--        ::SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      }
--      return v;
--    }
--  };
--
--  template <class Type> 
--  struct traits_as<Type, pointer_category> {
--    static Type as(PyObject *obj, bool throw_error) {
--      Type *v = 0;      
--      int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
--      if (SWIG_IsOK(res) && v) {
--      if (SWIG_IsNewObj(res)) {
--        Type r(*v);
--        delete v;
--        return r;
--      } else {
--        return *v;
--      }
--      } else {
--      // Uninitialized return value, no Type() constructor required.
--      static Type *v_def = (Type*) malloc(sizeof(Type));
--      if (!PyErr_Occurred()) {
--        SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      memset(v_def,0,sizeof(Type));
--      return *v_def;
--      }
--    }
--  };
--
--  template <class Type> 
--  struct traits_as<Type*, pointer_category> {
--    static Type* as(PyObject *obj, bool throw_error) {
--      Type *v = 0;      
--      int res = (obj ? traits_asptr<Type>::asptr(obj, &v) : SWIG_ERROR);
--      if (SWIG_IsOK(res)) {
--      return v;
--      } else {
--      if (!PyErr_Occurred()) {
--        SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
--      }
--      if (throw_error) throw std::invalid_argument("bad type");
--      return 0;
--      }
--    }
--  };
--    
--  template <class Type>
--  inline Type as(PyObject *obj, bool te = false) {
--    return traits_as<Type, typename traits<Type>::category>::as(obj, te);
--  }
--
--  template <class Type> 
--  struct traits_check<Type, value_category> {
--    static bool check(PyObject *obj) {
--      int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR;
--      return SWIG_IsOK(res) ? true : false;
--    }
--  };
--
--  template <class Type> 
--  struct traits_check<Type, pointer_category> {
--    static bool check(PyObject *obj) {
--      int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR;
--      return SWIG_IsOK(res) ? true : false;
--    }
--  };
--
--  template <class Type>
--  inline bool check(PyObject *obj) {
--    return traits_check<Type, typename traits<Type>::category>::check(obj);
--  }
--}
--
--
--#include <functional>
--
--namespace std {
--  template <>
--  struct less <PyObject *>: public binary_function<PyObject *, PyObject *, bool>
--  {
--    bool
--    operator()(PyObject * v, PyObject *w) const
--    { 
--      bool res;
--      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
--      res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false;
--      /* This may fall into a case of inconsistent
--               eg. ObjA > ObjX > ObjB
--               but ObjA < ObjB
--      */
--      if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) )
--      {
--        /* Objects can't be compared, this mostly occurred in Python 3.0 */
--        /* Compare their ptr directly for a workaround */
--        res = (v < w);
--        PyErr_Clear();
--      }
--      SWIG_PYTHON_THREAD_END_BLOCK;
--      return res;
--    }
--  };
--
--  template <>
--  struct less <swig::SwigPtr_PyObject>: public binary_function<swig::SwigPtr_PyObject, swig::SwigPtr_PyObject, bool>
--  {
--    bool
--    operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w) const
--    {
--      return std::less<PyObject *>()(v, w);
--    }
--  };
--
--  template <>
--  struct less <swig::SwigVar_PyObject>: public binary_function<swig::SwigVar_PyObject, swig::SwigVar_PyObject, bool>
--  {
--    bool
--    operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w) const
--    {
--      return std::less<PyObject *>()(v, w);
--    }
--  };
--
--}
--
--namespace swig {
--  template <> struct traits<PyObject *> {
--    typedef value_category category;
--    static const char* type_name() { return "PyObject *"; }
--  };  
--
--  template <>  struct traits_asval<PyObject * > {   
--    typedef PyObject * value_type;
--    static int asval(PyObject *obj, value_type *val) {
--      if (val) *val = obj;
--      return SWIG_OK;
--    }
--  };
--
--  template <> 
--  struct traits_check<PyObject *, value_category> {
--    static bool check(PyObject *) {
--      return true;
--    }
--  };
--
--  template <>  struct traits_from<PyObject *> {
--    typedef PyObject * value_type;
--    static PyObject *from(const value_type& val) {
--      Py_XINCREF(val);
--      return val;
--    }
--  };
--  
--}
--
--namespace swig {
--  template <class Difference>
--  inline size_t
--  check_index(Difference i, size_t size, bool insert = false) {
--    if ( i < 0 ) {
--      if ((size_t) (-i) <= size)
--      return (size_t) (i + size);
--    } else if ( (size_t) i < size ) {
--      return (size_t) i;
--    } else if (insert && ((size_t) i == size)) {
--      return size;
--    }
--    throw std::out_of_range("index out of range");
--  }
--
--  template <class Difference>
--  void
--  slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) {
--    if (step == 0) {
--      throw std::invalid_argument("slice step cannot be zero");
--    } else if (step > 0) {
--      // Required range: 0 <= i < size, 0 <= j < size
--      if (i < 0) {
--        ii = 0;
--      } else if (i < (Difference)size) {
--        ii = i;
--      } else if (insert && (i >= (Difference)size)) {
--        ii = (Difference)size;
--      }
--      if ( j < 0 ) {
--        jj = 0;
--      } else {
--        jj = (j < (Difference)size) ? j : (Difference)size;
--      }
--    } else {
--      // Required range: -1 <= i < size-1, -1 <= j < size-1
--      if (i < -1) {
--        ii = -1;
--      } else if (i < (Difference) size) {
--        ii = i;
--      } else if (i >= (Difference)(size-1)) {
--        ii = (Difference)(size-1);
--      }
--      if (j < -1) {
--        jj = -1;
--      } else {
--        jj = (j < (Difference)size ) ? j : (Difference)(size-1);
--      }
--    }
--  }
--
--  template <class Sequence, class Difference>
--  inline typename Sequence::iterator
--  getpos(Sequence* self, Difference i)  {
--    typename Sequence::iterator pos = self->begin();
--    std::advance(pos, check_index(i,self->size()));
--    return pos;
--  }
--
--  template <class Sequence, class Difference>
--  inline typename Sequence::const_iterator
--  cgetpos(const Sequence* self, Difference i)  {
--    typename Sequence::const_iterator pos = self->begin();
--    std::advance(pos, check_index(i,self->size()));
--    return pos;
--  }
--
--  template <class Sequence, class Difference>
--  inline Sequence*
--  getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj);
--
--    if (step > 0) {
--      typename Sequence::const_iterator sb = self->begin();
--      typename Sequence::const_iterator se = self->begin();
--      std::advance(sb,ii);
--      std::advance(se,jj);
--      if (step == 1) {
--        return new Sequence(sb, se);
--      } else {
--        Sequence *sequence = new Sequence();
--        typename Sequence::const_iterator it = sb;
--        while (it!=se) {
--          sequence->push_back(*it);
--          for (Py_ssize_t c=0; c<step && it!=se; ++c)
--            it++;
--        }
--        return sequence;
--      } 
--    } else {
--      Sequence *sequence = new Sequence();
--      if (ii > jj) {
--        typename Sequence::const_reverse_iterator sb = self->rbegin();
--        typename Sequence::const_reverse_iterator se = self->rbegin();
--        std::advance(sb,size-ii-1);
--        std::advance(se,size-jj-1);
--        typename Sequence::const_reverse_iterator it = sb;
--        while (it!=se) {
--          sequence->push_back(*it);
--          for (Py_ssize_t c=0; c<-step && it!=se; ++c)
--            it++;
--        }
--      }
--      return sequence;
--    }
--  }
--
--  template <class Sequence, class Difference, class InputSeq>
--  inline void
--  setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj, true);
--    if (step > 0) {
--      if (jj < ii)
--        jj = ii;
--      if (step == 1) {
--        size_t ssize = jj - ii;
--        if (ssize <= is.size()) {
--          // expanding/staying the same size
--          typename Sequence::iterator sb = self->begin();
--          typename InputSeq::const_iterator isit = is.begin();
--          std::advance(sb,ii);
--          std::advance(isit, jj - ii);
--          self->insert(std::copy(is.begin(), isit, sb), isit, is.end());
--        } else {
--          // shrinking
--          typename Sequence::iterator sb = self->begin();
--          typename Sequence::iterator se = self->begin();
--          std::advance(sb,ii);
--          std::advance(se,jj);
--          self->erase(sb,se);
--          sb = self->begin();
--          std::advance(sb,ii);
--          self->insert(sb, is.begin(), is.end());
--        }
--      } else {
--        size_t replacecount = (jj - ii + step - 1) / step;
--        if (is.size() != replacecount) {
--          char msg[1024];
--          sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
--          throw std::invalid_argument(msg);
--        }
--        typename Sequence::const_iterator isit = is.begin();
--        typename Sequence::iterator it = self->begin();
--        std::advance(it,ii);
--        for (size_t rc=0; rc<replacecount; ++rc) {
--          *it++ = *isit++;
--          for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
--            it++;
--        }
--      }
--    } else {
--      if (jj > ii)
--        jj = ii;
--      size_t replacecount = (ii - jj - step - 1) / -step;
--      if (is.size() != replacecount) {
--        char msg[1024];
--        sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
--        throw std::invalid_argument(msg);
--      }
--      typename Sequence::const_iterator isit = is.begin();
--      typename Sequence::reverse_iterator it = self->rbegin();
--      std::advance(it,size-ii-1);
--      for (size_t rc=0; rc<replacecount; ++rc) {
--        *it++ = *isit++;
--        for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
--          it++;
--      }
--    }
--  }
--
--  template <class Sequence, class Difference>
--  inline void
--  delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) {
--    typename Sequence::size_type size = self->size();
--    Difference ii = 0;
--    Difference jj = 0;
--    swig::slice_adjust(i, j, step, size, ii, jj, true);
--    if (step > 0) {
--      if (jj > ii) {
--        typename Sequence::iterator sb = self->begin();
--        std::advance(sb,ii);
--        if (step == 1) {
--          typename Sequence::iterator se = self->begin();
--          std::advance(se,jj);
--          self->erase(sb,se);
--        } else {
--          typename Sequence::iterator it = sb;
--          size_t delcount = (jj - ii + step - 1) / step;
--          while (delcount) {
--            it = self->erase(it);
--            for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
--              it++;
--            delcount--;
--          }
--        }
--      }
--    } else {
--      if (ii > jj) {
--        typename Sequence::reverse_iterator sb = self->rbegin();
--        std::advance(sb,size-ii-1);
--        typename Sequence::reverse_iterator it = sb;
--        size_t delcount = (ii - jj - step - 1) / -step;
--        while (delcount) {
--          it = typename Sequence::reverse_iterator(self->erase((++it).base()));
--          for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
--            it++;
--          delcount--;
--        }
--      }
--    }
--  }
--}
--
--
--#if defined(__SUNPRO_CC) && defined(_RWSTD_VER)
--#  if !defined(SWIG_NO_STD_NOITERATOR_TRAITS_STL)
--#    define SWIG_STD_NOITERATOR_TRAITS_STL
--#  endif
--#endif
--
--#if !defined(SWIG_STD_NOITERATOR_TRAITS_STL)
--#include <iterator>
--#else
--namespace std {
--  template <class Iterator>
--  struct iterator_traits {
--    typedef ptrdiff_t difference_type;
--    typedef typename Iterator::value_type value_type;
--  };
--
--  template <class Iterator, class Category,class T, class Reference, class Pointer, class Distance>
--  struct iterator_traits<__reverse_bi_iterator<Iterator,Category,T,Reference,Pointer,Distance> > {
--    typedef Distance difference_type;
--    typedef T value_type;
--  };
--
--  template <class T>
--  struct iterator_traits<T*> {
--    typedef T value_type;
--    typedef ptrdiff_t difference_type;
--  };
--
--  template<typename _InputIterator>
--  inline typename iterator_traits<_InputIterator>::difference_type
--  distance(_InputIterator __first, _InputIterator __last)
--  {
--    typename iterator_traits<_InputIterator>::difference_type __n = 0;
--    while (__first != __last) {
--      ++__first; ++__n;
--    }
--    return __n;
--  }
--}
--#endif
--
--
--namespace swig {
--  template<typename OutIterator>
--  class SwigPyIterator_T :  public SwigPyIterator
--  {
--  public:
--    typedef OutIterator out_iterator;
--    typedef typename std::iterator_traits<out_iterator>::value_type value_type;    
--    typedef SwigPyIterator_T<out_iterator> self_type;
--
--    SwigPyIterator_T(out_iterator curr, PyObject *seq)
--      : SwigPyIterator(seq), current(curr)
--    {
--    }
--
--    const out_iterator& get_current() const
--    {
--      return current;
--    }
--
--    
--    bool equal (const SwigPyIterator &iter) const
--    {
--      const self_type *iters = dynamic_cast<const self_type *>(&iter);
--      if (iters) {
--      return (current == iters->get_current());
--      } else {
--      throw std::invalid_argument("bad iterator type");
--      }
--    }
--    
--    ptrdiff_t distance(const SwigPyIterator &iter) const
--    {
--      const self_type *iters = dynamic_cast<const self_type *>(&iter);
--      if (iters) {
--      return std::distance(current, iters->get_current());
--      } else {
--      throw std::invalid_argument("bad iterator type");
--      }
--    }    
--    
--  protected:
--    out_iterator current;
--  };
--  
--  template <class ValueType>
--  struct from_oper 
--  {
--    typedef const ValueType& argument_type;
--    typedef PyObject *result_type;
--    result_type operator()(argument_type v) const
--    {
--      return swig::from(v);
--    }
--  };
--
--  template<typename OutIterator, 
--         typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
--         typename FromOper = from_oper<ValueType> >
--  class SwigPyIteratorOpen_T :  public SwigPyIterator_T<OutIterator>
--  {
--  public:
--    FromOper from;
--    typedef OutIterator out_iterator;
--    typedef ValueType value_type;
--    typedef SwigPyIterator_T<out_iterator>  base;
--    typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
--    
--    SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq)
--      : SwigPyIterator_T<OutIterator>(curr, seq)
--    {
--    }
--    
--    PyObject *value() const {
--      return from(static_cast<const value_type&>(*(base::current)));
--    }
--    
--    SwigPyIterator *copy() const
--    {
--      return new self_type(*this);
--    }
--
--    SwigPyIterator *incr(size_t n = 1)
--    {
--      while (n--) {
--      ++base::current;
--      }
--      return this;
--    }
--
--    SwigPyIterator *decr(size_t n = 1)
--    {
--      while (n--) {
--      --base::current;
--      }
--      return this;
--    }
--  };
--
--  template<typename OutIterator, 
--         typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
--         typename FromOper = from_oper<ValueType> >
--  class SwigPyIteratorClosed_T :  public SwigPyIterator_T<OutIterator>
--  {
--  public:
--    FromOper from;
--    typedef OutIterator out_iterator;
--    typedef ValueType value_type;
--    typedef SwigPyIterator_T<out_iterator>  base;    
--    typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
--    
--    SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
--      : SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
--    {
--    }
--    
--    PyObject *value() const {
--      if (base::current == end) {
--      throw stop_iteration();
--      } else {
--      return from(static_cast<const value_type&>(*(base::current)));
--      }
--    }
--    
--    SwigPyIterator *copy() const
--    {
--      return new self_type(*this);
--    }
--
--    SwigPyIterator *incr(size_t n = 1)
--    {
--      while (n--) {
--      if (base::current == end) {
--        throw stop_iteration();
--      } else {
--        ++base::current;
--      }
--      }
--      return this;
--    }
--
--    SwigPyIterator *decr(size_t n = 1)
--    {
--      while (n--) {
--      if (base::current == begin) {
--        throw stop_iteration();
--      } else {
--        --base::current;
--      }
--      }
--      return this;
--    }
--
--  private:
--    out_iterator begin;
--    out_iterator end;
--  };
--
--  template<typename OutIter>
--  inline SwigPyIterator*
--  make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0)
--  {
--    return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq);
--  }
--
--  template<typename OutIter>
--  inline SwigPyIterator*
--  make_output_iterator(const OutIter& current, PyObject *seq = 0)
--  {
--    return new SwigPyIteratorOpen_T<OutIter>(current, seq);
--  }
--
--}
--
--
--namespace swig
--{
--  template <class T>
--  struct SwigPySequence_Ref
--  {
--    SwigPySequence_Ref(PyObject* seq, int index)
--      : _seq(seq), _index(index)
--    {
--    }
--    
--    operator T () const
--    {
--      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
--      try {
--      return swig::as<T>(item, true);
--      } catch (std::exception& e) {
--      char msg[1024];
--      sprintf(msg, "in sequence element %d ", _index);
--      if (!PyErr_Occurred()) {
--        ::SWIG_Error(SWIG_TypeError,  swig::type_name<T>());
--      }
--      SWIG_Python_AddErrorMsg(msg);
--      SWIG_Python_AddErrorMsg(e.what());
--      throw;
--      }
--    }
--
--    SwigPySequence_Ref& operator=(const T& v)
--    {
--      PySequence_SetItem(_seq, _index, swig::from<T>(v));
--      return *this;
--    }
--
--  private:
--    PyObject* _seq;
--    int _index;
--  };
--
--  template <class T>
--  struct SwigPySequence_ArrowProxy
--  {
--    SwigPySequence_ArrowProxy(const T& x): m_value(x) {}
--    const T* operator->() const { return &m_value; }
--    operator const T*() const { return &m_value; }
--    T m_value;
--  };
--
--  template <class T, class Reference >
--  struct SwigPySequence_InputIterator
--  {
--    typedef SwigPySequence_InputIterator<T, Reference > self;
--
--    typedef std::random_access_iterator_tag iterator_category;
--    typedef Reference reference;
--    typedef T value_type;
--    typedef T* pointer;
--    typedef int difference_type;
--
--    SwigPySequence_InputIterator()
--    {
--    }
--
--    SwigPySequence_InputIterator(PyObject* seq, int index)
--      : _seq(seq), _index(index)
--    {
--    }
--
--    reference operator*() const
--    {
--      return reference(_seq, _index);
--    }
--
--    SwigPySequence_ArrowProxy<T>
--    operator->() const {
--      return SwigPySequence_ArrowProxy<T>(operator*());
--    }
--
--    bool operator==(const self& ri) const
--    {
--      return (_index == ri._index) && (_seq == ri._seq);
--    }
--
--    bool operator!=(const self& ri) const
--    {
--      return !(operator==(ri));
--    }
--
--    self& operator ++ ()
--    {
--      ++_index;
--      return *this;
--    }
--
--    self& operator -- ()
--    {
--      --_index;
--      return *this;
--    }
--
--    self& operator += (difference_type n)
--    {
--      _index += n;
--      return *this;
--    }
--
--    self operator +(difference_type n) const
--    {
--      return self(_seq, _index + n);
--    }
--
--    self& operator -= (difference_type n)
--    {
--      _index -= n;
--      return *this;
--    }
--
--    self operator -(difference_type n) const
--    {
--      return self(_seq, _index - n);
--    }
--
--    difference_type operator - (const self& ri) const
--    {
--      return _index - ri._index;
--    }
--
--    bool operator < (const self& ri) const
--    {
--      return _index < ri._index;
--    }
--
--    reference
--    operator[](difference_type n) const
--    {
--      return reference(_seq, _index + n);
--    }
--
--  private:
--    PyObject* _seq;
--    difference_type _index;
--  };
--
--  template <class T>
--  struct SwigPySequence_Cont
--  {
--    typedef SwigPySequence_Ref<T> reference;
--    typedef const SwigPySequence_Ref<T> const_reference;
--    typedef T value_type;
--    typedef T* pointer;
--    typedef int difference_type;
--    typedef int size_type;
--    typedef const pointer const_pointer;
--    typedef SwigPySequence_InputIterator<T, reference> iterator;
--    typedef SwigPySequence_InputIterator<T, const_reference> const_iterator;
--
--    SwigPySequence_Cont(PyObject* seq) : _seq(0)
--    {
--      if (!PySequence_Check(seq)) {
--      throw std::invalid_argument("a sequence is expected");
--      }
--      _seq = seq;
--      Py_INCREF(_seq);
--    }
--
--    ~SwigPySequence_Cont()
--    {
--      Py_XDECREF(_seq);
--    }
--
--    size_type size() const
--    {
--      return static_cast<size_type>(PySequence_Size(_seq));
--    }
--
--    bool empty() const
--    {
--      return size() == 0;
--    }
--
--    iterator begin()
--    {
--      return iterator(_seq, 0);
--    }
--
--    const_iterator begin() const
--    {
--      return const_iterator(_seq, 0);
--    }
--
--    iterator end()
--    {
--      return iterator(_seq, size());
--    }
--
--    const_iterator end() const
--    {
--      return const_iterator(_seq, size());
--    }
--
--    reference operator[](difference_type n)
--    {
--      return reference(_seq, n);
--    }
--
--    const_reference operator[](difference_type n)  const
--    {
--      return const_reference(_seq, n);
--    }
--
--    bool check(bool set_err = true) const
--    {
--      int s = size();
--      for (int i = 0; i < s; ++i) {
--      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
--      if (!swig::check<value_type>(item)) {
--        if (set_err) {
--          char msg[1024];
--          sprintf(msg, "in sequence element %d", i);
--          SWIG_Error(SWIG_RuntimeError, msg);
--        }
--        return false;
--      }
--      }
--      return true;
--    }
--
--  private:
--    PyObject* _seq;
--  };
--
--}
--
--
--SWIGINTERNINLINE PyObject*
--  SWIG_From_int  (int value)
--{
--  return PyInt_FromLong((long) value);
--}
--
--
--SWIGINTERN swig_type_info*
--SWIG_pchar_descriptor(void)
--{
--  static int init = 0;
--  static swig_type_info* info = 0;
--  if (!init) {
--    info = SWIG_TypeQuery("_p_char");
--    init = 1;
--  }
--  return info;
--}
--
--
--SWIGINTERNINLINE PyObject *
--SWIG_FromCharPtrAndSize(const char* carray, size_t size)
--{
--  if (carray) {
--    if (size > INT_MAX) {
--      swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--      return pchar_descriptor ? 
--      SWIG_InternalNewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
--    } else {
--#if PY_VERSION_HEX >= 0x03000000
--      return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
--#else
--      return PyString_FromStringAndSize(carray, static_cast< int >(size));
--#endif
--    }
--  } else {
--    return SWIG_Py_Void();
--  }
--}
--
--
--SWIGINTERNINLINE PyObject * 
--SWIG_FromCharPtr(const char *cptr)
--{ 
--  return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
--}
--
--
--#include <limits.h>
--#if !defined(SWIG_NO_LLONG_MAX)
--# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
--#   define LLONG_MAX __LONG_LONG_MAX__
--#   define LLONG_MIN (-LLONG_MAX - 1LL)
--#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
--# endif
--#endif
--
--
--SWIGINTERN int
--SWIG_AsVal_double (PyObject *obj, double *val)
--{
--  int res = SWIG_TypeError;
--  if (PyFloat_Check(obj)) {
--    if (val) *val = PyFloat_AsDouble(obj);
--    return SWIG_OK;
--  } else if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    double v = PyLong_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    double d = PyFloat_AsDouble(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = d;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      long v = PyLong_AsLong(obj);
--      if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
--      } else {
--      PyErr_Clear();
--      }
--    }
--  }
--#endif
--  return res;
--}
--
--
--#include <float.h>
--
--
--#include <math.h>
--
--
--SWIGINTERNINLINE int
--SWIG_CanCastAsInteger(double *d, double min, double max) {
--  double x = *d;
--  if ((min <= x && x <= max)) {
--   double fx = floor(x);
--   double cx = ceil(x);
--   double rd =  ((x - fx) < 0.5) ? fx : cx; /* simple rint */
--   if ((errno == EDOM) || (errno == ERANGE)) {
--     errno = 0;
--   } else {
--     double summ, reps, diff;
--     if (rd < x) {
--       diff = x - rd;
--     } else if (rd > x) {
--       diff = rd - x;
--     } else {
--       return 1;
--     }
--     summ = rd + x;
--     reps = diff/summ;
--     if (reps < 8*DBL_EPSILON) {
--       *d = rd;
--       return 1;
--     }
--   }
--  }
--  return 0;
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_long (PyObject *obj, long* val)
--{
--  if (PyInt_Check(obj)) {
--    if (val) *val = PyInt_AsLong(obj);
--    return SWIG_OK;
--  } else if (PyLong_Check(obj)) {
--    long v = PyLong_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_OK;
--    } else {
--      PyErr_Clear();
--    }
--  }
--#ifdef SWIG_PYTHON_CAST_MODE
--  {
--    int dispatch = 0;
--    long v = PyInt_AsLong(obj);
--    if (!PyErr_Occurred()) {
--      if (val) *val = v;
--      return SWIG_AddCast(SWIG_OK);
--    } else {
--      PyErr_Clear();
--    }
--    if (!dispatch) {
--      double d;
--      int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
--      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
--      if (val) *val = (long)(d);
--      return res;
--      }
--    }
--  }
--#endif
--  return SWIG_TypeError;
--}
--
--
--SWIGINTERN int
--SWIG_AsVal_int (PyObject * obj, int *val)
--{
--  long v;
--  int res = SWIG_AsVal_long (obj, &v);
--  if (SWIG_IsOK(res)) {
--    if ((v < INT_MIN || v > INT_MAX)) {
--      return SWIG_OverflowError;
--    } else {
--      if (val) *val = static_cast< int >(v);
--    }
--  }  
--  return res;
--}
--
--
--namespace swig {
--  template <> struct traits<int > {
--    typedef value_category category;
--    static const char* type_name() { return"int"; }
--  };  
--  template <>  struct traits_asval<int > {   
--    typedef int value_type;
--    static int asval(PyObject *obj, value_type *val) { 
--      return SWIG_AsVal_int (obj, val);
--    }
--  };
--  template <>  struct traits_from<int > {
--    typedef int value_type;
--    static PyObject *from(const value_type& val) {
--      return SWIG_From_int  (val);
--    }
--  };
--}
--
--
--namespace swig {
--  template <class SwigPySeq, class Seq>
--  inline void
--  assign(const SwigPySeq& swigpyseq, Seq* seq) {
--    // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
--    typedef typename SwigPySeq::value_type value_type;
--    typename SwigPySeq::const_iterator it = swigpyseq.begin();
--    for (;it != swigpyseq.end(); ++it) {
--      seq->insert(seq->end(),(value_type)(*it));
--    }
--  }
--
--  template <class Seq, class T = typename Seq::value_type >
--  struct traits_asptr_stdseq {
--    typedef Seq sequence;
--    typedef T value_type;
--
--    static int asptr(PyObject *obj, sequence **seq) {
--      if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) {
--      sequence *p;
--      if (::SWIG_ConvertPtr(obj,(void**)&p,
--                            swig::type_info<sequence>(),0) == SWIG_OK) {
--        if (seq) *seq = p;
--        return SWIG_OLDOBJ;
--      }
--      } else if (PySequence_Check(obj)) {
--      try {
--        SwigPySequence_Cont<value_type> swigpyseq(obj);
--        if (seq) {
--          sequence *pseq = new sequence();
--          assign(swigpyseq, pseq);
--          *seq = pseq;
--          return SWIG_NEWOBJ;
--        } else {
--          return swigpyseq.check() ? SWIG_OK : SWIG_ERROR;
--        }
--      } catch (std::exception& e) {
--        if (seq) {
--          if (!PyErr_Occurred()) {
--            PyErr_SetString(PyExc_TypeError, e.what());
--          }
--        }
--        return SWIG_ERROR;
--      }
--      }
--      return SWIG_ERROR;
--    }
--  };
--
--  template <class Seq, class T = typename Seq::value_type >
--  struct traits_from_stdseq {
--    typedef Seq sequence;
--    typedef T value_type;
--    typedef typename Seq::size_type size_type;
--    typedef typename sequence::const_iterator const_iterator;
--
--    static PyObject *from(const sequence& seq) {
--#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS
--      swig_type_info *desc = swig::type_info<sequence>();
--      if (desc && desc->clientdata) {
--      return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN);
--      }
--#endif
--      size_type size = seq.size();
--      if (size <= (size_type)INT_MAX) {
--      PyObject *obj = PyTuple_New((int)size);
--      int i = 0;
--      for (const_iterator it = seq.begin();
--           it != seq.end(); ++it, ++i) {
--        PyTuple_SetItem(obj,i,swig::from<value_type>(*it));
--      }
--      return obj;
--      } else {
--      PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python");
--      return NULL;
--      }
--    }
--  };
--}
--
--
--  namespace swig {
--    template <class T>
--    struct traits_asptr<std::vector<T> >  {
--      static int asptr(PyObject *obj, std::vector<T> **vec) {
--      return traits_asptr_stdseq<std::vector<T> >::asptr(obj, vec);
--      }
--    };
--    
--    template <class T>
--    struct traits_from<std::vector<T> > {
--      static PyObject *from(const std::vector<T>& vec) {
--      return traits_from_stdseq<std::vector<T> >::from(vec);
--      }
--    };
--  }
--
--
--      namespace swig {
--      template <>  struct traits<std::vector<int, std::allocator< int > > > {
--        typedef pointer_category category;
--        static const char* type_name() {
--          return "std::vector<" "int" "," "std::allocator< int >" " >";
--        }
--      };
--      }
--    
--
--SWIGINTERN int
--SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
--{
--#if PY_VERSION_HEX>=0x03000000
--  if (PyUnicode_Check(obj))
--#else  
--  if (PyString_Check(obj))
--#endif
--  {
--    char *cstr; Py_ssize_t len;
--#if PY_VERSION_HEX>=0x03000000
--    if (!alloc && cptr) {
--        /* We can't allow converting without allocation, since the internal
--           representation of string in Python 3 is UCS-2/UCS-4 but we require
--           a UTF-8 representation.
--           TODO(bhy) More detailed explanation */
--        return SWIG_RuntimeError;
--    }
--    obj = PyUnicode_AsUTF8String(obj);
--    PyBytes_AsStringAndSize(obj, &cstr, &len);
--    if(alloc) *alloc = SWIG_NEWOBJ;
--#else
--    PyString_AsStringAndSize(obj, &cstr, &len);
--#endif
--    if (cptr) {
--      if (alloc) {
--      /* 
--         In python the user should not be able to modify the inner
--         string representation. To warranty that, if you define
--         SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
--         buffer is always returned.
--
--         The default behavior is just to return the pointer value,
--         so, be careful.
--      */ 
--#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
--      if (*alloc != SWIG_OLDOBJ) 
--#else
--      if (*alloc == SWIG_NEWOBJ) 
--#endif
--        {
--          *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
--          *alloc = SWIG_NEWOBJ;
--        }
--      else {
--        *cptr = cstr;
--        *alloc = SWIG_OLDOBJ;
--      }
--      } else {
--        #if PY_VERSION_HEX>=0x03000000
--        assert(0); /* Should never reach here in Python 3 */
--        #endif
--      *cptr = SWIG_Python_str_AsChar(obj);
--      }
--    }
--    if (psize) *psize = len + 1;
--#if PY_VERSION_HEX>=0x03000000
--    Py_XDECREF(obj);
--#endif
--    return SWIG_OK;
--  } else {
--    swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
--    if (pchar_descriptor) {
--      void* vptr = 0;
--      if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
--      if (cptr) *cptr = (char *) vptr;
--      if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
--      if (alloc) *alloc = SWIG_OLDOBJ;
--      return SWIG_OK;
--      }
--    }
--  }
--  return SWIG_TypeError;
--}
--
--
--
--
--
--  #define SWIG_From_double   PyFloat_FromDouble 
--
--
--namespace swig {
--  template <> struct traits<double > {
--    typedef value_category category;
--    static const char* type_name() { return"double"; }
--  };  
--  template <>  struct traits_asval<double > {   
--    typedef double value_type;
--    static int asval(PyObject *obj, value_type *val) { 
--      return SWIG_AsVal_double (obj, val);
--    }
--  };
--  template <>  struct traits_from<double > {
--    typedef double value_type;
--    static PyObject *from(const value_type& val) {
--      return SWIG_From_double  (val);
--    }
--  };
--}
--
--
--      namespace swig {
--      template <>  struct traits<std::vector<double, std::allocator< double > > > {
--        typedef pointer_category category;
--        static const char* type_name() {
--          return "std::vector<" "double" "," "std::allocator< double >" " >";
--        }
--      };
--      }
--    
--#ifdef __cplusplus
--extern "C" {
--#endif
--SWIGINTERN PyObject *_wrap_new_VMask__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VMask")) SWIG_fail;
--  result = (vips::VMask *)new vips::VMask();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VMask__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VMask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_vips__VMask,  0  | 0);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VMask" "', argument " "1"" of type '" "vips::VMask const &""'"); 
--  }
--  if (!argp1) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VMask" "', argument " "1"" of type '" "vips::VMask const &""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  result = (vips::VMask *)new vips::VMask((vips::VMask const &)*arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VMask(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[2];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VMask__SWIG_0(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_vips__VMask, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VMask__SWIG_1(self, args);
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VMask'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VMask::VMask()\n"
--    "    vips::VMask::VMask(vips::VMask const &)\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask___assign__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  vips::VMask *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VMask___assign__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask___assign__" "', argument " "1"" of type '" "vips::VMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VMask,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VMask___assign__" "', argument " "2"" of type '" "vips::VMask const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VMask___assign__" "', argument " "2"" of type '" "vips::VMask const &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VMask * >(argp2);
--  result = (vips::VMask *) &(arg1)->operator =((vips::VMask const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VMask, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VMask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VMask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VMask" "', argument " "1"" of type '" "vips::VMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_xsize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_xsize",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_xsize" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  try {
--    result = (int)((vips::VMask const *)arg1)->xsize();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_ysize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_ysize",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_ysize" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  try {
--    result = (int)((vips::VMask const *)arg1)->ysize();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_size",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_size" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  try {
--    result = (int)((vips::VMask const *)arg1)->size();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_filename(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  char *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_filename",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_filename" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  try {
--    result = (char *)((vips::VMask const *)arg1)->filename();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_FromCharPtr((const char *)result);
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_type(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  _private_detail::VPMask::VMaskType result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_type",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_type" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  result = ((vips::VMask const *)arg1)->type();
--  resultobj = SWIG_NewPointerObj((new _private_detail::VPMask::VMaskType(static_cast< const _private_detail::VPMask::VMaskType& >(result))), SWIGTYPE_p__private_detail__VPMask__VMaskType, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_mask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  _private_detail::MASKUNION result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VMask_mask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_mask" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  result = ((vips::VMask const *)arg1)->mask();
--  resultobj = SWIG_NewPointerObj((new _private_detail::MASKUNION(static_cast< const _private_detail::MASKUNION& >(result))), SWIGTYPE_p__private_detail__MASKUNION, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VMask_ostream_print(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VMask *arg1 = (vips::VMask *) 0 ;
--  std::ostream *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VMask_ostream_print",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VMask_ostream_print" "', argument " "1"" of type '" "vips::VMask const *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VMask * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__ostream,  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VMask_ostream_print" "', argument " "2"" of type '" "std::ostream &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VMask_ostream_print" "', argument " "2"" of type '" "std::ostream &""'"); 
--  }
--  arg2 = reinterpret_cast< std::ostream * >(argp2);
--  ((vips::VMask const *)arg1)->ostream_print(*arg2);
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VMask_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VMask, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap___lshift____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  std::ostream *arg1 = 0 ;
--  vips::VMask *arg2 = 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  std::ostream *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:__lshift__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__ostream,  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "__lshift__" "', argument " "1"" of type '" "std::ostream &""'"); 
--  }
--  if (!argp1) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "__lshift__" "', argument " "1"" of type '" "std::ostream &""'"); 
--  }
--  arg1 = reinterpret_cast< std::ostream * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VMask,  0  | 0);
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "__lshift__" "', argument " "2"" of type '" "vips::VMask const &""'"); 
--  }
--  if (!argp2) {
--    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "__lshift__" "', argument " "2"" of type '" "vips::VMask const &""'"); 
--  }
--  arg2 = reinterpret_cast< vips::VMask * >(argp2);
--  result = (std::ostream *) &vips::operator <<(*arg1,(vips::VMask const &)*arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__ostream, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap___lshift__(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[3];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 2) {
--    int _v;
--    void *vptr = 0;
--    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_std__ostream, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_vips__VMask, 0);
--      _v = SWIG_CheckState(res);
--      if (_v) {
--        return _wrap___lshift____SWIG_1(self, args);
--      }
--    }
--  }
--  
--fail:
--  Py_INCREF(Py_NotImplemented);
--  return Py_NotImplemented;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VIMask__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VIMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_VIMask",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VIMask" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_VIMask" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  result = (vips::VIMask *)new vips::VIMask(arg1,arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VIMask__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int arg3 ;
--  int arg4 ;
--  std::vector< int,std::allocator< int > > arg5 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  int val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VIMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:new_VIMask",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VIMask" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_VIMask" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_VIMask" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  ecode4 = SWIG_AsVal_int(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_VIMask" "', argument " "4"" of type '" "int""'");
--  } 
--  arg4 = static_cast< int >(val4);
--  {
--    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
--    int res = swig::asptr(obj4, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_VIMask" "', argument " "5"" of type '" "std::vector< int,std::allocator< int > >""'"); 
--    }
--    arg5 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  result = (vips::VIMask *)new vips::VIMask(arg1,arg2,arg3,arg4,arg5);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VIMask__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VIMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VIMask",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VIMask" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  result = (vips::VIMask *)new vips::VIMask((char const *)arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_NEW |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VIMask__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VIMask")) SWIG_fail;
--  result = (vips::VIMask *)new vips::VIMask();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VIMask(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[6];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VIMask__SWIG_3(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VIMask__SWIG_2(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    {
--      int res = SWIG_AsVal_int(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_new_VIMask__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 5) {
--    int _v;
--    {
--      int res = SWIG_AsVal_int(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_int(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_int(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            int res = swig::asptr(argv[4], (std::vector<int,std::allocator< int > >**)(0));
--            _v = SWIG_CheckState(res);
--            if (_v) {
--              return _wrap_new_VIMask__SWIG_1(self, args);
--            }
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VIMask'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VIMask::VIMask(int,int)\n"
--    "    vips::VIMask::VIMask(int,int,int,int,std::vector< int,std::allocator< int > >)\n"
--    "    vips::VIMask::VIMask(char const *)\n"
--    "    vips::VIMask::VIMask()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_scale(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_scale",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_scale" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  result = (int)(arg1)->scale();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_offset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_offset",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_offset" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  result = (int)(arg1)->offset();
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_embed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  im__INTMASK *arg2 = (im__INTMASK *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_embed",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_embed" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_im__INTMASK, 0 |  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VIMask_embed" "', argument " "2"" of type '" "im__INTMASK *""'"); 
--  }
--  arg2 = reinterpret_cast< im__INTMASK * >(argp2);
--  try {
--    (arg1)->embed(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask___index__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask___index__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask___index__" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask___index__" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (int *) &(arg1)->operator [](arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask___call__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  int *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VIMask___call__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask___call__" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask___call__" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VIMask___call__" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (int *) &(arg1)->operator ()(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  int result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_get",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_get" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask_get" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (int)(arg1)->get(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_int(static_cast< int >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_gauss(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_gauss",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VIMask_gauss" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask_gauss" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VIMask::gauss(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_gauss_sep(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_gauss_sep",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VIMask_gauss_sep" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask_gauss_sep" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VIMask::gauss_sep(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_log(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_log",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VIMask_log" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VIMask_log" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VIMask::log(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_rotate45(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_rotate45",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_rotate45" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  try {
--    result = (arg1)->rotate45();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_rotate90(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_rotate90",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_rotate90" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  try {
--    result = (arg1)->rotate90();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_trn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_trn",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_trn" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  try {
--    result = (arg1)->trn();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_inv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VIMask_inv",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_inv" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  try {
--    result = (arg1)->inv();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_cat(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_cat",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_cat" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VIMask_cat" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VIMask_cat" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->cat(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VIMask_mul(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VIMask_mul",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VIMask_mul" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VIMask_mul" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VIMask_mul" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->mul(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VIMask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VIMask *arg1 = (vips::VIMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VIMask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VIMask, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VIMask" "', argument " "1"" of type '" "vips::VIMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VIMask * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VIMask_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VIMask, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--SWIGINTERN PyObject *_wrap_new_VDMask__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:new_VDMask",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VDMask" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_VDMask" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  result = (vips::VDMask *)new vips::VDMask(arg1,arg2);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDMask__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  int arg1 ;
--  int arg2 ;
--  double arg3 ;
--  double arg4 ;
--  std::vector< double,std::allocator< double > > arg5 ;
--  int val1 ;
--  int ecode1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  double val3 ;
--  int ecode3 = 0 ;
--  double val4 ;
--  int ecode4 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  PyObject * obj3 = 0 ;
--  PyObject * obj4 = 0 ;
--  vips::VDMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOOOO:new_VDMask",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
--  ecode1 = SWIG_AsVal_int(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VDMask" "', argument " "1"" of type '" "int""'");
--  } 
--  arg1 = static_cast< int >(val1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_VDMask" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_double(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_VDMask" "', argument " "3"" of type '" "double""'");
--  } 
--  arg3 = static_cast< double >(val3);
--  ecode4 = SWIG_AsVal_double(obj3, &val4);
--  if (!SWIG_IsOK(ecode4)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_VDMask" "', argument " "4"" of type '" "double""'");
--  } 
--  arg4 = static_cast< double >(val4);
--  {
--    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
--    int res = swig::asptr(obj4, &ptr);
--    if (!SWIG_IsOK(res) || !ptr) {
--      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_VDMask" "', argument " "5"" of type '" "std::vector< double,std::allocator< double > >""'"); 
--    }
--    arg5 = *ptr;
--    if (SWIG_IsNewObj(res)) delete ptr;
--  }
--  result = (vips::VDMask *)new vips::VDMask(arg1,arg2,arg3,arg4,arg5);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDMask__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  char *arg1 = (char *) 0 ;
--  int res1 ;
--  char *buf1 = 0 ;
--  int alloc1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:new_VDMask",&obj0)) SWIG_fail;
--  res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VDMask" "', argument " "1"" of type '" "char const *""'");
--  }
--  arg1 = reinterpret_cast< char * >(buf1);
--  result = (vips::VDMask *)new vips::VDMask((char const *)arg1);
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_NEW |  0 );
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return resultobj;
--fail:
--  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDMask__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)":new_VDMask")) SWIG_fail;
--  result = (vips::VDMask *)new vips::VDMask();
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_NEW |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_new_VDMask(PyObject *self, PyObject *args) {
--  int argc;
--  PyObject *argv[6];
--  int ii;
--  
--  if (!PyTuple_Check(args)) SWIG_fail;
--  argc = args ? (int)PyObject_Length(args) : 0;
--  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
--    argv[ii] = PyTuple_GET_ITEM(args,ii);
--  }
--  if (argc == 0) {
--    return _wrap_new_VDMask__SWIG_3(self, args);
--  }
--  if (argc == 1) {
--    int _v;
--    int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0);
--    _v = SWIG_CheckState(res);
--    if (_v) {
--      return _wrap_new_VDMask__SWIG_2(self, args);
--    }
--  }
--  if (argc == 2) {
--    int _v;
--    {
--      int res = SWIG_AsVal_int(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        return _wrap_new_VDMask__SWIG_0(self, args);
--      }
--    }
--  }
--  if (argc == 5) {
--    int _v;
--    {
--      int res = SWIG_AsVal_int(argv[0], NULL);
--      _v = SWIG_CheckState(res);
--    }
--    if (_v) {
--      {
--        int res = SWIG_AsVal_int(argv[1], NULL);
--        _v = SWIG_CheckState(res);
--      }
--      if (_v) {
--        {
--          int res = SWIG_AsVal_double(argv[2], NULL);
--          _v = SWIG_CheckState(res);
--        }
--        if (_v) {
--          {
--            int res = SWIG_AsVal_double(argv[3], NULL);
--            _v = SWIG_CheckState(res);
--          }
--          if (_v) {
--            int res = swig::asptr(argv[4], (std::vector<double,std::allocator< double > >**)(0));
--            _v = SWIG_CheckState(res);
--            if (_v) {
--              return _wrap_new_VDMask__SWIG_1(self, args);
--            }
--          }
--        }
--      }
--    }
--  }
--  
--fail:
--  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VDMask'.\n"
--    "  Possible C/C++ prototypes are:\n"
--    "    vips::VDMask::VDMask(int,int)\n"
--    "    vips::VDMask::VDMask(int,int,double,double,std::vector< double,std::allocator< double > >)\n"
--    "    vips::VDMask::VDMask(char const *)\n"
--    "    vips::VDMask::VDMask()\n");
--  return 0;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_embed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  im__DOUBLEMASK *arg2 = (im__DOUBLEMASK *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 = 0 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_embed",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_embed" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_im__DOUBLEMASK, 0 |  0 );
--  if (!SWIG_IsOK(res2)) {
--    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VDMask_embed" "', argument " "2"" of type '" "im__DOUBLEMASK *""'"); 
--  }
--  arg2 = reinterpret_cast< im__DOUBLEMASK * >(argp2);
--  try {
--    (arg1)->embed(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_scale(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_scale",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_scale" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (double)(arg1)->scale();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_offset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_offset",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_offset" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (double)(arg1)->offset();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask___index__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  double *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask___index__",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask___index__" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VDMask___index__" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (double *) &(arg1)->operator [](arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_double, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask___call__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  int arg2 ;
--  int arg3 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  int val3 ;
--  int ecode3 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  PyObject * obj2 = 0 ;
--  double *result = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OOO:VDMask___call__",&obj0,&obj1,&obj2)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask___call__" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VDMask___call__" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  ecode3 = SWIG_AsVal_int(obj2, &val3);
--  if (!SWIG_IsOK(ecode3)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VDMask___call__" "', argument " "3"" of type '" "int""'");
--  } 
--  arg3 = static_cast< int >(val3);
--  try {
--    result = (double *) &(arg1)->operator ()(arg2,arg3);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_double, 0 |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  int arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  int val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  double result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_get",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_get" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  ecode2 = SWIG_AsVal_int(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VDMask_get" "', argument " "2"" of type '" "int""'");
--  } 
--  arg2 = static_cast< int >(val2);
--  try {
--    result = (double)(arg1)->get(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_From_double(static_cast< double >(result));
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_gauss(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_gauss",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VDMask_gauss" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VDMask_gauss" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VDMask::gauss(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_log(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  double arg1 ;
--  double arg2 ;
--  double val1 ;
--  int ecode1 = 0 ;
--  double val2 ;
--  int ecode2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_log",&obj0,&obj1)) SWIG_fail;
--  ecode1 = SWIG_AsVal_double(obj0, &val1);
--  if (!SWIG_IsOK(ecode1)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "VDMask_log" "', argument " "1"" of type '" "double""'");
--  } 
--  arg1 = static_cast< double >(val1);
--  ecode2 = SWIG_AsVal_double(obj1, &val2);
--  if (!SWIG_IsOK(ecode2)) {
--    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VDMask_log" "', argument " "2"" of type '" "double""'");
--  } 
--  arg2 = static_cast< double >(val2);
--  try {
--    result = vips::VDMask::log(arg1,arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_rotate45(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_rotate45",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_rotate45" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (arg1)->rotate45();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_rotate90(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_rotate90",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_rotate90" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (arg1)->rotate90();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_scalei(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VIMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_scalei",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_scalei" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (arg1)->scalei();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VIMask(static_cast< const vips::VIMask& >(result))), SWIGTYPE_p_vips__VIMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_trn(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_trn",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_trn" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (arg1)->trn();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_inv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:VDMask_inv",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_inv" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  try {
--    result = (arg1)->inv();
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_cat(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_cat",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_cat" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VDMask_cat" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VDMask_cat" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->cat(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_VDMask_mul(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  vips::VDMask arg2 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  void *argp2 ;
--  int res2 = 0 ;
--  PyObject * obj0 = 0 ;
--  PyObject * obj1 = 0 ;
--  vips::VDMask result;
--  
--  if (!PyArg_ParseTuple(args,(char *)"OO:VDMask_mul",&obj0,&obj1)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, 0 |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VDMask_mul" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  {
--    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_vips__VDMask,  0  | 0);
--    if (!SWIG_IsOK(res2)) {
--      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VDMask_mul" "', argument " "2"" of type '" "vips::VDMask""'"); 
--    }  
--    if (!argp2) {
--      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VDMask_mul" "', argument " "2"" of type '" "vips::VDMask""'");
--    } else {
--      vips::VDMask * temp = reinterpret_cast< vips::VDMask * >(argp2);
--      arg2 = *temp;
--      if (SWIG_IsNewObj(res2)) delete temp;
--    }
--  }
--  try {
--    result = (arg1)->mul(arg2);
--  }
--  catch(vips::VError &_e) {
--    SWIG_Python_Raise(SWIG_NewPointerObj((new vips::VError(static_cast< const vips::VError& >(_e))),SWIGTYPE_p_vips__VError,SWIG_POINTER_OWN), "vips::VError", SWIGTYPE_p_vips__VError); SWIG_fail;
--  }
--  
--  resultobj = SWIG_NewPointerObj((new vips::VDMask(static_cast< const vips::VDMask& >(result))), SWIGTYPE_p_vips__VDMask, SWIG_POINTER_OWN |  0 );
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *_wrap_delete_VDMask(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *resultobj = 0;
--  vips::VDMask *arg1 = (vips::VDMask *) 0 ;
--  void *argp1 = 0 ;
--  int res1 = 0 ;
--  PyObject * obj0 = 0 ;
--  
--  if (!PyArg_ParseTuple(args,(char *)"O:delete_VDMask",&obj0)) SWIG_fail;
--  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_vips__VDMask, SWIG_POINTER_DISOWN |  0 );
--  if (!SWIG_IsOK(res1)) {
--    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VDMask" "', argument " "1"" of type '" "vips::VDMask *""'"); 
--  }
--  arg1 = reinterpret_cast< vips::VDMask * >(argp1);
--  delete arg1;
--  resultobj = SWIG_Py_Void();
--  return resultobj;
--fail:
--  return NULL;
--}
--
--
--SWIGINTERN PyObject *VDMask_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
--  PyObject *obj;
--  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
--  SWIG_TypeNewClientData(SWIGTYPE_p_vips__VDMask, SWIG_NewClientData(obj));
--  return SWIG_Py_Void();
--}
--
--static PyMethodDef SwigMethods[] = {
--       { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
--       { (char *)"new_VMask", _wrap_new_VMask, METH_VARARGS, NULL},
--       { (char *)"VMask___assign__", _wrap_VMask___assign__, METH_VARARGS, NULL},
--       { (char *)"delete_VMask", _wrap_delete_VMask, METH_VARARGS, NULL},
--       { (char *)"VMask_xsize", _wrap_VMask_xsize, METH_VARARGS, NULL},
--       { (char *)"VMask_ysize", _wrap_VMask_ysize, METH_VARARGS, NULL},
--       { (char *)"VMask_size", _wrap_VMask_size, METH_VARARGS, NULL},
--       { (char *)"VMask_filename", _wrap_VMask_filename, METH_VARARGS, NULL},
--       { (char *)"VMask_type", _wrap_VMask_type, METH_VARARGS, NULL},
--       { (char *)"VMask_mask", _wrap_VMask_mask, METH_VARARGS, NULL},
--       { (char *)"VMask_ostream_print", _wrap_VMask_ostream_print, METH_VARARGS, NULL},
--       { (char *)"VMask_swigregister", VMask_swigregister, METH_VARARGS, NULL},
--       { (char *)"__lshift__", _wrap___lshift__, METH_VARARGS, NULL},
--       { (char *)"new_VIMask", _wrap_new_VIMask, METH_VARARGS, NULL},
--       { (char *)"VIMask_scale", _wrap_VIMask_scale, METH_VARARGS, NULL},
--       { (char *)"VIMask_offset", _wrap_VIMask_offset, METH_VARARGS, NULL},
--       { (char *)"VIMask_embed", _wrap_VIMask_embed, METH_VARARGS, NULL},
--       { (char *)"VIMask___index__", _wrap_VIMask___index__, METH_VARARGS, NULL},
--       { (char *)"VIMask___call__", _wrap_VIMask___call__, METH_VARARGS, NULL},
--       { (char *)"VIMask_get", _wrap_VIMask_get, METH_VARARGS, NULL},
--       { (char *)"VIMask_gauss", _wrap_VIMask_gauss, METH_VARARGS, NULL},
--       { (char *)"VIMask_gauss_sep", _wrap_VIMask_gauss_sep, METH_VARARGS, NULL},
--       { (char *)"VIMask_log", _wrap_VIMask_log, METH_VARARGS, NULL},
--       { (char *)"VIMask_rotate45", _wrap_VIMask_rotate45, METH_VARARGS, NULL},
--       { (char *)"VIMask_rotate90", _wrap_VIMask_rotate90, METH_VARARGS, NULL},
--       { (char *)"VIMask_trn", _wrap_VIMask_trn, METH_VARARGS, NULL},
--       { (char *)"VIMask_inv", _wrap_VIMask_inv, METH_VARARGS, NULL},
--       { (char *)"VIMask_cat", _wrap_VIMask_cat, METH_VARARGS, NULL},
--       { (char *)"VIMask_mul", _wrap_VIMask_mul, METH_VARARGS, NULL},
--       { (char *)"delete_VIMask", _wrap_delete_VIMask, METH_VARARGS, NULL},
--       { (char *)"VIMask_swigregister", VIMask_swigregister, METH_VARARGS, NULL},
--       { (char *)"new_VDMask", _wrap_new_VDMask, METH_VARARGS, NULL},
--       { (char *)"VDMask_embed", _wrap_VDMask_embed, METH_VARARGS, NULL},
--       { (char *)"VDMask_scale", _wrap_VDMask_scale, METH_VARARGS, NULL},
--       { (char *)"VDMask_offset", _wrap_VDMask_offset, METH_VARARGS, NULL},
--       { (char *)"VDMask___index__", _wrap_VDMask___index__, METH_VARARGS, NULL},
--       { (char *)"VDMask___call__", _wrap_VDMask___call__, METH_VARARGS, NULL},
--       { (char *)"VDMask_get", _wrap_VDMask_get, METH_VARARGS, NULL},
--       { (char *)"VDMask_gauss", _wrap_VDMask_gauss, METH_VARARGS, NULL},
--       { (char *)"VDMask_log", _wrap_VDMask_log, METH_VARARGS, NULL},
--       { (char *)"VDMask_rotate45", _wrap_VDMask_rotate45, METH_VARARGS, NULL},
--       { (char *)"VDMask_rotate90", _wrap_VDMask_rotate90, METH_VARARGS, NULL},
--       { (char *)"VDMask_scalei", _wrap_VDMask_scalei, METH_VARARGS, NULL},
--       { (char *)"VDMask_trn", _wrap_VDMask_trn, METH_VARARGS, NULL},
--       { (char *)"VDMask_inv", _wrap_VDMask_inv, METH_VARARGS, NULL},
--       { (char *)"VDMask_cat", _wrap_VDMask_cat, METH_VARARGS, NULL},
--       { (char *)"VDMask_mul", _wrap_VDMask_mul, METH_VARARGS, NULL},
--       { (char *)"delete_VDMask", _wrap_delete_VDMask, METH_VARARGS, NULL},
--       { (char *)"VDMask_swigregister", VDMask_swigregister, METH_VARARGS, NULL},
--       { NULL, NULL, 0, NULL }
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
--
--static void *_p_vips__VIMaskTo_p_vips__VMask(void *x, int *SWIGUNUSEDPARM(newmemory)) {
--    return (void *)((vips::VMask *)  ((vips::VIMask *) x));
--}
--static void *_p_vips__VDMaskTo_p_vips__VMask(void *x, int *SWIGUNUSEDPARM(newmemory)) {
--    return (void *)((vips::VMask *)  ((vips::VDMask *) x));
--}
--static swig_type_info _swigt__p__private_detail__MASKUNION = {"_p__private_detail__MASKUNION", "_private_detail::MASKUNION *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p__private_detail__VPMask__VMaskType = {"_p__private_detail__VPMask__VMaskType", "_private_detail::VPMask::VMaskType *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_allocator_type = {"_p_allocator_type", "allocator_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_double = {"_p_double", "double *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_im__DOUBLEMASK = {"_p_im__DOUBLEMASK", "im__DOUBLEMASK *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_im__INTMASK = {"_p_im__INTMASK", "im__INTMASK *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_matrix = {"_p_matrix", "matrix *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_size_type = {"_p_size_type", "size_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_std__ostream = {"_p_std__ostream", "std::ostream *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VDMask = {"_p_vips__VDMask", "vips::VDMask *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VError = {"_p_vips__VError", "vips::VError *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VIMask = {"_p_vips__VIMask", "vips::VIMask *", 0, 0, (void*)0, 0};
--static swig_type_info _swigt__p_vips__VMask = {"_p_vips__VMask", "vips::VMask *", 0, 0, (void*)0, 0};
--
--static swig_type_info *swig_type_initial[] = {
--  &_swigt__p__private_detail__MASKUNION,
--  &_swigt__p__private_detail__VPMask__VMaskType,
--  &_swigt__p_allocator_type,
--  &_swigt__p_char,
--  &_swigt__p_difference_type,
--  &_swigt__p_double,
--  &_swigt__p_im__DOUBLEMASK,
--  &_swigt__p_im__INTMASK,
--  &_swigt__p_int,
--  &_swigt__p_matrix,
--  &_swigt__p_size_type,
--  &_swigt__p_std__ostream,
--  &_swigt__p_value_type,
--  &_swigt__p_vips__VDMask,
--  &_swigt__p_vips__VError,
--  &_swigt__p_vips__VIMask,
--  &_swigt__p_vips__VMask,
--};
--
--static swig_cast_info _swigc__p__private_detail__MASKUNION[] = {  {&_swigt__p__private_detail__MASKUNION, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p__private_detail__VPMask__VMaskType[] = {  {&_swigt__p__private_detail__VPMask__VMaskType, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_allocator_type[] = {  {&_swigt__p_allocator_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_difference_type[] = {  {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_double[] = {  {&_swigt__p_double, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_im__DOUBLEMASK[] = {  {&_swigt__p_im__DOUBLEMASK, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_im__INTMASK[] = {  {&_swigt__p_im__INTMASK, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_int[] = {  {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_matrix[] = {  {&_swigt__p_matrix, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_size_type[] = {  {&_swigt__p_size_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_std__ostream[] = {  {&_swigt__p_std__ostream, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_value_type[] = {  {&_swigt__p_value_type, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VDMask[] = {  {&_swigt__p_vips__VDMask, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VError[] = {  {&_swigt__p_vips__VError, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VIMask[] = {  {&_swigt__p_vips__VIMask, 0, 0, 0},{0, 0, 0, 0}};
--static swig_cast_info _swigc__p_vips__VMask[] = {  {&_swigt__p_vips__VDMask, _p_vips__VDMaskTo_p_vips__VMask, 0, 0},  {&_swigt__p_vips__VMask, 0, 0, 0},  {&_swigt__p_vips__VIMask, _p_vips__VIMaskTo_p_vips__VMask, 0, 0},{0, 0, 0, 0}};
--
--static swig_cast_info *swig_cast_initial[] = {
--  _swigc__p__private_detail__MASKUNION,
--  _swigc__p__private_detail__VPMask__VMaskType,
--  _swigc__p_allocator_type,
--  _swigc__p_char,
--  _swigc__p_difference_type,
--  _swigc__p_double,
--  _swigc__p_im__DOUBLEMASK,
--  _swigc__p_im__INTMASK,
--  _swigc__p_int,
--  _swigc__p_matrix,
--  _swigc__p_size_type,
--  _swigc__p_std__ostream,
--  _swigc__p_value_type,
--  _swigc__p_vips__VDMask,
--  _swigc__p_vips__VError,
--  _swigc__p_vips__VIMask,
--  _swigc__p_vips__VMask,
--};
--
--
--/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
--
--static swig_const_info swig_const_table[] = {
--{0, 0, 0, 0.0, 0, 0}};
--
--#ifdef __cplusplus
--}
--#endif
--/* -----------------------------------------------------------------------------
-- * Type initialization:
-- * This problem is tough by the requirement that no dynamic 
-- * memory is used. Also, since swig_type_info structures store pointers to 
-- * swig_cast_info structures and swig_cast_info structures store pointers back
-- * to swig_type_info structures, we need some lookup code at initialization. 
-- * The idea is that swig generates all the structures that are needed. 
-- * The runtime then collects these partially filled structures. 
-- * The SWIG_InitializeModule function takes these initial arrays out of 
-- * swig_module, and does all the lookup, filling in the swig_module.types
-- * array with the correct data and linking the correct swig_cast_info
-- * structures together.
-- *
-- * The generated swig_type_info structures are assigned staticly to an initial 
-- * array. We just loop through that array, and handle each type individually.
-- * First we lookup if this type has been already loaded, and if so, use the
-- * loaded structure instead of the generated one. Then we have to fill in the
-- * cast linked list. The cast data is initially stored in something like a
-- * two-dimensional array. Each row corresponds to a type (there are the same
-- * number of rows as there are in the swig_type_initial array). Each entry in
-- * a column is one of the swig_cast_info structures for that type.
-- * The cast_initial array is actually an array of arrays, because each row has
-- * a variable number of columns. So to actually build the cast linked list,
-- * we find the array of casts associated with the type, and loop through it 
-- * adding the casts to the list. The one last trick we need to do is making
-- * sure the type pointer in the swig_cast_info struct is correct.
-- *
-- * First off, we lookup the cast->type name to see if it is already loaded. 
-- * There are three cases to handle:
-- *  1) If the cast->type has already been loaded AND the type we are adding
-- *     casting info to has not been loaded (it is in this module), THEN we
-- *     replace the cast->type pointer with the type pointer that has already
-- *     been loaded.
-- *  2) If BOTH types (the one we are adding casting info to, and the 
-- *     cast->type) are loaded, THEN the cast info has already been loaded by
-- *     the previous module so we just ignore it.
-- *  3) Finally, if cast->type has not already been loaded, then we add that
-- *     swig_cast_info to the linked list (because the cast->type) pointer will
-- *     be correct.
-- * ----------------------------------------------------------------------------- */
--
--#ifdef __cplusplus
--extern "C" {
--#if 0
--} /* c-mode */
--#endif
--#endif
--
--#if 0
--#define SWIGRUNTIME_DEBUG
--#endif
--
--
--SWIGRUNTIME void
--SWIG_InitializeModule(void *clientdata) {
--  size_t i;
--  swig_module_info *module_head, *iter;
--  int found, init;
--  
--  /* check to see if the circular list has been setup, if not, set it up */
--  if (swig_module.next==0) {
--    /* Initialize the swig_module */
--    swig_module.type_initial = swig_type_initial;
--    swig_module.cast_initial = swig_cast_initial;
--    swig_module.next = &swig_module;
--    init = 1;
--  } else {
--    init = 0;
--  }
--  
--  /* Try and load any already created modules */
--  module_head = SWIG_GetModule(clientdata);
--  if (!module_head) {
--    /* This is the first module loaded for this interpreter */
--    /* so set the swig module into the interpreter */
--    SWIG_SetModule(clientdata, &swig_module);
--    module_head = &swig_module;
--  } else {
--    /* the interpreter has loaded a SWIG module, but has it loaded this one? */
--    found=0;
--    iter=module_head;
--    do {
--      if (iter==&swig_module) {
--        found=1;
--        break;
--      }
--      iter=iter->next;
--    } while (iter!= module_head);
--    
--    /* if the is found in the list, then all is done and we may leave */
--    if (found) return;
--    /* otherwise we must add out module into the list */
--    swig_module.next = module_head->next;
--    module_head->next = &swig_module;
--  }
--  
--  /* When multiple interpeters are used, a module could have already been initialized in
--       a different interpreter, but not yet have a pointer in this interpreter.
--       In this case, we do not want to continue adding types... everything should be
--       set up already */
--  if (init == 0) return;
--  
--  /* Now work on filling in swig_module.types */
--#ifdef SWIGRUNTIME_DEBUG
--  printf("SWIG_InitializeModule: size %d\n", swig_module.size);
--#endif
--  for (i = 0; i < swig_module.size; ++i) {
--    swig_type_info *type = 0;
--    swig_type_info *ret;
--    swig_cast_info *cast;
--    
--#ifdef SWIGRUNTIME_DEBUG
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--#endif
--    
--    /* if there is another module already loaded */
--    if (swig_module.next != &swig_module) {
--      type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
--    }
--    if (type) {
--      /* Overwrite clientdata field */
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: found type %s\n", type->name);
--#endif
--      if (swig_module.type_initial[i]->clientdata) {
--        type->clientdata = swig_module.type_initial[i]->clientdata;
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
--#endif
--      }
--    } else {
--      type = swig_module.type_initial[i];
--    }
--    
--    /* Insert casting types */
--    cast = swig_module.cast_initial[i];
--    while (cast->type) {
--      /* Don't need to add information already in the list */
--      ret = 0;
--#ifdef SWIGRUNTIME_DEBUG
--      printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
--#endif
--      if (swig_module.next != &swig_module) {
--        ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
--#ifdef SWIGRUNTIME_DEBUG
--        if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
--#endif
--      }
--      if (ret) {
--        if (type == swig_module.type_initial[i]) {
--#ifdef SWIGRUNTIME_DEBUG
--          printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
--#endif
--          cast->type = ret;
--          ret = 0;
--        } else {
--          /* Check for casting already in the list */
--          swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
--#ifdef SWIGRUNTIME_DEBUG
--          if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
--#endif
--          if (!ocast) ret = 0;
--        }
--      }
--      
--      if (!ret) {
--#ifdef SWIGRUNTIME_DEBUG
--        printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
--#endif
--        if (type->cast) {
--          type->cast->prev = cast;
--          cast->next = type->cast;
--        }
--        type->cast = cast;
--      }
--      cast++;
--    }
--    /* Set entry in modules->types array equal to the type */
--    swig_module.types[i] = type;
--  }
--  swig_module.types[i] = 0;
--  
--#ifdef SWIGRUNTIME_DEBUG
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--  for (i = 0; i < swig_module.size; ++i) {
--    int j = 0;
--    swig_cast_info *cast = swig_module.cast_initial[i];
--    printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
--    while (cast->type) {
--      printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
--      cast++;
--      ++j;
--    }
--    printf("---- Total casts: %d\n",j);
--  }
--  printf("**** SWIG_InitializeModule: Cast List ******\n");
--#endif
--}
--
--/* This function will propagate the clientdata field of type to
--* any new swig_type_info structures that have been added into the list
--* of equivalent types.  It is like calling
--* SWIG_TypeClientData(type, clientdata) a second time.
--*/
--SWIGRUNTIME void
--SWIG_PropagateClientData(void) {
--  size_t i;
--  swig_cast_info *equiv;
--  static int init_run = 0;
--  
--  if (init_run) return;
--  init_run = 1;
--  
--  for (i = 0; i < swig_module.size; i++) {
--    if (swig_module.types[i]->clientdata) {
--      equiv = swig_module.types[i]->cast;
--      while (equiv) {
--        if (!equiv->converter) {
--          if (equiv->type && !equiv->type->clientdata)
--          SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
--        }
--        equiv = equiv->next;
--      }
--    }
--  }
--}
--
--#ifdef __cplusplus
--#if 0
--{
--  /* c-mode */
--#endif
--}
--#endif
--
--
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--  
--  /* Python-specific SWIG API */
--#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
--#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
--#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
--  
--  /* -----------------------------------------------------------------------------
--   * global variable support code.
--   * ----------------------------------------------------------------------------- */
--  
--  typedef struct swig_globalvar {
--    char       *name;                  /* Name of global variable */
--    PyObject *(*get_attr)(void);       /* Return the current value */
--    int       (*set_attr)(PyObject *); /* Set the value */
--    struct swig_globalvar *next;
--  } swig_globalvar;
--  
--  typedef struct swig_varlinkobject {
--    PyObject_HEAD
--    swig_globalvar *vars;
--  } swig_varlinkobject;
--  
--  SWIGINTERN PyObject *
--  swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
--#if PY_VERSION_HEX >= 0x03000000
--    return PyUnicode_InternFromString("<Swig global variables>");
--#else
--    return PyString_FromString("<Swig global variables>");
--#endif
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_str(swig_varlinkobject *v) {
--#if PY_VERSION_HEX >= 0x03000000
--    PyObject *str = PyUnicode_InternFromString("(");
--    PyObject *tail;
--    PyObject *joined;
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      tail = PyUnicode_FromString(var->name);
--      joined = PyUnicode_Concat(str, tail);
--      Py_DecRef(str);
--      Py_DecRef(tail);
--      str = joined;
--      if (var->next) {
--        tail = PyUnicode_InternFromString(", ");
--        joined = PyUnicode_Concat(str, tail);
--        Py_DecRef(str);
--        Py_DecRef(tail);
--        str = joined;
--      }
--    }
--    tail = PyUnicode_InternFromString(")");
--    joined = PyUnicode_Concat(str, tail);
--    Py_DecRef(str);
--    Py_DecRef(tail);
--    str = joined;
--#else
--    PyObject *str = PyString_FromString("(");
--    swig_globalvar *var;
--    for (var = v->vars; var; var=var->next) {
--      PyString_ConcatAndDel(&str,PyString_FromString(var->name));
--      if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
--    }
--    PyString_ConcatAndDel(&str,PyString_FromString(")"));
--#endif
--    return str;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
--    char *tmp;
--    PyObject *str = swig_varlink_str(v);
--    fprintf(fp,"Swig global variables ");
--    fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
--    SWIG_Python_str_DelForPy3(tmp);
--    Py_DECREF(str);
--    return 0;
--  }
--  
--  SWIGINTERN void
--  swig_varlink_dealloc(swig_varlinkobject *v) {
--    swig_globalvar *var = v->vars;
--    while (var) {
--      swig_globalvar *n = var->next;
--      free(var->name);
--      free(var);
--      var = n;
--    }
--  }
--  
--  SWIGINTERN PyObject *
--  swig_varlink_getattr(swig_varlinkobject *v, char *n) {
--    PyObject *res = NULL;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->get_attr)();
--        break;
--      }
--      var = var->next;
--    }
--    if (res == NULL && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN int
--  swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
--    int res = 1;
--    swig_globalvar *var = v->vars;
--    while (var) {
--      if (strcmp(var->name,n) == 0) {
--        res = (*var->set_attr)(p);
--        break;
--      }
--      var = var->next;
--    }
--    if (res == 1 && !PyErr_Occurred()) {
--      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
--    }
--    return res;
--  }
--  
--  SWIGINTERN PyTypeObject*
--  swig_varlink_type(void) {
--    static char varlink__doc__[] = "Swig var link object";
--    static PyTypeObject varlink_type;
--    static int type_init = 0;
--    if (!type_init) {
--      const PyTypeObject tmp = {
--        /* PyObject header changed in Python 3 */
--#if PY_VERSION_HEX >= 0x03000000
--        PyVarObject_HEAD_INIT(NULL, 0)
--#else
--        PyObject_HEAD_INIT(NULL)
--        0,                                  /* ob_size */
--#endif
--        (char *)"swigvarlink",              /* tp_name */
--        sizeof(swig_varlinkobject),         /* tp_basicsize */
--        0,                                  /* tp_itemsize */
--        (destructor) swig_varlink_dealloc,  /* tp_dealloc */
--        (printfunc) swig_varlink_print,     /* tp_print */
--        (getattrfunc) swig_varlink_getattr, /* tp_getattr */
--        (setattrfunc) swig_varlink_setattr, /* tp_setattr */
--        0,                                  /* tp_compare */
--        (reprfunc) swig_varlink_repr,       /* tp_repr */
--        0,                                  /* tp_as_number */
--        0,                                  /* tp_as_sequence */
--        0,                                  /* tp_as_mapping */
--        0,                                  /* tp_hash */
--        0,                                  /* tp_call */
--        (reprfunc) swig_varlink_str,        /* tp_str */
--        0,                                  /* tp_getattro */
--        0,                                  /* tp_setattro */
--        0,                                  /* tp_as_buffer */
--        0,                                  /* tp_flags */
--        varlink__doc__,                     /* tp_doc */
--        0,                                  /* tp_traverse */
--        0,                                  /* tp_clear */
--        0,                                  /* tp_richcompare */
--        0,                                  /* tp_weaklistoffset */
--#if PY_VERSION_HEX >= 0x02020000
--        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
--#endif
--#if PY_VERSION_HEX >= 0x02030000
--        0,                                  /* tp_del */
--#endif
--#if PY_VERSION_HEX >= 0x02060000
--        0,                                  /* tp_version */
--#endif
--#ifdef COUNT_ALLOCS
--        0,0,0,0                             /* tp_alloc -> tp_next */
--#endif
--      };
--      varlink_type = tmp;
--      type_init = 1;
--#if PY_VERSION_HEX < 0x02020000
--      varlink_type.ob_type = &PyType_Type;
--#else
--      if (PyType_Ready(&varlink_type) < 0)
--      return NULL;
--#endif
--    }
--    return &varlink_type;
--  }
--  
--  /* Create a variable linking object for use later */
--  SWIGINTERN PyObject *
--  SWIG_Python_newvarlink(void) {
--    swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
--    if (result) {
--      result->vars = 0;
--    }
--    return ((PyObject*) result);
--  }
--  
--  SWIGINTERN void 
--  SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
--    swig_varlinkobject *v = (swig_varlinkobject *) p;
--    swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
--    if (gv) {
--      size_t size = strlen(name)+1;
--      gv->name = (char *)malloc(size);
--      if (gv->name) {
--        strncpy(gv->name,name,size);
--        gv->get_attr = get_attr;
--        gv->set_attr = set_attr;
--        gv->next = v->vars;
--      }
--    }
--    v->vars = gv;
--  }
--  
--  SWIGINTERN PyObject *
--  SWIG_globals(void) {
--    static PyObject *_SWIG_globals = 0; 
--    if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();  
--    return _SWIG_globals;
--  }
--  
--  /* -----------------------------------------------------------------------------
--   * constants/methods manipulation
--   * ----------------------------------------------------------------------------- */
--  
--  /* Install Constants */
--  SWIGINTERN void
--  SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
--    PyObject *obj = 0;
--    size_t i;
--    for (i = 0; constants[i].type; ++i) {
--      switch(constants[i].type) {
--      case SWIG_PY_POINTER:
--        obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
--        break;
--      case SWIG_PY_BINARY:
--        obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
--        break;
--      default:
--        obj = 0;
--        break;
--      }
--      if (obj) {
--        PyDict_SetItemString(d, constants[i].name, obj);
--        Py_DECREF(obj);
--      }
--    }
--  }
--  
--  /* -----------------------------------------------------------------------------*/
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  /* -----------------------------------------------------------------------------*/
--  
--  SWIGINTERN void
--  SWIG_Python_FixMethods(PyMethodDef *methods,
--    swig_const_info *const_table,
--    swig_type_info **types,
--    swig_type_info **types_initial) {
--    size_t i;
--    for (i = 0; methods[i].ml_name; ++i) {
--      const char *c = methods[i].ml_doc;
--      if (c && (c = strstr(c, "swig_ptr: "))) {
--        int j;
--        swig_const_info *ci = 0;
--        const char *name = c + 10;
--        for (j = 0; const_table[j].type; ++j) {
--          if (strncmp(const_table[j].name, name, 
--              strlen(const_table[j].name)) == 0) {
--            ci = &(const_table[j]);
--            break;
--          }
--        }
--        if (ci) {
--          void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
--          if (ptr) {
--            size_t shift = (ci->ptype) - types;
--            swig_type_info *ty = types_initial[shift];
--            size_t ldoc = (c - methods[i].ml_doc);
--            size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
--            char *ndoc = (char*)malloc(ldoc + lptr + 10);
--            if (ndoc) {
--              char *buff = ndoc;
--              strncpy(buff, methods[i].ml_doc, ldoc);
--              buff += ldoc;
--              strncpy(buff, "swig_ptr: ", 10);
--              buff += 10;
--              SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
--              methods[i].ml_doc = ndoc;
--            }
--          }
--        }
--      }
--    }
--  } 
--  
--#ifdef __cplusplus
--}
--#endif
--
--/* -----------------------------------------------------------------------------*
-- *  Partial Init method
-- * -----------------------------------------------------------------------------*/
--
--#ifdef __cplusplus
--extern "C"
--#endif
--
--SWIGEXPORT 
--#if PY_VERSION_HEX >= 0x03000000
--PyObject*
--#else
--void
--#endif
--SWIG_init(void) {
--  PyObject *m, *d, *md;
--#if PY_VERSION_HEX >= 0x03000000
--  static struct PyModuleDef SWIG_module = {
--# if PY_VERSION_HEX >= 0x03020000
--    PyModuleDef_HEAD_INIT,
--# else
--    {
--      PyObject_HEAD_INIT(NULL)
--      NULL, /* m_init */
--      0,    /* m_index */
--      NULL, /* m_copy */
--    },
--# endif
--    (char *) SWIG_name,
--    NULL,
--    -1,
--    SwigMethods,
--    NULL,
--    NULL,
--    NULL,
--    NULL
--  };
--#endif
--  
--#if defined(SWIGPYTHON_BUILTIN)
--  static SwigPyClientData SwigPyObject_clientdata = {
--    0, 0, 0, 0, 0, 0, 0
--  };
--  static PyGetSetDef this_getset_def = {
--    (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
--  };
--  static SwigPyGetSet thisown_getset_closure = {
--    (PyCFunction) SwigPyObject_own,
--    (PyCFunction) SwigPyObject_own
--  };
--  static PyGetSetDef thisown_getset_def = {
--    (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
--  };
--  PyObject *metatype_args;
--  PyTypeObject *builtin_pytype;
--  int builtin_base_count;
--  swig_type_info *builtin_basetype;
--  PyObject *tuple;
--  PyGetSetDescrObject *static_getset;
--  PyTypeObject *metatype;
--  SwigPyClientData *cd;
--  PyObject *public_interface, *public_symbol;
--  PyObject *this_descr;
--  PyObject *thisown_descr;
--  int i;
--  
--  (void)builtin_pytype;
--  (void)builtin_base_count;
--  (void)builtin_basetype;
--  (void)tuple;
--  (void)static_getset;
--  
--  /* metatype is used to implement static member variables. */
--  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
--  assert(metatype_args);
--  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
--  assert(metatype);
--  Py_DECREF(metatype_args);
--  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
--  assert(PyType_Ready(metatype) >= 0);
--#endif
--  
--  /* Fix SwigMethods to carry the callback ptrs when needed */
--  SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  m = PyModule_Create(&SWIG_module);
--#else
--  m = Py_InitModule((char *) SWIG_name, SwigMethods);
--#endif
--  md = d = PyModule_GetDict(m);
--  (void)md;
--  
--  SWIG_InitializeModule(0);
--  
--#ifdef SWIGPYTHON_BUILTIN
--  SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
--  assert(SwigPyObject_stype);
--  cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
--  if (!cd) {
--    SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
--    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
--  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
--    PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
--# if PY_VERSION_HEX >= 0x03000000
--    return NULL;
--# else
--    return;
--# endif
--  }
--  
--  /* All objects have a 'this' attribute */
--  this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
--  (void)this_descr;
--  
--  /* All objects have a 'thisown' attribute */
--  thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
--  (void)thisown_descr;
--  
--  public_interface = PyList_New(0);
--  public_symbol = 0;
--  (void)public_symbol;
--  
--  PyDict_SetItemString(md, "__all__", public_interface);
--  Py_DECREF(public_interface);
--  for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
--  for (i = 0; swig_const_table[i].name != 0; ++i)
--  SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
--#endif
--  
--  SWIG_InstallConstants(d,swig_const_table);
--  
--#if PY_VERSION_HEX >= 0x03000000
--  return m;
--#else
--  return;
--#endif
--}
--
-diff -u --recursive --new-file vips-7.38.5-vanilla/swig/vipsCC/VMask.py vips-7.38.5/swig/vipsCC/VMask.py
---- vips-7.38.5-vanilla/swig/vipsCC/VMask.py   2014-07-17 23:48:36.208794473 -0400
-+++ vips-7.38.5/swig/vipsCC/VMask.py   1969-12-31 19:00:00.000000000 -0500
-@@ -1,191 +0,0 @@
--# This file was automatically generated by SWIG (http://www.swig.org).
--# Version 2.0.10
+       doc/reference/Makefile
+diff -u --recursive --new-file vips-7.42.1-vanilla/libvips/Makefile.am vips-7.42.1/libvips/Makefile.am
+--- vips-7.42.1-vanilla/libvips/Makefile.am    2014-12-29 17:45:59.590996100 -0500
++++ vips-7.42.1/libvips/Makefile.am    2014-12-29 17:59:32.053375826 -0500
+@@ -33,14 +33,6 @@
+ # empty means default to C linking
+ libvips_la_SOURCES = 
+-# if we have C++ components enabled, make sure we link the top-level with c++
 -#
--# Do not make changes to this file unless you know what you are doing--modify
--# the SWIG interface file instead.
--
--
--
--from sys import version_info
--if version_info >= (2,6,0):
--    def swig_import_helper():
--        from os.path import dirname
--        import imp
--        fp = None
--        try:
--            fp, pathname, description = imp.find_module('vmaskmodule', [dirname(__file__)])
--        except ImportError:
--            import vmaskmodule
--            return vmaskmodule
--        if fp is not None:
--            try:
--                _mod = imp.load_module('vmaskmodule', fp, pathname, description)
--            finally:
--                fp.close()
--            return _mod
--    vmaskmodule = swig_import_helper()
--    del swig_import_helper
--else:
--    import vmaskmodule
--del version_info
--try:
--    _swig_property = property
--except NameError:
--    pass # Python < 2.2 doesn't have 'property'.
--def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
--    if (name == "thisown"): return self.this.own(value)
--    if (name == "this"):
--        if type(value).__name__ == 'SwigPyObject':
--            self.__dict__[name] = value
--            return
--    method = class_type.__swig_setmethods__.get(name,None)
--    if method: return method(self,value)
--    if (not static):
--        self.__dict__[name] = value
--    else:
--        raise AttributeError("You cannot add attributes to %s" % self)
--
--def _swig_setattr(self,class_type,name,value):
--    return _swig_setattr_nondynamic(self,class_type,name,value,0)
--
--def _swig_getattr(self,class_type,name):
--    if (name == "thisown"): return self.this.own()
--    method = class_type.__swig_getmethods__.get(name,None)
--    if method: return method(self)
--    raise AttributeError(name)
--
--def _swig_repr(self):
--    try: strthis = "proxy of " + self.this.__repr__()
--    except: strthis = ""
--    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
--
--try:
--    _object = object
--    _newclass = 1
--except AttributeError:
--    class _object : pass
--    _newclass = 0
--
--
--import VError
--import VImage
--import VDisplay
--class VMask(_object):
--    __swig_setmethods__ = {}
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VMask, name, value)
--    __swig_getmethods__ = {}
--    __getattr__ = lambda self, name: _swig_getattr(self, VMask, name)
--    __repr__ = _swig_repr
--    def __init__(self, *args): 
--        this = vmaskmodule.new_VMask(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def __assign__(self, *args): return vmaskmodule.VMask___assign__(self, *args)
--    __swig_destroy__ = vmaskmodule.delete_VMask
--    __del__ = lambda self : None;
--    def xsize(self): return vmaskmodule.VMask_xsize(self)
--    def ysize(self): return vmaskmodule.VMask_ysize(self)
--    def size(self): return vmaskmodule.VMask_size(self)
--    def filename(self): return vmaskmodule.VMask_filename(self)
--    def type(self): return vmaskmodule.VMask_type(self)
--    def mask(self): return vmaskmodule.VMask_mask(self)
--    def ostream_print(self, *args): return vmaskmodule.VMask_ostream_print(self, *args)
--VMask_swigregister = vmaskmodule.VMask_swigregister
--VMask_swigregister(VMask)
--
--
--def __lshift__(*args):
--  return vmaskmodule.__lshift__(*args)
--__lshift__ = vmaskmodule.__lshift__
--class VIMask(VMask):
--    __swig_setmethods__ = {}
--    for _s in [VMask]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VIMask, name, value)
--    __swig_getmethods__ = {}
--    for _s in [VMask]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))
--    __getattr__ = lambda self, name: _swig_getattr(self, VIMask, name)
--    __repr__ = _swig_repr
--    def __init__(self, *args): 
--        this = vmaskmodule.new_VIMask(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def scale(self): return vmaskmodule.VIMask_scale(self)
--    def offset(self): return vmaskmodule.VIMask_offset(self)
--    def embed(self, *args): return vmaskmodule.VIMask_embed(self, *args)
--    def __index__(self, *args): return vmaskmodule.VIMask___index__(self, *args)
--    def __call__(self, *args): return vmaskmodule.VIMask___call__(self, *args)
--    def get(self, *args): return vmaskmodule.VIMask_get(self, *args)
--    __swig_getmethods__["gauss"] = lambda x: vmaskmodule.VIMask_gauss
--    if _newclass:gauss = staticmethod(vmaskmodule.VIMask_gauss)
--    __swig_getmethods__["gauss_sep"] = lambda x: vmaskmodule.VIMask_gauss_sep
--    if _newclass:gauss_sep = staticmethod(vmaskmodule.VIMask_gauss_sep)
--    __swig_getmethods__["log"] = lambda x: vmaskmodule.VIMask_log
--    if _newclass:log = staticmethod(vmaskmodule.VIMask_log)
--    def rotate45(self): return vmaskmodule.VIMask_rotate45(self)
--    def rotate90(self): return vmaskmodule.VIMask_rotate90(self)
--    def trn(self): return vmaskmodule.VIMask_trn(self)
--    def inv(self): return vmaskmodule.VIMask_inv(self)
--    def cat(self, *args): return vmaskmodule.VIMask_cat(self, *args)
--    def mul(self, *args): return vmaskmodule.VIMask_mul(self, *args)
--    __swig_destroy__ = vmaskmodule.delete_VIMask
--    __del__ = lambda self : None;
--VIMask_swigregister = vmaskmodule.VIMask_swigregister
--VIMask_swigregister(VIMask)
--
--def VIMask_gauss(*args):
--  return vmaskmodule.VIMask_gauss(*args)
--VIMask_gauss = vmaskmodule.VIMask_gauss
--
--def VIMask_gauss_sep(*args):
--  return vmaskmodule.VIMask_gauss_sep(*args)
--VIMask_gauss_sep = vmaskmodule.VIMask_gauss_sep
+-# sadly the if/endif isn't enough to stop automake detecting a c++ link even
+-# when c++ is disabled ... comment out this line if you have linking problems
+-if ENABLE_CXX
+-nodist_EXTRA_libvips_la_SOURCES = resample/dummy2.cc
+-endif
 -
--def VIMask_log(*args):
--  return vmaskmodule.VIMask_log(*args)
--VIMask_log = vmaskmodule.VIMask_log
+ # DLLs need dependant libs there too ... put @VIPS_LIBS@ at the end
+ libvips_la_LIBADD = \
+       resample/libresample.la \
+diff -u --recursive --new-file vips-7.42.1-vanilla/libvips/resample/Makefile.am vips-7.42.1/libvips/resample/Makefile.am
+--- vips-7.42.1-vanilla/libvips/resample/Makefile.am   2014-12-29 17:45:59.591996138 -0500
++++ vips-7.42.1/libvips/resample/Makefile.am   2014-12-29 18:01:57.107188019 -0500
+@@ -1,30 +1,3 @@
+-# only build the C++ stuff if ENABLE_CXX
+-# you'd think we could just define a couple of variables, but that seems to
+-# confuse libtool and make it link the library with g++
+-# instead, have two completely different paths
+-if ENABLE_CXX
 -
--class VDMask(VMask):
--    __swig_setmethods__ = {}
--    for _s in [VMask]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))
--    __setattr__ = lambda self, name, value: _swig_setattr(self, VDMask, name, value)
--    __swig_getmethods__ = {}
--    for _s in [VMask]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))
--    __getattr__ = lambda self, name: _swig_getattr(self, VDMask, name)
--    __repr__ = _swig_repr
--    def __init__(self, *args): 
--        this = vmaskmodule.new_VDMask(*args)
--        try: self.this.append(this)
--        except: self.this = this
--    def embed(self, *args): return vmaskmodule.VDMask_embed(self, *args)
--    def scale(self): return vmaskmodule.VDMask_scale(self)
--    def offset(self): return vmaskmodule.VDMask_offset(self)
--    def __index__(self, *args): return vmaskmodule.VDMask___index__(self, *args)
--    def __call__(self, *args): return vmaskmodule.VDMask___call__(self, *args)
--    def get(self, *args): return vmaskmodule.VDMask_get(self, *args)
--    __swig_getmethods__["gauss"] = lambda x: vmaskmodule.VDMask_gauss
--    if _newclass:gauss = staticmethod(vmaskmodule.VDMask_gauss)
--    __swig_getmethods__["log"] = lambda x: vmaskmodule.VDMask_log
--    if _newclass:log = staticmethod(vmaskmodule.VDMask_log)
--    def rotate45(self): return vmaskmodule.VDMask_rotate45(self)
--    def rotate90(self): return vmaskmodule.VDMask_rotate90(self)
--    def scalei(self): return vmaskmodule.VDMask_scalei(self)
--    def trn(self): return vmaskmodule.VDMask_trn(self)
--    def inv(self): return vmaskmodule.VDMask_inv(self)
--    def cat(self, *args): return vmaskmodule.VDMask_cat(self, *args)
--    def mul(self, *args): return vmaskmodule.VDMask_mul(self, *args)
--    __swig_destroy__ = vmaskmodule.delete_VDMask
--    __del__ = lambda self : None;
--VDMask_swigregister = vmaskmodule.VDMask_swigregister
--VDMask_swigregister(VDMask)
+-libresample_la_SOURCES = \
+-      affine.c \
+-      quadratic.c \
+-      resample.c \
+-      similarity.c \
+-      resize.c \
+-      presample.h \
+-      shrink.c \
+-      interpolate.c \
+-      transform.c \
+-      bicubic.cpp \
+-      lbb.cpp \
+-      nohalo.cpp \
+-      vsqbs.cpp \
+-      templates.h 
 -
--def VDMask_gauss(*args):
--  return vmaskmodule.VDMask_gauss(*args)
--VDMask_gauss = vmaskmodule.VDMask_gauss
+-EXTRA_DIST = \
+-      dummy2.cc 
 -
--def VDMask_log(*args):
--  return vmaskmodule.VDMask_log(*args)
--VDMask_log = vmaskmodule.VDMask_log
+-else
 -
--# This file is compatible with both classic and new-style classes.
+ libresample_la_SOURCES = \
+       resample.c \
+       similarity.c \
+@@ -36,16 +9,6 @@
+       quadratic.c \
+       transform.c 
+-EXTRA_DIST = \
+-      dummy2.cc \
+-      bicubic.cpp \
+-      lbb.cpp \
+-      nohalo.cpp \
+-      vsqbs.cpp \
+-      templates.h 
 -
+-endif
 -
-diff -u --recursive --new-file vips-7.38.5-vanilla/vips.pc.in vips-7.38.5/vips.pc.in
---- vips-7.38.5-vanilla/vips.pc.in     2014-07-17 23:48:36.236794473 -0400
-+++ vips-7.38.5/vips.pc.in     2014-07-17 23:48:52.069794148 -0400
-@@ -7,5 +7,5 @@
- Description: Image processing library
- Version: @VERSION@
- Requires: @PACKAGES_USED@
--Libs: -L${libdir} -lvips @VIPS_LIBS@ @VIPS_CXX_LIBS@
-+Libs: -L${libdir} -lvips @VIPS_LIBS@
- Cflags: -I${includedir} 
+ noinst_LTLIBRARIES = libresample.la
+ AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ 
index 0e6be0f9b856c395fca7ac5c1e8894d021aee0cf..998219a9fc48ad57092b880c4696ea1db4858090 100644 (file)
@@ -20,7 +20,7 @@ PKG_SOURCE_PROTO:=svn
 
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 PKG_LICENSE:=VARIOUS
-PKG_LICENSE_FILE:=doc/COPYING
+PKG_LICENSE_FILES:=doc/COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/mail/alpine/Makefile b/mail/alpine/Makefile
new file mode 100644 (file)
index 0000000..322e954
--- /dev/null
@@ -0,0 +1,123 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=alpine
+PKG_VERSION:=2.20
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=http://patches.freeiz.com/alpine/release/src/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_MD5SUM:=043b67666af73b26f9627ad97e2aaf92
+
+PKG_MAINTAINER:=Antti Seppälä <a.seppala@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_INSTALL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/alpine/Default
+  SECTION:=mail
+  CATEGORY:=Mail
+  DEPENDS:=+libopenssl +libncurses +libpthread +libpam $(ICONV_DEPENDS) $(INTL_DEPENDS)
+  TITLE:=Alternatively Licensed Program for Internet News and Email
+  URL:=http://www.washington.edu/alpine
+endef
+
+define Package/alpine/Default/description
+ Alpine (Alternatively Licenced Program for Internet News and Email) is a
+ free software email client developed at the University of Washington.
+ It is suitable for both the inexperienced email user as well as for
+ the most demanding power user.
+endef
+
+define Package/alpine
+$(call Package/alpine/Default)
+  TITLE+= (with OpenSSL support)
+  DEPENDS+= +libcrypto +libopenssl
+  VARIANT:=ssl
+endef
+
+define Package/alpine/description
+$(call Package/alpine/Default/description)
+ This package is built with OpenSSL support.
+endef
+
+define Package/alpine-nossl
+$(call Package/alpine/Default)
+  TITLE+= (without OpenSSL support)
+  VARIANT:=nossl
+endef
+
+define Package/alpine-nossl/description
+$(call Package/alpine/Default/description)
+ This package is built without OpenSSL support.
+endef
+
+CONFIGURE_ARGS += \
+       --with-libiconv-prefix=$(ICONV_PREFIX) \
+       --with-libintl-prefix=$(INTL_PREFIX) \
+       --without-tcl \
+       --without-ldap \
+       --without-krb5 \
+       --with-system-pinerc=/etc/pine.conf \
+       --with-system-fixed-pinerc=/etc/pine.conf.fixed \
+       --with-supplied-regex \
+       --with-default-sshpath=/usr/bin/ssh \
+       --disable-debug \
+       --disable-mouse \
+       --with-c-client-target=slx \
+
+CONFIGURE_VARS += \
+       top_builddir=$(PKG_BUILD_DIR)
+
+ifeq ($(BUILD_VARIANT),ssl)
+       CONFIGURE_ARGS += \
+               --with-ssl-include-dir=$(STAGING_DIR)/usr/include/openssl/. \
+               --with-ssl-lib-dir=$(STAGING_DIR)/usr/lib
+endif
+
+ifeq ($(BUILD_VARIANT),nossl)
+       CONFIGURE_ARGS += \
+               --without-ssl
+endif
+
+ifeq ($(CONFIG_BUILD_NLS),y)
+  DISABLE_NLS:=
+endif
+
+ifeq ($(CONFIG_IPV6),y)
+  DISABLE_IPV6:=
+else
+  DISABLE_IPV6:=--without-ipv6
+endif
+
+define Build/Compile
+       ( cd $(PKG_BUILD_DIR)/pith ; \
+               $(HOSTCC) help_h_gen.c -c -o help_h_gen.o ; \
+               $(HOSTCC) help_h_gen.o -o help_h_gen ; \
+               $(HOSTCC) help_c_gen.c -c -o help_c_gen.o ; \
+               $(HOSTCC) help_c_gen.o -o help_c_gen ; \
+       )
+       $(call Build/Compile/Default)
+endef
+
+define Package/alpine/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/$(PKG_NAME)
+endef
+
+Package/alpine-nossl/install = $(Package/alpine/install)
+
+$(eval $(call BuildPackage,alpine))
+$(eval $(call BuildPackage,alpine-nossl))
diff --git a/mail/alpine/patches/100-no-openssl-check-cross-compile.patch b/mail/alpine/patches/100-no-openssl-check-cross-compile.patch
new file mode 100644 (file)
index 0000000..4043098
--- /dev/null
@@ -0,0 +1,29 @@
+diff -Nru alpine-2.20-orig/configure alpine-2.20/configure
+--- alpine-2.20-orig/configure 2015-01-18 09:00:42.100645053 +0200
++++ alpine-2.20/configure      2015-01-25 12:01:11.831015443 +0200
+@@ -17643,10 +17643,8 @@
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking Openssl library version >= 1.0.1c" >&5
+ $as_echo_n "checking Openssl library version >= 1.0.1c... " >&6; }
+   if test "$cross_compiling" = yes; then :
+-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
+-See \`config.log' for more details" "$LINENO" 5; }
++   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5
++$as_echo "$as_me: WARNING: cross compiling: not checking" >&2;}
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+diff -Nru alpine-2.20-orig/configure.ac alpine-2.20/configure.ac
+--- alpine-2.20-orig/configure.ac      2015-01-18 08:38:08.893495949 +0200
++++ alpine-2.20/configure.ac   2015-01-25 12:01:02.773015236 +0200
+@@ -1370,7 +1370,8 @@
+ }
+       ]])],
+       [ AC_MSG_RESULT(yes) ],
+-      [ alpine_SSLTYPE="none" ])
++      [ alpine_SSLTYPE="none" ],
++      [ AC_MSG_WARN([cross compiling: not checking])])
+     if test "x$alpine_SSLTYPE" = "xnone" ; then
+       AC_MSG_ERROR(Install openssl version >= 1.0.1c)
diff --git a/mail/bogofilter/Makefile b/mail/bogofilter/Makefile
new file mode 100644 (file)
index 0000000..de3646b
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bogofilter
+PKG_VERSION:=1.2.4
+PKG_RELEASE:=3
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/bogofilter
+PKG_MD5SUM:=d0a5eebb3274b23ceabe766a6443a1c5
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bogofilter
+  SECTION:=mail
+  CATEGORY:=Mail
+  DEPENDS:=+libdb47
+  TITLE:=bogofilter
+  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+  URL:=http://bogofilter.sourceforge.net/
+endef
+
+define Package/bogofilter/description
+       Bogofilter is a fast Bayesian spam filter
+endef
+
+CONFIGURE_ARGS += --disable-unicode
+
+define Package/bogofilter/install
+       $(INSTALL_DIR)  $(1)/etc/ \
+                        $(1)/usr/bin \
+                        $(1)/usr/sbin
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/bogofilter.cf.example $(1)/etc/bogofilter.cf
+       $(INSTALL_BIN) ./files/postfix-bogofilter $(1)/usr/sbin/postfix-bogofilter
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bf_compact $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bf_copy $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bf_tar $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bogofilter $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bogolexer $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bogotune $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/bogoutil $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,bogofilter))
diff --git a/mail/bogofilter/files/postfix-bogofilter b/mail/bogofilter/files/postfix-bogofilter
new file mode 100755 (executable)
index 0000000..952d8cd
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+FILTER=/usr/bin/bogofilter
+FILTER_DIR=/mnt/sda1/var/spool/bogofilter
+# WARNING! The -i is crucial, else you may see
+# messages truncated at the first period that is alone on a line
+# (which can happen with several kinds of messages, particularly
+# quoted-printable)
+# -G is ignored before Postfix 2.3 and tells it that the message
+# does not originate on the local system (Gateway submission),
+# so Postfix avoids some of the local expansions that can leave
+# misleading traces in headers, such as local address
+# canonicalizations.
+POSTFIX="/usr/sbin/sendmail -G -i"
+export BOGOFILTER_DIR=/etc/bogofilter
+
+# Exit codes from <sysexits.h>
+EX_TEMPFAIL=75
+EX_UNAVAILABLE=69
+
+cd $FILTER_DIR || \
+    { echo $FILTER_DIR does not exist; exit $EX_TEMPFAIL; }
+
+# Clean up when done or when aborting.
+trap "rm -f msg.$$ ; exit $EX_TEMPFAIL" 0 1 2 3 15
+
+# bogofilter -e returns: 0 for OK, nonzero for error
+rm -f msg.$$ || exit $EX_TEMPFAIL
+$FILTER -p -e > msg.$$ || exit $EX_TEMPFAIL
+
+exec <msg.$$ || exit $EX_TEMPFAIL
+rm -f msg.$$ # safe, we hold the file descriptor
+exec $POSTFIX "$@"
+exit $EX_TEMPFAIL
index da1f1d41f768675c2b9ac9eddaa147e23fcefd4b..1032d97718d396c33130a34d0c0fb9bd71cd0697 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=dovecot
-PKG_VERSION:=2.2.13
+PKG_VERSION:=2.2.15
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.dovecot.org/releases/2.2
-PKG_MD5SUM:=a3eb1c0b1822c4f2b0fe9247776baa71
+PKG_MD5SUM:=c6c176943bd832c780fbb5d2f8850952
 PKG_LICENSE:=LGPL-2.1 MIT BSD-3-Clause Unique
 PKG_LICENSE_FILES:=COPYING COPYING.LGPL COPYING.MIT
 
@@ -31,6 +31,7 @@ define Package/dovecot
   TITLE:=An IMAP and POP3 daemon
   MAINTAINER:=Peter Wagner <tripolar@gmx.at>
   URL:=http://www.dovecot.org/
+  USERID:=dovecot=59:dovecot=59
 endef
 
 define Package/dovecot/description
@@ -42,7 +43,7 @@ define Package/dovecot/config
                 depends on PACKAGE_dovecot
                 config DOVECOT_LDAP
                         bool "LDAP support"
-                        default y
+                        default n
                         help
                           Implements LDAP support in dovecot.
         endmenu
index 7739cd15a1fec699d122899ce62db17659ab46e5..1f831842a3aec98c6804fe08eb8af5dc1e09c687 100644 (file)
@@ -7,8 +7,6 @@ STOP=75
 USE_PROCD=1
 
 start_service() {
-       user_exists dovecot 59 || user_add dovecot 59
-       group_exists dovecot 59 || group_add dovecot 59
        mkdir -p -m 0755 /var/lib/dovecot
        mkdir -p -m 0755 /var/run/dovecot
        chmod 0750 /var/lib/dovecot
index 69328cb7dc79ae1cab0181bf375ef31cfc3df47f..70642d648f067237713566cf27f5dce5ec774a54 100644 (file)
@@ -12,7 +12,7 @@
        int main()
        {
        return epoll_create(5) < 1;
-@@ -675,7 +675,7 @@ fi
+@@ -639,7 +639,7 @@ fi
  dnl * Old glibcs have broken posix_fallocate(). Make sure not to use it.
  dnl * It may also be broken in AIX.
  AC_CACHE_CHECK([whether posix_fallocate() works],i_cv_posix_fallocate_works,[
@@ -21,7 +21,7 @@
      #define _XOPEN_SOURCE 600
      #include <stdio.h>
      #include <stdlib.h>
-@@ -684,6 +684,7 @@ AC_CACHE_CHECK([whether posix_fallocate(
+@@ -648,6 +648,7 @@ AC_CACHE_CHECK([whether posix_fallocate(
      #if defined(__GLIBC__) && (__GLIBC__ < 2 || __GLIBC_MINOR__ < 7)
        possibly broken posix_fallocate
      #endif
diff --git a/mail/fdm/Config.in b/mail/fdm/Config.in
new file mode 100644 (file)
index 0000000..084695b
--- /dev/null
@@ -0,0 +1,10 @@
+menu "Configuration"
+       depends on PACKAGE_fdm
+
+config FDM_WITH_PCRE
+       bool
+       default y
+       select libpcre
+       prompt "Enable PCRE support (elsewhere POSIX regex)"
+
+endmenu
diff --git a/mail/fdm/Makefile b/mail/fdm/Makefile
new file mode 100644 (file)
index 0000000..49c02f1
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fdm
+PKG_VERSION:=1.7
+PKG_RELEASE:=1
+PKG_LICENSE:=BSD-2-Clause
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/fdm
+PKG_MD5SUM:=aea0421571e8f3ec8f747a5d72c84348
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fdm
+  SECTION:=mail
+  CATEGORY:=Mail
+  TITLE:=fetch mail and deliver
+  URL:=http://fdm.sourceforge.net/
+  MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
+  MENU:=1
+  DEPENDS:=+tdb +zlib +libopenssl +FDM_WITH_PCRE:libpcre
+  USERID:=_fdm=99:_fdm=99
+endef
+
+define Package/fdm/description
+  fdm is a simple, lightweight replacement for mail fetch, filter
+  and delivery programs such as fetchmail and procmail. It can
+  fetch using POP3 or IMAP (with SSL) or from stdin, and deliver
+  to a pipe, file, maildir, mbox or SMTP server, based on $(if $(CONFIG_FDM_WITH_PCRE),PCRE,POSIX regexp)
+endef
+
+MAKE_FLAGS += \
+       PREFIX="/usr"\
+       $(if $(CONFIG_FDM_WITH_PCRE),PCRE=1)
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       $(CP) ./src/compat/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/fdm/config
+       source "$(SOURCE)/Config.in"
+endef
+
+define Package/fdm/conffiles
+/etc/fdm.conf
+endef
+
+define Package/fdm/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) ./files/etc/* $(1)/etc/
+       $(INSTALL_DIR) $(1)/opt/fdm
+       chmod a+rwx $(1)/opt/fdm
+endef
+
+define Package/fdm/postinst
+#!/bin/sh
+if [ -z "$${IPKG_INSTROOT}" ]; then
+       echo "Creating cron job template for user _fdm..."
+       (crontab -l -u _fdm 2>/dev/null; echo "# */13 * * * * fdm -q fetch") | crontab -u _fdm -
+       echo "Please, edit file /etc/fdm.conf and enable cron job!"
+fi
+exit 0
+endef
+
+define Package/fdm/prerm
+#!/bin/sh
+if [ -z "$${IPKG_INSTROOT}" ]; then
+       echo "Don't forget disable cron job!"
+       echo "# crontab -r -u _fdm"
+fi
+exit 0
+endef
+
+$(eval $(call BuildPackage,fdm))
diff --git a/mail/fdm/files/etc/fdm.conf b/mail/fdm/files/etc/fdm.conf
new file mode 100644 (file)
index 0000000..56c9db4
--- /dev/null
@@ -0,0 +1,36 @@
+# /etc/fdm.conf example file
+# 1. Edit this file
+# 2. Test: fdm -vv fetch
+# 3. Enable cron job: crontab -e -u _fdm
+
+set maximum-size      3M
+set delete-oversized
+set queue-high        1
+set queue-low         0
+set purge-after       5
+set unmatched-mail    keep
+
+action "drop" drop
+action "keep" keep
+
+action "wakeup" exec "wol -h 192.168.0.255 -p 9 00:11:22:33:44:55"
+action "my-test-action" exec "echo \"OK\" > /tmp/fdm.ok"
+
+# This action extract *.torrent files from incoming email and put it
+# to watch-dir your torrect client application
+
+action "torrent-add" pipe "munpack -f -q -C /your-path/watch-dir/ ; for i in /your-path/watch-dir/*.torrent ; do chmod a+r \$i ; done"
+
+account "xbmc" disabled
+        pop3s
+        server   "pop.yandex.ru"
+        port     995
+        user     "username-enter-here"
+        pass     "password-enter-here"
+        new-only
+        cache    "/opt/fdm/cache"
+
+match "^Subject:[ \t]+openwrt:[ \t]*wakeup[ \t]*$" in headers actions { "wakeup" "drop" }
+match "^Subject:[ \t]+openwrt:[ \t]*torrent[ \t]+add[ \t]*\$" in headers actions { "torrent-add" "drop" }
+match "^Subject:[ \t]+openwrt:[ \t]*test[ \t]*$" in headers actions { "my-test-action" "drop" }
+match all action "keep"
diff --git a/mail/fdm/patches/001-base64-fix.patch b/mail/fdm/patches/001-base64-fix.patch
new file mode 100644 (file)
index 0000000..ad9239b
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/fdm.h    2011-10-10 17:36:29.000000000 +0400
++++ b/fdm.h    2014-11-13 12:56:59.217083683 +0300
+@@ -719,6 +719,11 @@
+ size_t                 strlcat(char *, const char *, size_t);
+ #endif
++int local_b64_ntop(uint8_t const *src, size_t srclength, char *target,
++    size_t targsize);
++
++int local_b64_pton(char const *src, uint8_t *target, size_t targsize);
++
+ /* shm.c */
+ char                  *shm_path(struct shm *);
+ void          *shm_create(struct shm *, size_t);
diff --git a/mail/fdm/patches/002-base64-fix.patch b/mail/fdm/patches/002-base64-fix.patch
new file mode 100644 (file)
index 0000000..7f798a6
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/imap-common.c    2011-12-20 00:19:03.000000000 +0400
++++ b/imap-common.c    2014-11-13 12:56:06.930418446 +0300
+@@ -206,7 +206,7 @@
+       size = (strlen(in) * 2) + 1;
+       out = xcalloc(1, size);
+-      if (b64_ntop(in, strlen(in), out, size) < 0) {
++      if (local_b64_ntop(in, strlen(in), out, size) < 0) {
+               xfree(out);
+               return (NULL);
+       }
+@@ -222,7 +222,7 @@
+       size = (strlen(in) * 4) + 1;
+       out = xcalloc(1, size);
+-      if (b64_pton(in, out, size) < 0) {
++      if (local_b64_pton(in, out, size) < 0) {
+               xfree(out);
+               return (NULL);
+       }
diff --git a/mail/fdm/src/compat/b64_ntop.c b/mail/fdm/src/compat/b64_ntop.c
new file mode 100644 (file)
index 0000000..0d222cf
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+//#include <config.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fdm.h"
+
+#define Assert(Cond) if (!(Cond)) abort()
+
+static const char Base64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+   following cases can arise:
+
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+          output will be an integral multiple of 4 characters
+          with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+          characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+          characters followed by one "=" padding character.
+   */
+
+int
+local_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
+       size_t datalength = 0;
+       uint8_t input[3];
+       uint8_t output[4];
+       size_t i;
+
+       while (2 < srclength) {
+               input[0] = *src++;
+               input[1] = *src++;
+               input[2] = *src++;
+               srclength -= 3;
+
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               output[3] = input[2] & 0x3f;
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+               Assert(output[3] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               target[datalength++] = Base64[output[2]];
+               target[datalength++] = Base64[output[3]];
+       }
+
+       /* Now we worry about padding. */
+       if (0 != srclength) {
+               /* Get what's left. */
+               input[0] = input[1] = input[2] = '\0';
+               for (i = 0; i < srclength; i++)
+                       input[i] = *src++;
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               if (srclength == 1)
+                       target[datalength++] = Pad64;
+               else
+                       target[datalength++] = Base64[output[2]];
+               target[datalength++] = Pad64;
+       }
+       if (datalength >= targsize)
+               return (-1);
+       target[datalength] = '\0'; /* Returned value doesn't count \0. */
+       return (datalength);
+}
diff --git a/mail/fdm/src/compat/b64_pton.c b/mail/fdm/src/compat/b64_pton.c
new file mode 100644 (file)
index 0000000..0e9363a
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+//#include <config.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fdm.h"
+
+#define Assert(Cond) if (!(Cond)) abort()
+
+static const char Base64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+   following cases can arise:
+
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+          output will be an integral multiple of 4 characters
+          with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+          characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+          characters followed by one "=" padding character.
+   */
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+static int b64rmap_initialized = 0;
+static uint8_t b64rmap[256];
+
+static const uint8_t b64rmap_special = 0xf0;
+static const uint8_t b64rmap_end = 0xfd;
+static const uint8_t b64rmap_space = 0xfe;
+static const uint8_t b64rmap_invalid = 0xff;
+
+/**
+ * Initializing the reverse map is not thread safe.
+ * Which is fine for NSD. For now...
+ **/
+static void
+b64_initialize_rmap ()
+{
+       int i;
+       char ch;
+
+       /* Null: end of string, stop parsing */
+       b64rmap[0] = b64rmap_end;
+
+       for (i = 1; i < 256; ++i) {
+               ch = (char)i;
+               /* Whitespaces */
+               if (isspace(ch))
+                       b64rmap[i] = b64rmap_space;
+               /* Padding: stop parsing */
+               else if (ch == Pad64)
+                       b64rmap[i] = b64rmap_end;
+               /* Non-base64 char */
+               else
+                       b64rmap[i] = b64rmap_invalid;
+       }
+
+       /* Fill reverse mapping for base64 chars */
+       for (i = 0; Base64[i] != '\0'; ++i)
+               b64rmap[(uint8_t)Base64[i]] = i;
+
+       b64rmap_initialized = 1;
+}
+
+static int
+b64_pton_do(char const *src, uint8_t *target, size_t targsize)
+{
+       int tarindex, state, ch;
+       uint8_t ofs;
+
+       state = 0;
+       tarindex = 0;
+
+       while (1)
+       {
+               ch = *src++;
+               ofs = b64rmap[ch];
+
+               if (ofs >= b64rmap_special) {
+                       /* Ignore whitespaces */
+                       if (ofs == b64rmap_space)
+                               continue;
+                       /* End of base64 characters */
+                       if (ofs == b64rmap_end)
+                               break;
+                       /* A non-base64 character. */
+                       return (-1);
+               }
+
+               switch (state) {
+               case 0:
+                       if ((size_t)tarindex >= targsize)
+                               return (-1);
+                       target[tarindex] = ofs << 2;
+                       state = 1;
+                       break;
+               case 1:
+                       if ((size_t)tarindex + 1 >= targsize)
+                               return (-1);
+                       target[tarindex]   |=  ofs >> 4;
+                       target[tarindex+1]  = (ofs & 0x0f)
+                                               << 4 ;
+                       tarindex++;
+                       state = 2;
+                       break;
+               case 2:
+                       if ((size_t)tarindex + 1 >= targsize)
+                               return (-1);
+                       target[tarindex]   |=  ofs >> 2;
+                       target[tarindex+1]  = (ofs & 0x03)
+                                               << 6;
+                       tarindex++;
+                       state = 3;
+                       break;
+               case 3:
+                       if ((size_t)tarindex >= targsize)
+                               return (-1);
+                       target[tarindex] |= ofs;
+                       tarindex++;
+                       state = 0;
+                       break;
+               default:
+                       abort();
+               }
+       }
+
+       /*
+        * We are done decoding Base-64 chars.  Let's see if we ended
+        * on a byte boundary, and/or with erroneous trailing characters.
+        */
+
+       if (ch == Pad64) {              /* We got a pad char. */
+               ch = *src++;            /* Skip it, get next. */
+               switch (state) {
+               case 0:         /* Invalid = in first position */
+               case 1:         /* Invalid = in second position */
+                       return (-1);
+
+               case 2:         /* Valid, means one byte of info */
+                       /* Skip any number of spaces. */
+                       for ((void)NULL; ch != '\0'; ch = *src++)
+                               if (b64rmap[ch] != b64rmap_space)
+                                       break;
+                       /* Make sure there is another trailing = sign. */
+                       if (ch != Pad64)
+                               return (-1);
+                       ch = *src++;            /* Skip the = */
+                       /* Fall through to "single trailing =" case. */
+                       /* FALLTHROUGH */
+
+               case 3:         /* Valid, means two bytes of info */
+                       /*
+                        * We know this char is an =.  Is there anything but
+                        * whitespace after it?
+                        */
+                       for ((void)NULL; ch != '\0'; ch = *src++)
+                               if (b64rmap[ch] != b64rmap_space)
+                                       return (-1);
+
+                       /*
+                        * Now make sure for cases 2 and 3 that the "extra"
+                        * bits that slopped past the last full byte were
+                        * zeros.  If we don't check them, they become a
+                        * subliminal channel.
+                        */
+                       if (target[tarindex] != 0)
+                               return (-1);
+               }
+       } else {
+               /*
+                * We ended by seeing the end of the string.  Make sure we
+                * have no partial bytes lying around.
+                */
+               if (state != 0)
+                       return (-1);
+       }
+
+       return (tarindex);
+}
+
+
+static int
+b64_pton_len(char const *src)
+{
+       int tarindex, state, ch;
+       uint8_t ofs;
+
+       state = 0;
+       tarindex = 0;
+
+       while (1)
+       {
+               ch = *src++;
+               ofs = b64rmap[ch];
+
+               if (ofs >= b64rmap_special) {
+                       /* Ignore whitespaces */
+                       if (ofs == b64rmap_space)
+                               continue;
+                       /* End of base64 characters */
+                       if (ofs == b64rmap_end)
+                               break;
+                       /* A non-base64 character. */
+                       return (-1);
+               }
+
+               switch (state) {
+               case 0:
+                       state = 1;
+                       break;
+               case 1:
+                       tarindex++;
+                       state = 2;
+                       break;
+               case 2:
+                       tarindex++;
+                       state = 3;
+                       break;
+               case 3:
+                       tarindex++;
+                       state = 0;
+                       break;
+               default:
+                       abort();
+               }
+       }
+
+       /*
+        * We are done decoding Base-64 chars.  Let's see if we ended
+        * on a byte boundary, and/or with erroneous trailing characters.
+        */
+
+       if (ch == Pad64) {              /* We got a pad char. */
+               ch = *src++;            /* Skip it, get next. */
+               switch (state) {
+               case 0:         /* Invalid = in first position */
+               case 1:         /* Invalid = in second position */
+                       return (-1);
+
+               case 2:         /* Valid, means one byte of info */
+                       /* Skip any number of spaces. */
+                       for ((void)NULL; ch != '\0'; ch = *src++)
+                               if (b64rmap[ch] != b64rmap_space)
+                                       break;
+                       /* Make sure there is another trailing = sign. */
+                       if (ch != Pad64)
+                               return (-1);
+                       ch = *src++;            /* Skip the = */
+                       /* Fall through to "single trailing =" case. */
+                       /* FALLTHROUGH */
+
+               case 3:         /* Valid, means two bytes of info */
+                       /*
+                        * We know this char is an =.  Is there anything but
+                        * whitespace after it?
+                        */
+                       for ((void)NULL; ch != '\0'; ch = *src++)
+                               if (b64rmap[ch] != b64rmap_space)
+                                       return (-1);
+
+               }
+       } else {
+               /*
+                * We ended by seeing the end of the string.  Make sure we
+                * have no partial bytes lying around.
+                */
+               if (state != 0)
+                       return (-1);
+       }
+
+       return (tarindex);
+}
+
+
+int
+local_b64_pton(char const *src, uint8_t *target, size_t targsize)
+{
+       if (!b64rmap_initialized)
+               b64_initialize_rmap ();
+
+       if (target)
+               return b64_pton_do (src, target, targsize);
+       else
+               return b64_pton_len (src);
+}
diff --git a/mail/mailman/Makefile b/mail/mailman/Makefile
new file mode 100644 (file)
index 0000000..9e848a8
--- /dev/null
@@ -0,0 +1,126 @@
+# 
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mailman
+PKG_RELEASE:=1
+PKG_SOURCE_URL:=ftp://ftp.gnu.org/gnu/mailman/ http://ftp.gnu.org/gnu/mailman/
+PKG_VERSION:=2.1.18-1
+PKG_MD5SUM:=dc861ed9698a98499a951eaef7d4db9f
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
+PKG_MAINTAINER:=Denis Shulyaka <Shulyaka@gmail.com>
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=gnu-COPYING-GPL
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mailman
+  SECTION:=mail
+  CATEGORY:=Mail
+  TITLE:=The GNU Mailing List Manager
+  URL:=http://www.gnu.org/software/mailman/
+  DEPENDS:=+postfix +python-mini +uhttpd +python-dns #+python-dev
+endef
+
+define Package/mailman/description
+ Mailman is free software for managing electronic mail discussion and e-newsletter lists.
+endef
+
+prefix=/usr/local/mailman
+
+define Package/mailman/conffiles
+$(prefix)/Mailman/mm_cfg.py
+endef
+
+CONFIGURE_ARGS += \
+       --prefix="$(prefix)" \
+       --exec-prefix="$(prefix)" \
+       --with-username="root" \
+       --with-groupname="root" \
+       --with-mail-gid="nogroup" \
+       --with-cgi-gid="root" \
+       --without-permcheck \
+
+define Build/Compile
+endef
+
+define Package/mailman/install
+       $(INSTALL_DIR) $(1)$(prefix)
+       cd $(PKG_BUILD_DIR); $(MAKE) DESTDIR=$(1) install
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/mailman.init $(1)/etc/init.d/mailman
+       $(INSTALL_DIR) $(1)/usr/www
+       ln -s $(prefix)/cgi-bin/ $(1)/usr/www/mailman
+       ln -s $(prefix)/archives/public/ $(1)/usr/www/pipermail
+       ln -s $(prefix)/icons $(1)/usr/www/icons
+endef
+
+define Package/mailman/postinst
+#!/bin/sh
+# check if we are on real system
+if [ -z "$${IPKG_INSTROOT}" ]; then
+
+ if [ `postconf alias_maps | grep -ci mailman` -eq 0 ]
+ then
+  postconf -e "`postconf alias_maps`, cdb:$(prefix)/data/aliases"
+ fi
+ cd $(prefix)
+ hostname=`cat /proc/sys/kernel/hostname`
+ if [ ! -f data/aliases ]
+ then
+  ./bin/genaliases
+ fi
+ newaliases
+ if [ `grep -c DEFAULT_URL_HOST Mailman/mm_cfg.py` -eq 0 ]
+ then
+  echo "DEFAULT_EMAIL_HOST = '$$hostname'" >> Mailman/mm_cfg.py
+  echo "DEFAULT_URL_HOST = '$$hostname'" >> Mailman/mm_cfg.py
+  echo "add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)" >> Mailman/mm_cfg.py
+  echo "QRUNNERS.remove(('NewsRunner',1))" >> Mailman/mm_cfg.py
+ fi
+ if [ `./bin/list_lists | grep -ci mailman` -eq 0 ]
+ then
+  ./bin/newlist --urlhost=$$hostname --emailhost=$$hostname --quiet mailman root@$$hostname mailman
+  ./bin/config_list -i data/sitelist.cfg mailman
+  echo "NOTE: A default site-wide mailing list Mailman with password 'mailman' has been created. Please review it and change the password."
+  ./bin/mmsitepass mailman
+  echo "NOTE: The default site password 'mailman' has been created."
+ fi
+ # /etc/init.d/mailman enable
+ if [ `ps | grep "mailman/bin/qrunner" | grep -cv grep` -gt 0 ]
+ then
+  $(prefix)/bin/mailmanctl -q restart
+ fi
+ if [ `grep -c mailman /etc/config/uhttpd` -eq 0 ]
+ then #we assume that the server is not configured yet, thus print out some help for the first time:
+  echo "NOTE: Please set the site password using $(prefix)/bin/mmsitepass <your-site-password>"
+  echo "Please add uhttpd config section to your /etc/config/uhttpd like this:"
+  echo "config uhttpd mailman"
+  echo "       list listen_http        0.0.0.0:80"
+  echo "       option home             /usr/www"
+  echo "       option cgi_prefix       /mailman"
+  echo "       no_symlinks             0"
+  echo "Don't forget to setup firewall for accessing this website!"
+  echo "To add a mailing list go to http://$$hostname/mailman/create."
+ fi
+fi
+endef
+
+define Package/mailman/prerm
+#!/bin/sh
+# check if we are on real system
+if [ -z "$${IPKG_INSTROOT}" ]; then
+
+ if [ `ps | grep "mailman/bin/qrunner" | grep -cv grep` -gt 0 ]
+ then
+  $(prefix)/bin/mailmanctl stop
+ fi
+fi
+endef
+
+$(eval $(call BuildPackage,mailman))
diff --git a/mail/mailman/files/mailman.init b/mail/mailman/files/mailman.init
new file mode 100644 (file)
index 0000000..f68a456
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=50
+STOP=50
+
+PYTHON=/usr/bin/python
+MAILMANHOME=/usr/local/mailman
+MAILMANCTL=$MAILMANHOME/bin/mailmanctl
+
+start() {
+       #rm -f $MAILMANHOME/locks/*
+       $PYTHON $MAILMANCTL -s -q start
+}
+
+stop() {
+       $PYTHON $MAILMANCTL -q stop
+}
+
+restart() {
+       $PYTHON $MAILMANCTL -q restart
+}
diff --git a/mail/mailman/patches/100-postfix.patch b/mail/mailman/patches/100-postfix.patch
new file mode 100644 (file)
index 0000000..857b99b
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rupN mailman-2.1.14-1/Mailman/Defaults.py.in mailman-2.1.14-1_patched/Mailman/Defaults.py.in
+--- mailman-2.1.14-1/Mailman/Defaults.py.in    2011-03-01 23:35:57.000000000 +0300
++++ mailman-2.1.14-1_patched/Mailman/Defaults.py.in    2011-03-09 12:26:10.000000000 +0300
+@@ -439,7 +439,7 @@ DELIVERY_MODULE = 'SMTPDirect'
+ # standard out (or send an email to the site list owner) for manual twiddling
+ # of an /etc/aliases style file.  Use 'Postfix' if you are using the Postfix
+ # MTA -- but then also see POSTFIX_STYLE_VIRTUAL_DOMAINS.
+-MTA = 'Manual'
++MTA = 'Postfix'
+ # If you set MTA='Postfix', then you also want to set the following variable,
+ # depending on whether you're using virtual domains in Postfix, and which
diff --git a/mail/mailman/patches/200-nohostdnspython.patch b/mail/mailman/patches/200-nohostdnspython.patch
new file mode 100644 (file)
index 0000000..e321106
--- /dev/null
@@ -0,0 +1,68 @@
+diff -Naur mailman-2.1.18-1/configure mailman-2.1.18-1_patched/configure
+--- mailman-2.1.18-1/configure 2014-10-26 12:00:38.090360119 +0300
++++ mailman-2.1.18-1_patched/configure 2014-10-26 12:00:21.323016430 +0300
+@@ -2236,35 +2236,35 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $version" >&5
+ $as_echo "$version" >&6; }
+-# See if dnspython is installed.
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dnspython" >&5
+-$as_echo_n "checking dnspython... " >&6; }
+-
+-cat > conftest.py <<EOF
+-try:
+-    import dns.resolver
+-    res = 'ok'
+-except ImportError:
+-    res = 'no'
+-fp = open("conftest.out", "w")
+-fp.write("%s\n" % res)
+-fp.close()
+-EOF
+-
+-$PYTHON conftest.py
+-havednspython=`cat conftest.out`
+-rm -f conftest.out conftest.py
+-if test "$havednspython" = "no"
+-then
+-    as_fn_error $? "
+-
+-***** dnspython not found. It is required for the new
+-***** dmarc_moderation_action featurer. Get it from
+-***** <http://www.dnspython.org/> or
+-***** <https://pypi.python.org/pypi/dnspython/>" "$LINENO" 5
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $havednspython" >&5
+-$as_echo "$havednspython" >&6; }
++## See if dnspython is installed.
++#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dnspython" >&5
++#$as_echo_n "checking dnspython... " >&6; }
++#
++#cat > conftest.py <<EOF
++#try:
++#    import dns.resolver
++#    res = 'ok'
++#except ImportError:
++#    res = 'no'
++#fp = open("conftest.out", "w")
++#fp.write("%s\n" % res)
++#fp.close()
++#EOF
++#
++#$PYTHON conftest.py
++#havednspython=`cat conftest.out`
++#rm -f conftest.out conftest.py
++#if test "$havednspython" = "no"
++#then
++#    as_fn_error $? "
++#
++#***** dnspython not found. It is required for the new
++#***** dmarc_moderation_action featurer. Get it from
++#***** <http://www.dnspython.org/> or
++#***** <https://pypi.python.org/pypi/dnspython/>" "$LINENO" 5
++#fi
++#{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $havednspython" >&5
++#$as_echo "$havednspython" >&6; }
+ # Check the email package version.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking Python's email package" >&5
diff --git a/mail/mailman/patches/300-targetpython.patch b/mail/mailman/patches/300-targetpython.patch
new file mode 100644 (file)
index 0000000..1dd2859
--- /dev/null
@@ -0,0 +1,12 @@
+diff -Naur mailman-2.1.18-1/configure mailman-2.1.18-1_patched/configure
+--- mailman-2.1.18-1/configure 2014-05-06 20:43:56.000000000 +0400
++++ mailman-2.1.18-1_patched/configure 2014-11-04 15:02:32.892666331 +0300
+@@ -3927,6 +3927,8 @@
+ $as_echo "$URLHOST" >&6; }
+ rm -f conftest.out conftest.py
++PYTHON=/usr/bin/python
++
+ # Checks for libraries.
+ for ac_func in strerror setregid syslog
diff --git a/mail/mailman/patches/400-modules.patch b/mail/mailman/patches/400-modules.patch
new file mode 100644 (file)
index 0000000..9fa72a2
--- /dev/null
@@ -0,0 +1,35 @@
+diff -Naur mailman-2.1.18-1/Mailman/MailList.py mailman-2.1.18-1_patched/Mailman/MailList.py
+--- mailman-2.1.18-1/Mailman/MailList.py       2014-05-06 20:43:56.000000000 +0400
++++ mailman-2.1.18-1_patched/Mailman/MailList.py       2014-11-04 15:57:06.832636147 +0300
+@@ -30,7 +30,7 @@
+ import shutil
+ import socket
+ import urllib
+-import cPickle
++import pickle as cPickle
+ from cStringIO import StringIO
+ from UserDict import UserDict
+diff -Naur mailman-2.1.18-1/misc/paths.py.in mailman-2.1.18-1_patched/misc/paths.py.in
+--- mailman-2.1.18-1/misc/paths.py.in  2014-05-06 20:43:56.000000000 +0400
++++ mailman-2.1.18-1_patched/misc/paths.py.in  2014-11-04 15:55:49.594941540 +0300
+@@ -66,14 +66,14 @@
+ # In a normal interactive Python environment, the japanese.pth and korean.pth
+ # files would be imported automatically.  But because we inhibit the importing
+ # of the site module, we need to be explicit about importing these codecs.
+-if not jaok:
+-    import japanese
++#if not jaok:
++#    import japanese
+ # As of KoreanCodecs 2.0.5, you had to do the second import to get the Korean
+ # codecs installed, however leave the first import in there in case an upgrade
+ # changes this.
+-if not kook:
+-    import korean
+-    import korean.aliases
++#if not kook:
++#    import korean
++#    import korean.aliases
+ # Arabic and Hebrew (RFC-1556) encoding aliases. (temporary solution)
+ import encodings.aliases
+ encodings.aliases.aliases.update({
index 6274c9a4ef4969cfcb93a7b8fbaf01a36a5d3de6..29010e0828c50d4e3d522a753087fb37e4a5bf9b 100644 (file)
@@ -18,7 +18,7 @@ PKG_MD5SUM:=60103c411a8627e893d35e7836f904e8
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=BSD-3-Clause
-PKG_LICENSE_FILE:=COPYRIGHT
+PKG_LICENSE_FILES:=COPYRIGHT
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 
diff --git a/mail/msmtp/Makefile b/mail/msmtp/Makefile
new file mode 100644 (file)
index 0000000..cf137d1
--- /dev/null
@@ -0,0 +1,136 @@
+#
+# Copyright (C) 2009 David Cooper <dave@kupesoft.com>
+# Copyright (C) 2009-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=msmtp
+PKG_VERSION:=1.6.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/msmtp
+PKG_MD5SUM:=6ebba4809bbc665b8a665a018d1a5ee1
+
+PKG_LICENSE:=GPL-3.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/msmtp/Default
+  SECTION:=mail
+  CATEGORY:=Mail
+  TITLE:=Simple sendmail SMTP forwarding
+  URL:=http://msmtp.sourceforge.net/
+endef
+
+define Package/msmtp/Default/description
+ msmtp is an SMTP client. In the default mode, it transmits a mail to
+ an SMTP server (for example at a free mail provider) which does the
+ delivery. To use this program with your mail user agent (MUA), create
+ a configuration file with your mail account(s) and tell your MUA to
+ call msmtp instead of /usr/sbin/sendmail.
+endef
+
+define Package/msmtp
+$(call Package/msmtp/Default)
+  DEPENDS+= +libopenssl
+  TITLE+= (with SSL support)
+  VARIANT:=ssl
+endef
+
+define Package/msmtp/conffiles
+/etc/msmtprc
+endef
+
+define Package/msmtp/description
+$(call Package/msmtp/Default/description)
+ This package is built with SSL support.
+endef
+
+define Package/msmtp-nossl
+$(call Package/msmtp/Default)
+  TITLE+= (without SSL support)
+  VARIANT:=nossl
+endef
+
+define Package/msmtp-nossl/description
+$(call Package/msmtp/Default/description)
+ This package is built without SSL support.
+endef
+
+define Package/msmtp-queue
+$(call Package/msmtp/Default)
+  DEPENDS+= +bash
+  TITLE+= (queue scripts)
+endef
+
+define Package/msmtp-queue/description
+$(call Package/msmtp/Default/description)
+ This package contains the msmtp queue scripts.
+endef
+
+CONFIGURE_ARGS += \
+       --disable-rpath \
+       --without-libintl-prefix \
+       --without-libgsasl \
+       --without-libidn \
+       --without-gnome-keyring \
+       --without-macosx-keyring \
+
+MAKE_FLAGS :=
+
+ifeq ($(BUILD_VARIANT),ssl)
+       CONFIGURE_ARGS += \
+               --with-ssl=openssl
+endif
+
+ifeq ($(BUILD_VARIANT),nossl)
+       CONFIGURE_ARGS += \
+               --with-ssl=no
+endif
+
+define Package/msmtp/install
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/msmtprc-system.example \
+               $(1)/etc/msmtprc
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/msmtp $(1)/usr/bin/
+endef
+
+define Package/msmtp/postinst
+       [ -e $${IPKG_INSTROOT}/usr/sbin/sendmail ] || {
+               mkdir -p $${IPKG_INSTROOT}/usr/sbin
+               ln -sf ../bin/msmtp $${IPKG_INSTROOT}/usr/sbin/sendmail
+       }
+endef
+
+define Package/msmtp/prerm
+       [ "../bin/msmtp" = "$(readlink -qs $${IPKG_INSTROOT}/usr/sbin/sendmail)" ] && {
+               rm -f $${IPKG_INSTROOT}/usr/sbin/sendmail
+       }
+endef
+
+Package/msmtp-nossl/conffiles = $(Package/msmtp/conffiles)
+Package/msmtp-nossl/install = $(Package/msmtp/install)
+Package/msmtp-nossl/postinst = $(Package/msmtp/postinst)
+
+define Package/msmtp-queue/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/msmtpq/msmtp{q,-queue} $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/msmtpqueue/msmtp-{en,list,run}queue.sh $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,msmtp))
+$(eval $(call BuildPackage,msmtp-nossl))
+$(eval $(call BuildPackage,msmtp-queue))
diff --git a/mail/nail/Makefile b/mail/nail/Makefile
new file mode 100644 (file)
index 0000000..541d203
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nail
+PKG_VERSION:=12.5
+PKG_RELEASE:=1
+PKG_LICENSE:=BSD-2-Clause
+
+PKG_SOURCE:=heirloom-mailx_$(PKG_VERSION).orig.tar.gz
+PKG_SOURCE_URL:=http://ftp.de.debian.org/debian/pool/main/h/heirloom-mailx/
+PKG_MD5SUM:=29a6033ef1412824d02eb9d9213cb1f2
+PKG_BUILD_DIR:=$(BUILD_DIR)/heirloom-mailx-$(PKG_VERSION)
+
+PKG_INSTALL:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/nail
+  SECTION:=mail
+  CATEGORY:=Mail
+  TITLE:=Heirloom mailx (nail)
+  URL:=http://heirloom.sourceforge.net/mailx.html
+  MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
+  DEPENDS:=+libopenssl
+endef
+
+define Package/nail/description
+  Heirloom mailx (formerly known as "nail") is intended provide
+  the functionality of the POSIX mailx command with additional
+  support for MIME messages, IMAP (including caching), POP3,
+  SMTP, S/MIME, message threading/sorting, scoring, and filtering
+endef
+
+define Package/nail/conffiles
+/etc/nail.rc
+endef
+
+define Build/Install
+       $(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/bin
+       $(CP) $(PKG_BUILD_DIR)/mailx $(PKG_INSTALL_DIR)/usr/bin/
+       $(INSTALL_DIR) $(PKG_INSTALL_DIR)/etc
+       $(CP) $(PKG_BUILD_DIR)/nail.rc $(PKG_INSTALL_DIR)/etc/
+endef
+
+define Package/nail/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/etc/* $(1)/etc/
+endef
+
+$(eval $(call BuildPackage,nail))
+
diff --git a/mail/nail/patches/100-handle-openssl-without-sslv2.patch b/mail/nail/patches/100-handle-openssl-without-sslv2.patch
new file mode 100644 (file)
index 0000000..4352fe8
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/openssl.c
++++ b/openssl.c
+@@ -216,9 +216,12 @@ ssl_select_method(const char *uhp)
+       cp = ssl_method_string(uhp);
+       if (cp != NULL) {
++#ifndef OPENSSL_NO_SSL2
+               if (equal(cp, "ssl2"))
+                       method = SSLv2_client_method();
+-              else if (equal(cp, "ssl3"))
++              else
++#endif
++              if (equal(cp, "ssl3"))
+                       method = SSLv3_client_method();
+               else if (equal(cp, "tls1"))
+                       method = TLSv1_client_method();
diff --git a/mail/postfix/Makefile b/mail/postfix/Makefile
new file mode 100644 (file)
index 0000000..bb75cbb
--- /dev/null
@@ -0,0 +1,227 @@
+# 
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=postfix
+PKG_RELEASE:=2
+PKG_SOURCE_URL:=ftp://ftp.porcupine.org/mirrors/postfix-release/official/
+PKG_VERSION:=2.11.3
+PKG_MD5SUM:=c3f0f51d8865559b40e9350eb3816011
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MAINTAINER:=Denis Shulyaka <Shulyaka@gmail.com>
+PKG_LICENSE:=IPL-1.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_DEPENDS:=+POSTFIX_CDB:tinycdb
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/postfix
+  SECTION:=mail
+  CATEGORY:=Mail
+  TITLE:=Postfix Mail Transmit Agent
+  URL:=http://www.postfix.org/
+  DEPENDS:=+POSTFIX_TLS:libopenssl +POSTFIX_SASL:libsasl2 +POSTFIX_LDAP:libopenldap +POSTFIX_DB:libdb47 +libpcre
+endef
+
+define Package/postfix/description
+ Postfix is Wietse Venema's mailer that started life as an alternative to the widely-used Sendmail program. Postfix attempts to be fast, easy to administer, and secure, while at the same time being sendmail compatible enough to not upset existing users. Thus, the outside has a sendmail-ish flavor, but the inside is completely different.
+endef
+
+define Package/postfix/config
+       menu "Select postfix build options"
+               config POSTFIX_TLS
+                       bool "TLS support"
+                       default y
+                       help
+                         Implements TLS support in postfix (using OpenSSL).
+               config POSTFIX_SASL
+                       bool "SASL support"
+                       default y
+                       help
+                         Implements SASL support in postfix (using Cyrus SASL).
+               config POSTFIX_LDAP
+                       bool "LDAP support"
+                       default y
+                       help
+                         Implements LDAP support in postfix (using OpenLDAP).
+               config POSTFIX_DB
+                       bool "BerkeleyDB support"
+                       default n
+                       help
+                         Implements support for btree files using Berkeley DB. Note that hash files support is not compiled into Berkeley DB OpenWRT distribution
+               config POSTFIX_CDB
+                       bool "CDB support"
+                       default y
+                       help
+                         Implements support for cdb files using tinycdb
+       endmenu
+endef
+
+CCARGS=-DNO_EPOLL -DNO_SIGSETJMP -DNO_NIS
+AUXLIBS=-L$(STAGING_DIR)/usr/lib
+default_database_type=cdb
+
+ifdef CONFIG_POSTFIX_TLS
+  CCARGS+=-DUSE_TLS
+  AUXLIBS+=-lssl -lcrypto
+endif
+
+ifdef CONFIG_POSTFIX_SASL
+  CCARGS+=-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I$(STAGING_DIR)/usr/include/sasl
+  AUXLIBS+=-lsasl2
+endif
+
+ifdef CONFIG_POSTFIX_LDAP
+  CCARGS+=-DHAS_LDAP
+  AUXLIBS+=-lldap -llber
+endif
+
+ifdef CONFIG_POSTFIX_CDB
+  CCARGS+=-DHAS_CDB
+  AUXLIBS+=-lcdb
+endif
+
+ifdef CONFIG_POSTFIX_DB
+  AUXLIBS+=-ldb
+  CCARGS+=-DHAS_DB
+  ifndef CONFIG_POSTFIX_CDB
+    default_database_type=btree
+  endif
+else
+  CCARGS+=-DNO_DB
+endif
+
+CCARGS+=-DDEF_DB_TYPE=\"$(default_database_type)\"
+
+config_directory=/etc/postfix# also add this to postfix init file
+sample_directory=/etc/postfix
+command_directory=/usr/sbin
+daemon_directory=/usr/libexec/postfix
+data_directory=/usr/var/lib/postfix
+queue_directory=/usr/var/spool/postfix
+mail_spool_directory=/usr/var/mail
+html_directory=no
+manpage_directory=no
+readme_directory=no
+sendmail_path=/usr/sbin/sendmail
+newaliases_path=/usr/bin/newaliases
+mailq_path=/usr/bin/mailq
+
+ln_suffix=.postfix
+ln_old_suffix=.old
+
+define Package/postfix/conffiles
+$(config_directory)/main.cf
+$(config_directory)/master.cf
+$(config_directory)/aliases
+endef
+
+define Build/Configure
+       if [ "$(CONFIG_POSTFIX_DB)" = "" -a "$(CONFIG_POSTFIX_CDB)" = "" ]; then\
+         echo "Build error: You must select at least one of the DB types";\
+          exit 1;\
+       fi
+
+       cd $(PKG_BUILD_DIR); $(MAKE) makefiles CCARGS='$(CCARGS)' $(TARGET_CONFIGURE_OPTS) AUXLIBS="$(AUXLIBS)"
+endef
+
+define Build/Compile
+       # Currently postfix has a bug with Makefiles that CCARGS are not passed to the compiler, so we are copying them to CC
+       cd $(PKG_BUILD_DIR); $(MAKE) $(TARGET_CONFIGURE_OPTS) CC='$(TARGET_CC) $(CCARGS)'
+       cp ./files/main.cf.default $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "default_database_type = $(default_database_type)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "alias_database = $(default_database_type):$(config_directory)/aliases" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "alias_maps = $(default_database_type):$(config_directory)/aliases" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "sendmail_path = $(sendmail_path)$(ln_suffix)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "newaliases_path = $(newaliases_path)$(ln_suffix)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "mailq_path = $(mailq_path)$(ln_suffix)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "html_directory = $(html_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "manpage_directory = $(manpage_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "sample_directory = $(sample_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "readme_directory = $(readme_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "command_directory = $(command_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "daemon_directory = $(daemon_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "data_directory = $(data_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "queue_directory = $(queue_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "config_directory = $(config_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+       echo "mail_spool_directory = $(mail_spool_directory)" >> $(PKG_BUILD_DIR)/conf/main.cf.default
+endef
+
+define Package/postfix/install
+       cd $(PKG_BUILD_DIR); $(MAKE) install_root=$(1) command_directory=$(command_directory) daemon_directory=$(daemon_directory) data_directory=$(data_directory) html_directory=$(html_directory) mail_owner=postfix mailq_path=$(mailq_path)$(ln_suffix) manpage_directory=$(manpage_directory) newaliases_path=$(newaliases_path)$(ln_suffix) queue_directory=$(queue_directory) readme_directory=$(readme_directory) sendmail_path=$(sendmail_path)$(ln_suffix) setgid_group=postdrop sample_directory=$(sample_directory) config_directory=$(config_directory) non-interactive-package
+       $(INSTALL_DIR) $(1)$(mail_spool_directory)
+       $(INSTALL_DIR) $(1)/etc/init.d/
+       $(INSTALL_BIN) ./files/postfix.init $(1)/etc/init.d/postfix
+endef
+
+define Package/postfix/postinst
+#!/bin/sh
+
+ if [ -f "$${IPKG_INSTROOT}$(sendmail_path)" -a "$$(readlink "$${IPKG_INSTROOT}$(sendmail_path)")" != "$(sendmail_path)$(ln_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(sendmail_path)" "$${IPKG_INSTROOT}$(sendmail_path)$(ln_old_suffix)"
+  echo "Warning: $${IPKG_INSTROOT}$(sendmail_path) saved as $${IPKG_INSTROOT}$(sendmail_path)$(ln_old_suffix)"
+ fi
+ if [ ! -f "$${IPKG_INSTROOT}$(sendmail_path)" ]; then
+  ln -s "$${IPKG_INSTROOT}$(sendmail_path)$(ln_suffix)" "$(sendmail_path)"
+ fi
+
+ if [ -f "$${IPKG_INSTROOT}$(newaliases_path)" -a "$$(readlink "$${IPKG_INSTROOT}$(newaliases_path)")" != "$(newaliases_path)$(ln_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(newaliases_path)" "$${IPKG_INSTROOT}$(newaliases_path)$(ln_old_suffix)"
+  echo "Warning: $${IPKG_INSTROOT}$(newaliases_path) saved as $${IPKG_INSTROOT}$(newaliases_path)$(ln_old_suffix)"
+ fi
+ if [ ! -f "$${IPKG_INSTROOT}$(newaliases_path)" ]; then
+  ln -s "$${IPKG_INSTROOT}$(newaliases_path)$(ln_suffix)" "$(newaliases_path)"
+ fi
+
+ if [ -f "$${IPKG_INSTROOT}$(mailq_path)" -a "$$(readlink "$${IPKG_INSTROOT}$(mailq_path)")" != "$(mailq_path)$(ln_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(mailq_path)" "$${IPKG_INSTROOT}$(mailq_path)$(ln_old_suffix)"
+  echo "Warning: $${IPKG_INSTROOT}$(mailq_path) saved as $${IPKG_INSTROOT}$(mailq_path)$(ln_old_suffix)"
+ fi
+ if [ ! -f "$(mailq_path)" ]; then
+  ln -s "$${IPKG_INSTROOT}$(mailq_path)$(ln_suffix)" "$(mailq_path)"
+ fi
+
+ grep -qc main\.cf "$${IPKG_INSTROOT}"/etc/sysupgrade.conf >/dev/null || echo "$(config_directory)/main.cf" >> "$${IPKG_INSTROOT}"/etc/sysupgrade.conf
+ grep -qc master\.cf "$${IPKG_INSTROOT}"/etc/sysupgrade.conf >/dev/null || echo "$(config_directory)/master.cf" >> "$${IPKG_INSTROOT}"/etc/sysupgrade.conf
+ grep -qc aliases "$${IPKG_INSTROOT}"/etc/sysupgrade.conf >/dev/null || echo "$(config_directory)/aliases" >> "$${IPKG_INSTROOT}"/etc/sysupgrade.conf
+
+ touch "$${IPKG_INSTROOT}$(config_directory)"/opkg_postinst
+
+ if [ -z "$${IPKG_INSTROOT}" ]; then
+  ps | grep "postfix/master" | grep -cvq grep >/dev/null && /etc/init.d/postfix reload
+ fi
+
+endef
+
+define Package/postfix/prerm
+#!/bin/sh
+ ps | grep "postfix/master" | grep -cvq grep >/dev/null && postfix stop
+ /etc/init.d/postfix disable
+endef
+
+define Package/postfix/postrm
+#!/bin/sh
+ rm -f $${IPKG_INSTROOT}$(config_directory)/aliases.cdb $${IPKG_INSTROOT}$(config_directory)/aliases.db $${IPKG_INSTROOT}$(data_directory)/master.lock
+
+ rm -f "$${IPKG_INSTROOT}$(sendmail_path)" "$${IPKG_INSTROOT}$(newaliases_path)" "$${IPKG_INSTROOT}$(mailq_path)"
+
+ if [ -f "$${IPKG_INSTROOT}$(sendmail_path)$(ln_old_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(sendmail_path)$(ln_old_suffix)" "$${IPKG_INSTROOT}$(sendmail_path)"
+  echo "Warning: $${IPKG_INSTROOT}$(sendmail_path) restored from $${IPKG_INSTROOT}$(sendmail_path)$(ln_old_suffix)"
+ fi
+ if [ -f "$${IPKG_INSTROOT}$(newaliases_path)$(ln_old_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(newaliases_path)$(ln_old_suffix)" "$${IPKG_INSTROOT}$(newaliases_path)"
+  echo "Warning: $${IPKG_INSTROOT}$(newaliases_path) restored from $${IPKG_INSTROOT}$(newaliases_path)$(ln_old_suffix)"
+ fi
+ if [ -f "$${IPKG_INSTROOT}$(mailq_path)$(ln_old_suffix)" ]; then
+  mv "$${IPKG_INSTROOT}$(mailq_path)$(ln_old_suffix)" "$${IPKG_INSTROOT}$(mailq_path)"
+  echo "Warning: $${IPKG_INSTROOT}$(mailq_path) restored from $${IPKG_INSTROOT}$(mailq_path)$(ln_old_suffix)"
+ fi
+endef
+
+$(eval $(call BuildPackage,postfix))
diff --git a/mail/postfix/files/main.cf.default b/mail/postfix/files/main.cf.default
new file mode 100644 (file)
index 0000000..7947dbc
--- /dev/null
@@ -0,0 +1,816 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE
+# TEXT HERE JUST SHOWS DEFAULT SETTINGS BUILT INTO POSTFIX.
+#
+2bounce_notice_recipient = postmaster
+access_map_defer_code = 450
+access_map_reject_code = 554
+address_verify_cache_cleanup_interval = 12h
+address_verify_default_transport = $default_transport
+address_verify_local_transport = $local_transport
+address_verify_map = btree:$data_directory/verify_cache
+address_verify_negative_cache = yes
+address_verify_negative_expire_time = 3d
+address_verify_negative_refresh_time = 3h
+address_verify_poll_count = ${stress?1}${stress:3}
+address_verify_poll_delay = 3s
+address_verify_positive_expire_time = 31d
+address_verify_positive_refresh_time = 7d
+address_verify_relay_transport = $relay_transport
+address_verify_relayhost = $relayhost
+address_verify_sender = $double_bounce_sender
+address_verify_sender_dependent_default_transport_maps = $sender_dependent_default_transport_maps
+address_verify_sender_dependent_relayhost_maps = $sender_dependent_relayhost_maps
+address_verify_sender_ttl = 0s
+address_verify_service_name = verify
+address_verify_transport_maps = $transport_maps
+address_verify_virtual_transport = $virtual_transport
+allow_mail_to_commands = alias, forward
+allow_mail_to_files = alias, forward
+allow_min_user = no
+allow_percent_hack = yes
+allow_untrusted_routing = no
+alternate_config_directories =
+always_add_missing_headers = no
+always_bcc =
+anvil_rate_time_unit = 60s
+anvil_status_update_time = 600s
+append_at_myorigin = yes
+append_dot_mydomain = yes
+application_event_drain_time = 100s
+authorized_flush_users = static:anyone
+authorized_mailq_users = static:anyone
+authorized_submit_users = static:anyone
+backwards_bounce_logfile_compatibility = yes
+berkeley_db_create_buffer_size = 16777216
+berkeley_db_read_buffer_size = 131072
+best_mx_transport =
+biff = yes
+body_checks =
+body_checks_size_limit = 51200
+bounce_notice_recipient = postmaster
+bounce_queue_lifetime = 5d
+bounce_service_name = bounce
+bounce_size_limit = 50000
+bounce_template_file =
+broken_sasl_auth_clients = no
+canonical_classes = envelope_sender, envelope_recipient, header_sender, header_recipient
+canonical_maps =
+cleanup_service_name = cleanup
+command_execution_directory =
+command_expansion_filter = 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+command_time_limit = 1000s
+connection_cache_protocol_timeout = 5s
+connection_cache_service_name = scache
+connection_cache_status_update_time = 600s
+connection_cache_ttl_limit = 2s
+content_filter =
+cyrus_sasl_config_path =
+daemon_table_open_error_is_fatal = no
+daemon_timeout = 18000s
+debug_peer_level = 2
+debug_peer_list =
+debugger_command =
+default_delivery_slot_cost = 5
+default_delivery_slot_discount = 50
+default_delivery_slot_loan = 3
+default_destination_concurrency_failed_cohort_limit = 1
+default_destination_concurrency_limit = 20
+default_destination_concurrency_negative_feedback = 1
+default_destination_concurrency_positive_feedback = 1
+default_destination_rate_delay = 0s
+default_destination_recipient_limit = 50
+default_extra_recipient_limit = 1000
+default_filter_nexthop =
+default_minimum_delivery_slots = 3
+default_privs = nobody
+default_process_limit = 100
+default_rbl_reply = $rbl_code Service unavailable; $rbl_class [$rbl_what] blocked using $rbl_domain${rbl_reason?; $rbl_reason}
+default_recipient_limit = 20000
+default_recipient_refill_delay = 5s
+default_recipient_refill_limit = 100
+default_transport = smtp
+default_verp_delimiters = +=
+defer_code = 450
+defer_service_name = defer
+defer_transports =
+delay_logging_resolution_limit = 2
+delay_notice_recipient = postmaster
+delay_warning_time = 0h
+deliver_lock_attempts = 20
+deliver_lock_delay = 1s
+destination_concurrency_feedback_debug = no
+detect_8bit_encoding_header = yes
+disable_dns_lookups = no
+disable_mime_input_processing = no
+disable_mime_output_conversion = no
+disable_verp_bounces = no
+disable_vrfy_command = no
+dnsblog_reply_delay = 0s
+dnsblog_service_name = dnsblog
+dont_remove = 0
+double_bounce_sender = double-bounce
+duplicate_filter_limit = 1000
+empty_address_default_transport_maps_lookup_key = <>
+empty_address_recipient = MAILER-DAEMON
+empty_address_relayhost_maps_lookup_key = <>
+enable_long_queue_ids = no
+enable_original_recipient = yes
+error_delivery_slot_cost = $default_delivery_slot_cost
+error_delivery_slot_discount = $default_delivery_slot_discount
+error_delivery_slot_loan = $default_delivery_slot_loan
+error_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+error_destination_concurrency_limit = $default_destination_concurrency_limit
+error_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+error_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+error_destination_rate_delay = $default_destination_rate_delay
+error_destination_recipient_limit = $default_destination_recipient_limit
+error_extra_recipient_limit = $default_extra_recipient_limit
+error_initial_destination_concurrency = $initial_destination_concurrency
+error_minimum_delivery_slots = $default_minimum_delivery_slots
+error_notice_recipient = postmaster
+error_recipient_limit = $default_recipient_limit
+error_recipient_refill_delay = $default_recipient_refill_delay
+error_recipient_refill_limit = $default_recipient_refill_limit
+error_service_name = error
+execution_directory_expansion_filter = 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+expand_owner_alias = no
+export_environment = TZ MAIL_CONFIG LANG
+fallback_transport =
+fallback_transport_maps =
+fast_flush_domains = $relay_domains
+fast_flush_purge_time = 7d
+fast_flush_refresh_time = 12h
+fault_injection_code = 0
+flush_service_name = flush
+fork_attempts = 5
+fork_delay = 1s
+forward_expansion_filter = 1234567890!@%-_=+:,./abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+forward_path = $home/.forward${recipient_delimiter}${extension}, $home/.forward
+frozen_delivered_to = yes
+hash_queue_depth = 1
+hash_queue_names = deferred, defer
+header_address_token_limit = 10240
+header_checks =
+header_size_limit = 102400
+helpful_warnings = yes
+home_mailbox =
+hopcount_limit = 50
+ignore_mx_lookup_error = no
+import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C
+in_flow_delay = 1s
+inet_interfaces = all
+inet_protocols = all
+initial_destination_concurrency = 5
+internal_mail_filter_classes =
+invalid_hostname_reject_code = 501
+ipc_idle = 5s
+ipc_timeout = 3600s
+ipc_ttl = 1000s
+line_length_limit = 2048
+lmdb_map_size = 16777216
+lmtp_address_preference = any
+lmtp_assume_final = no
+lmtp_bind_address =
+lmtp_bind_address6 =
+lmtp_body_checks =
+lmtp_cname_overrides_servername = no
+lmtp_connect_timeout = 0s
+lmtp_connection_cache_destinations =
+lmtp_connection_cache_on_demand = yes
+lmtp_connection_cache_time_limit = 2s
+lmtp_connection_reuse_count_limit = 0
+lmtp_connection_reuse_time_limit = 300s
+lmtp_data_done_timeout = 600s
+lmtp_data_init_timeout = 120s
+lmtp_data_xfer_timeout = 180s
+lmtp_defer_if_no_mx_address_found = no
+lmtp_delivery_slot_cost = $default_delivery_slot_cost
+lmtp_delivery_slot_discount = $default_delivery_slot_discount
+lmtp_delivery_slot_loan = $default_delivery_slot_loan
+lmtp_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+lmtp_destination_concurrency_limit = $default_destination_concurrency_limit
+lmtp_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+lmtp_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+lmtp_destination_rate_delay = $default_destination_rate_delay
+lmtp_destination_recipient_limit = $default_destination_recipient_limit
+lmtp_discard_lhlo_keyword_address_maps =
+lmtp_discard_lhlo_keywords =
+lmtp_dns_resolver_options =
+lmtp_dns_support_level =
+lmtp_enforce_tls = no
+lmtp_extra_recipient_limit = $default_extra_recipient_limit
+lmtp_generic_maps =
+lmtp_header_checks =
+lmtp_host_lookup = dns
+lmtp_initial_destination_concurrency = $initial_destination_concurrency
+lmtp_lhlo_name = $myhostname
+lmtp_lhlo_timeout = 300s
+lmtp_line_length_limit = 998
+lmtp_mail_timeout = 300s
+lmtp_mime_header_checks =
+lmtp_minimum_delivery_slots = $default_minimum_delivery_slots
+lmtp_mx_address_limit = 5
+lmtp_mx_session_limit = 2
+lmtp_nested_header_checks =
+lmtp_per_record_deadline = no
+lmtp_pix_workaround_delay_time = 10s
+lmtp_pix_workaround_maps =
+lmtp_pix_workaround_threshold_time = 500s
+lmtp_pix_workarounds = disable_esmtp,delay_dotcrlf
+lmtp_quit_timeout = 300s
+lmtp_quote_rfc821_envelope = yes
+lmtp_randomize_addresses = yes
+lmtp_rcpt_timeout = 300s
+lmtp_recipient_limit = $default_recipient_limit
+lmtp_recipient_refill_delay = $default_recipient_refill_delay
+lmtp_recipient_refill_limit = $default_recipient_refill_limit
+lmtp_reply_filter =
+lmtp_rset_timeout = 20s
+lmtp_sasl_auth_cache_name =
+lmtp_sasl_auth_cache_time = 90d
+lmtp_sasl_auth_enable = no
+lmtp_sasl_auth_soft_bounce = yes
+lmtp_sasl_mechanism_filter =
+lmtp_sasl_password_maps =
+lmtp_sasl_path =
+lmtp_sasl_security_options = noplaintext, noanonymous
+lmtp_sasl_tls_security_options = $lmtp_sasl_security_options
+lmtp_sasl_tls_verified_security_options = $lmtp_sasl_tls_security_options
+lmtp_sasl_type = cyrus
+lmtp_send_dummy_mail_auth = no
+lmtp_send_xforward_command = no
+lmtp_sender_dependent_authentication = no
+lmtp_skip_5xx_greeting = yes
+lmtp_skip_quit_response = no
+lmtp_starttls_timeout = 300s
+lmtp_tcp_port = 24
+lmtp_tls_CAfile =
+lmtp_tls_CApath =
+lmtp_tls_block_early_mail_reply = no
+lmtp_tls_cert_file =
+lmtp_tls_ciphers = export
+lmtp_tls_dcert_file =
+lmtp_tls_dkey_file = $lmtp_tls_dcert_file
+lmtp_tls_eccert_file =
+lmtp_tls_eckey_file = $lmtp_tls_eccert_file
+lmtp_tls_enforce_peername = yes
+lmtp_tls_exclude_ciphers =
+lmtp_tls_fingerprint_cert_match =
+lmtp_tls_fingerprint_digest = md5
+lmtp_tls_force_insecure_host_tlsa_lookup = no
+lmtp_tls_key_file = $lmtp_tls_cert_file
+lmtp_tls_loglevel = 0
+lmtp_tls_mandatory_ciphers = medium
+lmtp_tls_mandatory_exclude_ciphers =
+lmtp_tls_mandatory_protocols = !SSLv2
+lmtp_tls_note_starttls_offer = no
+lmtp_tls_per_site =
+lmtp_tls_policy_maps =
+lmtp_tls_protocols = !SSLv2
+lmtp_tls_scert_verifydepth = 9
+lmtp_tls_secure_cert_match = nexthop
+lmtp_tls_security_level =
+lmtp_tls_session_cache_database =
+lmtp_tls_session_cache_timeout = 3600s
+lmtp_tls_trust_anchor_file =
+lmtp_tls_verify_cert_match = hostname
+lmtp_use_tls = no
+lmtp_xforward_timeout = 300s
+local_command_shell =
+local_delivery_slot_cost = $default_delivery_slot_cost
+local_delivery_slot_discount = $default_delivery_slot_discount
+local_delivery_slot_loan = $default_delivery_slot_loan
+local_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+local_destination_concurrency_limit = 2
+local_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+local_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+local_destination_rate_delay = $default_destination_rate_delay
+local_destination_recipient_limit = 1
+local_extra_recipient_limit = $default_extra_recipient_limit
+local_header_rewrite_clients = permit_inet_interfaces
+local_initial_destination_concurrency = $initial_destination_concurrency
+local_minimum_delivery_slots = $default_minimum_delivery_slots
+local_recipient_limit = $default_recipient_limit
+local_recipient_maps = proxy:unix:passwd.byname $alias_maps
+local_recipient_refill_delay = $default_recipient_refill_delay
+local_recipient_refill_limit = $default_recipient_refill_limit
+local_transport = local:$myhostname
+luser_relay =
+mail_name = Postfix
+mail_owner = postfix
+mail_release_date = 20140507
+mail_version = 2.11.1
+mailbox_command =
+mailbox_command_maps =
+mailbox_delivery_lock = fcntl, dotlock
+mailbox_size_limit = 51200000
+mailbox_transport =
+mailbox_transport_maps =
+maps_rbl_domains =
+maps_rbl_reject_code = 554
+masquerade_classes = envelope_sender, header_sender, header_recipient
+masquerade_domains =
+masquerade_exceptions =
+master_service_disable =
+max_idle = 100s
+max_use = 100
+maximal_backoff_time = 4000s
+maximal_queue_lifetime = 5d
+message_reject_characters =
+message_size_limit = 10240000
+message_strip_characters =
+milter_command_timeout = 30s
+milter_connect_macros = j {daemon_name} v
+milter_connect_timeout = 30s
+milter_content_timeout = 300s
+milter_data_macros = i
+milter_default_action = tempfail
+milter_end_of_data_macros = i
+milter_end_of_header_macros = i
+milter_header_checks =
+milter_helo_macros = {tls_version} {cipher} {cipher_bits} {cert_subject} {cert_issuer}
+milter_macro_daemon_name = $myhostname
+milter_macro_v = $mail_name $mail_version
+milter_mail_macros = i {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}
+milter_protocol = 6
+milter_rcpt_macros = i {rcpt_addr} {rcpt_host} {rcpt_mailer}
+milter_unknown_command_macros =
+mime_boundary_length_limit = 2048
+mime_header_checks = $header_checks
+mime_nesting_limit = 100
+minimal_backoff_time = 300s
+multi_instance_directories =
+multi_instance_enable = no
+multi_instance_group =
+multi_instance_name =
+multi_instance_wrapper =
+multi_recipient_bounce_reject_code = 550
+mydestination = $myhostname, localhost.$mydomain, localhost
+mynetworks_style = subnet
+myorigin = $myhostname
+nested_header_checks = $header_checks
+non_fqdn_reject_code = 504
+non_smtpd_milters =
+notify_classes = resource, software
+owner_request_special = yes
+parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,mynetworks,permit_mx_backup_networks,qmqpd_authorized_clients,relay_domains,smtpd_access_maps
+permit_mx_backup_networks =
+pickup_service_name = pickup
+plaintext_reject_code = 450
+postmulti_control_commands = reload flush
+postmulti_start_commands = start
+postmulti_stop_commands = stop abort drain quick-stop
+postscreen_access_list = permit_mynetworks
+postscreen_bare_newline_action = ignore
+postscreen_bare_newline_enable = no
+postscreen_bare_newline_ttl = 30d
+postscreen_blacklist_action = ignore
+postscreen_cache_cleanup_interval = 12h
+postscreen_cache_map = btree:$data_directory/postscreen_cache
+postscreen_cache_retention_time = 7d
+postscreen_client_connection_count_limit = $smtpd_client_connection_count_limit
+postscreen_command_count_limit = 20
+postscreen_command_filter =
+postscreen_command_time_limit = ${stress?10}${stress:300}s
+postscreen_disable_vrfy_command = $disable_vrfy_command
+postscreen_discard_ehlo_keyword_address_maps = $smtpd_discard_ehlo_keyword_address_maps
+postscreen_discard_ehlo_keywords = $smtpd_discard_ehlo_keywords
+postscreen_dnsbl_action = ignore
+postscreen_dnsbl_reply_map =
+postscreen_dnsbl_sites =
+postscreen_dnsbl_threshold = 1
+postscreen_dnsbl_ttl = 1h
+postscreen_dnsbl_whitelist_threshold = 0
+postscreen_enforce_tls = $smtpd_enforce_tls
+postscreen_expansion_filter = $smtpd_expansion_filter
+postscreen_forbidden_commands = $smtpd_forbidden_commands
+postscreen_greet_action = ignore
+postscreen_greet_banner = $smtpd_banner
+postscreen_greet_ttl = 1d
+postscreen_greet_wait = ${stress?2}${stress:6}s
+postscreen_helo_required = $smtpd_helo_required
+postscreen_non_smtp_command_action = drop
+postscreen_non_smtp_command_enable = no
+postscreen_non_smtp_command_ttl = 30d
+postscreen_pipelining_action = enforce
+postscreen_pipelining_enable = no
+postscreen_pipelining_ttl = 30d
+postscreen_post_queue_limit = $default_process_limit
+postscreen_pre_queue_limit = $default_process_limit
+postscreen_reject_footer = $smtpd_reject_footer
+postscreen_tls_security_level = $smtpd_tls_security_level
+postscreen_upstream_proxy_protocol =
+postscreen_upstream_proxy_timeout = 5s
+postscreen_use_tls = $smtpd_use_tls
+postscreen_watchdog_timeout = 10s
+postscreen_whitelist_interfaces = static:all
+prepend_delivered_header = command, file, forward
+process_id = 6537
+process_id_directory = pid
+process_name = postconf
+propagate_unmatched_extensions = canonical, virtual
+proxy_interfaces =
+proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps $sender_bcc_maps $recipient_bcc_maps $smtp_generic_maps $lmtp_generic_maps $alias_maps
+proxy_write_maps = $smtp_sasl_auth_cache_name $lmtp_sasl_auth_cache_name $address_verify_map $postscreen_cache_map
+proxymap_service_name = proxymap
+proxywrite_service_name = proxywrite
+qmgr_clog_warn_time = 300s
+qmgr_daemon_timeout = 1000s
+qmgr_fudge_factor = 100
+qmgr_ipc_timeout = 60s
+qmgr_message_active_limit = 20000
+qmgr_message_recipient_limit = 20000
+qmgr_message_recipient_minimum = 10
+qmqpd_authorized_clients =
+qmqpd_client_port_logging = no
+qmqpd_error_delay = 1s
+qmqpd_timeout = 300s
+queue_file_attribute_count_limit = 100
+queue_minfree = 0
+queue_run_delay = 300s
+queue_service_name = qmgr
+rbl_reply_maps =
+receive_override_options =
+recipient_bcc_maps =
+recipient_canonical_classes = envelope_recipient, header_recipient
+recipient_canonical_maps =
+recipient_delimiter =
+reject_code = 554
+reject_tempfail_action = defer_if_permit
+relay_clientcerts =
+relay_delivery_slot_cost = $default_delivery_slot_cost
+relay_delivery_slot_discount = $default_delivery_slot_discount
+relay_delivery_slot_loan = $default_delivery_slot_loan
+relay_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+relay_destination_concurrency_limit = $default_destination_concurrency_limit
+relay_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+relay_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+relay_destination_rate_delay = $default_destination_rate_delay
+relay_destination_recipient_limit = $default_destination_recipient_limit
+relay_domains = $mydestination
+relay_domains_reject_code = 554
+relay_extra_recipient_limit = $default_extra_recipient_limit
+relay_initial_destination_concurrency = $initial_destination_concurrency
+relay_minimum_delivery_slots = $default_minimum_delivery_slots
+relay_recipient_limit = $default_recipient_limit
+relay_recipient_maps =
+relay_recipient_refill_delay = $default_recipient_refill_delay
+relay_recipient_refill_limit = $default_recipient_refill_limit
+relay_transport = relay
+relayhost =
+relocated_maps =
+remote_header_rewrite_domain =
+require_home_directory = no
+reset_owner_alias = no
+resolve_dequoted_address = yes
+resolve_null_domain = no
+resolve_numeric_domain = no
+retry_delivery_slot_cost = $default_delivery_slot_cost
+retry_delivery_slot_discount = $default_delivery_slot_discount
+retry_delivery_slot_loan = $default_delivery_slot_loan
+retry_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+retry_destination_concurrency_limit = $default_destination_concurrency_limit
+retry_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+retry_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+retry_destination_rate_delay = $default_destination_rate_delay
+retry_destination_recipient_limit = $default_destination_recipient_limit
+retry_extra_recipient_limit = $default_extra_recipient_limit
+retry_initial_destination_concurrency = $initial_destination_concurrency
+retry_minimum_delivery_slots = $default_minimum_delivery_slots
+retry_recipient_limit = $default_recipient_limit
+retry_recipient_refill_delay = $default_recipient_refill_delay
+retry_recipient_refill_limit = $default_recipient_refill_limit
+rewrite_service_name = rewrite
+send_cyrus_sasl_authzid = no
+sender_bcc_maps =
+sender_canonical_classes = envelope_sender, header_sender
+sender_canonical_maps =
+sender_dependent_default_transport_maps =
+sender_dependent_relayhost_maps =
+sendmail_fix_line_endings = always
+service_throttle_time = 60s
+setgid_group = postdrop
+show_user_unknown_table_name = yes
+showq_service_name = showq
+smtp_address_preference = any
+smtp_always_send_ehlo = yes
+smtp_bind_address =
+smtp_bind_address6 =
+smtp_body_checks =
+smtp_cname_overrides_servername = no
+smtp_connect_timeout = 30s
+smtp_connection_cache_destinations =
+smtp_connection_cache_on_demand = yes
+smtp_connection_cache_time_limit = 2s
+smtp_connection_reuse_count_limit = 0
+smtp_connection_reuse_time_limit = 300s
+smtp_data_done_timeout = 600s
+smtp_data_init_timeout = 120s
+smtp_data_xfer_timeout = 180s
+smtp_defer_if_no_mx_address_found = no
+smtp_delivery_slot_cost = $default_delivery_slot_cost
+smtp_delivery_slot_discount = $default_delivery_slot_discount
+smtp_delivery_slot_loan = $default_delivery_slot_loan
+smtp_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+smtp_destination_concurrency_limit = $default_destination_concurrency_limit
+smtp_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+smtp_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+smtp_destination_rate_delay = $default_destination_rate_delay
+smtp_destination_recipient_limit = $default_destination_recipient_limit
+smtp_discard_ehlo_keyword_address_maps =
+smtp_discard_ehlo_keywords =
+smtp_dns_resolver_options =
+smtp_dns_support_level =
+smtp_enforce_tls = no
+smtp_extra_recipient_limit = $default_extra_recipient_limit
+smtp_fallback_relay = $fallback_relay
+smtp_generic_maps =
+smtp_header_checks =
+smtp_helo_name = $myhostname
+smtp_helo_timeout = 300s
+smtp_host_lookup = dns
+smtp_initial_destination_concurrency = $initial_destination_concurrency
+smtp_line_length_limit = 998
+smtp_mail_timeout = 300s
+smtp_mime_header_checks =
+smtp_minimum_delivery_slots = $default_minimum_delivery_slots
+smtp_mx_address_limit = 5
+smtp_mx_session_limit = 2
+smtp_nested_header_checks =
+smtp_never_send_ehlo = no
+smtp_per_record_deadline = no
+smtp_pix_workaround_delay_time = 10s
+smtp_pix_workaround_maps =
+smtp_pix_workaround_threshold_time = 500s
+smtp_pix_workarounds = disable_esmtp,delay_dotcrlf
+smtp_quit_timeout = 300s
+smtp_quote_rfc821_envelope = yes
+smtp_randomize_addresses = yes
+smtp_rcpt_timeout = 300s
+smtp_recipient_limit = $default_recipient_limit
+smtp_recipient_refill_delay = $default_recipient_refill_delay
+smtp_recipient_refill_limit = $default_recipient_refill_limit
+smtp_reply_filter =
+smtp_rset_timeout = 20s
+smtp_sasl_auth_cache_name =
+smtp_sasl_auth_cache_time = 90d
+smtp_sasl_auth_enable = no
+smtp_sasl_auth_soft_bounce = yes
+smtp_sasl_mechanism_filter =
+smtp_sasl_password_maps =
+smtp_sasl_path =
+smtp_sasl_security_options = noplaintext, noanonymous
+smtp_sasl_tls_security_options = $smtp_sasl_security_options
+smtp_sasl_tls_verified_security_options = $smtp_sasl_tls_security_options
+smtp_sasl_type = cyrus
+smtp_send_dummy_mail_auth = no
+smtp_send_xforward_command = no
+smtp_sender_dependent_authentication = no
+smtp_skip_5xx_greeting = yes
+smtp_skip_quit_response = yes
+smtp_starttls_timeout = 300s
+smtp_tls_CAfile =
+smtp_tls_CApath =
+smtp_tls_block_early_mail_reply = no
+smtp_tls_cert_file =
+smtp_tls_ciphers = export
+smtp_tls_dcert_file =
+smtp_tls_dkey_file = $smtp_tls_dcert_file
+smtp_tls_eccert_file =
+smtp_tls_eckey_file = $smtp_tls_eccert_file
+smtp_tls_enforce_peername = yes
+smtp_tls_exclude_ciphers =
+smtp_tls_fingerprint_cert_match =
+smtp_tls_fingerprint_digest = md5
+smtp_tls_force_insecure_host_tlsa_lookup = no
+smtp_tls_key_file = $smtp_tls_cert_file
+smtp_tls_loglevel = 0
+smtp_tls_mandatory_ciphers = medium
+smtp_tls_mandatory_exclude_ciphers =
+smtp_tls_mandatory_protocols = !SSLv2
+smtp_tls_note_starttls_offer = no
+smtp_tls_per_site =
+smtp_tls_policy_maps =
+smtp_tls_protocols = !SSLv2
+smtp_tls_scert_verifydepth = 9
+smtp_tls_secure_cert_match = nexthop, dot-nexthop
+smtp_tls_security_level =
+smtp_tls_session_cache_database =
+smtp_tls_session_cache_timeout = 3600s
+smtp_tls_trust_anchor_file =
+smtp_tls_verify_cert_match = hostname
+smtp_use_tls = no
+smtp_xforward_timeout = 300s
+smtpd_authorized_verp_clients = $authorized_verp_clients
+smtpd_authorized_xclient_hosts =
+smtpd_authorized_xforward_hosts =
+smtpd_banner = $myhostname ESMTP $mail_name
+smtpd_client_connection_count_limit = 50
+smtpd_client_connection_rate_limit = 0
+smtpd_client_event_limit_exceptions = ${smtpd_client_connection_limit_exceptions:$mynetworks}
+smtpd_client_message_rate_limit = 0
+smtpd_client_new_tls_session_rate_limit = 0
+smtpd_client_port_logging = no
+smtpd_client_recipient_rate_limit = 0
+smtpd_client_restrictions =
+smtpd_command_filter =
+smtpd_data_restrictions =
+smtpd_delay_open_until_valid_rcpt = yes
+smtpd_delay_reject = yes
+smtpd_discard_ehlo_keyword_address_maps =
+smtpd_discard_ehlo_keywords =
+smtpd_end_of_data_restrictions =
+smtpd_enforce_tls = no
+smtpd_error_sleep_time = 1s
+smtpd_etrn_restrictions =
+smtpd_expansion_filter = \t\40!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+smtpd_forbidden_commands = CONNECT GET POST
+smtpd_hard_error_limit = ${stress?1}${stress:20}
+smtpd_helo_required = no
+smtpd_helo_restrictions =
+smtpd_history_flush_threshold = 100
+smtpd_junk_command_limit = ${stress?1}${stress:100}
+smtpd_log_access_permit_actions =
+smtpd_milters =
+smtpd_noop_commands =
+smtpd_null_access_lookup_key = <>
+smtpd_peername_lookup = yes
+smtpd_per_record_deadline = ${stress?yes}${stress:no}
+smtpd_policy_service_max_idle = 300s
+smtpd_policy_service_max_ttl = 1000s
+smtpd_policy_service_timeout = 100s
+smtpd_proxy_ehlo = $myhostname
+smtpd_proxy_filter =
+smtpd_proxy_options =
+smtpd_proxy_timeout = 100s
+smtpd_recipient_limit = 1000
+smtpd_recipient_overshoot_limit = 1000
+smtpd_recipient_restrictions =
+smtpd_reject_footer =
+smtpd_reject_unlisted_recipient = yes
+smtpd_reject_unlisted_sender = no
+smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
+smtpd_restriction_classes =
+smtpd_sasl_auth_enable = no
+smtpd_sasl_authenticated_header = no
+smtpd_sasl_exceptions_networks =
+smtpd_sasl_local_domain =
+smtpd_sasl_path = smtpd
+smtpd_sasl_security_options = noanonymous
+smtpd_sasl_service = smtp
+smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
+smtpd_sasl_type = cyrus
+smtpd_sender_login_maps =
+smtpd_sender_restrictions =
+smtpd_service_name = smtpd
+smtpd_soft_error_limit = 10
+smtpd_starttls_timeout = ${stress?10}${stress:300}s
+smtpd_timeout = ${stress?10}${stress:300}s
+smtpd_tls_CAfile =
+smtpd_tls_CApath =
+smtpd_tls_always_issue_session_ids = yes
+smtpd_tls_ask_ccert = no
+smtpd_tls_auth_only = no
+smtpd_tls_ccert_verifydepth = 9
+smtpd_tls_cert_file =
+smtpd_tls_ciphers = export
+smtpd_tls_dcert_file =
+smtpd_tls_dh1024_param_file =
+smtpd_tls_dh512_param_file =
+smtpd_tls_dkey_file = $smtpd_tls_dcert_file
+smtpd_tls_eccert_file =
+smtpd_tls_eckey_file = $smtpd_tls_eccert_file
+smtpd_tls_eecdh_grade = strong
+smtpd_tls_exclude_ciphers =
+smtpd_tls_fingerprint_digest = md5
+smtpd_tls_key_file = $smtpd_tls_cert_file
+smtpd_tls_loglevel = 0
+smtpd_tls_mandatory_ciphers = medium
+smtpd_tls_mandatory_exclude_ciphers =
+smtpd_tls_mandatory_protocols = !SSLv2
+smtpd_tls_protocols =
+smtpd_tls_received_header = no
+smtpd_tls_req_ccert = no
+smtpd_tls_security_level =
+smtpd_tls_session_cache_database =
+smtpd_tls_session_cache_timeout = 3600s
+smtpd_tls_wrappermode = no
+smtpd_upstream_proxy_protocol =
+smtpd_upstream_proxy_timeout = 5s
+smtpd_use_tls = no
+soft_bounce = no
+stale_lock_time = 500s
+stress =
+strict_7bit_headers = no
+strict_8bitmime = no
+strict_8bitmime_body = no
+strict_mailbox_ownership = yes
+strict_mime_encoding_domain = no
+strict_rfc821_envelopes = no
+sun_mailtool_compatibility = no
+swap_bangpath = yes
+syslog_facility = mail
+syslog_name = ${multi_instance_name:postfix}${multi_instance_name?$multi_instance_name}
+tcp_windowsize = 0
+tls_append_default_CA = no
+tls_daemon_random_bytes = 32
+tls_dane_digest_agility = on
+tls_dane_digests = sha512 sha256
+tls_dane_trust_anchor_digest_enable = yes
+tls_disable_workarounds =
+tls_eecdh_strong_curve = prime256v1
+tls_eecdh_ultra_curve = secp384r1
+tls_export_cipherlist = ALL:+RC4:@STRENGTH
+tls_high_cipherlist = ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH
+tls_legacy_public_key_fingerprints = no
+tls_low_cipherlist = ALL:!EXPORT:+RC4:@STRENGTH
+tls_medium_cipherlist = ALL:!EXPORT:!LOW:+RC4:@STRENGTH
+tls_null_cipherlist = eNULL:!aNULL
+tls_preempt_cipherlist = no
+tls_random_bytes = 32
+tls_random_exchange_name = ${data_directory}/prng_exch
+tls_random_prng_update_period = 3600s
+tls_random_reseed_period = 3600s
+tls_random_source = dev:/dev/urandom
+tls_ssl_options =
+tls_wildcard_matches_multiple_labels = yes
+tlsmgr_service_name = tlsmgr
+tlsproxy_enforce_tls = $smtpd_enforce_tls
+tlsproxy_service_name = tlsproxy
+tlsproxy_tls_CAfile = $smtpd_tls_CAfile
+tlsproxy_tls_CApath = $smtpd_tls_CApath
+tlsproxy_tls_always_issue_session_ids = $smtpd_tls_always_issue_session_ids
+tlsproxy_tls_ask_ccert = $smtpd_tls_ask_ccert
+tlsproxy_tls_ccert_verifydepth = $smtpd_tls_ccert_verifydepth
+tlsproxy_tls_cert_file = $smtpd_tls_cert_file
+tlsproxy_tls_ciphers = $smtpd_tls_ciphers
+tlsproxy_tls_dcert_file = $smtpd_tls_dcert_file
+tlsproxy_tls_dh1024_param_file = $smtpd_tls_dh1024_param_file
+tlsproxy_tls_dh512_param_file = $smtpd_tls_dh512_param_file
+tlsproxy_tls_dkey_file = $smtpd_tls_dkey_file
+tlsproxy_tls_eccert_file = $smtpd_tls_eccert_file
+tlsproxy_tls_eckey_file = $smtpd_tls_eckey_file
+tlsproxy_tls_eecdh_grade = $smtpd_tls_eecdh_grade
+tlsproxy_tls_exclude_ciphers = $smtpd_tls_exclude_ciphers
+tlsproxy_tls_fingerprint_digest = $smtpd_tls_fingerprint_digest
+tlsproxy_tls_key_file = $smtpd_tls_key_file
+tlsproxy_tls_loglevel = $smtpd_tls_loglevel
+tlsproxy_tls_mandatory_ciphers = $smtpd_tls_mandatory_ciphers
+tlsproxy_tls_mandatory_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
+tlsproxy_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
+tlsproxy_tls_protocols = $smtpd_tls_protocols
+tlsproxy_tls_req_ccert = $smtpd_tls_req_ccert
+tlsproxy_tls_security_level = $smtpd_tls_security_level
+tlsproxy_use_tls = $smtpd_use_tls
+tlsproxy_watchdog_timeout = 10s
+trace_service_name = trace
+transport_maps =
+transport_retry_time = 60s
+trigger_timeout = 10s
+undisclosed_recipients_header =
+unknown_address_reject_code = 450
+unknown_address_tempfail_action = $reject_tempfail_action
+unknown_client_reject_code = 450
+unknown_helo_hostname_tempfail_action = $reject_tempfail_action
+unknown_hostname_reject_code = 450
+unknown_local_recipient_reject_code = 550
+unknown_relay_recipient_reject_code = 550
+unknown_virtual_alias_reject_code = 550
+unknown_virtual_mailbox_reject_code = 550
+unverified_recipient_defer_code = 450
+unverified_recipient_reject_code = 450
+unverified_recipient_reject_reason =
+unverified_recipient_tempfail_action = $reject_tempfail_action
+unverified_sender_defer_code = 450
+unverified_sender_reject_code = 450
+unverified_sender_reject_reason =
+unverified_sender_tempfail_action = $reject_tempfail_action
+verp_delimiter_filter = -=+
+virtual_alias_domains = $virtual_alias_maps
+virtual_alias_expansion_limit = 1000
+virtual_alias_maps = $virtual_maps
+virtual_alias_recursion_limit = 1000
+virtual_delivery_slot_cost = $default_delivery_slot_cost
+virtual_delivery_slot_discount = $default_delivery_slot_discount
+virtual_delivery_slot_loan = $default_delivery_slot_loan
+virtual_destination_concurrency_failed_cohort_limit = $default_destination_concurrency_failed_cohort_limit
+virtual_destination_concurrency_limit = $default_destination_concurrency_limit
+virtual_destination_concurrency_negative_feedback = $default_destination_concurrency_negative_feedback
+virtual_destination_concurrency_positive_feedback = $default_destination_concurrency_positive_feedback
+virtual_destination_rate_delay = $default_destination_rate_delay
+virtual_destination_recipient_limit = $default_destination_recipient_limit
+virtual_extra_recipient_limit = $default_extra_recipient_limit
+virtual_gid_maps =
+virtual_initial_destination_concurrency = $initial_destination_concurrency
+virtual_mailbox_base =
+virtual_mailbox_domains = $virtual_mailbox_maps
+virtual_mailbox_limit = 51200000
+virtual_mailbox_lock = fcntl, dotlock
+virtual_mailbox_maps =
+virtual_minimum_delivery_slots = $default_minimum_delivery_slots
+virtual_minimum_uid = 100
+virtual_recipient_limit = $default_recipient_limit
+virtual_recipient_refill_delay = $default_recipient_refill_delay
+virtual_recipient_refill_limit = $default_recipient_refill_limit
+virtual_transport = virtual
+virtual_uid_maps =
diff --git a/mail/postfix/files/postfix.init b/mail/postfix/files/postfix.init
new file mode 100644 (file)
index 0000000..1ed48dc
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=50
+STOP=50
+
+upgrade() {
+       config_directory="$IPKG_INSTROOT"/etc/postfix
+
+       if [ -f "$config_directory"/opkg_postinst ]; then
+               rm -f "$config_directory"/opkg_postinst
+
+               group_exists postfix || group_add postfix 87
+               user_exists postfix || user_add postfix 87
+               group_exists postdrop || group_add postdrop 88
+
+               echo "myhostname = $(uci get system.@system[0].hostname)" >> "$config_directory"/main.cf.default
+               echo "mydomain = $(uci get system.@system[0].hostname|sed -e "s/[^\.]*\.\(.*\)/\1/")" >> "$config_directory"/main.cf.default
+               ifconfig | grep "inet addr" | sed -e "s/.*inet addr:\([0-9.]*\).*Mask:/\1 /" | while read IP NETMASK; do eval "$(ipcalc.sh $IP $NETMASK)"; echo "$NETWORK/$PREFIX"; done | xargs echo "mynetworks =" >> "$config_directory"/main.cf.default
+
+               grep -qc "^sendmail_path" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^sendmail_path =" "$config_directory"/main.cf.default)"
+               grep -qc "^newaliases_path" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^newaliases_path =" "$config_directory"/main.cf.default)"
+               grep -qc "^mailq_path" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^mailq_path =" "$config_directory"/main.cf.default)"
+               grep -qc "^html_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^html_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^manpage_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^manpage_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^sample_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^sample_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^readme_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^readme_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^command_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^command_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^daemon_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^daemon_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^data_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^data_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^queue_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^queue_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^config_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^config_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^mail_spool_directory" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^mail_spool_directory =" "$config_directory"/main.cf.default)"
+               grep -qc "^mail_owner" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^mail_owner =" "$config_directory"/main.cf.default)"
+               grep -qc "^setgid_group" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^setgid_group =" "$config_directory"/main.cf.default)"
+               grep -qc "^myhostname" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^myhostname =" "$config_directory"/main.cf.default)"
+               grep -qc "^mydomain" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^mydomain =" "$config_directory"/main.cf.default)"
+               grep -qc "^mynetworks" "$config_directory"/main.cf >/dev/null || postconf -e "$(grep "^mynetworks =" "$config_directory"/main.cf.default)"
+
+               postfix set-permissions
+               postfix post-install upgrade-source
+               postfix upgrade-configuration
+               newaliases
+       fi
+}
+
+start() {
+       upgrade
+       postfix start
+}
+
+stop() {
+       postfix stop
+}
+
+reload() {
+       upgrade
+       postfix reload
+}
diff --git a/mail/postfix/patches/100-fsstat.patch b/mail/postfix/patches/100-fsstat.patch
new file mode 100644 (file)
index 0000000..c91acca
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rupN postfix-2.8.1/src/smtpd/smtpd_check.c postfix-2.8.1_patched/src/smtpd/smtpd_check.c
+--- postfix-2.8.1/src/smtpd/smtpd_check.c      2011-01-04 22:03:50.000000000 +0300
++++ postfix-2.8.1_patched/src/smtpd/smtpd_check.c      2011-03-06 19:35:39.000000000 +0300
+@@ -4894,7 +4894,7 @@ char   *smtpd_check_queue(SMTPD_STATE *s
+      */
+ #define BLOCKS(x)     ((x) / fsbuf.block_size)
+-    fsspace(".", &fsbuf);
++    fsspace("/overlay", &fsbuf);
+     if (msg_verbose)
+       msg_info("%s: blocks %lu avail %lu min_free %lu msg_size_limit %lu",
+                myname,
diff --git a/mail/postfix/patches/200-manpages.patch b/mail/postfix/patches/200-manpages.patch
new file mode 100644 (file)
index 0000000..948376c
--- /dev/null
@@ -0,0 +1,80 @@
+diff -Naur postfix-2.10.2/conf/post-install postfix-2.10.2_patched/conf/post-install
+--- postfix-2.10.2/conf/post-install   2013-06-13 18:07:46.000000000 +0400
++++ postfix-2.10.2_patched/conf/post-install   2013-11-19 21:17:49.572820573 +0400
+@@ -350,10 +350,10 @@
+ # Sanity checks
+-case $manpage_directory in
+- no) echo $0: Error: manpage_directory no longer accepts \"no\" values. 1>&2
+-     echo Try again with \"$0 manpage_directory=/pathname ...\". 1>&2; exit 1;;
+-esac
++#case $manpage_directory in
++# no) echo $0: Error: manpage_directory no longer accepts \"no\" values. 1>&2
++#     echo Try again with \"$0 manpage_directory=/pathname ...\". 1>&2; exit 1;;
++#esac
+ case $setgid_group in
+  no) echo $0: Error: setgid_group no longer accepts \"no\" values. 1>&2
+@@ -361,7 +361,7 @@
+ esac
+ for path in "$daemon_directory" "$command_directory" "$queue_directory" \
+-    "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
++    "$sendmail_path" "$newaliases_path" "$mailq_path"
+ do
+    case "$path" in
+    /*) ;;
+@@ -369,7 +369,7 @@
+    esac
+ done
+-for path in "$html_directory" "$readme_directory"
++for path in "$html_directory" "$readme_directory" "$manpage_directory"
+ do
+    case "$path" in
+    /*) ;;
+diff -Naur postfix-2.10.2/postfix-install postfix-2.10.2_patched/postfix-install
+--- postfix-2.10.2/postfix-install     2012-05-22 23:40:29.000000000 +0400
++++ postfix-2.10.2_patched/postfix-install     2013-11-19 21:12:20.694160734 +0400
+@@ -481,13 +481,13 @@
+      exit 1;;
+ esac
+-case "$manpage_directory" in
+- no) (echo $0: Error: the manpage_directory parameter no longer accepts 
+-     echo \"no\" values.  Try again with \"manpage_directory=/path/name\" 
+-     echo on the command line or execute \"make install\" and specify
+-     echo manpage_directory interactively.) | ${FMT} 1>&2
+-     exit 1;;
+-esac
++#case "$manpage_directory" in
++# no) (echo $0: Error: the manpage_directory parameter no longer accepts 
++#     echo \"no\" values.  Try again with \"manpage_directory=/path/name\" 
++#     echo on the command line or execute \"make install\" and specify
++#     echo manpage_directory interactively.) | ${FMT} 1>&2
++#     exit 1;;
++#esac
+ for path in "$html_directory" "$readme_directory"
+ do
+@@ -500,7 +500,7 @@
+ done
+ for path in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
+-    "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
++    "$sendmail_path" "$newaliases_path" "$mailq_path"
+ do
+    case "$path" in
+    /*) ;;
+@@ -680,8 +680,8 @@
+               compare_or_replace $mode "$owner" "$group" html/$file \
+                   $HTML_DIRECTORY/$file || exit 1;;
+       '$manpage_directory')
+-          check_parent $MANPAGE_DIRECTORY/$file || exit 1
+-          compare_or_replace $mode "$owner" "$group" man/$file \
++          test "$manpage_directory" = "no" || check_parent $MANPAGE_DIRECTORY/$file || exit 1
++          test "$manpage_directory" = "no" || compare_or_replace $mode "$owner" "$group" man/$file \
+               $MANPAGE_DIRECTORY/$file || exit 1;;
+       '$readme_directory')
+           test "$readme_directory" = "no" ||
diff --git a/mail/postfix/patches/300-bdb_hash_segfault.patch b/mail/postfix/patches/300-bdb_hash_segfault.patch
new file mode 100644 (file)
index 0000000..c7f0df0
--- /dev/null
@@ -0,0 +1,14 @@
+diff -Naur postfix-2.11.3/src/util/dict_db.c postfix-2.11.3_patched/src/util/dict_db.c
+--- postfix-2.11.3/src/util/dict_db.c  2012-01-25 04:41:08.000000000 +0400
++++ postfix-2.11.3_patched/src/util/dict_db.c  2014-11-01 12:36:44.287641712 +0300
+@@ -691,8 +691,8 @@
+       msg_panic("db_create null result");
+     if ((errno = db->set_cachesize(db, 0, dict_db_cache_size, 0)) != 0)
+       msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
+-    if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
+-      msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
++//    if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
++//    msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
+ #if DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
+     if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0)
+       FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags,
diff --git a/mail/postfix/patches/400-cdb.patch b/mail/postfix/patches/400-cdb.patch
new file mode 100644 (file)
index 0000000..cc04cd1
--- /dev/null
@@ -0,0 +1,14 @@
+diff -Naur postfix-2.11.1/src/util/sys_defs.h postfix-2.11.1.patched/src/util/sys_defs.h
+--- postfix-2.11.1/src/util/sys_defs.h 2013-09-30 00:51:55.000000000 +0400
++++ postfix-2.11.1.patched/src/util/sys_defs.h 2014-09-29 03:11:48.962277971 +0400
+@@ -767,9 +767,8 @@
+ #define INTERNAL_LOCK MYFLOCK_STYLE_FLOCK
+ #define DEF_MAILBOX_LOCK "fcntl, dotlock"     /* RedHat >= 4.x */
+ #define HAS_FSYNC
+-#define HAS_DB
+ #define NATIVE_DB_TYPE        "hash"
+-#define ALIAS_DB_MAP  DEF_DB_TYPE ":/etc/aliases"
++#define ALIAS_DB_MAP  DEF_DB_TYPE ":/etc/postfix/aliases"
+ #ifndef NO_NIS
+ #define HAS_NIS
+ #endif
diff --git a/mail/postfix/patches/500-crosscompile.patch b/mail/postfix/patches/500-crosscompile.patch
new file mode 100644 (file)
index 0000000..abd3f7d
--- /dev/null
@@ -0,0 +1,27 @@
+--- postfix-2.10.2/makedefs    2013-02-04 05:33:13.000000000 +0400
++++ postfix-2.10.2_patched/makedefs    2013-11-19 22:48:50.528560454 +0400
+@@ -107,9 +107,9 @@
+ case $# in
+  # Officially supported usage.
+- 0) SYSTEM=`(uname -s) 2>/dev/null`
+-    RELEASE=`(uname -r) 2>/dev/null`
+-    VERSION=`(uname -v) 2>/dev/null`
++ 0) SYSTEM="Linux"
++    RELEASE="3.10.18"
++    VERSION="OpenWRT"
+     case "$VERSION" in
+      dcosx*) SYSTEM=$VERSION;;
+     esac;;
+@@ -384,9 +384,9 @@
+               esac
+               for name in nsl resolv
+               do
+-                  for lib in /usr/lib64 /lib64 /usr/lib /usr/lib/* /lib /lib/*
++                  for lib in /usr/lib64 /usr/lib64/* /usr/lib /usr/lib/* /lib /lib/*
+                   do
+-                      test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
++                      test -e $PKG_BUILD_DIR/$lib/lib$name.a -o -e $PKG_BUILD_DIR/$lib/lib$name.so && {
+                           SYSLIBS="$SYSLIBS -l$name"
+                           break
+                       }
diff --git a/mail/postfix/patches/600-nopostconf.patch b/mail/postfix/patches/600-nopostconf.patch
new file mode 100644 (file)
index 0000000..78248c7
--- /dev/null
@@ -0,0 +1,40 @@
+diff -Naur postfix-2.11.1/postfix-install postfix-2.11.1.patched/postfix-install
+--- postfix-2.11.1/postfix-install     2014-10-05 20:43:58.598876904 +0400
++++ postfix-2.11.1.patched/postfix-install     2014-10-05 20:47:36.076700082 +0400
+@@ -729,21 +729,21 @@
+ # Postfix releases, and software should not suddenly be installed in
+ # the wrong place when Postfix is being upgraded.
+-bin/postconf -c $CONFIG_DIRECTORY -e \
+-    "daemon_directory = $daemon_directory" \
+-    "data_directory = $data_directory" \
+-    "command_directory = $command_directory" \
+-    "queue_directory = $queue_directory" \
+-    "mail_owner = $mail_owner" \
+-    "setgid_group = $setgid_group" \
+-    "sendmail_path = $sendmail_path" \
+-    "mailq_path = $mailq_path" \
+-    "newaliases_path = $newaliases_path" \
+-    "html_directory = $html_directory" \
+-    "manpage_directory = $manpage_directory" \
+-    "sample_directory = $sample_directory" \
+-    "readme_directory = $readme_directory" \
+-|| exit 1
++#bin/postconf -c $CONFIG_DIRECTORY -e \
++#    "daemon_directory = $daemon_directory" \
++#    "data_directory = $data_directory" \
++#    "command_directory = $command_directory" \
++#    "queue_directory = $queue_directory" \
++#    "mail_owner = $mail_owner" \
++#    "setgid_group = $setgid_group" \
++#    "sendmail_path = $sendmail_path" \
++#    "mailq_path = $mailq_path" \
++#    "newaliases_path = $newaliases_path" \
++#    "html_directory = $html_directory" \
++#    "manpage_directory = $manpage_directory" \
++#    "sample_directory = $sample_directory" \
++#    "readme_directory = $readme_directory" \
++#|| exit 1
+ # If Postfix is being installed locally from source code, do the
+ # post-install processing now.
diff --git a/mail/postfix/patches/700-defaultconfig.patch b/mail/postfix/patches/700-defaultconfig.patch
new file mode 100644 (file)
index 0000000..2f3dc3b
--- /dev/null
@@ -0,0 +1,93 @@
+diff -Naur postfix-2.11.1/conf/main.cf postfix-2.11.1.patched/conf/main.cf
+--- postfix-2.11.1/conf/main.cf        2013-12-24 18:57:25.000000000 +0400
++++ postfix-2.11.1.patched/conf/main.cf        2014-10-05 21:35:53.427534410 +0400
+@@ -21,43 +21,8 @@
+ #
+ #soft_bounce = no
+-# LOCAL PATHNAME INFORMATION
+-#
+-# The queue_directory specifies the location of the Postfix queue.
+-# This is also the root directory of Postfix daemons that run chrooted.
+-# See the files in examples/chroot-setup for setting up Postfix chroot
+-# environments on different UNIX systems.
+-#
+-queue_directory = /var/spool/postfix
+-
+-# The command_directory parameter specifies the location of all
+-# postXXX commands.
+-#
+-command_directory = /usr/sbin
+-
+-# The daemon_directory parameter specifies the location of all Postfix
+-# daemon programs (i.e. programs listed in the master.cf file). This
+-# directory must be owned by root.
+-#
+-daemon_directory = /usr/libexec/postfix
+-
+-# The data_directory parameter specifies the location of Postfix-writable
+-# data files (caches, random numbers). This directory must be owned
+-# by the mail_owner account (see below).
+-#
+-data_directory = /var/lib/postfix
+-
+ # QUEUE AND PROCESS OWNERSHIP
+ #
+-# The mail_owner parameter specifies the owner of the Postfix queue
+-# and of most Postfix daemon processes.  Specify the name of a user
+-# account THAT DOES NOT SHARE ITS USER OR GROUP ID WITH OTHER ACCOUNTS
+-# AND THAT OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM.  In
+-# particular, don't specify nobody or daemon. PLEASE USE A DEDICATED
+-# USER.
+-#
+-mail_owner = postfix
+-
+ # The default_privs parameter specifies the default rights used by
+ # the local delivery agent for delivery to external file or command.
+ # These rights are used in the absence of a recipient user context.
+@@ -613,45 +578,4 @@
+ #     -dmS $process_name gdb $daemon_directory/$process_name
+ #     $process_id & sleep 1
+-# INSTALL-TIME CONFIGURATION INFORMATION
+-#
+-# The following parameters are used when installing a new Postfix version.
+-# 
+-# sendmail_path: The full pathname of the Postfix sendmail command.
+-# This is the Sendmail-compatible mail posting interface.
+-# 
+-sendmail_path =
+-
+-# newaliases_path: The full pathname of the Postfix newaliases command.
+-# This is the Sendmail-compatible command to build alias databases.
+-#
+-newaliases_path =
+-
+-# mailq_path: The full pathname of the Postfix mailq command.  This
+-# is the Sendmail-compatible mail queue listing command.
+-# 
+-mailq_path =
+-
+-# setgid_group: The group for mail submission and queue management
+-# commands.  This must be a group name with a numerical group ID that
+-# is not shared with other accounts, not even with the Postfix account.
+-#
+-setgid_group =
+-
+-# html_directory: The location of the Postfix HTML documentation.
+-#
+-html_directory =
+-
+-# manpage_directory: The location of the Postfix on-line manual pages.
+-#
+-manpage_directory =
+-
+-# sample_directory: The location of the Postfix sample configuration files.
+-# This parameter is obsolete as of Postfix 2.1.
+-#
+-sample_directory =
+-
+-# readme_directory: The location of the Postfix README files.
+-#
+-readme_directory =
+ inet_protocols = ipv4
diff --git a/mail/postfix/patches/800-fmt.patch b/mail/postfix/patches/800-fmt.patch
new file mode 100644 (file)
index 0000000..7739e24
--- /dev/null
@@ -0,0 +1,12 @@
+diff -Naur postfix-2.11.1/conf/post-install postfix-2.11.1.patched/conf/post-install
+--- postfix-2.11.1/conf/post-install   2014-10-05 20:43:58.597876946 +0400
++++ postfix-2.11.1.patched/conf/post-install   2014-10-11 16:28:01.258874097 +0400
+@@ -310,7 +310,7 @@
+ case `uname -s` in
+ HP-UX*) FMT=cat;;
+ SunOS*) FMT=fake_fmt;;
+-     *) FMT=fmt;;
++     *) FMT="xargs echo";;
+ esac
+ # If a parameter is not set via the command line or environment,
diff --git a/mail/ssmtp/Makefile b/mail/ssmtp/Makefile
new file mode 100644 (file)
index 0000000..3d24394
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ssmtp
+PKG_VERSION:=2.64
+PKG_RELEASE:=1.1
+PKG_MAINTAINER:=Dirk Brenken <dibdot@gmail.com>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.bz2
+PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/s/ssmtp
+PKG_MD5SUM:=65b4e0df4934a6cd08c506cabcbe584f
+
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_CFLAGS += $(TARGET_CPPFLAGS)
+
+define Package/ssmtp
+  SECTION:=mail
+  CATEGORY:=Mail
+  DEPENDS:=+libopenssl
+  TITLE:=A minimal and secure mail sender with ssl support
+  URL:=http://packages.debian.org/ssmtp
+endef
+
+define Package/ssmtp/description
+ A secure, effective and simple way of getting mail off a system to your
+ mail hub. It contains no suid-binaries or other dangerous things - no
+ mail spool to poke around in, and no daemons running in the background.
+ Mail is simply forwarded to the configured mailhost. Extremely easy
+ configuration.
+endef
+
+define Package/ssmtp/conffiles
+/etc/ssmtp/ssmtp.conf
+/etc/ssmtp/revaliases
+endef
+
+CONFIGURE_VARS += \
+       LIBS="$(TARGET_LDFLAGS) -lcrypto -lssl"
+
+CONFIGURE_ARGS += \
+       --enable-ssl
+
+define Package/ssmtp/install
+       $(INSTALL_DIR) $(1)/etc/ssmtp
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/ssmtp.conf $(1)/etc/ssmtp/
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/revaliases $(1)/etc/ssmtp/
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/ssmtp $(1)/usr/sbin/
+endef
+
+define Package/ssmtp/postinst
+#!/bin/sh
+ln -sf ssmtp $${IPKG_INSTROOT}/usr/sbin/sendmail
+endef
+
+$(eval $(call BuildPackage,ssmtp))
diff --git a/mail/ssmtp/patches/002-fix_pointer.patch b/mail/ssmtp/patches/002-fix_pointer.patch
new file mode 100644 (file)
index 0000000..f22e3d6
--- /dev/null
@@ -0,0 +1,466 @@
+--- a/ssmtp.c
++++ b/ssmtp.c
+@@ -55,21 +55,21 @@ bool_t use_oldauth = False;                /* use old
+ #define ARPADATE_LENGTH 32            /* Current date in RFC format */
+ char arpadate[ARPADATE_LENGTH];
+-char *auth_user = (char)NULL;
+-char *auth_pass = (char)NULL;
+-char *auth_method = (char)NULL;               /* Mechanism for SMTP authentication */
+-char *mail_domain = (char)NULL;
+-char *from = (char)NULL;              /* Use this as the From: address */
++char *auth_user = NULL;
++char *auth_pass = NULL;
++char *auth_method = NULL;             /* Mechanism for SMTP authentication */
++char *mail_domain = NULL;
++char *from = NULL;            /* Use this as the From: address */
+ char *hostname;
+ char *mailhost = "mailhub";
+-char *minus_f = (char)NULL;
+-char *minus_F = (char)NULL;
++char *minus_f = NULL;
++char *minus_F = NULL;
+ char *gecos;
+-char *prog = (char)NULL;
++char *prog = NULL;
+ char *root = NULL;
+ char *tls_cert = "/etc/ssl/certs/ssmtp.pem";  /* Default Certificate */
+-char *uad = (char)NULL;
+-char *config_file = (char)NULL;               /* alternate configuration file */
++char *uad = NULL;
++char *config_file = NULL;             /* alternate configuration file */
+ headers_t headers, *ht;
+@@ -261,7 +261,7 @@ char *strip_post_ws(char *str)
+       p = (str + strlen(str));
+       while(isspace(*--p)) {
+-              *p = (char)NULL;
++              *p = '\0';
+       }
+       return(p);
+@@ -279,7 +279,7 @@ char *addr_parse(char *str)
+ #endif
+       /* Simple case with email address enclosed in <> */
+-      if((p = strdup(str)) == (char *)NULL) {
++      if((p = strdup(str)) == NULL) {
+               die("addr_parse(): strdup()");
+       }
+@@ -287,7 +287,7 @@ char *addr_parse(char *str)
+               q++;
+               if((p = strchr(q, '>'))) {
+-                      *p = (char)NULL;
++                      *p = '\0';
+               }
+ #if 0
+@@ -310,7 +310,7 @@ char *addr_parse(char *str)
+       q = strip_post_ws(p);
+       if(*q == ')') {
+               while((*--q != '('));
+-              *q = (char)NULL;
++              *q = '\0';
+       }
+       (void)strip_post_ws(p);
+@@ -349,7 +349,6 @@ standardise() -- Trim off '\n's and doub
+ */
+ bool_t standardise(char *str, bool_t *linestart)
+ {
+-      size_t sl;
+       char *p;
+       bool_t leadingdot = False;
+@@ -363,7 +362,7 @@ bool_t standardise(char *str, bool_t *li
+       *linestart = False;
+       if((p = strchr(str, '\n'))) {
+-              *p = (char)NULL;
++              *p = '\0';
+               *linestart = True;
+       }
+       return(leadingdot);
+@@ -384,7 +383,7 @@ void revaliases(struct passwd *pw)
+               while(fgets(buf, sizeof(buf), fp)) {
+                       /* Make comments invisible */
+                       if((p = strchr(buf, '#'))) {
+-                              *p = (char)NULL;
++                              *p = '\0';
+                       }
+                       /* Ignore malformed lines and comments */
+@@ -519,11 +518,11 @@ void rcpt_save(char *str)
+ #endif
+       /* Ignore missing usernames */
+-      if(*str == (char)NULL) {
++      if(*str == '\0') {
+               return;
+       }
+-      if((rt->string = strdup(str)) == (char *)NULL) {
++      if((rt->string = strdup(str)) == NULL) {
+               die("rcpt_save() -- strdup() failed");
+       }
+@@ -548,7 +547,7 @@ void rcpt_parse(char *str)
+       (void)fprintf(stderr, "*** rcpt_parse(): str = [%s]\n", str);
+ #endif
+-      if((p = strdup(str)) == (char *)NULL) {
++      if((p = strdup(str)) == NULL) {
+               die("rcpt_parse(): strdup() failed");
+       }
+       q = p;
+@@ -576,7 +575,7 @@ void rcpt_parse(char *str)
+               }
+               /* End of string? */
+-              if(*(q + 1) == (char)NULL) {
++              if(*(q + 1) == '\0') {
+                       got_addr = True;
+               }
+@@ -584,7 +583,7 @@ void rcpt_parse(char *str)
+               if((*q == ',') && (in_quotes == False)) {
+                       got_addr = True;
+-                      *q = (char)NULL;
++                      *q = '\0';
+               }
+               if(got_addr) {
+@@ -668,7 +667,7 @@ void header_save(char *str)
+       (void)fprintf(stderr, "header_save(): str = [%s]\n", str);
+ #endif
+-      if((p = strdup(str)) == (char *)NULL) {
++      if((p = strdup(str)) == NULL) {
+               die("header_save() -- strdup() failed");
+       }
+       ht->string = p;
+@@ -676,7 +675,7 @@ void header_save(char *str)
+       if(strncasecmp(ht->string, "From:", 5) == 0) {
+ #if 1
+               /* Hack check for NULL From: line */
+-              if(*(p + 6) == (char)NULL) {
++              if(*(p + 6) == '\0') {
+                       return;
+               }
+ #endif
+@@ -739,19 +738,19 @@ header_parse() -- Break headers into sep
+ void header_parse(FILE *stream)
+ {
+       size_t size = BUF_SZ, len = 0;
+-      char *p = (char *)NULL, *q;
++      char *p = NULL, *q;
+       bool_t in_header = True;
+-      char l = (char)NULL;
++      char l = '\0';
+       int c;
+       while(in_header && ((c = fgetc(stream)) != EOF)) {
+               /* Must have space for up to two more characters, since we
+                       may need to insert a '\r' */
+-              if((p == (char *)NULL) || (len >= (size - 1))) {
++              if((p == NULL) || (len >= (size - 1))) {
+                       size += BUF_SZ;
+                       p = (char *)realloc(p, (size * sizeof(char)));
+-                      if(p == (char *)NULL) {
++                      if(p == NULL) {
+                               die("header_parse() -- realloc() failed");
+                       }
+                       q = (p + len);
+@@ -776,9 +775,9 @@ void header_parse(FILE *stream)
+                                               in_header = False;
+                               default:
+-                                              *q = (char)NULL;
++                                              *q = '\0';
+                                               if((q = strrchr(p, '\n'))) {
+-                                                      *q = (char)NULL;
++                                                      *q = '\0';
+                                               }
+                                               header_save(p);
+@@ -809,9 +808,9 @@ void header_parse(FILE *stream)
+                                               in_header = False;
+                               default:
+-                                              *q = (char)NULL;
++                                              *q = '\0';
+                                               if((q = strrchr(p, '\n'))) {
+-                                                      *q = (char)NULL;
++                                                      *q = '\0';
+                                               }
+                                               header_save(p);
+@@ -876,11 +875,11 @@ bool_t read_config()
+               char *rightside;
+               /* Make comments invisible */
+               if((p = strchr(buf, '#'))) {
+-                      *p = (char)NULL;
++                      *p = '\0';
+               }
+               /* Ignore malformed lines and comments */
+-              if(strchr(buf, '=') == (char *)NULL) continue;
++              if(strchr(buf, '=') == NULL) continue;
+               /* Parse out keywords */
+               p=firsttok(&begin, "= \t\n");
+@@ -890,7 +889,7 @@ bool_t read_config()
+               }
+               if(p && q) {
+                       if(strcasecmp(p, "Root") == 0) {
+-                              if((root = strdup(q)) == (char *)NULL) {
++                              if((root = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -904,7 +903,7 @@ bool_t read_config()
+                                       port = atoi(r);
+                               }
+-                              if((mailhost = strdup(q)) == (char *)NULL) {
++                              if((mailhost = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -949,7 +948,7 @@ bool_t read_config()
+                                       mail_domain = strdup(q);
+                               }
+-                              if(mail_domain == (char *)NULL) {
++                              if(mail_domain == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+                               rewrite_domain = True;
+@@ -1025,7 +1024,7 @@ bool_t read_config()
+                               }
+                       }
+                       else if(strcasecmp(p, "TLSCert") == 0) {
+-                              if((tls_cert = strdup(q)) == (char *)NULL) {
++                              if((tls_cert = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -1036,7 +1035,7 @@ bool_t read_config()
+ #endif
+                       /* Command-line overrides these */
+                       else if(strcasecmp(p, "AuthUser") == 0 && !auth_user) {
+-                              if((auth_user = strdup(q)) == (char *)NULL) {
++                              if((auth_user = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -1045,7 +1044,7 @@ bool_t read_config()
+                               }
+                       }
+                       else if(strcasecmp(p, "AuthPass") == 0 && !auth_pass) {
+-                              if((auth_pass = strdup(q)) == (char *)NULL) {
++                              if((auth_pass = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -1054,7 +1053,7 @@ bool_t read_config()
+                               }
+                       }
+                       else if(strcasecmp(p, "AuthMethod") == 0 && !auth_method) {
+-                              if((auth_method = strdup(q)) == (char *)NULL) {
++                              if((auth_method = strdup(q)) == NULL) {
+                                       die("parse_config() -- strdup() failed");
+                               }
+@@ -1119,14 +1118,11 @@ int smtp_open(char *host, int port)
+       char buf[(BUF_SZ + 1)];
+       /* Init SSL stuff */
+-      SSL_CTX *ctx;
+-      SSL_METHOD *meth;
++      SSL_CTX *ctx = NULL;
+       X509 *server_cert;
+-
+       SSL_load_error_strings();
+       SSLeay_add_ssl_algorithms();
+-      meth=SSLv23_client_method();
+-      ctx = SSL_CTX_new(meth);
++      ctx = SSL_CTX_new(SSLv23_client_method());
+       if(!ctx) {
+               log_event(LOG_ERR, "No SSL support initiated\n");
+               return(-1);
+@@ -1310,7 +1306,7 @@ char *fd_gets(char *buf, int size, int f
+                       buf[i++] = c;
+               }
+       }
+-      buf[i] = (char)NULL;
++      buf[i] = '\0';
+       return(buf);
+ }
+@@ -1434,14 +1430,14 @@ int ssmtp(char *argv[])
+       }
+       if((p = strtok(pw->pw_gecos, ";,"))) {
+-              if((gecos = strdup(p)) == (char *)NULL) {
++              if((gecos = strdup(p)) == NULL) {
+                       die("ssmtp() -- strdup() failed");
+               }
+       }
+       revaliases(pw);
+       /* revaliases() may have defined this */
+-      if(uad == (char *)NULL) {
++      if(uad == NULL) {
+               uad = append_domain(pw->pw_name);
+       }
+@@ -1489,7 +1485,7 @@ int ssmtp(char *argv[])
+       /* Try to log in if username was supplied */
+       if(auth_user) {
+ #ifdef MD5AUTH
+-              if(auth_pass == (char *)NULL) {
++              if(auth_pass == NULL) {
+                       auth_pass = strdup("");
+               }
+@@ -1508,7 +1504,7 @@ int ssmtp(char *argv[])
+               else {
+ #endif
+               memset(buf, 0, bufsize);
+-              to64frombits(buf, auth_user, strlen(auth_user));
++              to64frombits(buf, (unsigned char *)auth_user, strlen(auth_user));
+               if (use_oldauth) {
+                       outbytes += smtp_write(sock, "AUTH LOGIN %s", buf);
+               }
+@@ -1520,7 +1516,7 @@ int ssmtp(char *argv[])
+                       }
+                       /* we assume server asked us for Username */
+                       memset(buf, 0, bufsize);
+-                      to64frombits(buf, auth_user, strlen(auth_user));
++                      to64frombits(buf, (unsigned char *)auth_user, strlen(auth_user));
+                       outbytes += smtp_write(sock, buf);
+               }
+@@ -1530,7 +1526,7 @@ int ssmtp(char *argv[])
+               }
+               memset(buf, 0, bufsize);
+-              to64frombits(buf, auth_pass, strlen(auth_pass));
++              to64frombits(buf, (unsigned char *)auth_pass, strlen(auth_pass));
+ #ifdef MD5AUTH
+               }
+ #endif
+@@ -1737,7 +1733,7 @@ char **parse_options(int argc, char *arg
+               j = 0;
+               add = 1;
+-              while(argv[i][++j] != (char)NULL) {
++              while(argv[i][++j] != '\0') {
+                       switch(argv[i][j]) {
+ #ifdef INET6
+                       case '6':
+@@ -1755,14 +1751,14 @@ char **parse_options(int argc, char *arg
+                                       if((!argv[i][(j + 1)])
+                                               && argv[(i + 1)]) {
+                                               auth_user = strdup(argv[i+1]);
+-                                              if(auth_user == (char *)NULL) {
++                                              if(auth_user == NULL) {
+                                                       die("parse_options() -- strdup() failed");
+                                               }
+                                               add++;
+                                       }
+                                       else {
+                                               auth_user = strdup(argv[i]+j+1);
+-                                              if(auth_user == (char *)NULL) {
++                                              if(auth_user == NULL) {
+                                                       die("parse_options() -- strdup() failed");
+                                               }
+                                       }
+@@ -1772,14 +1768,14 @@ char **parse_options(int argc, char *arg
+                                       if((!argv[i][(j + 1)])
+                                               && argv[(i + 1)]) {
+                                               auth_pass = strdup(argv[i+1]);
+-                                              if(auth_pass == (char *)NULL) {
++                                              if(auth_pass == NULL) {
+                                                       die("parse_options() -- strdup() failed");
+                                               }
+                                               add++;
+                                       }
+                                       else {
+                                               auth_pass = strdup(argv[i]+j+1);
+-                                              if(auth_pass == (char *)NULL) {
++                                              if(auth_pass == NULL) {
+                                                       die("parse_options() -- strdup() failed");
+                                               }
+                                       }
+@@ -1870,14 +1866,14 @@ char **parse_options(int argc, char *arg
+                       case 'F':
+                               if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
+                                       minus_F = strdup(argv[(i + 1)]);
+-                                      if(minus_F == (char *)NULL) {
++                                      if(minus_F == NULL) {
+                                               die("parse_options() -- strdup() failed");
+                                       }
+                                       add++;
+                               }
+                               else {
+                                       minus_F = strdup(argv[i]+j+1);
+-                                      if(minus_F == (char *)NULL) {
++                                      if(minus_F == NULL) {
+                                               die("parse_options() -- strdup() failed");
+                                       }
+                               }
+@@ -1889,14 +1885,14 @@ char **parse_options(int argc, char *arg
+                       case 'r':
+                               if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
+                                       minus_f = strdup(argv[(i + 1)]);
+-                                      if(minus_f == (char *)NULL) {
++                                      if(minus_f == NULL) {
+                                               die("parse_options() -- strdup() failed");
+                                       }
+                                       add++;
+                               }
+                               else {
+                                       minus_f = strdup(argv[i]+j+1);
+-                                      if(minus_f == (char *)NULL) {
++                                      if(minus_f == NULL) {
+                                               die("parse_options() -- strdup() failed");
+                                       }
+                               }
+--- a/base64.c
++++ b/base64.c
+@@ -31,7 +31,7 @@ static const char base64val[] = {
+ };
+ #define DECODE64(c)  (isascii(c) ? base64val[c] : BAD)
+-void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
++void to64frombits(char *out, const unsigned char *in, int inlen)
+ /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
+ {
+     for (; inlen >= 3; inlen -= 3)
+@@ -57,7 +57,7 @@ void to64frombits(unsigned char *out, co
+     *out = '\0';
+ }
+-int from64tobits(char *out, const char *in)
++int from64tobits(unsigned char *out, const char *in)
+ /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
+ {
+     int len = 0;
+--- a/ssmtp.h
++++ b/ssmtp.h
+@@ -41,5 +41,5 @@ typedef struct string_list rcpt_t;
+ void get_arpadate(char *);
+ /* base64.c */
+-void to64frombits(unsigned char *, const unsigned char *, int);
+-int from64tobits(char *, const char *);
++void to64frombits(char *, const unsigned char *, int);
++int from64tobits(unsigned char *, const char *);
index 3e6e2091d2974c7698f2d234f2f4007cf1235de4..c014987781555297ae27fddbcfdc31cc13508e4c 100644 (file)
@@ -60,6 +60,7 @@ config FFMPEG_CUSTOM_AUDIO_DEC_SUPPORT
        select FFMPEG_CUSTOM_DECODER_ape
        select FFMPEG_CUSTOM_DECODER_atrac3
        select FFMPEG_CUSTOM_DECODER_flac
+       select FFMPEG_CUSTOM_SELECT_libopus
        select FFMPEG_CUSTOM_DECODER_mp2
        select FFMPEG_CUSTOM_DECODER_mp3
        select FFMPEG_CUSTOM_DECODER_mpc7
@@ -108,6 +109,9 @@ config FFMPEG_CUSTOM_AUDIO_DEC_SUPPORT
 
 comment "External Libraries ---"
 
+config FFMPEG_CUSTOM_SELECT_libopus
+       bool "Opus"
+
 config FFMPEG_CUSTOM_SELECT_speex
        bool "Speex"
 
index 3923cc820684bd07bcafa7d6896b8ab597455d7d..7a3cf76b77b1c00de7b6d497812a7227080f30e5 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ffmpeg
-PKG_VERSION:=2.3.3
+PKG_VERSION:=2.4.5
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://ffmpeg.org/releases/
-PKG_MD5SUM:=72361d3b8717b6db3ad2b9da8df7af5e
+PKG_MD5SUM:=685362fc14d2c28568a5d36b3760795a
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=LGPL-2.1+ GPL-2+ LGPL-3
@@ -289,7 +289,7 @@ endef
 define Package/libffmpeg-custom
 $(call Package/libffmpeg/Default)
  TITLE+= (custom)
- DEPENDS+= @DEVEL +libspeex
+ DEPENDS+= @DEVEL @!ALL +libopus +libspeex
  VARIANT:=custom
  MENU:=1
 endef
@@ -308,7 +308,7 @@ endef
 define Package/libffmpeg-audio-dec
 $(call Package/libffmpeg/Default)
  TITLE+= (audio)
- DEPENDS+= @DEVEL +libspeex
+ DEPENDS+= @DEVEL +libopus +libspeex
  VARIANT:=audio-dec
 endef
 
@@ -399,6 +399,10 @@ FFMPEG_CONFIGURE:= \
        --disable-vdpau \
        --disable-outdevs
 
+ifeq ($(CONFIG_CPU_TYPE),"mips32")
+       FFMPEG_CONFIGURE +=--disable-mips32r2
+endif
+
 ifeq ($(BUILD_VARIANT),custom)
 
   FFMPEG_ENABLE= \
@@ -428,6 +432,12 @@ ifeq ($(CONFIG_FFMPEG_CUSTOM_SELECT_adpcm),y)
 
 endif
 
+ifeq ($(CONFIG_FFMPEG_CUSTOM_SELECT_libopus),y)
+  FFMPEG_CONFIGURE+= \
+       --enable-libopus --enable-decoder=libopus \
+
+endif
+
 ifeq ($(CONFIG_FFMPEG_CUSTOM_SELECT_speex),y)
   FFMPEG_CONFIGURE+= \
        --enable-libspeex --enable-decoder=libspeex \
@@ -454,6 +464,7 @@ ifeq ($(BUILD_VARIANT),audio-dec)
        $(call FFMPEG_ENABLE,demuxer,$(FFMPEG_AUDIO_DEMUXERS)) \
        $(call FFMPEG_ENABLE,parser,$(FFMPEG_AUDIO_PARSERS)) \
        $(call FFMPEG_ENABLE,protocol,$(FFMPEG_AUDIO_PROTOCOLS)) \
+       --enable-libopus --enable-decoder=libopus \
        --enable-libspeex --enable-decoder=libspeex \
        --disable-decoder=pcm_bluray,pcm_dvd \
 
diff --git a/multimedia/ffmpeg/patches/010-remove_unused_fminf_definition.patch b/multimedia/ffmpeg/patches/010-remove_unused_fminf_definition.patch
deleted file mode 100644 (file)
index 7dc0c27..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavutil/libm.h
-+++ b/libavutil/libm.h
-@@ -82,6 +82,7 @@ static av_always_inline float cbrtf(floa
- #define exp2f(x) ((float)exp2(x))
- #endif /* HAVE_EXP2F */
-+/* ---------- BROKEN: Defined in math.h but not present in uClibc 0.9.33.2 
- #if !HAVE_FMINF
- #undef fminf
- static av_always_inline av_const float fminf(float x, float y)
-@@ -91,6 +92,7 @@ static av_always_inline av_const float f
-     return x > y ? y : (x == x ? x : y);
- }
- #endif
-+------------------------------------------------------------------------- */
- #if !HAVE_ISINF
- static av_always_inline av_const int isinf(float x)
index edb46be6806c40dc74fc569bd0f970071dcb4caa..5a5f3b52cb0080b1c1a04f30f473e012079f7833 100644 (file)
@@ -17,7 +17,7 @@ PKG_SOURCE_URL:=http://www.firestorm.cx/fswebcam/files \
 PKG_MD5SUM:=1bfdb21904e816f100370ec8f4df986b
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=LICENCE
+PKG_LICENSE_FILES:=LICENCE
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_INSTALL:=1
index a4721ef9c47807ad73527c1dfdf1c892d3259f32..81ce237b34ac3f8176e669b0aa42f135eec52382 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gst1-libav
-PKG_VERSION:=1.2.3
+PKG_VERSION:=1.4.4
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_SOURCE:=gst-libav-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-libav
-PKG_MD5SUM:=58c7998a054d8d8ca041fa35738f72b6
+PKG_MD5SUM:=64a3e2cda2687132cadca4efdc63f3b4
 
 PKG_LICENSE:=GPL-2.0 LGPL-2.0
-PKG_LICENSE_FILE:=COPYING COPYING.LIB
+PKG_LICENSE_FILES:=COPYING COPYING.LIB
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gst-libav-$(PKG_VERSION)
 
@@ -109,7 +109,7 @@ PKG_CONFIG_DEPENDS:= \
        $(patsubst %,CONFIG_GST1_LIBAV_PARSER_%,$(LIBAV_PARSERS)) \
        $(patsubst %,CONFIG_GST1_LIBAV_PROTOCOL_%,$(LIBAV_PROTOCOLS))
 
-PKG_BUILD_DEPENDS:= libstreamer1 gstreamer1-plugins-base
+PKG_BUILD_DEPENDS:= libgstreamer1 gstreamer1-plugins-base
 
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/nls.mk
@@ -148,6 +148,7 @@ CONFIGURE_ARGS += \
        --without-system-libav \
        --with-libav-extra-configure="--target-os=linux \
        --disable-bsfs \
+       --disable-programs \
        --disable-devices \
        --disable-encoders \
        $(LIBAV_CONFIGURE_ENCODERS) \
@@ -161,6 +162,26 @@ CONFIGURE_ARGS += \
        $(LIBAV_CONFIGURE_PARSERS) \
        --disable-protocols \
        $(LIBAV_CONFIGURE_PROTOCOLS) \
+       --disable-asm \
+       --disable-altivec \
+       --disable-amd3dnow \
+       --disable-amd3dnowext \
+       --disable-mmx \
+       --disable-mmxext \
+       --disable-sse \
+       --disable-sse2 \
+       --disable-sse3 \
+       --disable-ssse3 \
+       --disable-sse4 \
+       --disable-sse42 \
+       --disable-avx \
+       --disable-xop \
+       --disable-fma3 \
+       --disable-fma4 \
+       --disable-avx2 \
+       --disable-vfp \
+       --disable-neon \
+       --disable-inline-asm \
        --disable-yasm"
 
 # XXX: trick to force use of embedded Libav headers
index c3b88aa720c97d9bb6a5afd46f99311080731650..105f127e953453441d81b2c509ac23e29c39a409 100644 (file)
@@ -8,18 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gst1-plugins-bad
-PKG_VERSION:=1.2.3
-PKG_RELEASE:=3
+PKG_VERSION:=1.4.4
+PKG_RELEASE:=4
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2 GPLv2
-PKG_LICENSE_FILE:=COPYING.LIB COPYING
+PKG_LICENSE_FILES:=COPYING.LIB COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-bad-$(PKG_VERSION)
 PKG_SOURCE:=gst-plugins-bad-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-bad/
-PKG_MD5SUM:=cfd6f303c8df2740b27cc63b945decef
+PKG_MD5SUM:=972c6e22dd2e44fcf0b04b9d810a56be
 
 PKG_BUILD_DEPENDS:= libgstreamer1 gstreamer1-plugins-base liboil
 
@@ -161,6 +161,7 @@ CONFIGURE_ARGS += \
        --disable-schro \
        --disable-zbar \
        --disable-vp8 \
+       --disable-srtp \
        \
        --without-libiconv-prefix \
        --without-libintl-prefix \
@@ -277,6 +278,7 @@ $(eval $(call GstBuildPlugin,segmentclip,segmentclip support,audio,,))
 $(eval $(call GstBuildPlugin,siren,siren support,audio rtp,,))
 $(eval $(call GstBuildPlugin,speed,speed support,audio,,))
 $(eval $(call GstBuildPlugin,subenc,subenc support,controller,,))
+#$(eval $(call GstBuildPlugin,srtp,srtp support,rtp,,+libsrtp))
 
 $(eval $(call BuildPackage,gstreamer1-plugins-bad))
 $(eval $(call BuildPackage,gst1-plugins-bad))
index 0ca6a8bf81019281f27c5548dad7c698d607bd46..73b2ce16a9ee131b344c4228431e2fb3ea385161 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2008-2014 OpenWrt.org
+# Copyright (C) 2008-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,18 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gst1-plugins-base
-PKG_VERSION:=1.2.3
-PKG_RELEASE:=2
+PKG_VERSION:=1.4.4
+PKG_RELEASE:=3
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2 GPLv2
-PKG_LICENSE_FILE:=COPYING.LIB COPYING
+PKG_LICENSE_FILES:=COPYING.LIB COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-base-$(PKG_VERSION)
 PKG_SOURCE:=gst-plugins-base-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-base/
-PKG_MD5SUM:=17aeabfbcd232526f50c9bee375f1b97
+PKG_MD5SUM:=0c42eca8f9e4efd56d2ce8e9249ce4a1
 
 PKG_BUILD_DEPENDS:= libgstreamer1 liboil
 PKG_CONFIG_DEPENDS:= \
@@ -33,6 +33,7 @@ PKG_CONFIG_DEPENDS:= \
        CONFIG_PACKAGE_gst1-mod-ogg \
        CONFIG_PACKAGE_gst1-mod-tcp \
        CONFIG_PACKAGE_gst1-mod-theora \
+       CONFIG_PACKAGE_gst1-mod-videoconvert \
        CONFIG_PACKAGE_gst1-mod-videotestsrc \
        CONFIG_PACKAGE_gst1-mod-volume \
        CONFIG_PACKAGE_gst1-mod-vorbis \
@@ -118,31 +119,26 @@ CONFIGURE_ARGS += \
        --disable-examples \
        \
        $(call GST_COND_SELECT,alsa) \
-       --disable-alsa-test \
        $(call GST_COND_SELECT,app) \
        $(call GST_COND_SELECT,audioconvert) \
        $(call GST_COND_SELECT,audiorate) \
        $(call GST_COND_SELECT,audioresample) \
        $(call GST_COND_SELECT,audiotestsrc) \
        --disable-cdparanoia \
-       --disable-ffmpegcolorspace \
        --disable-freetypetest \
        $(call GST_COND_SELECT,gio) \
-       --disable-gnome_vfs \
-       --disable-gst_v4l \
        --disable-libvisual \
        $(call GST_COND_SELECT,ogg) \
-       --disable-oggtest \
        --disable-pango \
        --disable-subparse \
        $(call GST_COND_SELECT,tcp) \
        $(call GST_COND_SELECT,theora) \
        --disable-videorate \
        --disable-videoscale \
+       $(call GST_COND_SELECT,videoconvert) \
        $(call GST_COND_SELECT,videotestsrc) \
        $(call GST_COND_SELECT,volume) \
        $(call GST_COND_SELECT,vorbis) \
-       --disable-vorbistest \
        --disable-x \
        --disable-xshm \
        --disable-xvideo \
@@ -157,7 +153,6 @@ EXTRA_LDFLAGS+= \
        -Wl,-rpath-link=$(STAGING_DIR)/usr/lib \
        $(if $(ICONV_FULL),-liconv) \
 
-
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include/gstreamer-$(GST_VERSION)
        ( cd $(PKG_INSTALL_DIR); $(CP) \
@@ -183,9 +178,12 @@ endef
 
 
 define Package/gst1-plugins-base/install
-       /bin/true
+  true
 endef
 
+define Package/gstreamer1-plugins-base/install
+  true
+endef
 
 # 1: short name
 # 2: description
@@ -221,6 +219,7 @@ define GstBuildLibrary
   $$(eval $$(call BuildPackage,libgst1$(1)))
 endef
 
+$(eval $(call GstBuildLibrary,allocators,allocators,,))
 $(eval $(call GstBuildLibrary,app,app,,))
 $(eval $(call GstBuildLibrary,audio,audio,tag,))
 $(eval $(call GstBuildLibrary,fft,FFT,,))
@@ -279,6 +278,7 @@ $(eval $(call GstBuildPlugin,ogg,Ogg,riff tag pbutils video,,+libogg))
 $(eval $(call GstBuildPlugin,tcp,TCP,,,))
 $(eval $(call GstBuildPlugin,theora,Theora,tag video,,+libogg +libtheora))
 $(eval $(call GstBuildPlugin,typefindfunctions,'typefind' functions,audio pbutils tag video,,))
+$(eval $(call GstBuildPlugin,videoconvert,video format conversion,video,,))
 $(eval $(call GstBuildPlugin,videotestsrc,video test,video,,+liboil))
 $(eval $(call GstBuildPlugin,volume,volume,audio controller,,+liboil))
 $(eval $(call GstBuildPlugin,vorbis,Vorbis,audio tag,ogg,+libvorbis))
index 082e736efb06b24dfbec80bac30001008e4b0883..bffabb31477d8476b09f874f496f8fa6acf0ccfd 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2009-2014 OpenWrt.org
+# Copyright (C) 2009-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,18 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gst1-plugins-good
-PKG_VERSION:=1.2.3
+PKG_VERSION:=1.4.4
 PKG_RELEASE:=2
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-good-$(PKG_VERSION)
 PKG_SOURCE:=gst-plugins-good-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-good/
-PKG_MD5SUM:=1a1f96bc27ad446e559474299160a9a8
+PKG_MD5SUM:=673cf9276952bd3937dafd817c9ead2b
 
 PKG_BUILD_DEPENDS:= libgstreamer1 gstreamer1-plugins-base liboil
 
@@ -102,7 +102,6 @@ CONFIGURE_ARGS += \
        --disable-gconf \
        --disable-gconftool \
        --disable-gdk_pixbuf \
-       --disable-gst_v4l2 \
        --disable-hal \
        --disable-libcaca \
        --disable-libdv \
@@ -222,12 +221,12 @@ $(eval $(call GstBuildPlugin,spectrum,spectrum data output,audio fft,,))
 #$(eval $(call GstBuildPlugin,sty4menc,sty4menc support,video,,))
 #$(eval $(call GstBuildPlugin,taglib,taglib support,tag,,))
 $(eval $(call GstBuildPlugin,udp,UDP,net,,))
-#$(eval $(call GstBuildPlugin,video4linux2,video4linux2 support,video,,))
+$(eval $(call GstBuildPlugin,video4linux2,video4linux2 support,video allocators,,+libv4l))
 $(eval $(call GstBuildPlugin,videobox,videobox support,video,,))
 $(eval $(call GstBuildPlugin,videocrop,videocrop support,video,,))
 $(eval $(call GstBuildPlugin,videofilter,videofilter support,video,,))
 $(eval $(call GstBuildPlugin,videomixer,videomixer support,video,,))
-#$(eval $(call GstBuildPlugin,vpx,vpx support,tag video,,))
+$(eval $(call GstBuildPlugin,vpx,vpx support,tag video,,+libvpx))
 $(eval $(call GstBuildPlugin,wavenc,Wav encoder,riff,,))
 #$(eval $(call GstBuildPlugin,wavpack,Wav packer,audio riff tag,,))
 $(eval $(call GstBuildPlugin,wavparse,Wav parser,audio riff tag,,))
index da574e0b464d474613bb612a788692ed40009cde..b8ed67080fe6eff3fb5d959ae4ec4abd7e799177 100644 (file)
@@ -8,18 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gst1-plugins-ugly
-PKG_VERSION:=1.2.3
-PKG_RELEASE:=2
+PKG_VERSION:=1.4.4
+PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-ugly-$(PKG_VERSION)
 PKG_SOURCE:=gst-plugins-ugly-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-ugly/
-PKG_MD5SUM:=7ae60e2f759f58f32af5fcdc3c9193c4
+PKG_MD5SUM:=abd832c5cab1a37fb1d9d15fb08e6e59
 
 PKG_BUILD_DEPENDS:= libgstreamer1 gstreamer1-plugins-base liboil
 PKG_CONFIG_DEPENDS:= \
index 7beec17480eb613854d1f7b1a971476602d346cf..a73cc1d85f944fff0c817647c3b41df293088454 100644 (file)
@@ -8,18 +8,18 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gstreamer1
-PKG_VERSION:=1.2.3
+PKG_VERSION:=1.4.4
 PKG_RELEASE:=2
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=LGPLv2
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/gstreamer-$(PKG_VERSION)
 PKG_SOURCE:=gstreamer-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gstreamer/
-PKG_MD5SUM:=8155b9c7574ccaa361cc504e8e0e72dc
+PKG_MD5SUM:=98f4a6d45a28dd195144baef0244ba38
 
 PKG_FIXUP:=autoreconf
 PKG_REMOVE_FILES:=autogen.sh aclocal.m4
@@ -161,6 +161,7 @@ define Package/gstreamer1/install
 endef
 
 define Package/gstreamer1-libs/install
+  true
 endef
 
 define Package/gstreamer1-utils/install
@@ -185,6 +186,8 @@ define Package/libgstreamer1/install
                ./usr/lib/gstreamer-$(GST_VERSION)/libgst*.so \
                $(1)/usr/lib/gstreamer-$(GST_VERSION)/ \
        )
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/gstreamer-$(GST_VERSION)/gst-plugin-scanner \
+                      $(1)/usr/lib/gstreamer-$(GST_VERSION)
 endef
 
 
diff --git a/multimedia/gstreamer1/patches/010-gstplugin_use_lazy_symbol_binding.patch b/multimedia/gstreamer1/patches/010-gstplugin_use_lazy_symbol_binding.patch
new file mode 100644 (file)
index 0000000..603e57c
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/gst/gstplugin.c
++++ b/gst/gstplugin.c
+@@ -723,15 +723,8 @@ gst_plugin_load_file (const gchar * file
+     goto return_error;
+   }
+-  flags = G_MODULE_BIND_LOCAL;
+-  /* libgstpython.so is the gst-python plugin loader. It needs to be loaded with
+-   * G_MODULE_BIND_LAZY.
+-   *
+-   * Ideally there should be a generic way for plugins to specify that they
+-   * need to be loaded with _LAZY.
+-   * */
+-  if (strstr (filename, "libgstpython"))
+-    flags |= G_MODULE_BIND_LAZY;
++  // No need to resolve all bindings until referenced
++  flags = G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY;
+   module = g_module_open (filename, flags);
+   if (module == NULL) {
index f883eeefb5ae2ba2c47088026014e9014a668fa5..796e9bb958e838588ffd60fbd1e1d95e9953fd27 100644 (file)
@@ -8,13 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=icecast
-PKG_VERSION:=2.4.0
+PKG_VERSION:=2.4.1
 PKG_RELEASE:=1
-PKG_MAINTAINER:=André Gaul <gaul@web-yard.de>
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=André Gaul <andre@gaul.io>
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://downloads.us.xiph.org/releases/icecast/
-PKG_MD5SUM:=bb00bfc0d6d2dde24974641085602b81
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/icecast/
+PKG_MD5SUM:=b1402712a79734d4720c8fe15fd9fb10
 
 PKG_FIXUP:=autoreconf
 
index 2b30ba83965696970abe79c44783383eef68c025..75fa39804f5d02d4ee174d5ff60288cfe588bef7 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=minidlna
-PKG_VERSION:=1.1.3
-PKG_RELEASE:=1
+PKG_VERSION:=1.1.4
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/minidlna
-PKG_MD5SUM:=879027192c89e5376cdd2ae2d1aa33b4
+PKG_MD5SUM:=67c9e91285bc3801fd91a5d26ea775d7
 PKG_LICENSE:=GPL-2.0 BSD-3-Clause
 PKG_LICENSE_FILES:=COPYING LICENCE.miniupnpd
 
@@ -75,7 +75,7 @@ CONFIGURE_ARGS +=\
 
 define Package/minidlna/install
        $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/minidlna $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/minidlnad $(1)/usr/bin/minidlna
        $(INSTALL_DIR) $(1)/etc/init.d
        $(INSTALL_BIN) ./files/minidlna.init $(1)/etc/init.d/minidlna
        $(INSTALL_DIR) $(1)/etc/config
index 581c8d1f5a421b717e2c755c6616623117804e2b..a92a064d3c04118ae4633cedabf68c49f9c1ab39 100644 (file)
@@ -4,6 +4,7 @@
 START=50
 
 SERVICE_USE_PID=1
+SERVICE_PID_FILE=/var/run/minidlna/minidlna.pid
 
 MINIDLNA_CONFIG_FILE="/tmp/minidlna.conf"
 
diff --git a/multimedia/minidlna/patches/020-makefileam-tweaks.patch b/multimedia/minidlna/patches/020-makefileam-tweaks.patch
deleted file mode 100644 (file)
index 93d3f3c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -19,9 +19,9 @@
- SUBDIRS=po
--sbin_PROGRAMS = minidlnad
-+sbin_PROGRAMS = minidlna
- check_PROGRAMS = testupnpdescgen
--minidlnad_SOURCES = minidlna.c upnphttp.c upnpdescgen.c upnpsoap.c \
-+minidlna_SOURCES = minidlna.c upnphttp.c upnpdescgen.c upnpsoap.c \
-                       upnpreplyparse.c minixml.c clients.c \
-                       getifaddr.c process.c upnpglobalvars.c \
-                       options.c minissdp.c uuid.c upnpevents.c \
-@@ -38,7 +38,7 @@
- flacoggflag = -logg
- #endif
--minidlnad_LDADD = \
-+minidlna_LDADD = \
-       @LIBJPEG_LIBS@ \
-       @LIBID3TAG_LIBS@ \
-       @LIBSQLITE3_LIBS@ \
-@@ -49,7 +49,7 @@
-       @LIBICONV@ \
-       -lFLAC  $(flacoggflag) $(vorbisflag)
--minidlnad_LDFLAGS = @STATIC_LDFLAGS@
-+minidlna_LDFLAGS = @STATIC_LDFLAGS@
- testupnpdescgen_SOURCES = testupnpdescgen.c upnpdescgen.c
- testupnpdescgen_LDADD = \
diff --git a/multimedia/minidlna/patches/030-upnphttp-fixPhilips.patch b/multimedia/minidlna/patches/030-upnphttp-fixPhilips.patch
deleted file mode 100644 (file)
index 8829bdc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/upnphttp.c
-+++ b/upnphttp.c
-@@ -1259,7 +1259,7 @@
-       int try_sendfile = 1;
- #endif
--      while( offset < end_offset )
-+      while( offset <= end_offset )
-       {
- #if HAVE_SENDFILE
-               if( try_sendfile )
-
index d8df190b5301abcbc9f35fcf978c17c6532caf99..24e569df8e101a711227bcf4c6d0a970c1bcff29 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=mjpg-streamer
 PKG_REV:=182
 PKG_VERSION:=r$(PKG_REV)
-PKG_RELEASE:=2
+PKG_RELEASE:=4
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).1.tar.bz2
@@ -20,18 +20,17 @@ PKG_SOURCE_VERSION:=$(PKG_REV)
 PKG_SOURCE_PROTO:=svn
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 
 include $(INCLUDE_DIR)/package.mk
 
+PKG_BUILD_DEPENDS:=MJPG_STREAMER_V4L2:libv4l
+
 define Package/mjpg-streamer
   SECTION:=multimedia
   CATEGORY:=Multimedia
   TITLE:=MJPG-streamer
-  DEPENDS:=+libpthread +libjpeg 
-  ifeq ($(CONFIG_MJPG_STREAMER_V4L2),y)
-       DEPENDS+=+libv4l
-  endif
+  DEPENDS:=+libpthread +libjpeg +MJPG_STREAMER_V4L2:libv4l
   URL:=http://mjpg-streamer.wiki.sourceforge.net/
   MENU:=1
 endef
index 36bfdbb60d99acf30bb05e42e60043f2c9d6da6e..7d6bfa454d965714324d4dadde091ba6935a90a5 100644 (file)
@@ -1,3 +1,4 @@
+
 config mjpg-streamer 'core'
        option enabled '0'
        option input 'uvc'
@@ -5,6 +6,7 @@ config mjpg-streamer 'core'
        option device '/dev/video0'
        option resolution '640x480'
        option fps '5'
+       option led 'auto'
        option www '/www/webcam'
        option port '8080'
        option username 'openwrt'
index eebd4f84a7bf90d82ea678f817186e7aaba612a3..1ce5ce1dbd1be4ab6ae590a1cffde8beaf896179 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh /etc/rc.common
-# Copyright (C) 2009-2013 OpenWrt.org
+# Copyright (C) 2009-2014 OpenWrt.org
 
 START=90
 STOP=10
@@ -45,6 +45,9 @@ start_instance() {
 
                config_get resolution "$s" 'resolution'
                [ -n "$resolution" ] && input_arg="${input_arg} --resolution $resolution"
+
+               config_get led "$s" 'led'
+               [ -n "$led" ] && input_arg="${input_arg} --led $led"
        fi
 
        if [ -z "$input_arg" ]; then
index 6f49a5df44dc221b121ffbfc7d394e8cc0700f80..412b5f90bc5b5a72e94360d7a61f63f3b501909d 100644 (file)
@@ -8,16 +8,21 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=motion
-PKG_VERSION:=20110826-051001
-PKG_RELEASE:=2
+PKG_VERSION=3.4.0-20141018-$(PKG_SOURCE_VERSION)
+PKG_RELEASE:=1
+
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=COPYING
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://www.lavrsen.dk/sources/motion-daily \
-               @SF/motion
-PKG_MD5SUM:=e703fce57ae2215cb05f25e3027f5818
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/Mr-Dave/motion.git
+PKG_SOURCE_VERSION:=9479d910f2149b5558788bb86f97f26522794212
 
-PKG_INSTALL:=1
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
+PKG_BUILD_PARALLEL:=1
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -30,7 +35,7 @@ define Package/motion
 endef
 
 define Package/motion/conffiles
-/etc/motion.conf
+  /etc/motion.conf
 endef
 
 CONFIGURE_ARGS+= \
@@ -44,9 +49,9 @@ CONFIGURE_ARGS+= \
 
 define Package/motion/install
        $(INSTALL_DIR) $(1)/etc
-       $(CP) $(PKG_INSTALL_DIR)/etc/motion-dist.conf $(1)/etc/motion.conf
+       $(CP) $(PKG_BUILD_DIR)/motion-dist.conf $(1)/etc/motion.conf
        $(INSTALL_DIR) $(1)/usr/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/motion $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/motion $(1)/usr/bin/
 
 endef
 
diff --git a/multimedia/motion/patches/002-honor_cppflags.patch b/multimedia/motion/patches/002-honor_cppflags.patch
deleted file mode 100644 (file)
index ac10f1e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -31,6 +31,7 @@ examplesdir = $(datadir)/@PACKAGE_NAME@-
- # install.                                                                     #
- ################################################################################
- CFLAGS       = @CFLAGS@ -Wall -DVERSION=\"@PACKAGE_VERSION@\" -Dsysconfdir=\"$(sysconfdir)\" 
-+CPPFLAGS     = @CPPFLAGS@
- LDFLAGS      = @LDFLAGS@
- LIBS         = @LIBS@ 
- VIDEO_OBJ    = @VIDEO@
-@@ -118,7 +119,7 @@ endif
- ################################################################################
- $(DEPEND_FILE): *.h $(SRC)
-       @echo "Generating dependencies, please wait..."
--      @$(CC) $(CFLAGS) -M $(SRC) > .tmp
-+      @$(CC) $(CFLAGS) $(CPPFLAGS) -M $(SRC) > .tmp
-       @mv -f .tmp $(DEPEND_FILE)
-       @echo
diff --git a/multimedia/shairplay/Makefile b/multimedia/shairplay/Makefile
new file mode 100644 (file)
index 0000000..1dc61f7
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=shairplay
+PKG_VERSION:=2014-10-27
+PKG_RELEASE:=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/juhovh/shairplay.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=64d59e3087f829006d091fa0d114efb50972a2bf
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+PKG_FIXUP:=libtool
+
+define Package/shairplay
+  SECTION:=multimedia
+  CATEGORY:=Multimedia
+  DEPENDS:=+libao +libavahi-compat-libdnssd +libltdl +libpthread
+  TITLE:=Shairplay
+endef
+
+define Build/Configure
+       (cd $(PKG_BUILD_DIR)/$(CONFIGURE_PATH); \
+       ./autogen.sh;)
+       $(call Build/Configure/Default)
+endef
+
+define Package/shairplay/description
+  Free portable AirPlay server implementation similar to ShairPort.
+endef
+
+define Package/shairplay/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/shairplay $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/share/shairplay
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/airport.key $(1)/usr/share/shairplay/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) files/shairplay.init $(1)/etc/init.d/shairplay
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) files/shairplay.config $(1)/etc/config/shairplay
+endef
+
+$(eval $(call BuildPackage,shairplay))
diff --git a/multimedia/shairplay/files/shairplay.config b/multimedia/shairplay/files/shairplay.config
new file mode 100644 (file)
index 0000000..6e1f939
--- /dev/null
@@ -0,0 +1,10 @@
+config shairplay main
+       option disabled '1'
+       option respawn '1'
+       option apname 'AirPlay'
+       option port '5000'
+       option password ''
+       option hwaddr ''
+       option ao_driver 'oss'
+       option ao_devicename ''
+       option ao_deviceid ''
diff --git a/multimedia/shairplay/files/shairplay.init b/multimedia/shairplay/files/shairplay.init
new file mode 100644 (file)
index 0000000..093a168
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=90
+USE_PROCD=1
+
+append_arg() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get val "$cfg" "$var"
+       [ -n "$val" -o -n "$def" ] && procd_append_param command $opt="${val:-$def}"
+}
+
+start_instance() {
+       local cfg="$1"
+       local aux
+
+       config_get_bool aux "$cfg" 'disabled' '0'
+       [ "$aux" = 1 ] && return 1
+
+       procd_open_instance
+
+       procd_set_param command /usr/bin/shairplay
+
+       append_arg "$cfg" apname "--apname" "AirPlay"
+       append_arg "$cfg" port "--server_port"
+       append_arg "$cfg" password "--password"
+       append_arg "$cfg" hwaddr "--hwaddr"
+
+       append_arg "$cfg" ao_driver "--ao_driver"
+       append_arg "$cfg" ao_devicename "--ao_devicename"
+       append_arg "$cfg" ao_deviceid "--ao_deviceid"
+
+       config_get_bool aux "$cfg" 'respawn' '0'
+       [ "$aux" = 1 ] && procd_set_param respawn
+
+       procd_close_instance
+}
+
+service_triggers() { 
+       procd_add_reload_trigger "shairplay" 
+}
+
+start_service() {
+       config_load shairplay
+       config_foreach start_instance shairplay
+}
diff --git a/multimedia/shairplay/patches/001-key_file_dir.patch b/multimedia/shairplay/patches/001-key_file_dir.patch
new file mode 100644 (file)
index 0000000..3c5e3a5
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/shairplay.c
++++ b/src/shairplay.c
+@@ -346,7 +346,7 @@ main(int argc, char *argv[])
+       raop_cbs.audio_destroy = audio_destroy;
+       raop_cbs.audio_set_volume = audio_set_volume;
+-      raop = raop_init_from_keyfile(10, &raop_cbs, "airport.key", NULL);
++      raop = raop_init_from_keyfile(10, &raop_cbs, "/usr/share/shairplay/airport.key", NULL);
+       if (raop == NULL) {
+               fprintf(stderr, "Could not initialize the RAOP service\n");
+               fprintf(stderr, "Please make sure the airport.key file is in the current directory.\n");
diff --git a/multimedia/shairplay/patches/002-libavahi-compat-dnssd.patch b/multimedia/shairplay/patches/002-libavahi-compat-dnssd.patch
new file mode 100644 (file)
index 0000000..ff70e24
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/lib/dnssd.c
++++ b/src/lib/dnssd.c
+@@ -167,7 +167,7 @@ dnssd_init(int *error)
+               return NULL;
+       }
+ #elif USE_LIBDL
+-      dnssd->module = dlopen("libdns_sd.so", RTLD_LAZY);
++      dnssd->module = dlopen("libdns_sd.so.1", RTLD_LAZY);
+       if (!dnssd->module) {
+               if (error) *error = DNSSD_ERROR_LIBNOTFOUND;
+               free(dnssd);
diff --git a/multimedia/shairplay/patches/003-fix_big-endian.patch b/multimedia/shairplay/patches/003-fix_big-endian.patch
new file mode 100644 (file)
index 0000000..7764aab
--- /dev/null
@@ -0,0 +1,24 @@
+--- a/src/lib/alac/alac.c
++++ b/src/lib/alac/alac.c
+@@ -29,11 +29,7 @@
+  *
+  */
+-#ifdef __BIG_ENDIAN__
+-static const int host_bigendian = 1;
+-#else
+-static const int host_bigendian = 0;
+-#endif
++static int host_bigendian = 0;
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -1181,6 +1177,8 @@ alac_file *create_alac(int samplesize, i
+ {
+     alac_file *newfile = malloc(sizeof(alac_file));
++    host_bigendian = (htonl(42) == 42);
++
+     newfile->samplesize = samplesize;
+     newfile->numchannels = numchannels;
+     newfile->bytespersample = (samplesize / 8) * numchannels;
index 35678c7cc9f32c184d66a923ca5bfb5498098080..0b7170766fdf8e542937d6d1fc14ca17ec15c1d7 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=shairport
-PKG_VERSION:=2014-08-22
+PKG_VERSION:=2014-10-28
 PKG_RELEASE:=$(PKG_SOURCE_VERSION)
 
 PKG_SOURCE_PROTO:=git
index 851c927e49a2489db8e20be4967231c6678138d8..9b2165a9a75162e081da12ac427a222280ab6956 100644 (file)
@@ -1,12 +1,16 @@
 config shairport main
+       option disabled '1'
+       option respawn '1'
        option bname 'AirPort'
        option password ''
        option port '5002'
-       option buffer '256'
-       option log ''
+       option buffer ''
+       option log_file ''
+       option err_file ''
+       option meta_dir ''
        option cmd_start ''
        option cmd_stop ''
-       option cmd_wait ''
+       option cmd_wait '0'
        option audio_output 'alsa'
        option mdns 'avahi'
 
@@ -16,3 +20,17 @@ config shairport main
        option mixer_type ''
        option mixer_control ''
        option mixer_index ''
+
+       # options for ao output
+       option ao_driver ''
+       option ao_name ''
+       option ao_id ''
+       option ao_options ''
+
+       # options for pipe output
+       option output_fifo ''
+
+       # options for pulse output
+       option pulse_server ''
+       option pulse_sink ''
+       option pulse_appname ''
index 0e649d68422dbccfad225abe1cef15b183bd5315..341ff6fee9ce198b0182d2db96df9df3676597cd 100644 (file)
@@ -28,16 +28,21 @@ append_bool() {
 
 start_instance() {
        local cfg="$1"
-       local ao dev
+       local ao dev aux
+
+       config_get_bool aux "$cfg" 'disabled' '0'
+       [ "$aux" = 1 ] && return 1
 
        procd_open_instance
 
        procd_set_param command /usr/bin/shairport
 
        append_arg "$cfg" bname "-a" "AirPort"
-       append_arg "$cfg" log "-l"
-       append_arg "$cfg" buffer "-b" "256"
-       append_arg "$cfg" port "-p" "5002"
+       append_arg "$cfg" log_file "-l"
+       append_arg "$cfg" err_file "-e"
+       append_arg "$cfg" meta_dir "-M"
+       append_arg "$cfg" buffer "-b"
+       append_arg "$cfg" port "-p"
        append_arg "$cfg" password "-k"
        append_arg "$cfg" mdns "-m"
 
@@ -58,8 +63,34 @@ start_instance() {
                        append_arg "$cfg" mixer_control "-c"
                        append_arg "$cfg" mixer_index "-i"
                fi
+       elif [ "$ao" = "ao" ]; then
+               config_get dev "$cfg" ao_driver ""
+               if [ -n "$dev" ]; then
+                       procd_append_param command "--"
+                       append_arg "$cfg" ao_driver "-d"
+                       append_arg "$cfg" ao_id "-i"
+                       append_arg "$cfg" ao_name "-n"
+                       append_arg "$cfg" ao_options "-o"
+               fi
+       elif [ "$ao" = "pipe" ]; then
+               config_get dev "$cfg" output_fifo ""
+               if [ -n "$dev" ]; then
+                       procd_append_param command "--"
+                       append_arg "$cfg" output_fifo ""
+               fi
+       elif [ "$ao" = "pulse" ]; then
+               config_get dev "$cfg" pulse_server ""
+               if [ -n "$dev" ]; then
+                       procd_append_param command "--"
+                       append_arg "$cfg" pulse_server "-a"
+                       append_arg "$cfg" pulse_sink "-s"
+                       append_arg "$cfg" pulse_appname "-n"
+               fi
        fi
 
+       config_get_bool aux "$cfg" 'respawn' '0'
+       [ "$aux" = 1 ] && procd_set_param respawn
+
        procd_close_instance
 }
 
diff --git a/multimedia/upmpdcli/Makefile b/multimedia/upmpdcli/Makefile
new file mode 100644 (file)
index 0000000..d921fee
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=upmpdcli
+PKG_VERSION:=0.9.0
+PKG_RELEASE:=2
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.lesbonscomptes.com/upmpdcli/downloads
+PKG_MD5SUM:=0e7b86037f19ea3a08067409af6f6902
+PKG_MAINTAINER:=Petko Bordjukov <bordjukov@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/upmpdcli
+  SECTION:=multimedia
+  CATEGORY:=Multimedia
+  URL:=http://www.lesbonscomptes.com/upmpdcli
+  DEPENDS+= +libupnpp +libmpdclient
+  TITLE:=A UPnP front-end to MPD, the Music Player Daemon
+  USERID:=upmpdcli=89:upmpdcli=89
+endef
+
+define Package/upmpdcli/description
+upmpdcli implements an UPnP Media Renderer, using MPD to perform the real work.
+endef
+
+define Package/upmpdcli/install
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/upmpdcli.conf $(1)/etc/
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/upmpdcli.config $(1)/etc/config/upmpdcli
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/upmpdcli $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/share/upmpdcli
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/upmpdcli/* $(1)/usr/share/upmpdcli/
+       $(INSTALL_DATA) ./files/upmpdcli.png $(1)/usr/share/upmpdcli/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/upmpdcli.init $(1)/etc/init.d/upmpdcli
+endef
+
+$(eval $(call BuildPackage,upmpdcli))
diff --git a/multimedia/upmpdcli/files/upmpdcli.config b/multimedia/upmpdcli/files/upmpdcli.config
new file mode 100644 (file)
index 0000000..56b0ba3
--- /dev/null
@@ -0,0 +1,15 @@
+config upmpdcli lan
+       option interface 'br-lan'
+#      option friendly_name 'upmpdcli'
+#      option mpd_host '127.0.0.1'
+#      option mpd_port '6600'
+#      option upmpd_port '0'
+#      option config '/etc/upmpdcli.conf'
+
+# Add additional interfaces
+#
+#config upmpdcli wifi
+#      option interface 'wlan0'
+
+#config upmpdcli wan
+#      option interface 'eth0'
diff --git a/multimedia/upmpdcli/files/upmpdcli.init b/multimedia/upmpdcli/files/upmpdcli.init
new file mode 100644 (file)
index 0000000..6c69209
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+NAME=upmpdcli
+START=95
+
+UPMPD_BIN=/usr/bin/${NAME}
+
+USE_PROCD=1
+
+append_arg() {
+        local cfg="$1"
+        local var="$2"
+        local opt="$3"
+        local def="$4"
+        local val
+
+        config_get val "$cfg" "$var"
+        [ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}"
+}
+
+start_instance() {
+       local cfg="$1"
+       local interface
+
+       procd_open_instance
+
+       procd_set_param command "${UPMPD_BIN}"
+
+#      config_get interface "$cfg" interface
+#      procd_add_reload_interface_trigger $interface
+
+       append_arg "$cfg" interface "-i"
+       append_arg "$cfg" mpd_host "-h"
+       append_arg "$cfg" mpd_port "-p"
+       append_arg "$cfg" upmpd_port "-P"
+
+       append_arg "$cfg" config "-c"
+       append_arg "$cfg" friendly_name "-f"
+
+       procd_close_instance
+}
+
+service_triggers() {
+       procd_add_reload_trigger "${NAME}"
+}
+
+start_service() {
+       config_load ${NAME}
+       config_foreach start_instance ${NAME}
+}
diff --git a/multimedia/upmpdcli/files/upmpdcli.png b/multimedia/upmpdcli/files/upmpdcli.png
new file mode 100644 (file)
index 0000000..ba50c64
Binary files /dev/null and b/multimedia/upmpdcli/files/upmpdcli.png differ
diff --git a/multimedia/upmpdcli/patches/010-Add_icon_config.patch b/multimedia/upmpdcli/patches/010-Add_icon_config.patch
new file mode 100644 (file)
index 0000000..9b1ca6d
--- /dev/null
@@ -0,0 +1,9 @@
+--- a/src/upmpdcli.conf
++++ b/src/upmpdcli.conf
+@@ -53,3 +53,6 @@ ohmetapersist = 1
+ #  Path to the sc2mpd if it is not in /usr/bin and the location is not in
+ #  the PATH for the init scripts.
+ #sc2mpd = /usr/bin/sc2mpd
++
++# Icon for MPD UPnP interface
++iconpath = /usr/share/upmpdcli/upmpdcli.png
index 29909290c7df3102eebc71117bbe285864f6f1ed..9522e83fd75b392b96e4a60ab746a9c7656c49ec 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2013-2014 OpenWrt.org
+# Copyright (C) 2013-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xupnpd
-PKG_REV:=399
+PKG_REV:=404
 PKG_VERSION:=$(PKG_REV)
 PKG_RELEASE:=1
 
diff --git a/net/announce/Makefile b/net/announce/Makefile
new file mode 100644 (file)
index 0000000..d2c17da
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=announce
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=src/LICENSE.txt
+PKG_MAINTAINER:=Simon Peter <probono@puredarwin.org>
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/probonopd/announce.git
+PKG_SOURCE_VERSION:=70d70f998686199deaa5d62b54688c869e237eef
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION)
+PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+PKG_BUILD_DEPENDS:= +libpthread
+
+define Package/announce
+       SECTION:=net
+       CATEGORY:=Network
+       SUBMENU:=IP Addresses and Names
+       TITLE:=Announce services on the network with Zeroconf/Bonjour 
+       URL:=https://github.com/probonopd/announce
+       DEPENDS:= +libpthread 
+endef
+
+define Package/announce/description
+  Announce services on the network with Zeroconf/Bonjour.
+  This announces services such as ssh, sftp, and http running on the local machine
+  to the network.
+endef
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       $(CP) $(PKG_BUILD_DIR)/src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/announce/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/announce $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/announce.initscript $(1)/etc/init.d/announce
+endef
+
+$(eval $(call BuildPackage,announce))
diff --git a/net/bcp38/Makefile b/net/bcp38/Makefile
new file mode 100644 (file)
index 0000000..280bcc5
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2014 Openwrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bcp38
+PKG_VERSION:=4
+PKG_RELEASE:=1
+PKG_LICENCE:=GPL-3.0+
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bcp38
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Routing and Redirection
+  TITLE:=BCP38 compliance
+  URL:=https://github.com/dtaht/ceropackages-3.10
+  MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
+  DEPENDS:=+ipset
+endef
+
+define Package/bcp38/description
+ bcp38 implements IETF BCP38 for home routers. See https://tools.ietf.org/html/bcp38.
+endef
+
+define Package/bcp38/conffiles
+/etc/config/bcp38
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/bcp38/install
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/bcp38.config $(1)/etc/config/bcp38
+       $(INSTALL_DIR) $(1)/usr/lib/bcp38
+       $(INSTALL_BIN) ./files/run.sh $(1)/usr/lib/bcp38/run.sh
+       $(INSTALL_DIR) $(1)/etc/uci-defaults
+       $(INSTALL_BIN) ./files/bcp38.defaults $(1)/etc/uci-defaults/bcp38
+endef
+
+define Package/bcp38/postinst
+#!/bin/sh
+[ -x /etc/uci-defaults/bcp38 ] && /etc/uci-defaults/bcp38 || exit 0
+endef
+
+define Package/bcp38/postrm
+#!/bin/sh
+uci delete firewall.bcp38
+uci commit
+endef
+
+$(eval $(call BuildPackage,bcp38))
diff --git a/net/bcp38/files/bcp38.config b/net/bcp38/files/bcp38.config
new file mode 100644 (file)
index 0000000..08e8e20
--- /dev/null
@@ -0,0 +1,22 @@
+config bcp38
+       option enabled 0
+       option interface 'eth1'
+       option detect_upstream 1
+       list match '127.0.0.0/8'
+       list match '0.0.0.0/8'       # RFC 1700
+       list match '240.0.0.0/4'     # RFC 5745
+       list match '192.0.2.0/24'    # RFC 5737
+       list match '198.51.100.0/24' # RFC 5737
+       list match '203.0.113.0/24'  # RFC 5737
+       list match '192.168.0.0/16'  # RFC 1918
+       list match '10.0.0.0/8'      # RFC 1918
+       list match '172.16.0.0/12'   # RFC 1918
+       list match '169.254.0.0/16'  # RFC 3927
+
+#      list nomatch '172.26.0.0/21' # Example of something not to match
+#      There is a dhcp trigger to do this for the netmask of a 
+#      double natted connection needed
+
+#      I will argue that this level of indirection doesn't scale
+#      very well - see how to block china as an example
+#      http://www.okean.com/china.txt
diff --git a/net/bcp38/files/bcp38.defaults b/net/bcp38/files/bcp38.defaults
new file mode 100644 (file)
index 0000000..d7e0d80
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+uci -q batch <<-EOT
+       delete firewall.bcp38
+       set firewall.bcp38=include
+       set firewall.bcp38.type=script
+       set firewall.bcp38.path=/usr/lib/bcp38/run.sh
+       set firewall.bcp38.family=IPv4
+       set firewall.bcp38.reload=1
+       commit firewall
+EOT
+
+exit 0
diff --git a/net/bcp38/files/run.sh b/net/bcp38/files/run.sh
new file mode 100755 (executable)
index 0000000..bafdf3b
--- /dev/null
@@ -0,0 +1,104 @@
+#!/bin/sh
+# BCP38 filtering implementation for CeroWrt.
+#
+# 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 3 of the License, or (at your option) any later
+# version.
+#
+# Author: Toke Høiland-Jørgensen <toke@toke.dk>
+
+STOP=$1
+IPSET_NAME=bcp38-ipv4
+IPTABLES_CHAIN=BCP38
+
+. /lib/functions.sh
+
+config_load bcp38
+
+add_bcp38_rule()
+{
+       local subnet="$1"
+       local action="$2"
+
+       if [ "$action" == "nomatch" ]; then
+               ipset add "$IPSET_NAME" "$subnet" nomatch
+       else
+               ipset add "$IPSET_NAME" "$subnet"
+       fi
+}
+
+detect_upstream()
+{
+       local interface="$1"
+
+       subnets=$(ip route show dev "$interface"  | grep 'scope link' | awk '{print $1}')
+       for subnet in $subnets; do
+               # ipset test doesn't work for subnets, so strip out the subnet part
+               # and test for that; add as exception if there's a match
+               addr=$(echo $subnet | sed 's|/[0-9]\+$||')
+               ipset test "$IPSET_NAME" $addr 2>/dev/null && add_bcp38_rule $subnet nomatch
+       done
+}
+
+run() {
+       local section="$1"
+       local enabled
+       local interface
+       local detect_upstream
+       config_get_bool enabled "$section" enabled 0
+       config_get interface "$section" interface
+       config_get detect_upstream "$section" detect_upstream
+
+       if [ "$enabled" -eq "1" -a -n "$interface" -a -z "$STOP" ] ; then
+               setup_ipset
+               setup_iptables "$interface"
+               config_list_foreach "$section" match add_bcp38_rule match
+               config_list_foreach "$section" nomatch add_bcp38_rule nomatch
+               [ "$detect_upstream" -eq "1" ] && detect_upstream "$interface"
+       fi
+       exit 0
+}
+
+setup_ipset()
+{
+       ipset create "$IPSET_NAME" hash:net family ipv4
+       ipset flush "$IPSET_NAME"
+}
+
+setup_iptables()
+{
+       local interface="$1"
+       iptables -N "$IPTABLES_CHAIN" 2>/dev/null
+       iptables -F "$IPTABLES_CHAIN" 2>/dev/null
+
+       iptables -I output_rule -j "$IPTABLES_CHAIN"
+       iptables -I input_rule -j "$IPTABLES_CHAIN"
+       iptables -I forwarding_rule -j "$IPTABLES_CHAIN"
+
+       # always accept DHCP traffic
+       iptables -A "$IPTABLES_CHAIN" -p udp --dport 67:68 --sport 67:68 -j RETURN
+       iptables -A "$IPTABLES_CHAIN" -o "$interface" -m set --match-set "$IPSET_NAME" dst -j REJECT --reject-with icmp-net-unreachable
+       iptables -A "$IPTABLES_CHAIN" -i "$interface" -m set --match-set "$IPSET_NAME" src -j DROP
+}
+
+destroy_ipset()
+{
+       ipset flush "$IPSET_NAME" 2>/dev/null
+       ipset destroy "$IPSET_NAME" 2>/dev/null
+}
+
+destroy_iptables()
+{
+       iptables -D output_rule -j "$IPTABLES_CHAIN" 2>/dev/null
+       iptables -D input_rule -j "$IPTABLES_CHAIN" 2>/dev/null
+       iptables -D forwarding_rule -j "$IPTABLES_CHAIN" 2>/dev/null
+       iptables -F "$IPTABLES_CHAIN" 2>/dev/null
+       iptables -X "$IPTABLES_CHAIN" 2>/dev/null
+}
+
+destroy_iptables
+destroy_ipset
+config_foreach run bcp38
+
+exit 0
index 99ac1c996f8dfff5535bf5ac55d94987e7e7f204..e4ee053d64d17965c87712444073deba79aeedbc 100644 (file)
@@ -9,8 +9,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=bind
-PKG_VERSION:=9.9.5-P1
-PKG_RELEASE:=1
+PKG_VERSION:=9.9.6-P1
+PKG_RELEASE:=2
+USERID:=bind=57:bind=57
 
 PKG_MAINTAINER := Noah Meyerhans <frodo@morgul.net>
 PKG_LICENSE := BSD-3-Clause
@@ -19,7 +20,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:= \
        ftp://ftp.isc.org/isc/bind9/$(PKG_VERSION) \
        http://www.mirrorservice.org/sites/ftp.isc.org/isc/bind9/$(PKG_VERSION)
-PKG_MD5SUM:=3408af8c6d27d6cb8a05287f2ee32ad0
+PKG_MD5SUM:=ca9d8f4d26e740668d361bfc50d90fc7
 
 PKG_FIXUP:=autoreconf
 PKG_REMOVE_FILES:=aclocal.m4 libtool.m4
index 986e5fe087bf1be3e8bae2d00920b2521d2e8af7..2ef7797ba0018ac7c4fca9fb765615255b13ebd9 100644 (file)
@@ -1,40 +1,36 @@
 #!/bin/sh /etc/rc.common
+# Copyright (C) 2014 Noah Meyerhans <frodo@morgul.net>
+# Licensed under the terms of the GNU General Public License version 2
+# or (at your discretion) any later later version
+
+USE_PROCD=1
+
 START=50
 
 config_file=/etc/bind/named.conf
 pid_file=/var/run/named/named.pid
 
-start() {
-  if [ -e $pid_file ]
-  then
-     echo "  named already running with PID `cat $pid_file`"
-     return 1
-  fi
-  echo Starting isc-bind
-
-  /usr/sbin/named -c $config_file
+logdir=/var/log/named/
+cachedir=/var/cache/bind
+libdir=/var/lib/bind
+config_file=/etc/bind/named.conf
 
-  if [ $? -ne 0 ]
-  then
-    echo "  isc-bind failed to start"
-  fi
+fix_perms() {
+    for dir in $libdir $logdir $cachedir; do
+       test -e "$dir" || {
+            mkdir -p "$dir"
+            chgrp bind "$dir"
+            chmod g+w "$dir"
+       }
+    done
 }
 
-stop() {
-  echo "Stopping isc-bind"
-  if [ -e $pid_file ]
-  then
-    kill `cat $pid_file`
-
-    if [ $? -ne 0 ]
-    then
-      echo "  PID " `cat $pid_file` not found
-      echo "  Is the named server running?"
-    fi
-
-    rm -f $pid_file
-
-    else
-    echo "  $pid_file not found"
-  fi
+start_service() {
+    user_exists bind 57 || user_add bind 57
+    group_exists bind 57 || group_add bind 57
+    fix_perms
+    procd_open_instance
+    procd_set_param command /usr/sbin/named -u bind -f -c $config_file
+    procd_set_param respawn
+    procd_close_instance
 }
diff --git a/net/bmon/Makefile b/net/bmon/Makefile
new file mode 100644 (file)
index 0000000..44da26c
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bmon
+PKG_VERSION:=3.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/tgraf/bmon/releases/download/v$(PKG_VERSION)/
+PKG_MD5SUM:=b7d0d055727f2cf1e452f26dfbf6a825
+PKG_MAINTAINER:=Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>
+PKG_LICENSE:=MIT
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bmon
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+PACKAGE_libncursesw:libncursesw +!PACKAGE_libncursesw:libncurses +libnl +confuse
+  TITLE:=bmon is a portable bandwidth monitor
+  URL:=https://github.com/tgraf/bmon/
+endef
+
+define Package/bmon/description
+       bmon is a portable bandwidth monitor
+       and rate estimator running on various
+       operating systems. It supports various
+       input methods for different architectures.
+endef
+
+CONFIGURE_ARGS += \
+       --disable-cnt-workaround \
+
+CONFIGURE_VARS += \
+       ac_cv_lib_nl_nl_connect=no \
+
+define Package/bmon/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/bmon $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,bmon))
diff --git a/net/bwm-ng/Config.in b/net/bwm-ng/Config.in
new file mode 100644 (file)
index 0000000..d822e12
--- /dev/null
@@ -0,0 +1,35 @@
+# bwm-ng advanced configuration
+
+menu "Configuration"
+       depends on PACKAGE_bwm-ng
+
+config BWMNG_CONFIGFILE
+       bool "enable configfile support"
+       default n
+
+config BWMNG_HTML
+       bool "enable html output"
+       default n
+
+config BWMNG_CSV
+       bool "enable csv output"
+       default n
+
+config BWMNG_EXTENDEDSTATS
+       bool "enable max, sum and avg stats"
+       default y
+
+config BWMNG_LIBNCURSES
+       bool "enable libncurses support"
+       default n
+
+config BWMNG_TIME
+       bool "enable accurate time calculating"
+       default y
+
+config BWMNG_GETOPT_LONG
+       bool "enable long options"
+       default n
+
+endmenu
+
diff --git a/net/bwm-ng/Makefile b/net/bwm-ng/Makefile
new file mode 100644 (file)
index 0000000..695f7f0
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bwm-ng
+PKG_VERSION:=0.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.gropp.org/bwm-ng
+PKG_MD5SUM:=d3a02484fb7946371bfb4e10927cebfb
+PKG_MAINTAINER:=Julen Landa Alustiza <julen@zokormazo.info>
+PKG_LICENSE:=GPL2-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bwm-ng
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+BWMNG_LIBNCURSES:libncurses
+  TITLE:=bwm-ng
+  URL:=http://www.gropp.org/?id=projects&sub=bwm-ng
+  MENU:=1
+endef
+
+define Package/bwm-ng/description
+  Bandwidth Monitor NG is a small and simple console-based live
+  network and disk io bandwidth monitor.
+endef
+
+define Package/bwm-ng/config
+  source "$(SOURCE)/Config.in"
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default, \
+       $(if $(CONFIG_BWMNG_CONFIGFILE),--enable,--disable)-configfile \
+       $(if $(CONFIG_BWMNG_HTML),--enable,--disable)-html \
+       $(if $(CONFIG_BWMNG_CSV),--enable,--disable)-csv \
+       $(if $(CONFIG_BWMNG_EXTENDEDSTATS),--enable,--disable)-extendedstats \
+       $(if $(CONFIG_BWMNG_LIBNCURSES),--with,--without)-ncurses \
+       $(if $(CONFIG_BWMNG_TIME),--with,--without)-time \
+       $(if $(CONFIG_BWMNG_GETOPT_LONG),--with,--without)-getopt_long \
+       --with-strip \
+       --with-procnetdev \
+       --with-diskstats \
+       )
+endef
+
+define Package/bwm-ng/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/bwm-ng $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,bwm-ng))
diff --git a/net/coova-chilli/Config.in b/net/coova-chilli/Config.in
new file mode 100644 (file)
index 0000000..c0c671f
--- /dev/null
@@ -0,0 +1,52 @@
+# CoovaChilli advanced configuration
+
+menu "Configuration"
+       depends on PACKAGE_coova-chilli
+
+config COOVACHILLI_PROXY
+        bool "Enable support for chilli proxy. Required for AAA Proxy through http"
+        default n
+
+config COOVACHILLI_REDIR
+       bool "Enable support for redir server. Required for uamregex"
+       default n
+
+config COOVACHILLI_MINIPORTAL
+       bool "Enable support Coova miniportal"
+       default n
+
+config COOVACHILLI_USERAGENT
+       bool "Enable recording user-agent"
+       default n
+
+config COOVACHILLI_DNSLOG
+       bool "Enable support to log DNS name queries"
+       default n
+
+config COOVACHILLI_UAMDOMAINFILE
+       bool "Enable loading of mass uamdomains from file"
+       default n
+
+config COOVACHILLI_LARGELIMITS
+       bool "Enable larger limits for use with non-embedded systems"
+       default n
+
+choice
+       prompt "SSL library"
+       default COOVACHILLI_NOSSL
+
+config COOVACHILLI_NOSSL
+       bool "No SSL support"
+
+config COOVACHILLI_MATRIXSSL
+       bool "MatrixSSL"
+
+config COOVACHILLI_CYASSL
+       bool "CyaSSL"
+
+config COOVACHILLI_OPENSSL
+       bool "OpenSSL"
+
+endchoice
+
+endmenu
diff --git a/net/coova-chilli/Makefile b/net/coova-chilli/Makefile
new file mode 100644 (file)
index 0000000..2ff8729
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=coova-chilli
+PKG_VERSION:=1.3.0+20141128
+PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/coova/coova-chilli
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=b93de20a288c01c2ba28e96e31ad6da01627f45f
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MD5SUM:=2adb27ec56172b18c5beee359dd7898d
+
+PKG_INSTALL:=1
+
+PKG_CONFIG_DEPENDS := \
+  COOVACHILLI_MINIPORTAL \
+  COOVACHILLI_REDIR \
+  COOVACHILLI_USERAGENT \
+  COOVACHILLI_DNSLOG \
+  COOVACHILLI_UAMDOMAINFILE \
+  COOVACHILLI_LARGELIMITS \
+  COOVACHILLI_NOSSL \
+  COOVACHILLI_MATRIXSSL \
+  COOVACHILLI_CYASSL \
+  COOVACHILLI_OPENSSL
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/coova-chilli
+  SUBMENU:=Captive Portals
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+kmod-tun +librt +COOVACHILLI_MATRIXSSL:libmatrixssl +COOVACHILLI_CYASSL:libcyassl +COOVACHILLI_OPENSSL:libopenssl
+  TITLE:=Wireless LAN HotSpot controller (Coova Chilli Version)
+  URL:=http://www.coova.org/CoovaChilli
+  MENU:=1
+endef
+
+define Package/coova-chilli/description
+       CoovaChilli is an open source access controller for wireless LAN
+       access points and is based on ChilliSpot. It is used for authenticating
+       users of a wireless (or wired) LAN. It supports web based login (UAM)
+       which is today's standard for public HotSpots and it supports Wireless
+       Protected Access (WPA) which is the standard of the future.
+       Authentication, authorization and accounting (AAA) is handled by your
+       favorite radius server.
+endef
+
+define Package/coova-chilli/config
+  source "$(SOURCE)/Config.in"
+endef
+
+define Build/Prepare
+$(call Build/Prepare/Default)
+       ( cd $(PKG_BUILD_DIR) ; \
+               [ -f ./configure ] || { \
+                       ./bootstrap ; \
+               } \
+       )
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default, \
+       $(if $(CONFIG_COOVACHILLI_PROXY),--enable,--disable)-chilliproxy \
+       $(if $(CONFIG_COOVACHILLI_REDIR),--enable,--disable)-chilliredir \
+       $(if $(CONFIG_COOVACHILLI_DNSLOG),--enable,--disable)-dnslog \
+       $(if $(CONFIG_COOVACHILLI_MINIPORTAL),--enable,--disable)-miniportal \
+       $(if $(CONFIG_COOVACHILLI_USERAGENT),--enable,--disable)-useragent \
+       $(if $(CONFIG_COOVACHILLI_LARGELIMITS),--enable,--disable)-largelimits \
+       $(if $(CONFIG_COOVACHILLI_UAMDOMAINFILE),--enable,--disable)-uamdomainfile \
+       $(if $(CONFIG_COOVACHILLI_MATRIXSSL),--with,--without)-matrixssl \
+       $(if $(CONFIG_COOVACHILLI_CYASSL),--with,--without)-cyaxssl \
+       $(if $(CONFIG_COOVACHILLI_OPENSSL),--with,--without)-openssl \
+       )
+endef
+
+define Package/coova-chilli/conffiles
+/etc/chilli.conf
+endef
+
+define Package/coova-chilli/install
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/chilli.conf $(1)/etc/
+       $(INSTALL_DIR) $(1)/etc/chilli
+       $(CP) $(PKG_INSTALL_DIR)/etc/chilli/* $(1)/etc/chilli/
+       $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+       $(INSTALL_DATA) ./files/chilli.hotplug $(1)/etc/hotplug.d/iface/30-chilli
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/chilli* $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,coova-chilli))
diff --git a/net/coova-chilli/files/chilli.hotplug b/net/coova-chilli/files/chilli.hotplug
new file mode 100644 (file)
index 0000000..e12812b
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+[ "$ACTION" == "ifup" ] || exit 0
+
+[ "$INTERFACE" = "wan" ] && {
+       /etc/init.d/chilli restart
+}
diff --git a/net/coova-chilli/patches/100-fix-sysinfo-redeclaration.patch b/net/coova-chilli/patches/100-fix-sysinfo-redeclaration.patch
new file mode 100644 (file)
index 0000000..2efecbe
--- /dev/null
@@ -0,0 +1,24 @@
+--- a/src/system.h
++++ b/src/system.h
+@@ -83,10 +83,6 @@
+ #include <linux/sysinfo.h>
+ #endif
+-#ifdef HAVE_SYS_SYSINFO_H
+-#include <sys/sysinfo.h>
+-#endif
+-
+ #ifdef HAVE_TIME_H
+ #include <time.h>
+ #endif
+@@ -139,6 +135,10 @@
+ #include <linux/un.h>
+ #endif
++#ifdef HAVE_SYS_SYSINFO_H
++#include <sys/sysinfo.h>
++#endif
++
+ #elif defined (__FreeBSD__)  || defined (__APPLE__) || defined (__OpenBSD__) || defined (__NetBSD__) 
+ #include <net/if.h>
+ #include <net/bpf.h>
diff --git a/net/dansguardian/Makefile b/net/dansguardian/Makefile
new file mode 100644 (file)
index 0000000..eefefaa
--- /dev/null
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2008-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dansguardian
+PKG_VERSION:=2.12.0.3
+PKG_RELEASE:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/dansguardian
+PKG_MD5SUM:=2a88d0392cd28eaec02b7ee727b2e253
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dansguardian
+  SECTION:=net
+  DEPENDS:=+libpthread $(CXX_DEPENDS) +zlib
+  CATEGORY:=Network
+  SUBMENU:=Web Servers/Proxies
+  TITLE:=DansGuardian
+  URL:=http://dansguardian.org
+endef
+
+define Package/dansguardian/conffiles
+/etc/dansguardian/dansguardianf1.conf
+/etc/config/dansguardian
+endef
+
+CONFIGURE_VARS += \
+       INCLUDES="" \
+       CXXFLAGS="$$$$CXXFLAGS -fno-rtti" \
+       LIBS="-lpthread" \
+
+define Build/Configure
+       $(call Build/Configure/Default,\
+               --disable-clamav \
+               --with-sysconfsubdir=dansguardian \
+               --with-proxyuser=root \
+               --with-proxygroup=root \
+               --disable-pcre \
+       )
+endef
+
+define Package/dansguardian/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dansguardian $(1)/usr/sbin/
+
+       $(INSTALL_DIR) $(1)/etc
+       $(CP) $(PKG_INSTALL_DIR)/etc/dansguardian $(1)/etc/
+       $(INSTALL_CONF) ./files/dansguardianf1.conf $(1)/etc/dansguardian/dansguardianf1.conf
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/dansguardian.config $(1)/etc/config/dansguardian
+
+       $(INSTALL_DIR) $(1)/usr/share/dansguardian
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/dansguardian/transparent1x1.gif $(1)/usr/share/dansguardian/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/dansguardian/blockedflash.swf $(1)/usr/share/dansguardian/
+
+       $(INSTALL_DIR) $(1)/usr/share/dansguardian/languages/ukenglish
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/dansguardian/languages/ukenglish/* $(1)/usr/share/dansguardian/languages/ukenglish/
+
+       $(INSTALL_DIR) $(1)/etc/init.d/
+       $(INSTALL_BIN) ./files/dansguardian.init $(1)/etc/init.d/dansguardian
+endef
+
+$(eval $(call BuildPackage,dansguardian))
diff --git a/net/dansguardian/files/dansguardian.config b/net/dansguardian/files/dansguardian.config
new file mode 100644 (file)
index 0000000..86640af
--- /dev/null
@@ -0,0 +1,71 @@
+config dansguardian 'dansguardian'
+       option config_file '/etc/dansguardian/dansguardianf1.conf'
+       option accessdeniedaddress 'http://YOURSERVER.YOURDOMAIN/cgi-bin/dansguardian.pl'
+       option bannediplist '/etc/dansguardian/lists/bannediplist'
+       option contentscanexceptions 'off'
+       option contentscannertimeout '60'
+       option createlistcachefiles 'on'
+       option custombannedflashfile '/usr/share/dansguardian/blockedflash.swf'
+       option custombannedimagefile '/usr/share/dansguardian/transparent1x1.gif'
+       option deletedownloadedtempfiles 'on'
+       option downloadmanager '/etc/dansguardian/downloadmanagers/default.conf'
+       option exceptioniplist '/etc/dansguardian/lists/exceptioniplist'
+       option filecachedir '/tmp'
+       option filtergroups '1'
+       option filtergroupslist '/etc/dansguardian/lists/filtergroupslist'
+       option filterip ''
+       option filterports '8080'
+       option forcequicksearch 'off'
+       option forwardedfor 'off'
+       option hexdecodecontent 'off'
+       option initialtrickledelay '20'
+       option ipcfilename '/tmp/.dguardianipc'
+       option ipipcfilename '/tmp/.dguardianipipc'
+       option languagedir '/usr/share/dansguardian/languages'
+       option language 'ukenglish'
+       option logadblocks 'off'
+       option logchildprocesshandling 'off'
+       option logclienthostnames 'off'
+       option logconnectionhandlingerrors 'on'
+       option logexceptionhits '2'
+       option logfileformat '1'
+       option loglevel '2'
+       option loglocation '/dev/null'
+       option logsyslog 'on'
+       option loguseragent 'off'
+       option maxagechildren '500'
+       option maxchildren '120'
+       option maxcontentfilecachescansize '20000'
+       option maxcontentfiltersize '256'
+       option maxcontentramcachescansize '2000'
+       option maxips '0'
+       option maxsparechildren '32'
+       option maxuploadsize '-1'
+       option minchildren '8'
+       option minsparechildren '4'
+       option nodaemon 'off'
+       option nologger 'off'
+       option nonstandarddelimiter 'on'
+       option perroomblockingdirectory '/etc/dansguardian/lists/bannedrooms/'
+       option phrasefiltermode '2'
+       option prefercachedlists 'off'
+       option preforkchildren '6'
+       option preservecase '0'
+       option proxyip '127.0.0.1'
+       option proxyport '3128'
+       option proxytimeout '20'
+       option recheckreplacedurls 'off'
+       option reportinglevel '3'
+       option reverseaddresslookups 'off'
+       option reverseclientiplookups 'off'
+       option scancleancache 'on'
+       option showweightedfound 'on'
+       option softrestart 'off'
+       option trickledelay '10'
+       option urlcacheage '900'
+       option urlcachenumber '1000'
+       option urlipcfilename '/tmp/.dguardianurlipc'
+       option usecustombannedflash 'on'
+       option usecustombannedimage 'on'
+       option usexforwardedfor 'off'
+       option weightedphrasemode '2'
diff --git a/net/dansguardian/files/dansguardian.init b/net/dansguardian/files/dansguardian.init
new file mode 100644 (file)
index 0000000..67ec6bd
--- /dev/null
@@ -0,0 +1,190 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/sbin/dansguardian
+CONFIGFILE="/tmp/dansguardian/dansguardian.conf"
+
+validate_dansguardian_section() {
+       uci_validate_section dansguardian dansguardian "${1}" \
+               'config_file:string' \
+               'accessdeniedaddress:string' \
+               'bannediplist:string' \
+               'contentscanexceptions:string' \
+               'contentscannertimeout:uinteger' \
+               'createlistcachefiles:string' \
+               'custombannedflashfile:string' \
+               'custombannedimagefile:string' \
+               'deletedownloadedtempfiles:string' \
+               'downloadmanager:string' \
+               'exceptioniplist:string' \
+               'filecachedir:string' \
+               'filtergroups:uinteger' \
+               'filtergroupslist:string' \
+               'filterip:ipaddr' \
+               'filterports:port:8080' \
+               'forcequicksearch:string' \
+               'forwardedfor:string' \
+               'hexdecodecontent:string' \
+               'initialtrickledelay:uinteger' \
+               'ipcfilename:string' \
+               'ipipcfilename:string' \
+               'languagedir:string' \
+               'language:string' \
+               'logadblocks:string' \
+               'logchildprocesshandling:string' \
+               'logclienthostnames:string' \
+               'logconnectionhandlingerrors:string' \
+               'logexceptionhits:range(0,2)' \
+               'logfileformat:range(1,4)' \
+               'loglevel:range(0,3)' \
+               'loglocation:string' \
+               'loguseragent:string' \
+               'maxagechildren:uinteger' \
+               'maxchildren:uinteger' \
+               'maxcontentfilecachescansize:uinteger' \
+               'maxcontentfiltersize:uinteger' \
+               'maxcontentramcachescansize:uinteger' \
+               'maxips:uinteger' \
+               'maxsparechildren:uinteger' \
+               'maxuploadsize:integer' \
+               'minchildren:uinteger' \
+               'minsparechildren:uinteger' \
+               'nodaemon:string' \
+               'nologger:string' \
+               'nonstandarddelimiter:string' \
+               'perroomblockingdirectory:string' \
+               'phrasefiltermode:range(0,3)' \
+               'prefercachedlists:string' \
+               'preforkchildren:uinteger' \
+               'preservecase:range(0,2)' \
+               'proxyip:ipaddr' \
+               'proxyport:port:3128' \
+               'proxytimeout:range(20,30)' \
+               'recheckreplacedurls:string' \
+               'reportinglevel:range(-1,3)' \
+               'reverseaddresslookups:string' \
+               'reverseclientiplookups:string' \
+               'scancleancache:string' \
+               'showweightedfound:string' \
+               'softrestart:string' \
+               'trickledelay:uinteger' \
+               'urlcacheage:uinteger' \
+               'urlcachenumber:uinteger' \
+               'urlipcfilename:string' \
+               'usecustombannedflash:string' \
+               'usecustombannedimage:string' \
+               'usexforwardedfor:string' \
+               'weightedphrasemode:range(0,2)'
+}
+
+start_service() {
+       local config_file accessdeniedaddress bannediplist contentscanexceptions contentscannertimeout \
+               createlistcachefiles custombannedflashfile custombannedimagefile deletedownloadedtempfiles \
+               downloadmanager exceptioniplist filecachedir filtergroups filtergroupslist filterip filterports \
+               forcequicksearch forwardedfor hexdecodecontent initialtrickledelay ipcfilename ipipcfilename \
+               language languagedir logadblocks logchildprocesshandling logclienthostnames logconnectionhandlingerrors \
+               logexceptionhits logfileformat loglevel loguseragent maxagechildren maxchildren maxcontentfilecachescansize \
+               maxcontentfiltersize maxcontentramcachescansize maxips maxsparechildren maxuploadsize minchildren minsparechildren \
+               nodaemon nologger nonstandarddelimiter perroomblockingdirectory phrasefiltermode prefercachedlists preforkchildren \
+               preservecase proxyip proxyport proxytimeout recheckreplacedurls reportinglevel reverseaddresslookups \
+               reverseclientiplookups scancleancache showweightedfound softrestart trickledelay urlcacheage urlcachenumber \
+               urlipcfilename usecustombannedflash usecustombannedimage usexforwardedfor weightedphrasemode
+
+       validate_dansguardian_section dansguardian || {
+               echo "validation failed"
+               return 1
+       }
+
+       mkdir -p $(dirname $CONFIGFILE)
+       ln -sf $config_file $(dirname $CONFIGFILE)
+
+       echo "accessdeniedaddress = " $accessdeniedaddress > $CONFIGFILE
+       echo "bannediplist = " $bannediplist >> $CONFIGFILE
+       echo "contentscanexceptions = " $contentscanexceptions >> $CONFIGFILE
+       echo "contentscannertimeout = " $contentscannertimeout >> $CONFIGFILE
+       echo "createlistcachefiles = " $createlistcachefiles >> $CONFIGFILE
+       echo "custombannedflashfile = " $custombannedflashfile >> $CONFIGFILE
+       echo "custombannedimagefile = " $custombannedimagefile >> $CONFIGFILE
+       echo "deletedownloadedtempfiles = " $deletedownloadedtempfiles >> $CONFIGFILE
+       echo "downloadmanager = " $downloadmanager >> $CONFIGFILE
+       echo "exceptioniplist = " $exceptioniplist >> $CONFIGFILE
+       echo "filecachedir = " $filecachedir >> $CONFIGFILE
+       echo "filtergroups = " $filtergroups >> $CONFIGFILE
+       echo "filtergroupslist = " $filtergroupslist >> $CONFIGFILE
+       echo "filterip = " $filterip >> $CONFIGFILE
+       echo "filterports = " $filterports >> $CONFIGFILE
+       echo "forcequicksearch = " $forcequicksearch >> $CONFIGFILE
+       echo "forwardedfor = " $forwardedfor >> $CONFIGFILE
+       echo "hexdecodecontent = " $hexdecodecontent >> $CONFIGFILE
+       echo "initialtrickledelay = " $initialtrickledelay >> $CONFIGFILE
+       echo "ipcfilename = " $ipcfilename >> $CONFIGFILE
+       echo "ipipcfilename = " $ipipcfilename >> $CONFIGFILE
+       echo "language = " $language >> $CONFIGFILE
+       echo "languagedir = " $languagedir >> $CONFIGFILE
+       echo "logadblocks = " $logadblocks >> $CONFIGFILE
+       echo "logchildprocesshandling = " $logchildprocesshandling >> $CONFIGFILE
+       echo "logclienthostnames = " $logclienthostnames >> $CONFIGFILE
+       echo "logconnectionhandlingerrors = " $logconnectionhandlingerrors >> $CONFIGFILE
+       echo "logexceptionhits = " $logexceptionhits >> $CONFIGFILE
+       echo "logfileformat = " $logfileformat >> $CONFIGFILE
+       echo "loglevel = " $loglevel >> $CONFIGFILE
+       echo "loglocation = " $loglocation >> $CONFIGFILE
+       echo "loguseragent = " $loguseragent >> $CONFIGFILE
+       echo "maxagechildren = " $maxagechildren >> $CONFIGFILE
+       echo "maxchildren = " $maxchildren >> $CONFIGFILE
+       echo "maxcontentfilecachescansize = " $maxcontentfilecachescansize >> $CONFIGFILE
+       echo "maxcontentfiltersize = " $maxcontentfiltersize >> $CONFIGFILE
+       echo "maxcontentramcachescansize = " $maxcontentramcachescansize >> $CONFIGFILE
+       echo "maxips = " $maxips >> $CONFIGFILE
+       echo "maxsparechildren = " $maxsparechildren >> $CONFIGFILE
+       echo "maxuploadsize = " $maxuploadsize >> $CONFIGFILE
+       echo "minchildren = " $minchildren >> $CONFIGFILE
+       echo "minsparechildren = " $minsparechildren >> $CONFIGFILE
+       echo "nodaemon = " $nodaemon >> $CONFIGFILE
+       echo "nologger = " $nologger >> $CONFIGFILE
+       echo "nonstandarddelimiter = " $nonstandarddelimiter >> $CONFIGFILE
+       echo "perroomblockingdirectory = " $perroomblockingdirectory >> $CONFIGFILE
+       echo "phrasefiltermode = " $phrasefiltermode >> $CONFIGFILE
+       echo "prefercachedlists = " $prefercachedlists >> $CONFIGFILE
+       echo "preforkchildren = " $preforkchildren >> $CONFIGFILE
+       echo "preservecase = " $preservecase >> $CONFIGFILE
+       echo "proxyip = " $proxyip >> $CONFIGFILE
+       echo "proxyport = " $proxyport >> $CONFIGFILE
+       echo "proxytimeout = " $proxytimeout >> $CONFIGFILE
+       echo "recheckreplacedurls = " $recheckreplacedurls >> $CONFIGFILE
+       echo "reportinglevel = " $reportinglevel >> $CONFIGFILE
+       echo "reverseaddresslookups = " $reverseaddresslookups >> $CONFIGFILE
+       echo "reverseclientiplookups = " $reverseclientiplookups >> $CONFIGFILE
+       echo "scancleancache = " $scancleancache >> $CONFIGFILE
+       echo "showweightedfound = " $showweightedfound >> $CONFIGFILE
+       echo "softrestart = " $softrestart >> $CONFIGFILE
+       echo "trickledelay = " $trickledelay >> $CONFIGFILE
+       echo "urlcacheage = " $urlcacheage >> $CONFIGFILE
+       echo "urlcachenumber = " $urlcachenumber >> $CONFIGFILE
+       echo "urlipcfilename = " $urlipcfilename >> $CONFIGFILE
+       echo "usecustombannedflash = " $usecustombannedflash >> $CONFIGFILE
+       echo "usecustombannedimage = " $usecustombannedimage >> $CONFIGFILE
+       echo "usexforwardedfor = " $usexforwardedfor >> $CONFIGFILE
+       echo "weightedphrasemode = " $weightedphrasemode >> $CONFIGFILE
+
+       procd_open_instance
+       procd_set_param command $PROG -N -c "$CONFIGFILE"
+       procd_set_param file $CONFIGFILE
+       procd_set_param respawn
+       procd_close_instance
+}
+
+stop_service()
+{
+       dansguardian -s | awk -F':' '{ print $2}' | xargs kill -9
+}
+
+service_triggers()
+{
+       procd_add_reload_trigger "dansguardian"
+       procd_add_validation validate_dansguardian_section
+}
diff --git a/net/dansguardian/files/dansguardianf1.conf b/net/dansguardian/files/dansguardianf1.conf
new file mode 100644 (file)
index 0000000..01e09ae
--- /dev/null
@@ -0,0 +1,348 @@
+# DansGuardian filter group config file for version 2.12.0.0
+
+
+# Filter group mode
+# This option determines whether members of this group have their web access
+# unfiltered, filtered, or banned. This mechanism replaces the "banneduserlist"
+# and "exceptionuserlist" files from previous versions.
+#
+# 0 = banned
+# 1 = filtered
+# 2 = unfiltered (exception)
+#
+# Only filter groups with a mode of 1 need to define phrase, URL, site, extension,
+# mimetype and PICS lists; in other modes, these options are ignored to conserve
+# memory.
+#
+# Defaults to 0 if unspecified.
+# Unauthenticated users are treated as being in the first filter group.
+groupmode = 1
+
+# Filter group name
+# Used to fill in the -FILTERGROUP- placeholder in the HTML template file, and to
+# name the group in the access logs
+# Defaults to empty string
+#groupname = ''
+
+# Content filtering files location
+bannedphraselist = '/etc/dansguardian/lists/bannedphraselist'
+weightedphraselist = '/etc/dansguardian/lists/weightedphraselist'
+exceptionphraselist = '/etc/dansguardian/lists/exceptionphraselist'
+bannedsitelist = '/etc/dansguardian/lists/bannedsitelist'
+greysitelist = '/etc/dansguardian/lists/greysitelist'
+exceptionsitelist = '/etc/dansguardian/lists/exceptionsitelist'
+bannedurllist = '/etc/dansguardian/lists/bannedurllist'
+greyurllist = '/etc/dansguardian/lists/greyurllist'
+exceptionurllist = '/etc/dansguardian/lists/exceptionurllist'
+exceptionregexpurllist = '/etc/dansguardian/lists/exceptionregexpurllist'
+bannedregexpurllist = '/etc/dansguardian/lists/bannedregexpurllist'
+picsfile = '/etc/dansguardian/lists/pics'
+contentregexplist = '/etc/dansguardian/lists/contentregexplist'
+urlregexplist = '/etc/dansguardian/lists/urlregexplist'
+
+# Filetype filtering
+#
+# Blanket download blocking
+# If enabled, all files will be blocked, unless they match the
+# exceptionextensionlist or exceptionmimetypelist.
+# These lists do not override virus scanning.
+# Exception lists defined above override all types of filtering, including
+# the blanket download block.
+# Defaults to disabled.
+# (on | off)
+#
+blockdownloads = off
+exceptionextensionlist = '/etc/dansguardian/lists/exceptionextensionlist'
+exceptionmimetypelist = '/etc/dansguardian/lists/exceptionmimetypelist'
+#
+# Use the following lists to block specific kinds of file downloads.
+# The two exception lists above can be used to override these.
+#
+bannedextensionlist = '/etc/dansguardian/lists/bannedextensionlist'
+bannedmimetypelist = '/etc/dansguardian/lists/bannedmimetypelist'
+#
+# In either file filtering mode, the following list can be used to override
+# MIME type & extension blocks for particular domains & URLs (trusted download sites).
+#
+exceptionfilesitelist = '/etc/dansguardian/lists/exceptionfilesitelist'
+exceptionfileurllist = '/etc/dansguardian/lists/exceptionfileurllist'
+
+# Categorise without blocking:
+# Supply categorised lists here and the category string shall be logged against
+# matching requests, but matching these lists does not perform any filtering
+# action.
+#logsitelist = '/etc/dansguardian/lists/logsitelist'
+#logurllist = '/etc/dansguardian/lists/logurllist'
+#logregexpurllist = '/etc/dansguardian/lists/logregexpurllist'
+
+# Outgoing HTTP header rules:
+# Optional lists for blocking based on, and modification of, outgoing HTTP
+# request headers.  Format for headerregexplist is one modification rule per
+# line, similar to content/URL modifications.  Format for
+# bannedregexpheaderlist is one regular expression per line, with matching
+# headers causing a request to be blocked.
+# Headers are matched/replaced on a line-by-line basis, not as a contiguous
+# block.
+# Use for example, to remove cookies or prevent certain user-agents.
+headerregexplist = '/etc/dansguardian/lists/headerregexplist'
+bannedregexpheaderlist = '/etc/dansguardian/lists/bannedregexpheaderlist'
+
+# Weighted phrase mode
+# Optional; overrides the weightedphrasemode option in dansguardian.conf
+# for this particular group.  See documentation for supported values in
+# that file.
+#weightedphrasemode = 0
+
+# Naughtiness limit
+# This the limit over which the page will be blocked.  Each weighted phrase is given
+# a value either positive or negative and the values added up.  Phrases to do with
+# good subjects will have negative values, and bad subjects will have positive
+# values.  See the weightedphraselist file for examples.
+# As a guide:
+# 50 is for young children,  100 for old children,  160 for young adults.
+naughtynesslimit = 50
+
+# Search term blocking
+# Search terms can be extracted from search URLs and filtered using the
+# bannedphraselist, weightedphraselist and exceptionphraselist, with a separate
+# threshold for blocking than that used for normal page content.
+# To do this, the first two options below must be enabled.
+#
+# Search engine regular expression list
+# List of regular expressions for matching search engine URLs.  It is assumed
+# that the search terms themselves will be contained within the first submatch
+# of each expression.
+#searchengineregexplist = '/etc/dansguardian/lists/searchengineregexplist'
+#
+# Search term limit
+# The limit over which requests will be blocked for containing search terms
+# which match the weightedphraselist.  This should usually be lower than the
+# 'naughtynesslimit' value above, because the amount of text being filtered
+# is only a few words, rather than a whole page.
+# This option must be uncommented if searchengineregexplist is uncommented.
+# A value of 0 here indicates that search terms should be extracted,
+# for logging/reporting purposes, but no filtering should be performed
+# on the resulting text.
+#searchtermlimit = 30
+#
+# Search term lists
+# If the three lines below are uncommented, search term blocking will use
+# the banned, weighted & exception phrases from these lists, instead of using
+# the same phrase lists as for page content.  This is optional but recommended,
+# as weights for individual phrases in the "normal" lists may not be
+# appropriate for blocking when those phrases appear in a much smaller block
+# of text.
+# Please note that all or none of the below should be uncommented, not a
+# mixture.
+#bannedsearchtermlist = '/etc/dansguardian/lists/bannedsearchtermlist'
+#weightedsearchtermlist = '/etc/dansguardian/lists/weightedsearchtermlist'
+#exceptionsearchtermlist = '/etc/dansguardian/lists/exceptionsearchtermlist'
+
+# Category display threshold
+# This option only applies to pages blocked by weighted phrase filtering.
+# Defines the minimum score that must be accumulated within a particular
+# category in order for it to show up on the block pages' category list.
+# All categories under which the page scores positively will be logged; those
+# that were not displayed to the user appear in brackets.
+#
+# -1 = display only the highest scoring category
+# 0 = display all categories (default)
+# > 0 = minimum score for a category to be displayed
+categorydisplaythreshold = 0
+
+# Embedded URL weighting
+# When set to something greater than zero, this option causes URLs embedded within a
+# page's HTML (from links, image tags, etc.) to be extracted and checked against the
+# bannedsitelist and bannedurllist. Each link to a banned page causes the amount set
+# here to be added to the page's weighting.
+# The behaviour of this option with regards to multiple occurrences of a site/URL is
+# affected by the weightedphrasemode setting.
+#
+# NB: Currently, this feature uses regular expressions that require the PCRE library.
+# As such, it is only available if you compiled DansGuardian with '--enable-pcre=yes'.
+# You can check compile-time options by running 'dansguardian -v'.
+#
+# Set to 0 to disable.
+# Defaults to 0.
+# WARNING: This option is highly CPU intensive!
+embeddedurlweight = 0
+
+# Enable PICS rating support
+#
+# Defaults to disabled
+# (on | off)
+enablepics = off
+
+# Temporary Denied Page Bypass
+# This provides a link on the denied page to bypass the ban for a few minutes.  To be
+# secure it uses a random hashed secret generated at daemon startup.  You define the
+# number of seconds the bypass will function for before the deny will appear again.
+# To allow the link on the denied page to appear you will need to edit the template.html
+# or dansguardian.pl file for your language.
+# 300 = enable for 5 minutes
+# 0 = disable ( defaults to 0 )
+# -1 = enable but you require a separate program/CGI to generate a valid link
+bypass = 0
+
+# Temporary Denied Page Bypass Secret Key
+# Rather than generating a random key you can specify one.  It must be more than 8 chars.
+# '' = generate a random one (recommended and default)
+# 'Mary had a little lamb.' = an example
+# '76b42abc1cd0fdcaf6e943dcbc93b826' = an example
+bypasskey = ''
+
+# Infection/Scan Error Bypass
+# Similar to the 'bypass' setting, but specifically for bypassing files scanned and found
+# to be infected, or files that trigger scanner errors - for example, archive types with
+# recognised but unsupported compression schemes, or corrupt archives.
+# The option specifies the number of seconds for which the bypass link will be valid.
+# 300 = enable for 5 minutes
+# 0 = disable (default)
+# -1 = enable, but require a separate program/CGI to generate a valid link
+infectionbypass = 0
+
+# Infection/Scan Error Bypass Secret Key
+# Same as the 'bypasskey' option, but used for infection bypass mode.
+infectionbypasskey = ''
+
+# Infection/Scan Error Bypass on Scan Errors Only
+# Enable this option to allow infectionbypass links only when virus scanning fails,
+# not when a file is found to contain a virus.
+# on = enable (default and highly recommended)
+# off = disable
+infectionbypasserrorsonly = on
+
+# Disable content scanning
+# If you enable this option you will disable content scanning for this group.
+# Content scanning primarily is AV scanning (if enabled) but could include
+# other types.
+# (on|off) default = off.
+disablecontentscan = off
+
+# Enable Deep URL Analysis
+# When enabled, DG looks for URLs within URLs, checking against the bannedsitelist and
+# bannedurllist. This can be used, for example, to block images originating from banned
+# sites from appearing in Google Images search results, as the original URLs are
+# embedded in the thumbnail GET requests.
+# (on|off) default = off
+deepurlanalysis = off
+
+# reportinglevel
+#
+# -1 = log, but do not block - Stealth mode
+#  0 = just say 'Access Denied'
+#  1 = report why but not what denied phrase
+#  2 = report fully
+#  3 = use HTML template file (accessdeniedaddress ignored) - recommended
+#
+# If defined, this overrides the global setting in dansguardian.conf for
+# members of this filter group.
+#
+#reportinglevel = 3
+
+# accessdeniedaddress is the address of your web server to which the cgi
+# dansguardian reporting script was copied. Only used in reporting levels
+# 1 and 2.
+#
+# This webserver must be either:
+#  1. Non-proxied. Either a machine on the local network, or listed as an
+#     exception in your browser's proxy configuration.
+#  2. Added to the exceptionsitelist. Option 1 is preferable; this option is
+#     only for users using both transparent proxying and a non-local server
+#     to host this script.
+#
+# If defined, this overrides the global setting in dansguardian.conf for
+# members of this filter group.
+#
+#accessdeniedaddress = 'http://YOURSERVER.YOURDOMAIN/cgi-bin/dansguardian.pl'
+
+# HTML Template override
+# If defined, this specifies a custom HTML template file for members of this
+# filter group, overriding the global setting in dansguardian.conf. This is
+# only used in reporting level 3.
+#
+# The default template file path is <languagedir>/<language>/template.html
+# e.g. /usr/share/dansguardian/languages/ukenglish/template.html when using 'ukenglish'
+# language.
+#
+# This option generates a file path of the form:
+# <languagedir>/<language>/<htmltemplate>
+# e.g. /usr/share/dansguardian/languages/ukenglish/custom.html
+#
+#htmltemplate = 'custom.html'
+
+# Email reporting - original patch by J. Gauthier
+
+# Use SMTP
+# If on, will enable system wide events to be reported by email.
+# need to configure mail program (see 'mailer' in global config)
+# and email recipients
+# default usesmtp = off
+#!! Not compiled !!usesmtp = off
+
+# mailfrom
+# who the email would come from
+# example: mailfrom = 'dansguardian@mycompany.com'
+#!! Not compiled !!mailfrom = ''
+
+# avadmin
+# who the virus emails go to (if notify av is on)
+# example: avadmin = 'admin@mycompany.com'
+#!! Not compiled !!avadmin = ''
+
+# contentdmin
+# who the content emails go to (when thresholds are exceeded)
+# and contentnotify is on
+# example: contentadmin = 'admin@mycompany.com'
+#!! Not compiled !!contentadmin = ''
+
+# avsubject
+# Subject of the email sent when a virus is caught.
+# only applicable if notifyav is on
+# default avsubject = 'dansguardian virus block'
+#!! Not compiled !!avsubject = 'dansguardian virus block'
+
+# content
+# Subject of the email sent when violation thresholds are exceeded
+# default contentsubject = 'dansguardian violation'
+#!! Not compiled !!contentsubject = 'dansguardian violation'
+
+# notifyAV
+# This will send a notification, if usesmtp/notifyav is on, any time an
+# infection is found.
+# Important: If this option is off, viruses will still be recorded like a
+# content infraction.
+#!! Not compiled !!notifyav = off
+
+# notifycontent
+# This will send a notification, if usesmtp is on, based on thresholds
+# below
+#!! Not compiled !!notifycontent = off
+
+# thresholdbyuser
+# results are only predictable with user authenticated configs
+# if enabled the violation/threshold count is kept track of by the user
+#!! Not compiled !!thresholdbyuser = off
+
+#violations
+# number of violations before notification
+# setting to 0 will never trigger a notification
+#!! Not compiled !!violations = 0
+
+#threshold
+# this is in seconds. If 'violations' occur in 'threshold' seconds, then
+# a notification is made.
+# if this is set to 0, then whenever the set number of violations are made a
+# notifaction will be sent.
+#!! Not compiled !!threshold = 0
+
+#SSL certificate checking
+# Check that ssl certificates for servers on https connections are valid
+# and signed by a ca in the configured path
+sslcertcheck = off
+
+#SSL man in the middle
+# Forge ssl certificates for all sites, decrypt the data then re encrypt it
+# using a different private key. Used to filter ssl sites
+sslmitm = off
+
diff --git a/net/dansguardian/patches/001-compile.patch b/net/dansguardian/patches/001-compile.patch
new file mode 100644 (file)
index 0000000..db8efa4
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/configure
++++ b/configure
+@@ -827,7 +827,7 @@ sysconfdir='${prefix}/etc'
+ sharedstatedir='${prefix}/com'
+ localstatedir='${prefix}/var'
+ includedir='${prefix}/include'
+-oldincludedir='/usr/include'
++oldincludedir='${prefix}/usr/include'
+ docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+ infodir='${datarootdir}/info'
+ htmldir='${docdir}'
+@@ -5265,7 +5265,7 @@ $as_echo_n "checking for zlib... " >&6;
+ # Check whether --with-zlib was given.
+ if test "${with_zlib+set}" = set; then :
+   withval=$with_zlib;  # check for header & func (in library) in given prefix
+-      CPPFLAGS="${CPPFLAGS} -I${withval}/include"
++      CPPFLAGS="${CPPFLAGS}"
+       if test "x$staticzlib" = "xtrue"; then
+               LIBS="-Bstatic -L${withval} -lz -Bdynamic ${LIBS}"
+       else
+@@ -7095,7 +7095,7 @@ $as_echo "#define ENABLE_NTLM /**/" >>co
+ if test "${with_libiconv+set}" = set; then :
+   withval=$with_libiconv;  # check for header & func (in library) in given prefix
+                       if test "x$withval" != "x"; then
+-                              CPPFLAGS="${CPPFLAGS} -I${withval}/include"
++                              CPPFLAGS="${CPPFLAGS}"
+                               LIBS="-L${withval}/lib -liconv ${LIBS}"
+                       else
+                               LIBS="-liconv ${LIBS}"
index fc247b8eb9d9927b08c01fb13f6eadc38361d14b..96de63c22eda34f9271dfd4bb821abae624083ea 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -15,6 +15,8 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/davfs2/
 PKG_MD5SUM:=376bc9346454135cba78afacbcb23f86
 
+PKG_FIXUP:=gettext-version autoreconf
+
 include $(INCLUDE_DIR)/package.mk
 
 define Package/davfs2
index 71ab4b66e58a3650818b1edd3af9a13203ec1419..231d1ca196c572de76be998304da23e7c9ca2086 100644 (file)
@@ -1,9 +1,10 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ddns-scripts
-PKG_VERSION:=2.0.1
-PKG_RELEASE:=8
+PKG_VERSION:=2.1.0
+PKG_RELEASE:=5
 PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 
@@ -15,12 +16,10 @@ define Package/ddns-scripts
     SUBMENU:=IP Addresses and Names
     TITLE:=Dynamic DNS Scripts (with IPv6 support)
     PKGARCH:=all
-    MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
 endef
 
 define Package/ddns-scripts/description
-       A highly configurable set of scripts for doing dynamic dns updates. 
-       NEW in this version:
+A highly configurable set of scripts for doing dynamic dns updates.
        - IPv6 support
        - force communication to IPv4 or IPv6 only
        - DNS server support
@@ -55,22 +54,23 @@ define Package/ddns-scripts/install
        $(INSTALL_BIN) ./files/etc/init.d/* $(1)/etc/init.d/
 
        $(INSTALL_DIR) $(1)/usr/lib/ddns
-       $(INSTALL_DATA) ./files/usr/lib/ddns/service* $(1)/usr/lib/ddns
+       $(INSTALL_DATA) ./files/usr/lib/ddns/* $(1)/usr/lib/ddns
        $(INSTALL_BIN)  ./files/usr/lib/ddns/*.sh $(1)/usr/lib/ddns
 endef
 
 define Package/ddns-scripts/postinst
        #!/bin/sh
        # if run within buildroot exit
-       [ -n "${IPKG_INSTROOT}" ] && exit 0
+       [ -n "$${IPKG_INSTROOT}" ] && exit 0
 
        # add new section "ddns" "global" if not exists
        uci -q get ddns.global > /dev/null || uci -q set ddns.global='ddns'
        uci -q get ddns.global.date_format > /dev/null || uci -q set ddns.global.date_format='%F %R'
        uci -q get ddns.global.log_lines > /dev/null || uci -q set ddns.global.log_lines='250'
+       uci -q get ddns.global.allow_local_ip > /dev/null || uci -q set ddns.global.allow_local_ip='0'
        uci -q commit ddns
 
-       # clear LuCI indexcache 
+       # clear LuCI indexcache
        rm -f /tmp/luci-indexcache >/dev/null 2>&1
 
        exit 0
@@ -79,13 +79,13 @@ endef
 define Package/ddns-scripts/prerm
        #!/bin/sh
        # if run within buildroot exit
-       [ -n "${IPKG_INSTROOT}" ] && exit 0
+       [ -n "$${IPKG_INSTROOT}" ] && exit 0
 
        # stop running scripts
        /etc/init.d/ddns disable
        /etc/init.d/ddns stop
 
-       # clear LuCI indexcache 
+       # clear LuCI indexcache
        rm -f /tmp/luci-indexcache >/dev/null 2>&1
 
        exit 0
index 54ec42c125d7e380bafeab5c83a588932b299833..57b5477f88ed1c6a7e9700655e331cd7ed6db366 100644 (file)
@@ -1,16 +1,18 @@
 #
 # Please read ddns.sample
+# or http://wiki.openwrt.org/doc/uci/ddns
 #
 config ddns "global"
        option date_format "%F %R"
 #      option run_dir "/var/run/ddns"
 #      option log_dir "/var/log/ddns"
        option log_lines "250"
+       option allow_local_ip "0"
 
 
 config service "myddns_ipv4"
-       option service_name     "dyndns.org"
-       option domain           "yourhost.dyndns.org"
+       option service_name     "example.org"
+       option domain           "yourhost.example.com"
        option username         "your_username"
        option password         "your_password"
        option interface        "wan"
@@ -19,11 +21,11 @@ config service "myddns_ipv4"
 
 config service "myddns_ipv6"
        option update_url       "http://[USERNAME]:[PASSWORD]@your.provider.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
-       option domain           "yourhost.dyndns.org"
+       option domain           "yourhost.example.com"
        option username         "your_username"
        option password         "your_password"
        option use_ipv6         "1"
        option interface        "wan6"
        option ip_source        "network"
        option ip_network       "wan6"
-       
+
index 8625b3899850ce81fb4ec1e033237235828859bd..8d59ab8595cddb97c9180c2ff85b71d9e6b8ed03 100644 (file)
@@ -4,18 +4,18 @@
 # and used by ddns-scripts and corresponding LuCI application
 #
 # Inside your ddns configuration file (/etc/config/ddns)
-# you might not find some of below described options. 
+# you might not find some of below described options.
 # This is because you don't need to define options
 # if using there defaults. The LuCI application will delete
 # options that configured to there default values.
 #
 # If you have a working ddns configuration from old ddns-scripts (Version 1.x)
-# everything will function the same with new scripts 
+# everything will function the same with new scripts
 # without any changes to the configuration.
 #
 # If you like to use this file for your configuration then
-# use a copy, because the used software to modify the 
-# configuration files will throw away all empty lines 
+# use a copy, because the used software to modify the
+# configuration files will throw away all empty lines
 # and those starting with # (comments).
 #
 
@@ -48,6 +48,12 @@ config ddns "global"
        # default: "250" lines
 #      option log_lines "250"
 
+       ###########
+       # Whether to allow to send Private/Special IP's to the DDNS provider
+       # IPv4: 0.x, 10.x, 127.x, 172.16.x-172.31.x, 192.168.x
+       # IPv6: ::, Fxxx:
+       # default: "0"  disabled
+#      option allow_local_ip "0"
 
 #####################################################################
 # DDNS service settings
@@ -55,10 +61,10 @@ config ddns "global"
 # for each service you want to serve you need a separate configuration
 # if you need IPv4 and IPv6 you need to setup 2 separate configurations
 # with different names. (i.e. "myddns_ipv4" and "myddns_ipv6")
-# do not use white-spaces or dashes "-" or "@" ":" "!" or 
+# do not use white-spaces or dashes "-" or "@" ":" "!" or
 # other special characters inside name.
 config service "myddns"
-       
+
        ########### Basic settings ########################
 
        ###########
@@ -74,22 +80,22 @@ config service "myddns"
 
        ###########
        # defines the network as defined in /etc/config/network
-       # to be monitored for up/down events to start via hotplug 
+       # to be monitored for up/down events to start via hotplug
        default: "wan"  for IPv4
        default: "wan6" for IPv6
        option interface "wan"
 
        ###########
-       # Next you need to specify the name of the service you are 
+       # Next you need to specify the name of the service you are
        # connecting to "eg. dyndns.org".  The format of the update
        # urls for several different dynamic dns services is specified
-       # in the "/usr/lib/ddns/services" file for IPv4 and in 
+       # in the "/usr/lib/ddns/services" file for IPv4 and in
        # "/usr/lib/ddns/service_ipv6" file. This list is hardly complete
        # as there are many, many different dynamic dns services.
-       # If your service is on the list you can merely specify it with the 
+       # If your service is on the list you can merely specify it with the
        # "service_name" option.  Otherwise you will need to determine
        # the format of the url to update with.  You can either add an
-       # entry to the "/usr/lib/ddns/services" or "services_ipv6" file 
+       # entry to the "/usr/lib/ddns/services" or "services_ipv6" file
        # or specify this with the "update_url" option.
        # If your ddns provider doesn't work with ddns-scripts because
        # there are additional parameters or other special thinks to be done,
@@ -100,18 +106,18 @@ config service "myddns"
        # default: none
        option service_name "dyndns.org"
 
-       # sample: 
+       # sample:
        # "http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
 #      option update_url   ""
 
-       # sample: 
+       # sample:
        # "/usr/lib/ddns/update_sample.sh"
 #      option update_script   ""
 
        ###########
        # You must specify your domain/host name, your username and your password
        # as you get from you DDNS provider. Keep an eye on providers help pages.
-       #       
+       #
        # Your DNS name / replace [DOMAIN] in update_url
        # default: none
        option domain ""
@@ -126,21 +132,21 @@ config service "myddns"
 
        ###########
        # use HTTPS for secure communication with you DDNS provider
-       # personally found some providers having problems when not sending 
-       # updates via HTTPS. Yyou must not specify "https://" in update_url. 
+       # personally found some providers having problems when not sending
+       # updates via HTTPS. You must not specify "https://" in update_url.
        # It's modified by the scripts themselves
        # Needs GNU Wget (with SSL support) or cURL to be installed.
        # default: "0"  do not use HTTPS
        option use_https "0"
 
-       # if using HTTPS (see above) the transfer program tries to verify 
+       # if using HTTPS (see above) the transfer program tries to verify
        # the providers server certificate. For verification there needs to be
        # the counterpart on this machine. Specify the path or path/file where
        # the transfer program can find them. (might need package CA-certificates)
        # if you don't want to verify servers certificate (insecure) you should
        # this parameter to "IGNORE" (in capital letters)
-       # default: "/etc/cacert"        path where CA-certificate package is installed
-       option cacert "/etc/cacert"
+       # default: (none)       path where CA-certificate package is installed
+       option cacert "/etc/ssl/certs"
 
        ###########
        # for logging and control if everything work fine you can get information inside
@@ -176,7 +182,7 @@ config service "myddns"
        option ip_source  "network"
        option ip_network "wan"
 
-       # ip_source "web" additional uses option ip_url and detects the current 
+       # ip_source "web" additional uses option ip_url and detects the current
        # local ip from special web sides that response with the ip address of
        # calling host. If you are behind a firewall/NAT this is the best option
        # since none of the local networks or interfaces will have the external ip.
@@ -201,8 +207,8 @@ config service "myddns"
 #      option ip_script ""
 
        ###########
-       # force_ipversion option will set the "-4" respectively "-6" parameter 
-       # on command line of transfer and DNS lookup program. 
+       # force_ipversion option will set the "-4" respectively "-6" parameter
+       # on command line of transfer and DNS lookup program.
        # So the whole communication uses the selected IP version between both ends.
        # needs GNU Wget or cURL installed for transfer and
        # BIND's host for DNS lookup.
@@ -210,11 +216,10 @@ config service "myddns"
        option force_ipversion "0"
 
        ###########
-       # normally the current (in the internet) registered ip is detected using the
+       # Normally the current (in the internet) registered ip is detected using the
        # local defined name lookup policies (i.e. /etc/resolve.conf etc.)
        # Specify here a DNS server to use instead of the defaults.
        # you can use hostname or ip address
-       # IPv6 address must be in squared brackets "[...]"
        # i.e. "google-public-dns-a.google.com"
        # default: none
 #      option dns_server "google-public-dns-a.google.com"
@@ -231,11 +236,12 @@ config service "myddns"
        # If a Proxy is need to access HTTP/HTTPS pages on the WEB
        # it can be configured here also for sending updates to the
        # DDNS provider. If you configured use_https='1' above, you
-       # need to setup your HTTPS proxy here, otherwise your 
+       # need to setup your HTTPS proxy here, otherwise your
        # HTTP proxy. !!! You should not detect your current IP
-       # ip_source='web' (see above) because this request is also 
+       # ip_source='web' (see above) because this request is also
        # send via the configured proxy !!!
        # Syntax: [user:password@]proxy:port !port is required !
+       # IPv6 address must be in squared brackets "[...]"
        # default: none
 #      option proxy ''
 
@@ -245,9 +251,9 @@ config service "myddns"
        # defines the time interval to check if local IP has changed
        # After the first start and first update send, the system will
        # wait this time before verify if update was successful send.
-       # !!! checks below 5 minutes make no sense because the Internet 
+       # !!! checks below 5 minutes make no sense because the Internet
        # needs about 5-10 minutes to sync an IP-change to all DNS servers !!!
-       # accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
+       # accepted unit entry’s: 'seconds' 'minutes' 'hours'
        # minimum 5 minutes == 300 seconds
        # default 10 minutes
        option check_interval   '10'
@@ -256,11 +262,11 @@ config service "myddns"
        ###########
        # force to send an update to service provider, if no change was detected.
        # consult DDNS providers documentation if your DDNS entry might timeout.
-       # accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
+       # accepted unit entry’s: 'minutes' 'hours' 'days'
        # minimum needs to be greater or equal check interval (see above)
        # A special setting of '0' is allowed, which forces the script to run once.
-       # It sends an update, verify if update was accepted by DNS 
-       # (retry if not) and finish. Useful if you want to start by your own (i.e. cron) 
+       # It sends an update, verify if update was accepted by DNS
+       # (retry if not) and finish. Useful if you want to start by your own (i.e. cron)
        # default 3 days == 72 hours
        option force_interval   '72'
        option force_unit       'hours'
@@ -276,7 +282,7 @@ config service "myddns"
        # if error happen on detecting, sending or updating the
        # script will retry the relevant action.
        # here you define the time to wait before retry is started
-       # accepted unit entry’s: 'seconds' 'minutes' 'hours' 'days'
+       # accepted unit entry’s: 'seconds' 'minutes'
        # default: 60 seconds
        option retry_interval   '60'
        option retry_unit       'seconds'
diff --git a/net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns b/net/ddns-scripts/files/etc/hotplug.d/iface/25-ddns
deleted file mode 100644 (file)
index dab2385..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-if [ "$ACTION" = "ifup" ]; then
-       . /usr/lib/ddns/dynamic_dns_functions.sh
-       /etc/init.d/ddns enabled && start_daemon_for_all_ddns_sections "$INTERFACE"
-fi
-
-
diff --git a/net/ddns-scripts/files/etc/hotplug.d/iface/95-ddns b/net/ddns-scripts/files/etc/hotplug.d/iface/95-ddns
new file mode 100644 (file)
index 0000000..dfb35f6
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# there are other ACTIONs like ifupdate we don't need
+# so parse dynamic_dns_functions.sh only when needed
+case "$ACTION" in
+       ifup)
+               . /usr/lib/ddns/dynamic_dns_functions.sh
+               /etc/init.d/ddns enabled && start_daemon_for_all_ddns_sections "$INTERFACE"
+               ;;
+       ifdown)
+               . /usr/lib/ddns/dynamic_dns_functions.sh
+               stop_daemon_for_all_ddns_sections "$INTERFACE"
+               ;;
+esac
index 1194543cbac3f3d3c15e6bf9c263835ab96234e7..3618621160e7314afb5fc5313c6a48ae11c2ec99 100644 (file)
@@ -1,16 +1,26 @@
 #!/bin/sh /etc/rc.common
 START=95
+STOP=10
 
 boot() {
        return 0
 }
 
+reload() {
+       killall -1 dynamic_dns_updater.sh 2>/dev/null   # send SIGHUP
+}
+
+restart() {
+       stop
+       sleep 1 # give time to shutdown
+       start
+}
+
 start() {
        . /usr/lib/ddns/dynamic_dns_functions.sh
        start_daemon_for_all_ddns_sections
 }
 
 stop() {
-       killall -9 dynamic_dns_updater.sh
+       killall dynamic_dns_updater.sh 2>/dev/null
 }
-
diff --git a/net/ddns-scripts/files/usr/lib/ddns/create_cert_hashes.sh b/net/ddns-scripts/files/usr/lib/ddns/create_cert_hashes.sh
deleted file mode 100644 (file)
index ff788c3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-#set -vx
-
-[ -d /etc/ssl/certs ] || {
-        echo "CA-Certificates not istalled - please install first"
-        exit 1
-}
-
-NUMCERT=$(find /etc/ssl/certs -name *.crt 2>/dev/null | wc -l)
-NUMLINK=$(find /etc/ssl/certs -type l 2>/dev/null | wc -l)
-
-[ $NUMLINK -gt 0 ] && {
-       echo "File-Links already exist. Exiting"
-       exit 0
-}
-
-[ -f /usr/bin/openssl ] && OPENSSL="EXIST"
-[ -z "$OPENSSL" ] && {
-       opkg update || exit 1
-       opkg install openssl-util 2>/dev/null
-}
-
-for CERTFILE in `ls -1 $(1)/etc/ssl/certs`; do \
-       HASH=`openssl x509 -hash -noout -in /etc/ssl/certs/$CERTFILE`
-       SUFFIX=0
-       while [ -h "/etc/ssl/certs/$HASH.$SUFFIX" ]; do
-               let "SUFFIX += 1"
-       done
-       ln -s "$CERTFILE" "/etc/ssl/certs/$HASH.$SUFFIX"
-       echo "link $HASH.$SUFFIX created for $CERTFILE"
-done
-
-[ -z "$OPENSSL" ] && opkg remove --force-remove --autoremove openssl-util 2>/dev/null
index 33aeb19793a5b71d064d053bd24196c6d340a7cc..4160911197a20b63ee6ac232f106e489e3087db1 100644 (file)
@@ -6,24 +6,24 @@
 # (Loosely) based on the script on the one posted by exobyte in the forums here:
 # http://forum.openwrt.org/viewtopic.php?id=14040
 #
-# extended and partial rewritten in August 2014 
+# extended and partial rewritten in August 2014
 # by Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
 # to support:
 # - IPv6 DDNS services
 # - setting DNS Server to retrieve current IP including TCP transport
 # - Proxy Server to send out updates or retrieving WEB based IP detection
-# - force_interval=0 to run once (usefull for cron jobs etc.)
+# - force_interval=0 to run once (useful for cron jobs etc.)
 # - the usage of BIND's host instead of BusyBox's nslookup if installed (DNS via TCP)
-# - extended Verbose Mode and log file support for better error detection 
+# - extended Verbose Mode and log file support for better error detection
 #
-# function __timeout
+# function timeout
 # copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh
 # @author Anthony Thyssen  6 April 2011
 #
 # variables in small chars are read from /etc/config/ddns
 # variables in big chars are defined inside these scripts as global vars
 # variables in big chars beginning with "__" are local defined inside functions only
-#set -vx       #script debugger
+# set -vx      #script debugger
 
 . /lib/functions.sh
 . /lib/functions/network.sh
 # GLOBAL VARIABLES #
 SECTION_ID=""          # hold config's section name
 VERBOSE_MODE=1         # default mode is log to console, but easily changed with parameter
-LUCI_HELPER=""         # set by dynamic_dns_lucihelper.sh, if filled supress all error logging
 
+                       # allow NON-public IP's
+ALLOW_LOCAL_IP=$(uci -q get ddns.global.allow_local_ip) || ALLOW_LOCAL_IP=0
+                       # directory to store run information to.
+RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns"
+[ -d $RUNDIR ] || mkdir -p -m755 $RUNDIR
+                       # directory to store log files
+LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns"
+[ -d $LOGDIR ] || mkdir -p -m755 $LOGDIR
+LOGFILE=""             # logfile - all files are set in dynamic_dns_updater.sh
 PIDFILE=""             # pid file
 UPDFILE=""             # store UPTIME of last update
+DATFILE=""             # save stdout data of WGet and other external programs called
+ERRFILE=""             # save stderr output of WGet and other external programs called
+TLDFILE=/usr/lib/ddns/tld_names.dat    # TLD file used by split_FQDN
 
-# directory to store run information to. 
-RUNDIR=$(uci -q get ddns.global.run_dir) || RUNDIR="/var/run/ddns"
-# NEW # directory to store log files
-LOGDIR=$(uci -q get ddns.global.log_dir) || LOGDIR="/var/log/ddns"
-LOGFILE=""             # NEW # logfile can be enabled as new option
-# number of lines to before rotate logfile
+                       # number of lines to before rotate logfile
 LOGLINES=$(uci -q get ddns.global.log_lines) || LOGLINES=250
+LOGLINES=$((LOGLINES + 1))     # correct sed handling
 
 CHECK_SECONDS=0                # calculated seconds out of given
 FORCE_SECONDS=0                # interval and unit
 RETRY_SECONDS=0                # in configuration
 
-OLD_PID=0              # Holds the PID of already running process for the same config section
-
 LAST_TIME=0            # holds the uptime of last successful update
 CURR_TIME=0            # holds the current uptime
 NEXT_TIME=0            # calculated time for next FORCED update
@@ -58,12 +63,14 @@ EPOCH_TIME=0                # seconds since 1.1.1970 00:00:00
 REGISTERED_IP=""       # holds the IP read from DNS
 LOCAL_IP=""            # holds the local IP read from the box
 
+URL_USER=""            # url encoded $username from config file
+URL_PASS=""            # url encoded $password from config file
+
 ERR_LAST=0             # used to save $? return code of program and function calls
-ERR_LOCAL_IP=0         # error counter on getting local ip
-ERR_REG_IP=0           # error counter on getting DNS registered ip
-ERR_SEND=0             # error counter on sending update to DNS provider
 ERR_UPDATE=0           # error counter on different local and registered ip
 
+PID_SLEEP=0            # ProcessID of current background "sleep"
+
 # format to show date information in log and luci-app-ddns default ISO 8601 format
 DATE_FORMAT=$(uci -q get ddns.global.date_format) || DATE_FORMAT="%F %R"
 DATE_PROG="date +'$DATE_FORMAT'"
@@ -74,6 +81,9 @@ IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
 # IPv6       ( ( 0-9a-f  1-4char ":") min 1x) ( ( 0-9a-f  1-4char   )optional) ( (":" 0-9a-f 1-4char  ) min 1x)
 IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
 
+# detect if called by dynamic_dns_lucihelper.sh script, disable retrys (empty variable == false)
+[ "$(basename $0)" = "dynamic_dns_lucihelper.sh" ] && LUCI_HELPER="TRUE" || LUCI_HELPER=""
+
 # loads all options for a given package and section
 # also, sets all_option_variables to a list of the variable names
 # $1 = ddns, $2 = SECTION_ID
@@ -101,7 +111,7 @@ load_all_config_options()
        }
 
        config_load "$__PKGNAME"
-       
+
        # Given SECTION_ID not found so no data, so return 1
        [ -z "$__ALL_OPTION_VARIABLES" ] && return 1
 
@@ -112,9 +122,26 @@ load_all_config_options()
        return 0
 }
 
+# read's all service sections from ddns config
+# $1 = Name of variable to store
+load_all_service_sections() {
+       local __DATA=""
+       config_cb()
+       {
+               # only look for section type "service", ignore everything else
+               [ "$1" = "service" ] && __DATA="$__DATA $2"
+       }
+       config_load "ddns"
+
+       eval "$1=\"$__DATA\""
+       return
+}
+
 # starts updater script for all given sections or only for the one given
 # $1 = interface (Optional: when given only scripts are started
 # configured for that interface)
+# used by /etc/hotplug.d/iface/25-ddns on IFUP
+# and by /etc/init.d/ddns start
 start_daemon_for_all_ddns_sections()
 {
        local __EVENTIF="$1"
@@ -122,59 +149,101 @@ start_daemon_for_all_ddns_sections()
        local __SECTIONID=""
        local __IFACE=""
 
-       config_cb() 
-       {
-               # only look for section type "service", ignore everything else
-               [ "$1" == "service" ] && __SECTIONS="$__SECTIONS $2"
+       load_all_service_sections __SECTIONS
+       for __SECTIONID in $__SECTIONS; do
+               config_get __IFACE "$__SECTIONID" interface "wan"
+               [ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue
+               /usr/lib/ddns/dynamic_dns_updater.sh $__SECTIONID 0 >/dev/null 2>&1 &
+       done
+}
+
+# stop sections process incl. childs (sleeps)
+# $1 = section
+stop_section_processes() {
+       local __PID=0
+       local __PIDFILE="$RUNDIR/$1.pid"
+       [ $# -ne 1 ] && write_log 12 "Error calling 'stop_section_processes()' - wrong number of parameters"
+
+       [ -e "$__PIDFILE" ] && {
+               __PID=$(cat $__PIDFILE)
+               ps | grep "^[\t ]*$__PID" >/dev/null 2>&1 && kill $__PID || __PID=0     # terminate it
        }
-       config_load "ddns"
+       [ $__PID -eq 0 ] # report if process was running
+}
 
-       for __SECTIONID in $__SECTIONS
-       do
+# stop updater script for all defines sections or only for one given
+# $1 = interface (optional)
+# used by /etc/hotplug.d/iface/25-ddns on 'ifdown'
+# and by /etc/init.d/ddns stop
+# needed because we also need to kill "sleep" child processes
+stop_daemon_for_all_ddns_sections() {
+       local __EVENTIF="$1"
+       local __SECTIONS=""
+       local __SECTIONID=""
+       local __IFACE=""
+
+       load_all_service_sections __SECTIONS
+       for __SECTIONID in $__SECTIONS; do
                config_get __IFACE "$__SECTIONID" interface "wan"
                [ -z "$__EVENTIF" -o "$__IFACE" = "$__EVENTIF" ] || continue
-               /usr/lib/ddns/dynamic_dns_updater.sh $__SECTIONID 0 > /dev/null 2>&1 &
+               stop_section_processes "$__SECTIONID"
        done
 }
 
-verbose_echo()
-{
-       [ -n "$LUCI_HELPER" ] && return # nothing to report when used by LuCI helper script
-       [ $VERBOSE_MODE -gt 0 ] && echo -e " $*"
-       if [ ${use_logfile:-0} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then
-               [ -d $LOGDIR ] || mkdir -p -m 755 $LOGDIR
-               echo -e " $*" >> $LOGFILE
+# reports to console, logfile, syslog
+# $1   loglevel 7 == Debug to 0 == EMERG
+#      value +10 will exit the scripts
+# $2..n        text to report
+write_log() {
+       local __LEVEL __EXIT __CMD __MSG
+       local __TIME=$(date +%H%M%S)
+       [ $1 -ge 10 ] && {
+               __LEVEL=$(($1-10))
+               __EXIT=1
+       } || {
+               __LEVEL=$1
+               __EXIT=0
+       }
+       shift   # remove loglevel
+       [ $__EXIT -eq 0 ] && __MSG="$*" || __MSG="$* - TERMINATE"
+       case $__LEVEL in                # create log message and command depending on loglevel
+               0)      __CMD="logger -p user.emerg -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME EMERG : $__MSG" ;;
+               1)      __CMD="logger -p user.alert -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME ALERT : $__MSG" ;;
+               2)      __CMD="logger -p user.crit -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME  CRIT : $__MSG" ;;
+               3)      __CMD="logger -p user.err -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME ERROR : $__MSG" ;;
+               4)      __CMD="logger -p user.warn -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME  WARN : $__MSG" ;;
+               5)      __CMD="logger -p user.notice -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME  note : $__MSG" ;;
+               6)      __CMD="logger -p user.info -t ddns-scripts[$$] $SECTION_ID: $__MSG"
+                       __MSG=" $__TIME  info : $__MSG" ;;
+               7)      __MSG=" $__TIME       : $__MSG";;
+               *)      return;;
+       esac
+
+       # verbose echo
+       [ $VERBOSE_MODE -gt 0 -o $__EXIT -gt 0 ] && echo -e "$__MSG"
+       # write to logfile
+       if [ ${use_logfile:-1} -eq 1 -o $VERBOSE_MODE -gt 1 ]; then
+               echo -e "$__MSG" >> $LOGFILE
                # VERBOSE_MODE > 1 then NO loop so NO truncate log to $LOGLINES lines
                [ $VERBOSE_MODE -gt 1 ] || sed -i -e :a -e '$q;N;'$LOGLINES',$D;ba' $LOGFILE
        fi
+       [ $LUCI_HELPER ]   && return    # nothing else todo when running LuCI helper script
+       [ $__LEVEL -eq 7 ] && return    # no syslog for debug messages
+       [ $__EXIT  -eq 1 ] && {
+               $__CMD          # force syslog before exit
+               exit 1
+       }
+       [ $use_syslog -eq 0 ] && return
+       [ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD
        return
 }
 
-syslog_info(){
-       [ $use_syslog -eq 1 ] && logger -p user.info -t ddns-scripts[$$] "$SECTION_ID: $*"
-       return
-}
-syslog_notice(){
-       [ $use_syslog -ge 1 -a $use_syslog -le 2 ] && logger -p user.notice -t ddns-scripts[$$] "$SECTION_ID: $*"
-       return
-}
-syslog_warn(){
-       [ $use_syslog -ge 1 -a $use_syslog -le 3 ] && logger -p user.warn -t ddns-scripts[$$] "$SECTION_ID: $*"
-       return
-}
-syslog_err(){
-       [ $use_syslog -ge 1 ] && logger -p user.err -t ddns-scripts[$$] "$SECTION_ID: $*"
-       return
-}
-
-critical_error() {
-       [ -n "$LUCI_HELPER" ] && return # nothing to report when used by LuCI helper script
-       verbose_echo "\n CRITICAL ERROR =: $* - EXITING\n"
-       [ $VERBOSE_MODE -eq 0 ] && echo -e "\n$SECTION_ID: CRITICAL ERROR - $* - EXITING\n"
-       logger -t ddns-scripts[$$] -p user.crit "$SECTION_ID: CRITICAL ERROR - $* - EXITING"
-       exit 1          # critical error -> leave here
-}
-
 # replace all special chars to their %hex value
 # used for USERNAME and PASSWORD in update_url
 # unchanged: "-"(minus) "_"(underscore) "."(dot) "~"(tilde)
@@ -182,13 +251,15 @@ critical_error() {
 #            "$"(Dollar)                               # because used as variable output
 # tested with the following string stored via Luci Application as password / username
 # A B!"#AA$1BB%&'()*+,-./:;<=>?@[\]^_`{|}~     without problems at Dollar or quotes
-__urlencode() {
+urlencode() {
        # $1    Name of Variable to store encoded string to
        # $2    string to encode
        local __STR __LEN __CHAR __OUT
        local __ENC=""
        local __POS=1
 
+       [ $# -ne 2 ] && write_log 12 "Error calling 'urlencode()' - wrong number of parameters"
+
        __STR="$2"              # read string to encode
        __LEN=${#__STR}         # get string length
 
@@ -210,33 +281,33 @@ __urlencode() {
                __POS=$(( $__POS + 1 ))         # increment position
        done
 
-       eval "$1='$__ENC'"      # transfer back to variable
+       eval "$1=\"$__ENC\""    # transfer back to variable
        return 0
 }
 
-# extract update_url for given DDNS Provider from
+# extract url or script for given DDNS Provider from
 # file /usr/lib/ddns/services for IPv4 or from
 # file /usr/lib/ddns/services_ipv6 for IPv6
+# $1   Name of Variable to store url to
+# $2   Name of Variable to store script to
 get_service_data() {
-       # $1    Name of Variable to store url to
-       # $2    Name of Variable to store script to
        local __LINE __FILE __NAME __URL __SERVICES __DATA
        local __SCRIPT=""
        local __OLD_IFS=$IFS
        local __NEWLINE_IFS='
-' #__NEWLINE_IFS
+' # __NEWLINE_IFS
+       [ $# -ne 2 ] && write_log 12 "Error calling 'get_service_data()' - wrong number of parameters"
 
        __FILE="/usr/lib/ddns/services"                                 # IPv4
        [ $use_ipv6 -ne 0 ] && __FILE="/usr/lib/ddns/services_ipv6"     # IPv6
 
-       #remove any lines not containing data, and then make sure fields are enclosed in double quotes
+       # remove any lines not containing data, and then make sure fields are enclosed in double quotes
        __SERVICES=$(cat $__FILE | grep "^[\t ]*[^#]" | \
                awk ' gsub("\x27", "\"") { if ($1~/^[^\"]*$/) $1="\""$1"\"" }; { if ( $NF~/^[^\"]*$/) $NF="\""$NF"\""  }; { print $0 }')
 
        IFS=$__NEWLINE_IFS
-       for __LINE in $__SERVICES
-       do
-               #grep out proper parts of data and use echo to remove quotes
+       for __LINE in $__SERVICES; do
+               # grep out proper parts of data and use echo to remove quotes
                __NAME=$(echo $__LINE | grep -o "^[\t ]*\"[^\"]*\"" | xargs -r -n1 echo)
                __DATA=$(echo $__LINE | grep -o "\"[^\"]*\"[\t ]*$" | xargs -r -n1 echo)
 
@@ -246,19 +317,21 @@ get_service_data() {
        done
        IFS=$__OLD_IFS
 
-       # check is URL or SCRIPT is given
-       __URL=$(echo "$__DATA" | grep "^http:")
+       # check if URL or SCRIPT is given
+       __URL=$(echo "$__DATA" | grep "^http")
        [ -z "$__URL" ] && __SCRIPT="/usr/lib/ddns/$__DATA"
-       
-       eval "$1='$__URL'"
-       eval "$2='$__SCRIPT'"
+
+       eval "$1=\"$__URL\""
+       eval "$2=\"$__SCRIPT\""
        return 0
 }
 
+# Calculate seconds from interval and unit
+# $1   Name of Variable to store result in
+# $2   Number and
+# $3   Unit of time interval
 get_seconds() {
-       # $1    Name of Variable to store result in
-       # $2    Number and
-       # $3    Unit of time interval
+       [ $# -ne 3 ] && write_log 12 "Error calling 'get_seconds()' - wrong number of parameters"
        case "$3" in
                "days" )        eval "$1=$(( $2 * 86400 ))";;
                "hours" )       eval "$1=$(( $2 * 3600 ))";;
@@ -268,17 +341,17 @@ get_seconds() {
        return 0
 }
 
-__timeout() {
+timeout() {
        # copied from http://www.ict.griffith.edu.au/anthony/software/timeout.sh
-       # only did the folloing changes
+       # only did the following changes
        #       - commented out "#!/bin/bash" and usage section
        #       - replace exit by return for usage as function
-       #       - some reformating
+       #       - some reformatting
        #
        # timeout [-SIG] time [--] command args...
        #
        # Run the given command until completion, but kill it if it runs too long.
-       # Specifically designed to exit immediatally (no sleep interval) and clean up
+       # Specifically designed to exit immediately (no sleep interval) and clean up
        # nicely without messages or leaving any extra processes when finished.
        #
        # Example use
@@ -313,7 +386,7 @@ __timeout() {
 
        SIG=-TERM
 
-       while [  $# -gt 0 ]; do
+       while [ $# -gt 0 ]; do
                case "$1" in
                        --)
                                # forced end of user options
@@ -332,7 +405,7 @@ __timeout() {
                shift   # next option
        done
 
-       # run main command in backgrouds and get its pid
+       # run main command in backgrounds and get its pid
        "$@" &
        command_pid=$!
 
@@ -367,101 +440,147 @@ __timeout() {
        return $status
 }
 
-__verify_host_port() {
-       # $1    Host/IP to verify
-       # $2    Port to verify
+# verify given host and port is connectable
+# $1   Host/IP to verify
+# $2   Port to verify
+verify_host_port() {
        local __HOST=$1
        local __PORT=$2
-       local __TMP __IP __IPV4 __IPV6 __RUNPROG __ERRPROG __ERR
+       local __IP __IPV4 __IPV6 __RUNPROG __PROG __ERR
        # return codes
        # 1     system specific error
-       # 2     nslookup error
+       # 2     nslookup/host error
        # 3     nc (netcat) error
        # 4     unmatched IP version
 
-       __RUNPROG="nslookup $__HOST 2>/dev/null"
-       __ERRPROG="nslookup $__HOST 2>&1"
-       verbose_echo " resolver prog =: '$__RUNPROG'"
-       __TMP=$(eval $__RUNPROG)        # test if nslookup runs without errors
-       __ERR=$?
-       # command error
-       [ $__ERR -gt 0 ] && {
-               verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nslookup Error '$__ERR'\n$(eval $__ERRPROG)\n"
-               syslog_err "DNS Resolver Error - BusyBox nslookup Error: '$__ERR'"
-               return 2
-       } || {
-               # we need to run twice because multi-line output needs to be directly piped to grep because
-               # pipe returns return code of last prog in pipe but we need errors from nslookup command
-               __IPV4=$(eval $__RUNPROG | sed '1,2d' | grep -o "Name:\|Address.*" | grep -m 1 -o "$IPV4_REGEX")
-               __IPV6=$(eval $__RUNPROG | sed '1,2d' | grep -o "Name:\|Address.*" | grep -m 1 -o "$IPV6_REGEX")
+       [ $# -ne 2 ] && write_log 12 "Error calling 'verify_host_port()' - wrong number of parameters"
+
+       # check if ip or FQDN was given
+       __IPV4=$(echo $__HOST | grep -m 1 -o "$IPV4_REGEX$")    # do not detect ip in 0.0.0.0.example.com
+       __IPV6=$(echo $__HOST | grep -m 1 -o "$IPV6_REGEX")
+       # if FQDN given get IP address
+       [ -z "$__IPV4" -a -z "$__IPV6" ] && {
+               if [ -x /usr/bin/host ]; then   # use BIND host if installed
+                       __PROG="BIND host"
+                       __RUNPROG="/usr/bin/host -t ANY $__HOST >$DATFILE 2>$ERRFILE"
+               else    # use BusyBox nslookup
+                       __PROG="BusyBox nslookup"
+                       __RUNPROG="/usr/bin/nslookup $__HOST >$DATFILE 2>$ERRFILE"
+               fi
+               write_log 7 "#> $__RUNPROG"
+               eval $__RUNPROG
+               __ERR=$?
+               # command error
+               [ $__ERR -gt 0 ] && {
+                       write_log 3 "DNS Resolver Error - $__PROG Error '$__ERR'"
+                       write_log 7 "$(cat $ERRFILE)"
+                       return 2
+               }
+               # extract IP address
+               if [ -x /usr/bin/host ]; then   # use BIND host if installed
+                       __IPV4=$(cat $DATFILE | awk -F "address " '/has address/ {print $2; exit}' )
+                       __IPV6=$(cat $DATFILE | awk -F "address " '/has IPv6/ {print $2; exit}' )
+               else    # use BusyBox nslookup
+                       __IPV4=$(cat $DATFILE | sed -ne "3,\$ { s/^Address[0-9 ]\{0,\}: \($IPV4_REGEX\).*$/\\1/p }")
+                       __IPV6=$(cat $DATFILE | sed -ne "3,\$ { s/^Address[0-9 ]\{0,\}: \($IPV6_REGEX\).*$/\\1/p }")
+               fi
        }
 
        # check IP version if forced
        if [ $force_ipversion -ne 0 ]; then
-               [ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && return 4
-               [ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && return 4
+               __ERR=0
+               [ $use_ipv6 -eq 0 -a -z "$__IPV4" ] && __ERR=4
+               [ $use_ipv6 -eq 1 -a -z "$__IPV6" ] && __ERR=6
+               [ $__ERR -gt 0 ] && {
+                       [ $LUCI_HELPER ] && return 4
+                       write_log 14 "Verify host Error '4' - Forced IP Version IPv$__ERR don't match"
+               }
        fi
 
        # verify nc command
        # busybox nc compiled without -l option "NO OPT l!" -> critical error
-       nc --help 2>&1 | grep -iq "NO OPT l!" && \
-               critical_error "Busybox nc: netcat compiled with errors"
+       /usr/bin/nc --help 2>&1 | grep -i "NO OPT l!" >/dev/null 2>&1 && \
+               write_log 12 "Busybox nc (netcat) compiled without '-l' option, error 'NO OPT l!'"
        # busybox nc compiled with extensions
-       nc --help 2>&1 | grep -q "\-w" && __NCEXT="TRUE"
+       /usr/bin/nc --help 2>&1 | grep "\-w" >/dev/null 2>&1 && __NCEXT="TRUE"
 
        # connectivity test
        # run busybox nc to HOST PORT
        # busybox might be compiled with "FEATURE_PREFER_IPV4_ADDRESS=n"
-       # then nc will try to connect via IPv6 if there is an IPv6 availible for host
-       # not worring if there is an IPv6 wan address
-       # so if not "forced_ipversion" to use ipv6 then connect test via ipv4 if availible
-       [ $force_ipversion -ne 0 -a $use_ipv6 -ne 0 -o -z "$__IPV4" ] && {
-               # force IPv6
-               __IP=$__IPV6
-       } || __IP=$__IPV4
-
-       if [ -n "$__NCEXT" ]; then      # nc compiled with extensions (timeout support)
-               __RUNPROG="nc -w 1 $__IP $__PORT </dev/null >/dev/null 2>&1"
-               __ERRPROG="nc -vw 1 $__IP $__PORT </dev/null 2>&1"
-               verbose_echo "  connect prog =: '$__RUNPROG'"
+       # then nc will try to connect via IPv6 if there is any IPv6 available on any host interface
+       # not worrying, if there is an IPv6 wan address
+       # so if not "force_ipversion" to use_ipv6 then connect test via ipv4, if available
+       [ $force_ipversion -ne 0 -a $use_ipv6 -ne 0 -o -z "$__IPV4" ] && __IP=$__IPV6 || __IP=$__IPV4
+
+       if [ -n "$__NCEXT" ]; then      # BusyBox nc compiled with extensions (timeout support)
+               __RUNPROG="/usr/bin/nc -vw 1 $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
+               write_log 7 "#> $__RUNPROG"
                eval $__RUNPROG
                __ERR=$?
                [ $__ERR -eq 0 ] && return 0
-               verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nc Error '$__ERR'\n$(eval $__ERRPROG)\n"
-               syslog_err "host verify Error - BusyBox nc Error: '$__ERR'"
+               write_log 3 "Connect error - BusyBox nc (netcat) Error '$__ERR'"
+               write_log 7 "$(cat $ERRFILE)"
                return 3
        else            # nc compiled without extensions (no timeout support)
-               __RUNPROG="__timeout 2 -- nc $__IP $__PORT </dev/null >/dev/null 2>&1"
-               verbose_echo "  connect prog =: '$__RUNPROG'"
+               __RUNPROG="timeout 2 -- /usr/bin/nc $__IP $__PORT </dev/null >$DATFILE 2>$ERRFILE"
+               write_log 7 "#> $__RUNPROG"
                eval $__RUNPROG
                __ERR=$?
                [ $__ERR -eq 0 ] && return 0
-               verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nc Error '$__ERR' (timeout)"
-               syslog_err "host verify Error - BusyBox nc Error: '$__ERR' (timeout)"
+               write_log 3 "Connect error - BusyBox nc (netcat) timeout Error '$__ERR'"
                return 3
        fi
 }
 
+# verify given DNS server if connectable
+# $1   DNS server to verify
 verify_dns() {
-       # $1    DNS server to verify
-       # we need DNS server to verify otherwise exit with ERROR 1
-       [ -z "$1" ] && return 1
+       local __ERR=255 # last error buffer
+       local __CNT=0   # error counter
 
-       # DNS uses port 53
-       __verify_host_port "$1" "53"
+       [ $# -ne 1 ] && write_log 12 "Error calling 'verify_dns()' - wrong number of parameters"
+       write_log 7 "Verify DNS server '$1'"
+
+       while [ $__ERR -ne 0 ]; do
+               # DNS uses port 53
+               verify_host_port "$1" "53"
+               __ERR=$?
+               if [ $LUCI_HELPER ]; then       # no retry if called by LuCI helper script
+                       return $__ERR
+               elif [ $__ERR -ne 0 -a $VERBOSE_MODE -gt 1 ]; then      # VERBOSE_MODE > 1 then NO retry
+                       write_log 4 "Verify DNS server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
+                       return $__ERR
+               elif [ $__ERR -ne 0 ]; then
+                       __CNT=$(( $__CNT + 1 )) # increment error counter
+                       # if error count > retry_count leave here
+                       [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
+                               write_log 14 "Verify DNS server '$1' failed after $retry_count retries"
+
+                       write_log 4 "Verify DNS server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
+                       sleep $RETRY_SECONDS &
+                       PID_SLEEP=$!
+                       wait $PID_SLEEP # enable trap-handler
+                       PID_SLEEP=0
+               fi
+       done
+       return 0
 }
 
+# analyze and verify given proxy string
+# $1   Proxy-String to verify
 verify_proxy() {
-       # $1    Proxy-String to verify
-       #               complete entry          user:password@host:port
-       #               host and port only      host:port
-       #               host only               host            unsupported
-       #               IPv4 address instead of host    123.234.234.123
-       #               IPv6 address instead of host    [xxxx:....:xxxx]        in square bracket
+       #       complete entry          user:password@host:port
+       #                               inside user and password NO '@' of ":" allowed
+       #       host and port only      host:port
+       #       host only               host            ERROR unsupported
+       #       IPv4 address instead of host    123.234.234.123
+       #       IPv6 address instead of host    [xxxx:....:xxxx]        in square bracket
        local __TMP __HOST __PORT
+       local __ERR=255 # last error buffer
+       local __CNT=0   # error counter
 
-       # we need Proxy-Sting to verify otherwise exit with ERROR 1
-       [ -z "$1" ] && return 1
+       [ $# -ne 1 ] && write_log 12 "Error calling 'verify_proxy()' - wrong number of parameters"
+       write_log 7 "Verify Proxy server 'http://$1'"
 
        # try to split user:password "@" host:port
        __TMP=$(echo $1 | awk -F "@" '{print $2}')
@@ -477,24 +596,50 @@ verify_proxy() {
                __HOST=$(echo $__TMP | awk -F ":" '{print $1}')
                __PORT=$(echo $__TMP | awk -F ":" '{print $2}')
        fi
-       # No Port detected ERROR 5
-       [ -z "$__PORT" ] && return 5
+       # No Port detected - EXITING
+       [ -z "$__PORT" ] && {
+               [ $LUCI_HELPER ] && return 5
+               write_log 14 "Invalid Proxy server Error '5' - proxy port missing"
+       }
 
-       __verify_host_port "$__HOST" "$__PORT"
+       while [ $__ERR -gt 0 ]; do
+               verify_host_port "$__HOST" "$__PORT"
+               __ERR=$?
+               if [ $LUCI_HELPER ]; then       # no retry if called by LuCI helper script
+                       return $__ERR
+               elif [ $__ERR -gt 0 -a $VERBOSE_MODE -gt 1 ]; then      # VERBOSE_MODE > 1 then NO retry
+                       write_log 4 "Verify Proxy server '$1' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
+                       return $__ERR
+               elif [ $__ERR -gt 0 ]; then
+                       __CNT=$(( $__CNT + 1 )) # increment error counter
+                       # if error count > retry_count leave here
+                       [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
+                               write_log 14 "Verify Proxy server '$1' failed after $retry_count retries"
+
+                       write_log 4 "Verify Proxy server '$1' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
+                       sleep $RETRY_SECONDS &
+                       PID_SLEEP=$!
+                       wait $PID_SLEEP # enable trap-handler
+                       PID_SLEEP=0
+               fi
+       done
+       return 0
 }
 
-__do_transfer() {
-       # $1    # Variable to store Answer of transfer
-       # $2    # URL to use
-       local __URL="$2"
+do_transfer() {
+       # $1    # URL to use
+       local __URL="$1"
        local __ERR=0
-       local __PROG  __RUNPROG  __ERRPROG  __DATA
+       local __CNT=0   # error counter
+       local __PROG  __RUNPROG
+
+       [ $# -ne 1 ] && write_log 12 "Error in 'do_transfer()' - wrong number of parameters"
 
        # lets prefer GNU Wget because it does all for us - IPv4/IPv6/HTTPS/PROXY/force IP version
-       if /usr/bin/wget --version 2>&1 | grep -q "\+ssl"; then
-               __PROG="/usr/bin/wget -t 2 -O -"        # standard output only 2 retrys on error
+       if /usr/bin/wget --version 2>&1 | grep "\+ssl" >/dev/null 2>&1 ; then
+               __PROG="/usr/bin/wget -nv -t 1 -O $DATFILE -o $ERRFILE" # non_verbose no_retry outfile errfile
                # force ip version to use
-               if [ $force_ipversion -eq 1 ]; then     
+               if [ $force_ipversion -eq 1 ]; then
                        [ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"       # force IPv4/IPv6
                fi
                # set certificate parameters
@@ -506,29 +651,21 @@ __do_transfer() {
                        elif [ -d "$cacert" ]; then
                                __PROG="$__PROG --ca-directory=${cacert}"
                        else    # exit here because it makes no sense to start loop
-                               critical_error "Wget: No valid certificate(s) found for running HTTPS"
+                               write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
                        fi
                fi
                # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
                [ -z "$proxy" ] && __PROG="$__PROG --no-proxy"
 
-               __RUNPROG="$__PROG -q '$__URL' 2>/dev/null"     # do transfer with "-q" to suppress not needed output
-               __ERRPROG="$__PROG -d '$__URL' 2>&1"            # do transfer with "-d" for debug mode
-               verbose_echo " transfer prog =: $__RUNPROG"
-               __DATA=$(eval $__RUNPROG)
-               __ERR=$?
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: GNU Wget Error '$__ERR'\n$(eval $__ERRPROG)\n"
-                       syslog_err "Communication Error - GNU Wget Error: '$__ERR'"
-                       return 1
-               }
+               __RUNPROG="$__PROG '$__URL'"    # build final command
+               __PROG="GNU Wget"               # reuse for error logging
 
        # 2nd choice is cURL IPv4/IPv6/HTTPS
        # libcurl might be compiled without Proxy Support (default in trunk)
        elif [ -x /usr/bin/curl ]; then
-               __PROG="/usr/bin/curl"
+               __PROG="/usr/bin/curl -RsS -o $DATFILE --stderr $ERRFILE"
                # force ip version to use
-               if [ $force_ipversion -eq 1 ]; then     
+               if [ $force_ipversion -eq 1 ]; then
                        [ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4" || __PROG="$__PROG -6"       # force IPv4/IPv6
                fi
                # set certificate parameters
@@ -540,7 +677,7 @@ __do_transfer() {
                        elif [ -d "$cacert" ]; then
                                __PROG="$__PROG --capath $cacert"
                        else    # exit here because it makes no sense to start loop
-                               critical_error "cURL: No valid certificate(s) found for running HTTPS"
+                               write_log 14 "No valid certificate(s) found at '$cacert' for HTTPS communication"
                        fi
                fi
                # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
@@ -550,221 +687,391 @@ __do_transfer() {
                else
                        # if libcurl has no proxy support and proxy should be used then force ERROR
                        # libcurl currently no proxy support by default
-                       grep -iq all_proxy /usr/lib/libcurl.so* || \
-                               critical_error "cURL: libcurl compiled without Proxy support"
+                       grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1 || \
+                               write_log 13 "cURL: libcurl compiled without Proxy support"
                fi
 
-               __RUNPROG="$__PROG -q '$__URL' 2>/dev/null"     # do transfer with "-s" to suppress not needed output
-               __ERRPROG="$__PROG -v '$__URL' 2>&1"            # do transfer with "-v" for verbose mode
-               verbose_echo " transfer prog =: $__RUNPROG"
-               __DATA=$(eval $__RUNPROG)
-               __ERR=$?
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: cURL Error '$__ERR'\n$(eval $__ERRPROG)\n"
-                       syslog_err "Communication Error - cURL Error: '$__ERR'"
-                       return 1
-               }
+               __RUNPROG="$__PROG '$__URL'"    # build final command
+               __PROG="cURL"                   # reuse for error logging
 
        # busybox Wget (did not support neither IPv6 nor HTTPS)
        elif [ -x /usr/bin/wget ]; then
-               __PROG="/usr/bin/wget -O -"
+               __PROG="/usr/bin/wget -q -O $DATFILE"
                # force ip version not supported
                [ $force_ipversion -eq 1 ] && \
-                       critical_error "BusyBox Wget: can not force IP version to use"
+                       write_log 14 "BusyBox Wget: can not force IP version to use"
                # https not supported
                [ $use_https -eq 1 ] && \
-                       critical_error "BusyBox Wget: no HTTPS support"
+                       write_log 14 "BusyBox Wget: no HTTPS support"
                # disable proxy if no set (there might be .wgetrc or .curlrc or wrong environment set)
                [ -z "$proxy" ] && __PROG="$__PROG -Y off"
-               
-               __RUNPROG="$__PROG -q '$__URL' 2>/dev/null"     # do transfer with "-q" to suppress not needed output
-               __ERRPROG="$__PROG '$__URL' 2>&1"
-               verbose_echo " transfer prog =: $__RUNPROG"
-               __DATA=$(eval $__RUNPROG)
-               __ERR=$?
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: BusyBox Wget Error '$__ERR'\n$(eval $__ERRPROG)\n"
-                       syslog_err "Communication Error - BusyBox Wget Error: '$__ERR'"
-                       return 1
-               }
+
+               __RUNPROG="$__PROG '$__URL' 2>$ERRFILE"         # build final command
+               __PROG="Busybox Wget"                           # reuse for error logging
 
        else
-               critical_error "Program not found - Neither 'Wget' nor 'cURL' installed or executable"
+               write_log 13 "Neither 'Wget' nor 'cURL' installed or executable"
        fi
 
-       eval "$1='$__DATA'"
-       return 0
+       while : ; do
+               write_log 7 "#> $__RUNPROG"
+               eval $__RUNPROG                 # DO transfer
+               __ERR=$?                        # save error code
+               [ $__ERR -eq 0 ] && return 0    # no error leave
+               [ $LUCI_HELPER ] && return 1    # no retry if called by LuCI helper script
+
+               write_log 3 "$__PROG Error: '$__ERR'"
+               write_log 7 "$(cat $ERRFILE)"           # report error
+
+               [ $VERBOSE_MODE -gt 1 ] && {
+                       # VERBOSE_MODE > 1 then NO retry
+                       write_log 4 "Transfer failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
+                       return 1
+               }
+
+               __CNT=$(( $__CNT + 1 )) # increment error counter
+               # if error count > retry_count leave here
+               [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
+                       write_log 14 "Transfer failed after $retry_count retries"
+
+               write_log 4 "Transfer failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
+               sleep $RETRY_SECONDS &
+               PID_SLEEP=$!
+               wait $PID_SLEEP # enable trap-handler
+               PID_SLEEP=0
+       done
+       # we should never come here there must be a programming error
+       write_log 12 "Error in 'do_transfer()' - program coding error"
 }
 
 send_update() {
        # $1    # IP to set at DDNS service provider
        local __IP
 
-       # verify given IP / no private IPv4's / no IPv6 addr starting with fxxx of with ":"
-       [ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10\.|^127|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168)")
-       [ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")
-       [ -z "$__IP" ] && critical_error "Private or invalid or no IP '$1' given"
+       [ $# -ne 1 ] && write_log 12 "Error calling 'send_update()' - wrong number of parameters"
+
+       if [ $ALLOW_LOCAL_IP -eq 0 ]; then
+               # verify given IP / no private IPv4's / no IPv6 addr starting with fxxx of with ":"
+               [ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10\.|^127|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168)")
+               [ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")
+               [ -z "$__IP" ] && write_log 14 "Private or invalid or no IP '$1' given! Please check your configuration"
+       else
+               __IP="$1"
+       fi
 
        if [ -n "$update_script" ]; then
-               verbose_echo "        update =: parsing script '$update_script'"
+               write_log 7 "parsing script '$update_script'"
                . $update_script
        else
-               local __URL __ANSWER __ERR __USER __PASS
+               local __URL __ERR
 
                # do replaces in URL
-               __urlencode __USER "$username"  # encode username, might be email or something like this
-               __urlencode __PASS "$password"  # encode password, might have special chars for security reason
-               __URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$__USER#g" -e "s#\[PASSWORD\]#$__PASS#g" \
+               __URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
                                               -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
                [ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
 
-               __do_transfer __ANSWER "$__URL"
-               __ERR=$?
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: Error sending update to DDNS Provider\n"
-                       return 1
-               }
-               verbose_echo "   update send =: DDNS Provider answered\n$__ANSWER"
+               do_transfer "$__URL" || return 1
+
+               write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)"
+
                return 0
+               # TODO analyze providers answer
+               # "good" or "nochg"             = dyndns.com compatible API
+               # grep -i -E "good|nochg" $DATFILE >/dev/null 2>&1
+               # return $?     # "0" if found
        fi
 }
 
 get_local_ip () {
        # $1    Name of Variable to store local IP (LOCAL_IP)
-       local __RUNPROG __IP __URL __ANSWER
-
-       case $ip_source in
-               network )
-                       # set correct program
-                       [ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
-                                           || __RUNPROG="network_get_ipaddr6"
-                       $__RUNPROG __IP "$ip_network"
-                       verbose_echo "      local ip =: '$__IP' detected on network '$ip_network'"
-                       ;;
-               interface )
-                       if [ $use_ipv6 -eq 0 ]; then
-                               __IP=$(ifconfig $ip_interface | awk '
-                                       /inet addr:/ {  # Filter IPv4
-                                       #   inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
-                                       $1="";          # remove inet
-                                       $3="";          # remove Bcast: ...
-                                       $4="";          # remove Mask: ...
-                                       FS=":";         # separator ":"
-                                       $0=$0;          # reread to activate separator
-                                       $1="";          # remove addr
-                                       FS=" ";         # set back separator to default " "
-                                       $0=$0;          # reread to activate separator (remove whitespaces)
-                                       print $1;       # print IPv4 addr
-                                       }'
-                               )
-                       else
-                               __IP=$(ifconfig $ip_interface | awk '
-                                       /inet6/ && /: [0-9a-eA-E]/ && !/\/128/ {        # Filter IPv6 exclude fxxx and /128 prefix
-                                       #   inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
-                                       FS="/";         # separator "/"
-                                       $0=$0;          # reread to activate separator
-                                       $2="";          # remove everything behind "/"
-                                       FS=" ";         # set back separator to default " "
-                                       $0=$0;          # reread to activate separator
-                                       print $3;       # print IPv6 addr
-                                       }'
-                               )
-                       fi
-                       verbose_echo "      local ip =: '$__IP' detected on interface '$ip_interface'"
-                       ;;
-               script )
-                       # get ip from script
-                       __IP=$($ip_script)
-                       verbose_echo "      local ip =: '$__IP' detected via script '$ip_script'"
-                       ;;
-               * )
-                       for __URL in $ip_url; do
-                               __do_transfer __ANSWER "$__URL"
-                               [ -n "$__IP" ] && break # Answer detected, leave for loop
-                       done
-                       # use correct regular expression
-                       [ $use_ipv6 -eq 0 ] \
-                               && __IP=$(echo "$__ANSWER" | grep -m 1 -o "$IPV4_REGEX") \
-                               || __IP=$(echo "$__ANSWER" | grep -m 1 -o "$IPV6_REGEX")
-                       verbose_echo "      local ip =: '$__IP' detected via web at '$__URL'"
-                       ;;
-       esac
+       local __CNT=0   # error counter
+       local __RUNPROG __DATA __URL __ERR
+
+       [ $# -ne 1 ] && write_log 12 "Error calling 'get_local_ip()' - wrong number of parameters"
+       write_log 7 "Detect local IP"
+
+       while : ; do
+               case $ip_source in
+                       network)
+                               # set correct program
+                               [ $use_ipv6 -eq 0 ] && __RUNPROG="network_get_ipaddr" \
+                                                   || __RUNPROG="network_get_ipaddr6"
+                               write_log 7 "#> $__RUNPROG __DATA '$ip_network'"
+                               eval "$__RUNPROG __DATA $ip_network" || write_log 3 "$__RUNPROG Error: '$?'"
+                               [ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on network '$ip_network'"
+                               ;;
+                       interface)
+                               write_log 7 "#> ifconfig $ip_interface >$DATFILE 2>$ERRFILE"
+                               ifconfig $ip_interface >$DATFILE 2>$ERRFILE
+                               __ERR=$?
+                               if [ $__ERR -eq 0 ]; then
+                                       if [ $use_ipv6 -eq 0 ]; then
+                                               __DATA=$(awk '
+                                                       /inet addr:/ {  # Filter IPv4
+                                                       #   inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
+                                                       $1="";          # remove inet
+                                                       $3="";          # remove Bcast: ...
+                                                       $4="";          # remove Mask: ...
+                                                       FS=":";         # separator ":"
+                                                       $0=$0;          # reread to activate separator
+                                                       $1="";          # remove addr
+                                                       FS=" ";         # set back separator to default " "
+                                                       $0=$0;          # reread to activate separator (remove whitespaces)
+                                                       print $1;       # print IPv4 addr
+                                                       }' $DATFILE
+                                               )
+                                       else
+                                               __DATA=$(awk '
+                                                       /inet6/ && /: [0-9a-eA-E]/ && !/\/128/ {        # Filter IPv6 exclude fxxx and /128 prefix
+                                                       #   inet6 addr: 2001:db8::xxxx:xxxx/32 Scope:Global
+                                                       FS="/";         # separator "/"
+                                                       $0=$0;          # reread to activate separator
+                                                       $2="";          # remove everything behind "/"
+                                                       FS=" ";         # set back separator to default " "
+                                                       $0=$0;          # reread to activate separator
+                                                       print $3;       # print IPv6 addr
+                                                       }' $DATFILE
+                                               )
+                                       fi
+                                       [ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on interface '$ip_interface'"
+                               else
+                                       write_log 3 "ifconfig Error: '$__ERR'"
+                                       write_log 7 "$(cat $ERRFILE)"           # report error
+                               fi
+                               ;;
+                       script)
+                               write_log 7 "#> $ip_script >$DATFILE 2>$ERRFILE"
+                               eval $ip_script >$DATFILE 2>$ERRFILE
+                               __ERR=$?
+                               if [ $__ERR -eq 0 ]; then
+                                       __DATA=$(cat $DATFILE)
+                                       [ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected via script '$ip_script'"
+                               else
+                                       write_log 3 "$ip_script Error: '$__ERR'"
+                                       write_log 7 "$(cat $ERRFILE)"           # report error
+                               fi
+                               ;;
+                       web)
+                               do_transfer "$ip_url"
+                               # use correct regular expression
+                               [ $use_ipv6 -eq 0 ] \
+                                       && __DATA=$(grep -m 1 -o "$IPV4_REGEX" $DATFILE) \
+                                       || __DATA=$(grep -m 1 -o "$IPV6_REGEX" $DATFILE)
+                               [ -n "$__DATA" ] && write_log 7 "Local IP '$__DATA' detected on web at '$__URL'"
+                               ;;
+                       *)
+                               write_log 12 "Error in 'get_local_ip()' - unhandled ip_source '$ip_source'"
+                               ;;
+               esac
+               # valid data found return here
+               [ -n "$__DATA" ] && {
+                       eval "$1=\"$__DATA\""
+                       return 0
+               }
 
-       # if NO IP was found
-       [ -z "$__IP" ] && return 1
+               [ $LUCI_HELPER ] && return 1    # no retry if called by LuCI helper script
 
-       eval "$1='$__IP'"
-       return 0
+               write_log 7 "Data detected:\n$(cat $DATFILE)"
+
+               [ $VERBOSE_MODE -gt 1 ] && {
+                       # VERBOSE_MODE > 1 then NO retry
+                       write_log 4 "Get local IP via '$ip_source' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
+                       return 1
+               }
+
+               __CNT=$(( $__CNT + 1 )) # increment error counter
+               # if error count > retry_count leave here
+               [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
+                       write_log 14 "Get local IP via '$ip_source' failed after $retry_count retries"
+               write_log 4 "Get local IP via '$ip_source' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
+               sleep $RETRY_SECONDS &
+               PID_SLEEP=$!
+               wait $PID_SLEEP # enable trap-handler
+               PID_SLEEP=0
+       done
+       # we should never come here there must be a programming error
+       write_log 12 "Error in 'get_local_ip()' - program coding error"
 }
 
 get_registered_ip() {
        # $1    Name of Variable to store public IP (REGISTERED_IP)
-       local __IP  __REGEX  __PROG  __RUNPROG  __ERRPROG  __ERR
+       # $2    (optional) if set, do not retry on error
+       local __CNT=0   # error counter
+       local __ERR=255
+       local __REGEX  __PROG  __RUNPROG  __DATA
        # return codes
        # 1     no IP detected
 
+       [ $# -lt 1 -o $# -gt 2 ] && write_log 12 "Error calling 'get_registered_ip()' - wrong number of parameters"
+       write_log 7 "Detect registered/public IP"
+
        # set correct regular expression
        [ $use_ipv6 -eq 0 ] && __REGEX="$IPV4_REGEX" || __REGEX="$IPV6_REGEX"
 
-       if [ -x /usr/bin/host ]; then           # otherwise try to use BIND host
+       if [ -x /usr/bin/host ]; then
                __PROG="/usr/bin/host"
                [ $use_ipv6 -eq 0 ] && __PROG="$__PROG -t A"  || __PROG="$__PROG -t AAAA"
                if [ $force_ipversion -eq 1 ]; then                     # force IP version
                        [ $use_ipv6 -eq 0 ] && __PROG="$__PROG -4"  || __PROG="$__PROG -6"
-               fi                      
+               fi
                [ $force_dnstcp -eq 1 ] && __PROG="$__PROG -T"  # force TCP
 
-               __RUNPROG="$__PROG $domain $dns_server 2>/dev/null"
-               __ERRPROG="$__PROG -v $domain $dns_server 2>&1"
-               verbose_echo " resolver prog =: $__RUNPROG"
-               __IP=$(eval $__RUNPROG)
-               __ERR=$?
-               # command error
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: BIND host Error '$__ERR'\n$(eval $__ERRPROG)\n"
-                       syslog_err "DNS Resolver Error - BIND host Error: '$__ERR'"
-                       return 1
-               } || {
-                       # we need to run twice because multi-line output needs to be directly piped to grep because
-                       # pipe returns return code of last prog in pipe but we need errors from host command
-                       __IP=$(eval $__RUNPROG | awk -F "address " '/has/ {print $2; exit}' )
-               }
-
+               __RUNPROG="$__PROG $domain $dns_server >$DATFILE 2>$ERRFILE"
+               __PROG="BIND host"
        elif [ -x /usr/bin/nslookup ]; then     # last use BusyBox nslookup
                [ $force_ipversion -ne 0 -o $force_dnstcp -ne 0 ] && \
-                       critical_error "nslookup - no support to 'force IP Version' or 'DNS over TCP'"
+                       write_log 14 "Busybox nslookup - no support to 'force IP Version' or 'DNS over TCP'"
 
-               __RUNPROG="nslookup $domain $dns_server 2>/dev/null"
-               __ERRPROG="nslookup $domain $dns_server 2>&1"
-               verbose_echo " resolver prog =: $__RUNPROG"
-               __IP=$(eval $__RUNPROG)
-               __ERR=$?
-               # command error
-               [ $__ERR -gt 0 ] && {
-                       verbose_echo "\n!!!!!!!!! ERROR =: BusyBox nslookup Error '$__ERR'\n$(eval $__ERRPROG)\n"
-                       syslog_err "DNS Resolver Error - BusyBox nslookup Error: '$__ERR'"
-                       return 1
-               } || {
-                       # we need to run twice because multi-line output needs to be directly piped to grep because
-                       # pipe returns return code of last prog in pipe but we need errors from nslookup command
-                       __IP=$(eval $__RUNPROG | sed -ne "3,\$ { s/^Address [0-9]*: \($__REGEX\).*$/\\1/p }" )
-               }
-
-       else                                    # there must be an error
-               critical_error "No program found to request public registered IP"
+               __RUNPROG="/usr/bin/nslookup $domain $dns_server >$DATFILE 2>$ERRFILE"
+               __PROG="BusyBox nslookup"
+       else    # there must be an error
+               write_log 12 "Error in 'get_registered_ip()' - no supported Name Server lookup software accessible"
        fi
 
-       verbose_echo "   resolved ip =: '$__IP'"
+       while : ; do
+               write_log 7 "#> $__RUNPROG"
+               eval $__RUNPROG
+               __ERR=$?
+               if [ $__ERR -ne 0 ]; then
+                       write_log 3 "$__PROG error: '$__ERR'"
+                       write_log 7 "$(cat $ERRFILE)"
+               else
+                       if [ "$__PROG" = "BIND host" ]; then
+                               __DATA=$(cat $DATFILE | awk -F "address " '/has/ {print $2; exit}' )
+                       else
+                               __DATA=$(cat $DATFILE | sed -ne "3,\$ { s/^Address[0-9 ]\{0,\}: \($__REGEX\).*$/\\1/p }" )
+                       fi
+                       [ -n "$__DATA" ] && {
+                               write_log 7 "Registered IP '$__DATA' detected"
+                               eval "$1=\"$__DATA\""   # valid data found
+                               return 0                # leave here
+                       }
+                       write_log 4 "NO valid IP found"
+                       __ERR=127
+               fi
+
+               [ $LUCI_HELPER ] && return $__ERR       # no retry if called by LuCI helper script
+               [ -n "$2" ] && return $__ERR            # $2 is given -> no retry
+               [ $VERBOSE_MODE -gt 1 ] && {
+                       # VERBOSE_MODE > 1 then NO retry
+                       write_log 4 "Get registered/public IP for '$domain' failed - Verbose Mode: $VERBOSE_MODE - NO retry on error"
+                       return $__ERR
+               }
 
-       # if NO IP was found
-       [ -z "$__IP" ] && return 1
+               __CNT=$(( $__CNT + 1 )) # increment error counter
+               # if error count > retry_count leave here
+               [ $retry_count -gt 0 -a $__CNT -gt $retry_count ] && \
+                       write_log 14 "Get registered/public IP for '$domain' failed after $retry_count retries"
 
-       eval "$1='$__IP'"
-       return 0
+               write_log 4 "Get registered/public IP for '$domain' failed - retry $__CNT/$retry_count in $RETRY_SECONDS seconds"
+               sleep $RETRY_SECONDS &
+               PID_SLEEP=$!
+               wait $PID_SLEEP # enable trap-handler
+               PID_SLEEP=0
+       done
+       # we should never come here there must be a programming error
+       write_log 12 "Error in 'get_registered_ip()' - program coding error"
 }
 
 get_uptime() {
        # $1    Variable to store result in
+       [ $# -ne 1 ] && write_log 12 "Error calling 'verify_host_port()' - wrong number of parameters"
        local __UPTIME=$(cat /proc/uptime)
-       eval "$1='${__UPTIME%%.*}'"
+       eval "$1=\"${__UPTIME%%.*}\""
+}
+
+trap_handler() {
+       # $1    trap signal
+       # $2    optional (exit status)
+       local __PIDS __PID
+       local __ERR=${2:-0}
+       local __OLD_IFS=$IFS
+       local __NEWLINE_IFS='
+' # __NEWLINE_IFS
+
+       [ $PID_SLEEP -ne 0 ] && kill -$1 $PID_SLEEP 2>/dev/null # kill pending sleep if exist
+
+       case $1 in
+                0)     if [ $__ERR -eq 0 ]; then
+                               write_log 5 "PID '$$' exit normal at $(eval $DATE_PROG)\n"
+                       else
+                               write_log 4 "PID '$$' exit WITH ERROR '$__ERR' at $(eval $DATE_PROG)\n"
+                       fi ;;
+                1)     write_log 6 "PID '$$' received 'SIGHUP' at $(eval $DATE_PROG)"
+                       # reload config via starting the script again
+                       eval "/usr/lib/ddns/dynamic_dns_updater.sh $SECTION_ID $VERBOSE_MODE &"
+                       exit 0 ;;       # and leave this one
+                2)     write_log 5 "PID '$$' terminated by 'SIGINT' at $(eval $DATE_PROG)\n";;
+                3)     write_log 5 "PID '$$' terminated by 'SIGQUIT' at $(eval $DATE_PROG)\n";;
+               15)     write_log 5 "PID '$$' terminated by 'SIGTERM' at $(eval $DATE_PROG)\n";;
+                *)     write_log 13 "Unhandled signal '$1' in 'trap_handler()'";;
+       esac
+
+       __PIDS=$(pgrep -P $$)   # get my childs (pgrep prints with "newline")
+       IFS=$__NEWLINE_IFS
+       for __PID in $__PIDS; do
+               kill -$1 $__PID # terminate it
+       done
+       IFS=$__OLD_IFS
+
+       # remove out and err file
+       [ -f $DATFILE ] && rm -f $DATFILE
+       [ -f $ERRFILE ] && rm -f $ERRFILE
+
+       # exit with correct handling:
+       # remove trap handling settings and send kill to myself
+       trap - 0 1 2 3 15
+       [ $1 -gt 0 ] && kill -$1 $$
+}
+
+split_FQDN() {
+       # $1    FQDN to split
+       # $2    name of variable to store TLD
+       # $3    name of variable to store (reg)Domain
+       # $4    name of variable to store Host/Subdomain
+
+       [ $# -ne 4 ] && write_log 12 "Error calling 'split_FQDN()' - wrong number of parameters"
+
+       _SET="$@"                                       # save given parameters
+       local _FHOST _FTLD _FOUND
+       local _FDOM=$(echo "$1" | tr [A-Z] [a-z])       # to lower
+
+       set -- $(echo "$_FDOM" | tr "." " ")            # replace DOT with SPACE and set as script parameters
+       _FDOM=""                                        # clear variable for later reuse
+
+       while [ -n "$1" ] ; do                          # as long we have parameters
+               _FTLD=$(echo $@ | tr " " ".")           # build back dot separated as TLD
+               # look if match excludes "!" in tld_names.dat
+               grep -E "^!$_FTLD$" $TLDFILE >/dev/null 2>&1 || {
+                       # Don't match excludes
+                       # check if match any "*" in tld_names.dat
+                       grep -E "^*.$_FTLD$" $TLDFILE >/dev/null 2>&1 && {
+                               _FOUND="VALID"
+                               break   # found leave while
+                       }
+                       # check if exact match in tld_names.dat
+                       grep -E "^$_FTLD$" $TLDFILE >/dev/null 2>&1 && {
+                               _FOUND="VALID"
+                               break   # found leave while
+                       }
+               }
+               # nothing match so
+               _FHOST="$_FHOST $_FDOM"         # append DOMAIN to last found HOST
+               _FDOM="$1"                      # set 1st parameter as DOMAIN
+               _FTLD=""                        # clear TLD
+               shift                           # delete 1st parameter and retry with the rest
+       done
+
+       set -- $_SET                            # set back parameters from function call
+       [ -n "$_FHOST" ] && _FHOST=$(echo $_FHOST | tr " " ".") # put dots back into HOST
+       [ -n "$_FOUND" ] && {
+               eval "$2=$_FTLD"        # set found TLD
+               eval "$3=$_FDOM"        # set found registrable domain
+               eval "$4=$_FHOST"       # set found HOST/SUBDOMAIN
+               return 0
+       }
+       eval "$2=''"            # clear TLD
+       eval "$3=''"            # clear registrable domain
+       eval "$4=''"            # clear HOST/SUBDOMAIN
+       return 1
 }
diff --git a/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh b/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_lucihelper.sh
new file mode 100755 (executable)
index 0000000..0c54492
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/sh
+# /usr/lib/ddns/luci_dns_helper.sh
+#
+# Written in August 2014
+# by Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+# This script is used by luci-app-ddns
+# - getting registered IP
+# - check if possible to get local IP
+# - verifing given DNS- or Proxy-Server
+#
+# variables in small chars are read from /etc/config/ddns as parameter given here
+# variables in big chars are defined inside these scripts as gloval vars
+# variables in big chars beginning with "__" are local defined inside functions only
+# set -vx      #script debugger
+
+[ $# -lt 2 ] && exit 1
+
+. /usr/lib/ddns/dynamic_dns_functions.sh       # global vars are also defined here
+
+# preset some variables, wrong or not set in dynamic_dns_functions.sh
+SECTION_ID="lucihelper"
+LOGFILE="$LOGDIR/$SECTION_ID.log"
+DATFILE="$RUNDIR/$SECTION_ID.dat"      # save stdout data of WGet and other extern programs called
+ERRFILE="$RUNDIR/$SECTION_ID.err"      # save stderr output of WGet and other extern programs called
+VERBOSE_MODE=0         # no console logging
+# global variables normally set by reading DDNS UCI configuration
+use_syslog=0           # no syslog
+use_logfile=0          # by default no logfile, can be changed here
+
+__RET=0
+case "$1" in
+       get_registered_ip)
+               local IP
+               domain=$2                       # Hostname/Domain
+               use_ipv6=${3:-"0"}              # Use IPv6 - default IPv4
+               force_ipversion=${4:-"0"}       # Force IP Version - default 0 - No
+               force_dnstcp=${5:-"0"}          # Force TCP on DNS - default 0 - No
+               dns_server=${6:-""}             # DNS server - default No DNS
+               write_log 7 "-----> get_registered_ip IP"
+               get_registered_ip IP
+               __RET=$?
+               [ $__RET -ne 0 ] && IP=""
+               echo -n "$IP"                   # suppress LF
+               ;;
+       verify_dns)
+               # $2 : dns-server to verify     # no need for force_dnstcp because
+                                               # verify with nc (netcat) uses tcp anyway
+               use_ipv6=${3:-"0"}              # Use IPv6 - default IPv4
+               force_ipversion=${4:-"0"}       # Force IP Version - default 0 - No
+               write_log 7 "-----> verify_dns '$2'"
+               verify_dns "$2"
+               __RET=$?
+               ;;
+       verify_proxy)
+               # $2 : proxy string to verify
+               use_ipv6=${3:-"0"}              # Use IPv6 - default IPv4
+               force_ipversion=${4:-"0"}       # Force IP Version - default 0 - No
+               write_log 7 "-----> verify_proxy '$2'"
+               verify_proxy "$2"
+               __RET=$?
+               ;;
+       get_local_ip)
+               local IP
+               use_ipv6="$2"                   # Use IPv6
+               ip_source="$3"                  # IP source
+               ip_network="$4"                 # set if source = "network" otherwise "-"
+               ip_url="$5"                     # set if source = "web" otherwise "-"
+               ip_interface="$6"               # set if source = "interface" itherwiase "-"
+               ip_script="$7"                  # set if source = "script" otherwise "-"
+               proxy="$8"                      # proxy if set
+               force_ipversion="0"             # not needed but must be set
+               use_https="0"                   # not needed but must be set
+               [ -n "$proxy" -a "$ip_source" = "web" ] && {
+                       # proxy defined, used for ip_source=web
+                       export HTTP_PROXY="http://$proxy"
+                       export HTTPS_PROXY="http://$proxy"
+                       export http_proxy="http://$proxy"
+                       export https_proxy="http://$proxy"
+               }
+               # don't need IP only the return code
+               [ "$ip_source" = "web" -o  "$ip_source" = "script" ] && {
+                       # we wait only 3 seconds for an
+                       # answer from "web" or "script"
+                       write_log 7 "-----> timeout 3 -- get_local_ip IP"
+                       timeout 3 -- get_local_ip IP
+               } || {
+                       write_log 7 "-----> get_local_ip IP"
+                       get_local_ip IP
+               }
+               __RET=$?
+               ;;
+       *)
+               __RET=255
+               ;;
+esac
+
+# remove out and err file
+[ -f $DATFILE ] && rm -f $DATFILE
+[ -f $ERRFILE ] && rm -f $ERRFILE
+return $__RET
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index 3892c69..8127f5b
@@ -6,20 +6,21 @@
 # (Loosely) based on the script on the one posted by exobyte in the forums here:
 # http://forum.openwrt.org/viewtopic.php?id=14040
 #
-# extended and partial rewritten in August 2014 
+# extended and partial rewritten in August 2014
 # by Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
 # to support:
 # - IPv6 DDNS services
-# - DNS Server to retrieve registered IP including TCP transport
+# - DNS Server to retrieve registered IP including TCP transport (Ticket 7820)
 # - Proxy Server to send out updates
-# - force_interval=0 to run once
+# - force_interval=0 to run once (Luci Ticket 538)
 # - the usage of BIND's host command instead of BusyBox's nslookup if installed
-# - extended Verbose Mode and log file support for better error detection 
+# - extended Verbose Mode and log file support for better error detection
+# - wait for interface to fully come up, before the first update is done
 #
 # variables in small chars are read from /etc/config/ddns
 # variables in big chars are defined inside these scripts as global vars
 # variables in big chars beginning with "__" are local defined inside functions only
-#set -vx       #script debugger
+# set -vx      #script debugger
 
 [ $# -lt 1 -o -n "${2//[0-3]/}" -o ${#2} -gt 1 ] && {
        echo -e "\n  USAGE:"
 . /usr/lib/ddns/dynamic_dns_functions.sh       # global vars are also defined here
 
 SECTION_ID="$1"
-VERBOSE_MODE=${2:-1}   #default mode is log to console
+VERBOSE_MODE=${2:-1}   # default mode is log to console
 
 # set file names
 PIDFILE="$RUNDIR/$SECTION_ID.pid"      # Process ID file
 UPDFILE="$RUNDIR/$SECTION_ID.update"   # last update successful send (system uptime)
+DATFILE="$RUNDIR/$SECTION_ID.dat"      # save stdout data of WGet and other extern programs called
+ERRFILE="$RUNDIR/$SECTION_ID.err"      # save stderr output of WGet and other extern programs called
 LOGFILE="$LOGDIR/$SECTION_ID.log"      # log file
 
 # VERBOSE_MODE > 1 delete logfile if exist to create an empty one
 # only with this data of this run for easier diagnostic
-# new one created by verbose_echo function
+# new one created by write_log function
 [ $VERBOSE_MODE -gt 1 -a -f $LOGFILE ] && rm -f $LOGFILE
 
+# TRAP handler
+trap "trap_handler 0 \$?" 0    # handle script exit with exit status
+trap "trap_handler 1"  1       # SIGHUP        Hangup / reload config
+trap "trap_handler 2"  2       # SIGINT        Terminal interrupt
+trap "trap_handler 3"  3       # SIGQUIT       Terminal quit
+# trap "trap_handler 9"  9     # SIGKILL       no chance to trap
+trap "trap_handler 15" 15      # SIGTERM       Termination
+
 ################################################################################
 # Leave this comment here, to clearly document variable names that are expected/possible
 # Use load_all_config_options to load config options, which is a much more flexible solution.
 #
 # config_load "ddns"
-# config_get <variable> $SECTION_ID <option]>
+# config_get <variable> $SECTION_ID <option>
 #
 # defined options (also used as variable):
-# 
+#
 # enable       self-explanatory
 # interface    network interface used by hotplug.d i.e. 'wan' or 'wan6'
 #
@@ -79,9 +90,9 @@ LOGFILE="$LOGDIR/$SECTION_ID.log"     # log file
 # ip_network   local defined network to read IP from i.e. 'wan' or 'wan6'
 # ip_url       URL to read local address from i.e. http://checkip.dyndns.com/ or http://checkipv6.dyndns.com/
 # ip_script    full path and name of your script to detect local IP
-# ip_interface physical interface to use for detecting 
+# ip_interface physical interface to use for detecting
 #
-# check_interval       check for changes every  !!! checks below 10 minutes make no sense because the Internet 
+# check_interval       check for changes every  !!! checks below 10 minutes make no sense because the Internet
 # check_unit           'days' 'hours' 'minutes' !!! needs about 5-10 minutes to sync an IP-change for an DNS entry
 #
 # force_interval       force to send an update to your service if no change was detected
@@ -89,52 +100,33 @@ LOGFILE="$LOGDIR/$SECTION_ID.log"  # log file
 #
 # retry_interval       if error was detected retry in
 # retry_unit           'days' 'hours' 'minutes' 'seconds'
-# retry_count          #NEW# number of retries before scripts stops
+# retry_count          number of retries before scripts stops
 #
-# use_ipv6             #NEW# detecting/sending IPv6 address
-# force_ipversion      #NEW# force usage of IPv4 or IPv6 for the whole detection and update communication
-# dns_server           #NEW# using a non default dns server to get Registered IP from Internet
-# force_dnstcp         #NEW# force communication with DNS server via TCP instead of default UDP
-# proxy                        #NEW# using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!!
-# use_logfile          #NEW# self-explanatory "/var/log/ddns/$SECTION_ID.log"
+# use_ipv6             detecting/sending IPv6 address
+# force_ipversion      force usage of IPv4 or IPv6 for the whole detection and update communication
+# dns_server           using a non default dns server to get Registered IP from Internet
+# force_dnstcp         force communication with DNS server via TCP instead of default UDP
+# proxy                        using a proxy for communication !!! ALSO used to detect local IP via web => return proxy's IP !!!
+# use_logfile          self-explanatory "/var/log/ddns/$SECTION_ID.log"
 #
-# some functionality needs 
+# some functionality needs
 # - GNU Wget or cURL installed for sending updates to DDNS service
 # - BIND host installed to detect Registered IP
 #
 ################################################################################
 
-# verify and load SECTION_ID is exists
-[ "$(uci_get ddns $SECTION_ID)" != "service" ] && {
-       [ $VERBOSE_MODE -le 1 ] && VERBOSE_MODE=2       # force console out and logfile output
-       [ -f $LOGFILE ] && rm -f $LOGFILE               # clear logfile before first entry
-       verbose_echo "\n ************** =: ************** ************** **************"
-       verbose_echo "       STARTED =: PID '$$' at $(eval $DATE_PROG)"
-       verbose_echo "    UCI CONFIG =:\n$(uci -q show ddns | grep '=service' | sort)"
-       critical_error "Service '$SECTION_ID' not defined"
-}
 load_all_config_options "ddns" "$SECTION_ID"
-
-verbose_echo "\n ************** =: ************** ************** **************"
-verbose_echo "       STARTED =: PID '$$' at $(eval $DATE_PROG)"
-case $VERBOSE_MODE in
-       0) verbose_echo "  verbose mode =: '0' - run normal, NO console output";;
-       1) verbose_echo "  verbose mode =: '1' - run normal, console mode";;
-       2) verbose_echo "  verbose mode =: '2' - run once, NO retry on error";;
-       3) verbose_echo "  verbose mode =: '3' - run once, NO retry on error, NOT sending update";;
-       *) critical_error "ERROR detecting VERBOSE_MODE '$VERBOSE_MODE'"
-esac
-verbose_echo "    UCI CONFIG =:\n$(uci -q show ddns.$SECTION_ID | sort)"
+ERR_LAST=$?    # save return code - equal 0 if SECTION_ID found
 
 # set defaults if not defined
 [ -z "$enabled" ]        && enabled=0
 [ -z "$retry_count" ]    && retry_count=5
-[ -z "$use_syslog" ]      && use_syslog=0      # not use syslog
+[ -z "$use_syslog" ]      && use_syslog=2      # syslog "Notice"
 [ -z "$use_https" ]       && use_https=0       # not use https
-[ -z "$use_logfile" ]     && use_logfile=1     # NEW - use logfile by default
-[ -z "$use_ipv6" ]       && use_ipv6=0         # NEW - use IPv4 by default
-[ -z "$force_ipversion" ] && force_ipversion=0 # NEW - default let system decide
-[ -z "$force_dnstcp" ]   && force_dnstcp=0     # NEW - default UDP
+[ -z "$use_logfile" ]     && use_logfile=1     # use logfile by default
+[ -z "$use_ipv6" ]       && use_ipv6=0         # use IPv4 by default
+[ -z "$force_ipversion" ] && force_ipversion=0 # default let system decide
+[ -z "$force_dnstcp" ]   && force_dnstcp=0     # default UDP
 [ -z "$ip_source" ]      && ip_source="network"
 [ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 0 ] && ip_network="wan"  # IPv4: default wan
 [ "$ip_source" = "network" -a -z "$ip_network" -a $use_ipv6 -eq 1 ] && ip_network="wan6" # IPv6: default wan6
@@ -142,56 +134,81 @@ verbose_echo "    UCI CONFIG =:\n$(uci -q show ddns.$SECTION_ID | sort)"
 [ "$ip_source" = "web" -a -z "$ip_url" -a $use_ipv6 -eq 1 ] && ip_url="http://checkipv6.dyndns.com"
 [ "$ip_source" = "interface" -a -z "$ip_interface" ] && ip_interface="eth1"
 
-# check configuration and enabled state
-[ -z "$domain" -o -z "$username" -o -z "$password" ] && critical_error "Service Configuration not correctly configured"
-[ $enabled -eq 0 ] && critical_error "Service Configuration is disabled"
+# SECTION_ID does not exists
+[ $ERR_LAST -ne 0 ] && {
+       [ $VERBOSE_MODE -le 1 ] && VERBOSE_MODE=2       # force console out and logfile output
+       [ -f $LOGFILE ] && rm -f $LOGFILE               # clear logfile before first entry
+       write_log  7 "************ ************** ************** **************"
+       write_log  5 "PID '$$' started at $(eval $DATE_PROG)"
+       write_log  7 "uci configuration:\n$(uci -q show ddns | grep '=service' | sort)"
+       write_log 14 "Service section '$SECTION_ID' not defined"
+}
+
+write_log 7 "************ ************** ************** **************"
+write_log 5 "PID '$$' started at $(eval $DATE_PROG)"
+write_log 7 "uci configuration:\n$(uci -q show ddns.$SECTION_ID | sort)"
+write_log 7 "ddns version  : $(opkg list-installed ddns-scripts | awk '{print $3}')"
+case $VERBOSE_MODE in
+       0) write_log  7 "verbose mode  : 0 - run normal, NO console output";;
+       1) write_log  7 "verbose mode  : 1 - run normal, console mode";;
+       2) write_log  7 "verbose mode  : 2 - run once, NO retry on error";;
+       3) write_log  7 "verbose mode  : 3 - run once, NO retry on error, NOT sending update";;
+       *) write_log 14 "error detecting VERBOSE_MODE '$VERBOSE_MODE'";;
+esac
+
+# check enabled state otherwise we don't need to continue
+[ $enabled -eq 0 ] && write_log 14 "Service section disabled!"
+
+# determine what update url we're using if a service_name is supplied
+# otherwise update_url is set inside configuration (custom update url)
+# or update_script is set inside configuration (custom update script)
+[ -n "$service_name" ] && get_service_data update_url update_script
+[ -z "$update_url" -a -z "$update_script" ] && write_log 14 "No update_url found/defined or no update_script found/defined!"
+[ -n "$update_script" -a ! -f "$update_script" ] && write_log 14 "Custom update_script not found!"
+
+# without domain and possibly username and password we can do nothing for you
+[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing 'domain'"
+[ -n "$update_url" ] && {
+       # only check if update_url is given, update_scripts have to check themselves
+       [ -z "$username" ] && $(echo "$update_url" | grep "\[USERNAME\]" >/dev/null 2>&1) && \
+               write_log 14 "Service section not configured correctly! Missing 'username'"
+       [ -z "$password" ] && $(echo "$update_url" | grep "\[PASSWORD\]" >/dev/null 2>&1) && \
+               write_log 14 "Service section not configured correctly! Missing 'password'"
+}
 
-# verify script if configured and executable
+# url encode username (might be email or something like this)
+# and password (might have special chars for security reason)
+[ -n "$username" ] && urlencode URL_USER "$username"
+[ -n "$password" ] && urlencode URL_PASS "$password"
+
+# verify ip_source 'script' if script is configured and executable
 if [ "$ip_source" = "script" ]; then
-       [ -z "$ip_script" ] && critical_error "No script defined to detect local IP"
-       [ -x "$ip_script" ] || critical_error "Script to detect local IP not found or not executable"
+       set -- $ip_script       #handling script with parameters, we need a trick
+       [ -z "$1" ] && write_log 14 "No script defined to detect local IP!"
+       [ -x "$1" ] || write_log 14 "Script to detect local IP not executable!"
 fi
 
 # compute update interval in seconds
 get_seconds CHECK_SECONDS ${check_interval:-10} ${check_unit:-"minutes"} # default 10 min
 get_seconds FORCE_SECONDS ${force_interval:-72} ${force_unit:-"hours"}  # default 3 days
 get_seconds RETRY_SECONDS ${retry_interval:-60} ${retry_unit:-"seconds"} # default 60 sec
-verbose_echo "check interval =: $CHECK_SECONDS seconds"
-verbose_echo "force interval =: $FORCE_SECONDS seconds"
-verbose_echo "retry interval =: $RETRY_SECONDS seconds"
-verbose_echo " retry counter =: $retry_count times"
-
-# determine what update url we're using if a service_name is supplied
-# otherwise update_url is set inside configuration (custom service)
-# or update_script is set inside configuration (custom update script)
-[ -n "$service_name" ] && get_service_data update_url update_script
-[ -z "$update_url" -a -z "$update_script" ] && critical_error "no update_url found/defined or no update_script found/defined"
-[ -n "$update_script" -a ! -f "$update_script" ] && critical_error "custom update_script not found"
-
-#kill old process if it exists & set new pid file
-if [ -d $RUNDIR ]; then
-       #if process is already running, stop it
-       if [ -e "$PIDFILE" ]; then
-               OLD_PID=$(cat $PIDFILE)
-               ps | grep -q "^[\t ]*$OLD_PID" && {
-                       verbose_echo "   old process =: PID '$OLD_PID'"
-                       kill $OLD_PID
-               } || verbose_echo "old process id =: PID 'none'"
-       else
-               verbose_echo "old process id =: PID 'none'"
-       fi
-else
-       #make dir since it doesn't exist
-       mkdir -p $RUNDIR
-       verbose_echo "old process id =: PID 'none'"
-fi
+[ $CHECK_SECONDS -lt 300 ] && CHECK_SECONDS=300                # minimum 5 minutes
+[ $FORCE_SECONDS -gt 0 -a $FORCE_SECONDS -lt $CHECK_SECONDS ] && FORCE_SECONDS=$CHECK_SECONDS  # FORCE_SECONDS >= CHECK_SECONDS or 0
+write_log 7 "check interval: $CHECK_SECONDS seconds"
+write_log 7 "force interval: $FORCE_SECONDS seconds"
+write_log 7 "retry interval: $RETRY_SECONDS seconds"
+write_log 7 "retry counter : $retry_count times"
+
+# kill old process if it exists & set new pid file
+stop_section_processes "$SECTION_ID"
+[ $? -gt 0 ] && write_log 7 "Send 'SIGTERM' was send to old process" || write_log 7 "No old process"
 echo $$ > $PIDFILE
 
 # determine when the last update was
-# the following lines should prevent multiple updates if hotplug fires multiple startups 
+# the following lines should prevent multiple updates if hotplug fires multiple startups
 # as described in Ticket #7820, but did not function if never an update take place
 # i.e. after a reboot (/var is linked to /tmp)
-# using uptime as reference because date might not be updated via NTP client 
+# using uptime as reference because date might not be updated via NTP client
 get_uptime CURR_TIME
 [ -e "$UPDFILE" ] && {
        LAST_TIME=$(cat $UPDFILE)
@@ -201,203 +218,117 @@ get_uptime CURR_TIME
        [ $LAST_TIME -gt $CURR_TIME ] && LAST_TIME=0
 }
 if [ $LAST_TIME -eq 0 ]; then
-       verbose_echo "   last update =: never"
+       write_log 7 "last update: never"
 else
        EPOCH_TIME=$(( $(date +%s) - CURR_TIME + LAST_TIME ))
        EPOCH_TIME="date -d @$EPOCH_TIME +'$DATE_FORMAT'"
-       verbose_echo "   last update =: $(eval $EPOCH_TIME)"
+       write_log 7 "last update: $(eval $EPOCH_TIME)"
 fi
 
-# we need time here because hotplug.d is fired by netifd
-# but IP addresses are not set by DHCP/DHCPv6 etc.
-verbose_echo "       waiting =: 10 seconds for interfaces to fully come up"
-sleep 10
-
 # verify DNS server
-[ -n "$dns_server" ] && {
-       verbose_echo "******* VERIFY =: DNS server '$dns_server'"
-       verify_dns "$dns_server"
-       case $? in
-               0)      ;;      # everything OK
-               2)      critical_error "Invalid DNS server Error: '2' - nslookup can not resolve host";;
-               3)      critical_error "Invalid DNS server Error: '3' - nc (netcat) can not connect";;
-               4)      critical_error "Invalid DNS server Error: '4' - Forced IP Version don't matched";;
-               *)      critical_error "Invalid DNS server Error: '1' - unspecific error";;
-       esac
-}
+[ -n "$dns_server" ] && verify_dns "$dns_server"
 
 # verify Proxy server and set environment
 [ -n "$proxy" ] && {
-       verbose_echo "******* VERIFY =: Proxy server 'http://$proxy'"
-       verify_proxy "$proxy"
-       case $? in
-               0)      # everything OK
-                       export HTTP_PROXY="http://$proxy"
-                       export HTTPS_PROXY="http://$proxy"
-                       export http_proxy="http://$proxy"
-                       export https_proxy="http://$proxy"
-                       ;;
-               2)      critical_error "Invalid Proxy server Error: '2' - nslookup can not resolve host";;
-               3)      critical_error "Invalid Proxy server Error: '3' - nc (netcat) can not connect";;
-               4)      critical_error "Invalid Proxy server Error: '4' - Forced IP Version don't matched";;
-               5)      critical_error "Invalid Proxy server Error: '5' - proxy port missing";;
-               *)      critical_error "Invalid Proxy server Error: '1' - unspecific error";;
-       esac
+       verify_proxy "$proxy" && {
+               # everything ok set proxy
+               export HTTP_PROXY="http://$proxy"
+               export HTTPS_PROXY="http://$proxy"
+               export http_proxy="http://$proxy"
+               export https_proxy="http://$proxy"
+       }
 }
 
-# let's check if there is already an IP registered at the web
-# but ignore errors if not
-verbose_echo "******* DETECT =: Registered IP"
-get_registered_ip REGISTERED_IP
+# let's check if there is already an IP registered on the web
+get_registered_ip REGISTERED_IP "NO_RETRY"
+ERR_LAST=$?
+#     No error    or     No IP set      otherwise retry
+[ $ERR_LAST -eq 0 -o $ERR_LAST -eq 127 ] || get_registered_ip REGISTERED_IP
 
 # loop endlessly, checking ip every check_interval and forcing an updating once every force_interval
-# NEW: ### Luci Ticket 538
-# a "force_interval" of "0" will run this script only once
-# the update is only done once when an interface goes up
-# or you run /etc/init.d/ddns start or you can use a cron job
-# it will force an update without check when lastupdate happen
-# but it will verify after "check_interval" if update is seen in the web 
-# and retries on error retry_count times
-# CHANGES: ### Ticket 16363
-# modified nslookup / sed / grep to detect registered ip
-# NEW: ### Ticket 7820
-# modified nslookup to support non standard dns_server (needs to be defined in /etc/config/ddns)
-# support for BIND host command.
-# Wait for interface to fully come up, before the first update is done
-verbose_echo "*** START LOOP =: $(eval $DATE_PROG)"
-# we run NOT once
-[ $FORCE_SECONDS -gt 0 -o $VERBOSE_MODE -le 1 ] && syslog_info "Starting main loop"
-
+write_log 6 "Starting main loop at $(eval $DATE_PROG)"
 while : ; do
 
-       # read local IP
-       verbose_echo "******* DETECT =: Local IP"
-       get_local_ip LOCAL_IP
-       ERR_LAST=$?     # save return value
-       # Error in function
-       [ $ERR_LAST -gt 0 ] && {
-               if [ $VERBOSE_MODE -le 1 ]; then        # VERBOSE_MODE <= 1 then retry
-                       # we can't read local IP
-                       ERR_LOCAL_IP=$(( $ERR_LOCAL_IP + 1 ))
-                       [ $ERR_LOCAL_IP -gt $retry_count ] && critical_error "Can not detect local IP"
-                       verbose_echo "\n!!!!!!!!! ERROR =: detecting local IP - retry $ERR_LOCAL_IP/$retry_count in $RETRY_SECONDS seconds\n"
-                       syslog_err "Error detecting local IP - retry $ERR_LOCAL_IP/$retry_count in $RETRY_SECONDS seconds"
-                       sleep $RETRY_SECONDS
-                       continue        # jump back to the beginning of while loop
-               else
-                       verbose_echo "\n!!!!!!!!! ERROR =: detecting local IP - NO retry\n"
-               fi
-       }
-       ERR_LOCAL_IP=0  # reset err counter
+       get_local_ip LOCAL_IP           # read local IP
 
        # prepare update
-       # never updated or forced immediate then NEXT_TIME = 0 
+       # never updated or forced immediate then NEXT_TIME = 0
        [ $FORCE_SECONDS -eq 0 -o $LAST_TIME -eq 0 ] \
                && NEXT_TIME=0 \
                || NEXT_TIME=$(( $LAST_TIME + $FORCE_SECONDS ))
-       # get current uptime
-       get_uptime CURR_TIME
-       
-       # send update when current time > next time or local ip different from registered ip (as loop on error)
-       ERR_SEND=0
-       while [ $CURR_TIME -ge $NEXT_TIME -o "$LOCAL_IP" != "$REGISTERED_IP" ]; do
+
+       get_uptime CURR_TIME            # get current uptime
+
+       # send update when current time > next time or local ip different from registered ip
+       if [ $CURR_TIME -ge $NEXT_TIME -o "$LOCAL_IP" != "$REGISTERED_IP" ]; then
                if [ $VERBOSE_MODE -gt 2 ]; then
-                       verbose_echo "  VERBOSE MODE =: NO UPDATE send to DDNS provider"
+                       write_log 7 "Verbose Mode: $VERBOSE_MODE - NO UPDATE send"
                elif [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
-                       verbose_echo "******* UPDATE =: LOCAL: '$LOCAL_IP' <=> REGISTERED: '$REGISTERED_IP'"
+                       write_log 7 "Update needed - L: '$LOCAL_IP' <> R: '$REGISTERED_IP'"
                else
-                       verbose_echo "******* FORCED =: LOCAL: '$LOCAL_IP' == REGISTERED: '$REGISTERED_IP'"
+                       write_log 7 "Forced Update - L: '$LOCAL_IP' == R: '$REGISTERED_IP'"
                fi
-               # only send if VERBOSE_MODE < 3
+
                ERR_LAST=0
                [ $VERBOSE_MODE -lt 3 ] && {
-                       send_update "$LOCAL_IP" 
+                       # only send if VERBOSE_MODE < 3
+                       send_update "$LOCAL_IP"
                        ERR_LAST=$?     # save return value
                }
 
-               # Error in function 
-               if [ $ERR_LAST -gt 0 ]; then
-                       if [ $VERBOSE_MODE -le 1 ]; then        # VERBOSE_MODE <=1 then retry
-                               # error sending local IP
-                               ERR_SEND=$(( $ERR_SEND + 1 ))
-                               [ $ERR_SEND -gt $retry_count ] && critical_error "can not send update to DDNS Provider"
-                               verbose_echo "\n!!!!!!!!! ERROR =: sending update - retry $ERR_SEND/$retry_count in $RETRY_SECONDS seconds\n"
-                               syslog_err "Error sending update - retry $ERR_SEND/$retry_count in $RETRY_SECONDS seconds"
-                               sleep $RETRY_SECONDS
-                               continue # re-loop
-                       else
-                               verbose_echo "\n!!!!!!!!! ERROR =: sending update to DDNS service - NO retry\n"
-                               break
-                       fi
-               else
-                       # we send data so save "last time"
-                       get_uptime LAST_TIME
+               # error sending local IP to provider
+               # we have no communication error (handled inside send_update/do_transfer)
+               # but update was not recognized
+               # do NOT retry after RETRY_SECONDS, do retry after CHECK_SECONDS
+               # to early retrys will block most DDNS provider
+               # providers answer is checked inside send_update() function
+               if [ $ERR_LAST -eq 0 ]; then
+                       get_uptime LAST_TIME            # we send update, so
                        echo $LAST_TIME > $UPDFILE      # save LASTTIME to file
                        [ "$LOCAL_IP" != "$REGISTERED_IP" ] \
-                               && syslog_notice "Changed IP: '$LOCAL_IP' successfully send" \
-                               || syslog_notice "Forced Update: IP: '$LOCAL_IP' successfully send"
-                       break # leave while
+                               && write_log 6 "Update successful - IP '$LOCAL_IP' send" \
+                               || write_log 6 "Forced update successful - IP: '$LOCAL_IP' send"
+               else
+                       write_log 3 "Can not update IP at DDNS Provider"
                fi
-       done
+       fi
 
        # now we wait for check interval before testing if update was recognized
-       # only sleep if VERBOSE_MODE <= 2 because nothing send so do not wait
+       # only sleep if VERBOSE_MODE <= 2 because otherwise nothing was send
        [ $VERBOSE_MODE -le 2 ] && {
-               verbose_echo "****** WAITING =: $CHECK_SECONDS seconds (Check Interval) before continue"
-               sleep $CHECK_SECONDS
-       } || verbose_echo "  VERBOSE MODE =: NO WAITING for Check Interval\n"
-
-       # read at DDNS service registered IP (in loop on error)
-       REGISTERED_IP=""
-       ERR_REG_IP=0
-       while : ; do
-               verbose_echo "******* DETECT =: Registered IP"
-               get_registered_ip REGISTERED_IP
-               ERR_LAST=$?     # save return value
-
-               # No Error in function we leave while loop
-               [ $ERR_LAST -eq 0  ] && break
-
-               # we can't read Registered IP
-               if [ $VERBOSE_MODE -le 1 ]; then        # VERBOSE_MODE <=1 then retry
-                       ERR_REG_IP=$(( $ERR_REG_IP + 1 ))
-                       [ $ERR_REG_IP -gt $retry_count ] && critical_error "can not detect registered local IP"
-                       verbose_echo "\n!!!!!!!!! ERROR =: detecting Registered IP - retry $ERR_REG_IP/$retry_count in $RETRY_SECONDS seconds\n"
-                       syslog_err "Error detecting Registered IP - retry $ERR_REG_IP/$retry_count in $RETRY_SECONDS seconds"
-                       sleep $RETRY_SECONDS
-               else
-                       verbose_echo "\n!!!!!!!!! ERROR =: detecting Registered IP - NO retry\n"
-                       break   # leave while loop
-               fi
-       done
+               write_log 7 "Waiting $CHECK_SECONDS seconds (Check Interval)"
+               sleep $CHECK_SECONDS &
+               PID_SLEEP=$!
+               wait $PID_SLEEP # enable trap-handler
+               PID_SLEEP=0
+       } || write_log 7 "Verbose Mode: $VERBOSE_MODE - NO Check Interval waiting"
+
+       REGISTERED_IP=""                # clear variable
+       get_registered_ip REGISTERED_IP # get registered/public IP
 
        # IP's are still different
        if [ "$LOCAL_IP" != "$REGISTERED_IP" ]; then
                if [ $VERBOSE_MODE -le 1 ]; then        # VERBOSE_MODE <=1 then retry
                        ERR_UPDATE=$(( $ERR_UPDATE + 1 ))
-                       [ $ERR_UPDATE -gt $retry_count ] && critical_error "Registered IP <> Local IP - LocalIP: '$LOCAL_IP' - RegisteredIP: '$REGISTERED_IP'"
-                       verbose_echo "\n!!!!!!!!! ERROR =: Registered IP <> Local IP - starting retry $ERR_UPDATE/$retry_count\n"
-                       syslog_warn "Warning: Registered IP <> Local IP - starting retry $ERR_UPDATE/$retry_count"
+                       [ $retry_count -gt 0 -a $ERR_UPDATE -gt $retry_count ] && \
+                               write_log 14 "Updating IP at DDNS provider failed after $retry_count retries"
+                       write_log 4 "Updating IP at DDNS provider failed - starting retry $ERR_UPDATE/$retry_count"
                        continue # loop to beginning
                else
-                       verbose_echo "\n!!!!!!!!! ERROR =: Registered IP <> Local IP - LocalIP: '$LOCAL_IP' - RegisteredIP: '$REGISTERED_IP' - NO retry\n"
+                       write_log 4 "Updating IP at DDNS provider failed"
+                       write_log 7 "Verbose Mode: $VERBOSE_MODE - NO retry"; exit 1
                fi
-       fi              
+       else
+               # we checked successful the last update
+               ERR_UPDATE=0                    # reset error counter
+       fi
 
-       # we checked successful the last update
-       ERR_UPDATE=0                    # reset error counter
+       # force_update=0 or VERBOSE_MODE > 1 - leave here
+       [ $VERBOSE_MODE -gt 1 ]  && write_log 7 "Verbose Mode: $VERBOSE_MODE - NO reloop"
+       [ $FORCE_SECONDS -eq 0 ] && write_log 6 "Configured to run once"
+       [ $VERBOSE_MODE -gt 1 -o $FORCE_SECONDS -eq 0 ] && exit 0
 
-       # force_update=0 or VERBOSE_MODE > 1 - leave the main loop
-       [ $FORCE_SECONDS -eq 0 -o $VERBOSE_MODE -gt 1 ] && {
-               verbose_echo "****** LEAVING =: $(eval $DATE_PROG)"
-               syslog_info "Leaving"
-               break
-       }
-       verbose_echo "********* LOOP =: $(eval $DATE_PROG)"
-       syslog_info "Rerun IP check"
+       write_log 6 "Rerun IP check at $(eval $DATE_PROG)"
 done
-
-verbose_echo "****** STOPPED =: PID '$$' at $(eval $DATE_PROG)\n"
-syslog_info "Done"
-
-exit 0
+# we should never come here there must be a programming error
+write_log 12 "Error in 'dynamic_dns_updater.sh - program coding error"
diff --git a/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh b/net/ddns-scripts/files/usr/lib/ddns/getlocalip_sample.sh
new file mode 100755 (executable)
index 0000000..b98806b
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# sample script for detecting local IP
+# 2014-2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+#
+# activated inside /etc/config/ddns by setting
+#
+# option ip_source     'script'
+# option ip_script     '/usr/lib/ddns/getlocalip_sample.sh -6' !!! parameters ALLOWED
+#
+# the script is executed (not parsed) inside get_local_ip() function
+# of /usr/lib/ddns/dynamic_dns_functions.sh
+#
+# useful when this box is the only DDNS client in the network
+# IP adresses of "internal" boxes could be detected with this script
+# so no need to install ddns client on every "internal" box
+# On IPv6 every internal box normally has it's own external IP
+#
+# This script should
+#      - return the IP address via stdout      echo -n "...."  !!! without line feed
+#      - report errors via stderr              echo "...." >&2
+#      - return an error code ('0' for success)        exit 123
+
+case $1 in
+       -4)     echo -n "8.8.8.8"               # never append linefeed or simular
+               exit 0
+               ;;                              # IP's of Googles public DNS
+       -6)     echo -n "2001:4860:4860::8888"
+               exit 0
+               ;;
+       *)      echo "$0 - Invalid or missing parameter" >&2
+               exit 1
+esac
+echo "Should never come here" >&2
+exit 2
index 19bbb62f0220caf2a5b7ececa03e8becdd19bdd9..830bf2895555321355c360326acfac1d16841d2c 100644 (file)
@@ -1,45 +1,54 @@
+# 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
+#
 # This file contains the update urls for various dynamic dns services.
 # Column one contains the service name, column two contains the update url.
-# within the update url there are 4 variables you can use: [USERNAME], 
-# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username, 
-# password, and domain name specified in the /etc/config/ddns file when an 
+# within the update url there are 4 variables you can use: [USERNAME],
+# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username,
+# password, and domain name specified in the /etc/config/ddns file when an
 # update is performed.  The IP is substituted for the current ip address of the
-# router.  These variables are case sensitive, while urls generally are not, so 
-# if you need to enter the same text in the url (which seems very unlikely) put 
+# router.  These variables are case sensitive, while urls generally are not, so
+# if you need to enter the same text in the url (which seems very unlikely) put
 # that text in lowercase, while the variables should remain in uppercase
+#
+# There are TONS of dynamic dns services out there. There's a huge list of them at:
+# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/
+# If anyone has time they could update this file to be compatible with a bunch of them
+#
+# !!! Since ddns-scripts Version 2.x the update of IPv6 addresses is also supported
+# !!! This file is used for update of IPv4 adresses only. For IPv6 use services_ipv6
+#
+# !!! Since ddns-scripts Version 2.x the update via provider specific update scripts is supported.
+# !!! This scripts must be located at /usr/lib/ddns directory if defined inside this file.
+# !!! Use only the script name (without path). Sample:
+# !!! "example.com"    "update_sample.sh"
+#
+# 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
 
 "dyndns.org"           "http://[USERNAME]:[PASSWORD]@members.dyndns.org/nic/update?hostname=[DOMAIN]&myip=[IP]"
 "changeip.com"         "http://[USERNAME]:[PASSWORD]@nic.changeip.com/nic/update?u=[USERNAME]&p=[PASSWORD]&cmd=update&hostname=[DOMAIN]&ip=[IP]"
 "zoneedit.com"         "http://[USERNAME]:[PASSWORD]@dynamic.zoneedit.com/auth/dynamic.html?host=[DOMAIN]&dnsto=[IP]"
 "free.editdns.net"     "http://dyndns-free.editdns.net/api/dynLinux.php?p=[PASSWORD]&r=[DOMAIN]"
 
-#noip is an alias of no-ip, so allow both names for the same service
-"no-ip.com"            "http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
-"noip.com"             "http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
+# noip is an alias of no-ip, so allow both names for the same service
+# use provider specific update script
+"no-ip.com"    "update_no-ip.sh"
+"noip.com"     "update_no-ip.sh"
 
-#freedns.afraid.org is weird, you just need an update code, for which we use the password variable
+# freedns.afraid.org is weird, you just need an update code, for which we use the password variable
 "freedns.afraid.org"   "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
 
-#### ADD YOURS HERE! ######################################################################################
-#                                                                                                         #
-# There are TONS of dynamic dns services out there. There's a huge list of them at:                       #
-# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/        #
-# If anyone has time they could update this file to be compatible with a bunch of them                    #
-#                                                                                                         #
-###########################################################################################################
-
 # DNS Max and resellers' update urls
 "dnsmax.com"   "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=1&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]"
 "thatip.com"   "http://update.dnsmax.com/update/?username=[USERNAME]&password=[PASSWORD]&resellerid=2&clientname=openwrt&clientversion=8.09&protocolversion=2.0&updatehostname=[DOMAIN]&ip=[IP]"
 
 # Hurricane Electric Dynamic DNS
-"he.net"               "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]" 
+"he.net"       "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
 
 # DNSdynamic.org
 "dnsdynamic.org"       "http://[USERNAME]:[PASSWORD]@www.dnsdynamic.org/api/?hostname=[DOMAIN]&myip=[IP]"
 
 # dnsExit.com free dynamic DNS update url
-"dnsexit.com"          "http://www.dnsexit.com/RemoteUpdate.sv?login=[USERNAME]&password=[PASSWORD]&host=[DOMAIN]&myip=[IP]"
+"dnsexit.com"  "http://www.dnsexit.com/RemoteUpdate.sv?login=[USERNAME]&password=[PASSWORD]&host=[DOMAIN]&myip=[IP]"
 
 # OVH
 "ovh.com" "http://[USERNAME]:[PASSWORD]@www.ovh.com/nic/update?system=dyndns&hostname=[DOMAIN]&myip=[IP]"
@@ -56,7 +65,7 @@
 "namecheap.com" "http://dynamicdns.park-your-domain.com/update?host=[USERNAME]&domain=[DOMAIN]&password=[PASSWORD]&ip=[IP]"
 
 # easydns.com dynamic DNS
-"easydns.com"          "http://[USERNAME]:[PASSWORD]@api.cp.easydns.com/dyn/tomato.php?hostname=[DOMAIN]&myip=[IP]"
+"easydns.com"  "http://[USERNAME]:[PASSWORD]@api.cp.easydns.com/dyn/tomato.php?hostname=[DOMAIN]&myip=[IP]"
 
 # Winco DDNS
 "ddns.com.br"  "http://[DOMAIN]:[PASSWORD]@members.ddns.com.br/nic/update?hostname=[DOMAIN]&myip=[IP]"
 "duiadns.net"   "http://ipv4.duia.ro/dynamic.duia?host=[DOMAIN]&password=[PASSWORD]&ip4=[IP]"
 
 # Two-DNS - Simply. Connected. Everywhere.
-"Two-DNS" "http://[USERNAME]:[PASSWORD]@update.twodns.de/update?hostname=[DOMAIN]&ip=[IP]"
+"twodns.de" "http://[USERNAME]:[PASSWORD]@update.twodns.de/update?hostname=[DOMAIN]&ip=[IP]"
+
+# MyDNS.JP
+"mydns.jp"     "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV4ADDR=[IP]"
+
+# LoopiaDNS
+"loopia.se" "http://[USERNAME]:[PASSWORD]@dns.loopia.se/XDynDNSServer/XDynDNS.php?system=custom&hostname=[DOMAIN]&myip=[IP]"
+
+# Cloudflare
+"cloudflare.com"       "update_cloudflare.sh"
+
+# SelfHost.de
+"selfhost.de"  "http://carol.selfhost.de/update?username=[USERNAME]&password=[PASSWORD]&myip=[IP]&hostname=1"
+
+# no-ip.pl nothing to do with no-ip.com (domain registered to www.domeny.tv) (IP autodetected by provider)
+"no-ip.pl"     "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
index bc64cd0cb708f12ea44f99a2d900d8f7bd42037d..798e11e42e12a860b6ed1df54452197150b29d8d 100644 (file)
@@ -1,29 +1,43 @@
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-# !!!!! IPv6 Version of original services file                 !!!!!
-# !!!!! funtionally and syntax is the same                     !!!!!
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
+#
 # This file contains the update urls for various dynamic dns services.
 # Column one contains the service name, column two contains the update url.
-# within the update url there are 4 variables you can use: [USERNAME], 
-# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username, 
-# password, and domain name specified in the /etc/config/ddns file when an 
+# within the update url there are 4 variables you can use: [USERNAME],
+# [PASSWORD], [DOMAIN] and [IP].  These are substituted for the username,
+# password, and domain name specified in the /etc/config/ddns file when an
 # update is performed.  The IP is substituted for the current ip address of the
-# router.  These variables are case sensitive, while urls generally are not, so 
-# if you need to enter the same text in the url (which seems very unlikely) put 
+# router.  These variables are case sensitive, while urls generally are not, so
+# if you need to enter the same text in the url (which seems very unlikely) put
 # that text in lowercase, while the variables should remain in uppercase
+#
+# There are TONS of dynamic dns services out there. There's a huge list of them at:
+# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/
+# If anyone has time they could update this file to be compatible with a bunch of them
+#
+# !!! Since ddns-scripts Version 2.x the update of IPv6 addresses is also supported
+# !!! This file is used for update of IPv6 adresses only. For IPv4 use services
+#
+# !!! Since ddns-scripts Version 2.x the update via provider specific update scripts is supported.
+# !!! This scripts must be located at /usr/lib/ddns directory if defined inside this file.
+# !!! Use only the script name (without path). Sample:
+# !!! "example.com"    "update_sample.sh"
+#
+# 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
 
-# tested with
-
-# Securepoint Dynamic-DNS-Service
+# IPv6 @ Securepoint Dynamic-DNS-Service
 "spdns.de"     "http://[USERNAME]:[PASSWORD]@update.spdns.de/nic/update?hostname=[DOMAIN]&myip=[IP]"
 
-# Hurricane Electric Dynamic DNS
-"he.net"       "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]" 
+# IPv6 @ Hurricane Electric Dynamic DNS
+"he.net"       "http://[DOMAIN]:[PASSWORD]@dyn.dns.he.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
+
+# IPv6 @ MyDNS.JP
+"mydns.jp"     "http://www.mydns.jp/directip.html?MID=[USERNAME]&PWD=[PASSWORD]&IPV6ADDR=[IP]"
+
+# IPv6 @ Cloudflare
+"cloudflare.com"       "update_cloudflare.sh"
+
+# IPv6 @ no-ip.pl nothing to do with no-ip.com (domain registered to www.domeny.tv) (IP autodetected by provider)
+"no-ip.pl"     "http://[USERNAME]:[PASSWORD]@update.no-ip.pl/?hostname=[DOMAIN]"
 
-#### ADD YOURS HERE! ######################################################################################
-#                                                                                                         #
-# There are TONS of dynamic dns services out there. There's a huge list of them at:                       #
-# http://www.dmoz.org/Computers/Software/Internet/Servers/Address_Management/Dynamic_DNS_Services/        #
-# If anyone has time they could update this file to be compatible with a bunch of them                    #
-#                                                                                                         #
-###########################################################################################################
+# IPv6 @ freedns.afraid.org
+"freedns.afraid.org"   "http://freedns.afraid.org/dynamic/update.php?[PASSWORD]&address=[IP]"
diff --git a/net/ddns-scripts/files/usr/lib/ddns/tld_names.dat b/net/ddns-scripts/files/usr/lib/ddns/tld_names.dat
new file mode 100644 (file)
index 0000000..92e65e6
--- /dev/null
@@ -0,0 +1,9884 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// ===BEGIN ICANN DOMAINS===
+
+// ac : http://en.wikipedia.org/wiki/.ac
+ac
+com.ac
+edu.ac
+gov.ac
+net.ac
+mil.ac
+org.ac
+
+// ad : http://en.wikipedia.org/wiki/.ad
+ad
+nom.ad
+
+// ae : http://en.wikipedia.org/wiki/.ae
+// see also: "Domain Name Eligibility Policy" at http://www.aeda.ae/eng/aepolicy.php
+ae
+co.ae
+net.ae
+org.ae
+sch.ae
+ac.ae
+gov.ae
+mil.ae
+
+// aero : see http://www.information.aero/index.php?id=66
+aero
+accident-investigation.aero
+accident-prevention.aero
+aerobatic.aero
+aeroclub.aero
+aerodrome.aero
+agents.aero
+aircraft.aero
+airline.aero
+airport.aero
+air-surveillance.aero
+airtraffic.aero
+air-traffic-control.aero
+ambulance.aero
+amusement.aero
+association.aero
+author.aero
+ballooning.aero
+broker.aero
+caa.aero
+cargo.aero
+catering.aero
+certification.aero
+championship.aero
+charter.aero
+civilaviation.aero
+club.aero
+conference.aero
+consultant.aero
+consulting.aero
+control.aero
+council.aero
+crew.aero
+design.aero
+dgca.aero
+educator.aero
+emergency.aero
+engine.aero
+engineer.aero
+entertainment.aero
+equipment.aero
+exchange.aero
+express.aero
+federation.aero
+flight.aero
+freight.aero
+fuel.aero
+gliding.aero
+government.aero
+groundhandling.aero
+group.aero
+hanggliding.aero
+homebuilt.aero
+insurance.aero
+journal.aero
+journalist.aero
+leasing.aero
+logistics.aero
+magazine.aero
+maintenance.aero
+marketplace.aero
+media.aero
+microlight.aero
+modelling.aero
+navigation.aero
+parachuting.aero
+paragliding.aero
+passenger-association.aero
+pilot.aero
+press.aero
+production.aero
+recreation.aero
+repbody.aero
+res.aero
+research.aero
+rotorcraft.aero
+safety.aero
+scientist.aero
+services.aero
+show.aero
+skydiving.aero
+software.aero
+student.aero
+taxi.aero
+trader.aero
+trading.aero
+trainer.aero
+union.aero
+workinggroup.aero
+works.aero
+
+// af : http://www.nic.af/help.jsp
+af
+gov.af
+com.af
+org.af
+net.af
+edu.af
+
+// ag : http://www.nic.ag/prices.htm
+ag
+com.ag
+org.ag
+net.ag
+co.ag
+nom.ag
+
+// ai : http://nic.com.ai/
+ai
+off.ai
+com.ai
+net.ai
+org.ai
+
+// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31
+al
+com.al
+edu.al
+gov.al
+mil.al
+net.al
+org.al
+
+// am : http://en.wikipedia.org/wiki/.am
+am
+
+// an : http://www.una.an/an_domreg/default.asp
+an
+com.an
+net.an
+org.an
+edu.an
+
+// ao : http://en.wikipedia.org/wiki/.ao
+// http://www.dns.ao/REGISTR.DOC
+ao
+ed.ao
+gv.ao
+og.ao
+co.ao
+pb.ao
+it.ao
+
+// aq : http://en.wikipedia.org/wiki/.aq
+aq
+
+// ar : https://nic.ar/normativa-vigente.xhtml
+ar
+com.ar
+edu.ar
+gob.ar
+gov.ar
+int.ar
+mil.ar
+net.ar
+org.ar
+tur.ar
+
+// arpa : http://en.wikipedia.org/wiki/.arpa
+// Confirmed by registry <iana-questions@icann.org> 2008-06-18
+arpa
+e164.arpa
+in-addr.arpa
+ip6.arpa
+iris.arpa
+uri.arpa
+urn.arpa
+
+// as : http://en.wikipedia.org/wiki/.as
+as
+gov.as
+
+// asia : http://en.wikipedia.org/wiki/.asia
+asia
+
+// at : http://en.wikipedia.org/wiki/.at
+// Confirmed by registry <it@nic.at> 2008-06-17
+at
+ac.at
+co.at
+gv.at
+or.at
+
+// au : http://en.wikipedia.org/wiki/.au
+// http://www.auda.org.au/
+au
+// 2LDs
+com.au
+net.au
+org.au
+edu.au
+gov.au
+asn.au
+id.au
+// Historic 2LDs (closed to new registration, but sites still exist)
+info.au
+conf.au
+oz.au
+// CGDNs - http://www.cgdn.org.au/
+act.au
+nsw.au
+nt.au
+qld.au
+sa.au
+tas.au
+vic.au
+wa.au
+// 3LDs
+act.edu.au
+nsw.edu.au
+nt.edu.au
+qld.edu.au
+sa.edu.au
+tas.edu.au
+vic.edu.au
+wa.edu.au
+// act.gov.au Bug 984824 - Removed at request of Greg Tankard
+// nsw.gov.au Bug 547985 - Removed at request of <Shae.Donelan@services.nsw.gov.au>
+// nt.gov.au Bug 940478 - Removed at request of Greg Connors <Greg.Connors@nt.gov.au>
+qld.gov.au
+sa.gov.au
+tas.gov.au
+vic.gov.au
+wa.gov.au
+
+// aw : http://en.wikipedia.org/wiki/.aw
+aw
+com.aw
+
+// ax : http://en.wikipedia.org/wiki/.ax
+ax
+
+// az : http://en.wikipedia.org/wiki/.az
+az
+com.az
+net.az
+int.az
+gov.az
+org.az
+edu.az
+info.az
+pp.az
+mil.az
+name.az
+pro.az
+biz.az
+
+// ba : http://en.wikipedia.org/wiki/.ba
+ba
+org.ba
+net.ba
+edu.ba
+gov.ba
+mil.ba
+unsa.ba
+unbi.ba
+co.ba
+com.ba
+rs.ba
+
+// bb : http://en.wikipedia.org/wiki/.bb
+bb
+biz.bb
+co.bb
+com.bb
+edu.bb
+gov.bb
+info.bb
+net.bb
+org.bb
+store.bb
+tv.bb
+
+// bd : http://en.wikipedia.org/wiki/.bd
+*.bd
+
+// be : http://en.wikipedia.org/wiki/.be
+// Confirmed by registry <tech@dns.be> 2008-06-08
+be
+ac.be
+
+// bf : http://en.wikipedia.org/wiki/.bf
+bf
+gov.bf
+
+// bg : http://en.wikipedia.org/wiki/.bg
+// https://www.register.bg/user/static/rules/en/index.html
+bg
+a.bg
+b.bg
+c.bg
+d.bg
+e.bg
+f.bg
+g.bg
+h.bg
+i.bg
+j.bg
+k.bg
+l.bg
+m.bg
+n.bg
+o.bg
+p.bg
+q.bg
+r.bg
+s.bg
+t.bg
+u.bg
+v.bg
+w.bg
+x.bg
+y.bg
+z.bg
+0.bg
+1.bg
+2.bg
+3.bg
+4.bg
+5.bg
+6.bg
+7.bg
+8.bg
+9.bg
+
+// bh : http://en.wikipedia.org/wiki/.bh
+bh
+com.bh
+edu.bh
+net.bh
+org.bh
+gov.bh
+
+// bi : http://en.wikipedia.org/wiki/.bi
+// http://whois.nic.bi/
+bi
+co.bi
+com.bi
+edu.bi
+or.bi
+org.bi
+
+// biz : http://en.wikipedia.org/wiki/.biz
+biz
+
+// bj : http://en.wikipedia.org/wiki/.bj
+bj
+asso.bj
+barreau.bj
+gouv.bj
+
+// bm : http://www.bermudanic.bm/dnr-text.txt
+bm
+com.bm
+edu.bm
+gov.bm
+net.bm
+org.bm
+
+// bn : http://en.wikipedia.org/wiki/.bn
+*.bn
+
+// bo : http://www.nic.bo/
+bo
+com.bo
+edu.bo
+gov.bo
+gob.bo
+int.bo
+org.bo
+net.bo
+mil.bo
+tv.bo
+
+// br : http://registro.br/dominio/categoria.html
+// Submitted by registry <fneves@registro.br> 2014-08-11
+br
+adm.br
+adv.br
+agr.br
+am.br
+arq.br
+art.br
+ato.br
+b.br
+bio.br
+blog.br
+bmd.br
+cim.br
+cng.br
+cnt.br
+com.br
+coop.br
+ecn.br
+eco.br
+edu.br
+emp.br
+eng.br
+esp.br
+etc.br
+eti.br
+far.br
+flog.br
+fm.br
+fnd.br
+fot.br
+fst.br
+g12.br
+ggf.br
+gov.br
+imb.br
+ind.br
+inf.br
+jor.br
+jus.br
+leg.br
+lel.br
+mat.br
+med.br
+mil.br
+mp.br
+mus.br
+net.br
+*.nom.br
+not.br
+ntr.br
+odo.br
+org.br
+ppg.br
+pro.br
+psc.br
+psi.br
+qsl.br
+radio.br
+rec.br
+slg.br
+srv.br
+taxi.br
+teo.br
+tmp.br
+trd.br
+tur.br
+tv.br
+vet.br
+vlog.br
+wiki.br
+zlg.br
+
+// bs : http://www.nic.bs/rules.html
+bs
+com.bs
+net.bs
+org.bs
+edu.bs
+gov.bs
+
+// bt : http://en.wikipedia.org/wiki/.bt
+bt
+com.bt
+edu.bt
+gov.bt
+net.bt
+org.bt
+
+// bv : No registrations at this time.
+// Submitted by registry <jarle@uninett.no> 2006-06-16
+bv
+
+// bw : http://en.wikipedia.org/wiki/.bw
+// http://www.gobin.info/domainname/bw.doc
+// list of other 2nd level tlds ?
+bw
+co.bw
+org.bw
+
+// by : http://en.wikipedia.org/wiki/.by
+// http://tld.by/rules_2006_en.html
+// list of other 2nd level tlds ?
+by
+gov.by
+mil.by
+// Official information does not indicate that com.by is a reserved
+// second-level domain, but it's being used as one (see www.google.com.by and
+// www.yahoo.com.by, for example), so we list it here for safety's sake.
+com.by
+
+// http://hoster.by/
+of.by
+
+// bz : http://en.wikipedia.org/wiki/.bz
+// http://www.belizenic.bz/
+bz
+com.bz
+net.bz
+org.bz
+edu.bz
+gov.bz
+
+// ca : http://en.wikipedia.org/wiki/.ca
+ca
+// ca geographical names
+ab.ca
+bc.ca
+mb.ca
+nb.ca
+nf.ca
+nl.ca
+ns.ca
+nt.ca
+nu.ca
+on.ca
+pe.ca
+qc.ca
+sk.ca
+yk.ca
+// gc.ca: http://en.wikipedia.org/wiki/.gc.ca
+// see also: http://registry.gc.ca/en/SubdomainFAQ
+gc.ca
+
+// cat : http://en.wikipedia.org/wiki/.cat
+cat
+
+// cc : http://en.wikipedia.org/wiki/.cc
+cc
+
+// cd : http://en.wikipedia.org/wiki/.cd
+// see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1
+cd
+gov.cd
+
+// cf : http://en.wikipedia.org/wiki/.cf
+cf
+
+// cg : http://en.wikipedia.org/wiki/.cg
+cg
+
+// ch : http://en.wikipedia.org/wiki/.ch
+ch
+
+// ci : http://en.wikipedia.org/wiki/.ci
+// http://www.nic.ci/index.php?page=charte
+ci
+org.ci
+or.ci
+com.ci
+co.ci
+edu.ci
+ed.ci
+ac.ci
+net.ci
+go.ci
+asso.ci
+aéroport.ci
+xn--aroport-bya.ci
+int.ci
+presse.ci
+md.ci
+gouv.ci
+
+// ck : http://en.wikipedia.org/wiki/.ck
+*.ck
+!www.ck
+
+// cl : http://en.wikipedia.org/wiki/.cl
+cl
+gov.cl
+gob.cl
+co.cl
+mil.cl
+
+// cm : http://en.wikipedia.org/wiki/.cm plus bug 981927
+cm
+co.cm
+com.cm
+gov.cm
+net.cm
+
+// cn : http://en.wikipedia.org/wiki/.cn
+// Submitted by registry <tanyaling@cnnic.cn> 2008-06-11
+cn
+ac.cn
+com.cn
+edu.cn
+gov.cn
+net.cn
+org.cn
+mil.cn
+公司.cn
+xn--55qx5d.cn
+网络.cn
+xn--io0a7i.cn
+網絡.cn
+xn--od0alg.cn
+// cn geographic names
+ah.cn
+bj.cn
+cq.cn
+fj.cn
+gd.cn
+gs.cn
+gz.cn
+gx.cn
+ha.cn
+hb.cn
+he.cn
+hi.cn
+hl.cn
+hn.cn
+jl.cn
+js.cn
+jx.cn
+ln.cn
+nm.cn
+nx.cn
+qh.cn
+sc.cn
+sd.cn
+sh.cn
+sn.cn
+sx.cn
+tj.cn
+xj.cn
+xz.cn
+yn.cn
+zj.cn
+hk.cn
+mo.cn
+tw.cn
+
+// co : http://en.wikipedia.org/wiki/.co
+// Submitted by registry <tecnico@uniandes.edu.co> 2008-06-11
+co
+arts.co
+com.co
+edu.co
+firm.co
+gov.co
+info.co
+int.co
+mil.co
+net.co
+nom.co
+org.co
+rec.co
+web.co
+
+// com : http://en.wikipedia.org/wiki/.com
+com
+
+// coop : http://en.wikipedia.org/wiki/.coop
+coop
+
+// cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do
+cr
+ac.cr
+co.cr
+ed.cr
+fi.cr
+go.cr
+or.cr
+sa.cr
+
+// cu : http://en.wikipedia.org/wiki/.cu
+cu
+com.cu
+edu.cu
+org.cu
+net.cu
+gov.cu
+inf.cu
+
+// cv : http://en.wikipedia.org/wiki/.cv
+cv
+
+// cw : http://www.una.cw/cw_registry/
+// Confirmed by registry <registry@una.net> 2013-03-26
+cw
+com.cw
+edu.cw
+net.cw
+org.cw
+
+// cx : http://en.wikipedia.org/wiki/.cx
+// list of other 2nd level tlds ?
+cx
+gov.cx
+
+// cy : http://en.wikipedia.org/wiki/.cy
+*.cy
+
+// cz : http://en.wikipedia.org/wiki/.cz
+cz
+
+// de : http://en.wikipedia.org/wiki/.de
+// Confirmed by registry <ops@denic.de> (with technical
+// reservations) 2008-07-01
+de
+
+// dj : http://en.wikipedia.org/wiki/.dj
+dj
+
+// dk : http://en.wikipedia.org/wiki/.dk
+// Confirmed by registry <robert@dk-hostmaster.dk> 2008-06-17
+dk
+
+// dm : http://en.wikipedia.org/wiki/.dm
+dm
+com.dm
+net.dm
+org.dm
+edu.dm
+gov.dm
+
+// do : http://en.wikipedia.org/wiki/.do
+do
+art.do
+com.do
+edu.do
+gob.do
+gov.do
+mil.do
+net.do
+org.do
+sld.do
+web.do
+
+// dz : http://en.wikipedia.org/wiki/.dz
+dz
+com.dz
+org.dz
+net.dz
+gov.dz
+edu.dz
+asso.dz
+pol.dz
+art.dz
+
+// ec : http://www.nic.ec/reg/paso1.asp
+// Submitted by registry <vabboud@nic.ec> 2008-07-04
+ec
+com.ec
+info.ec
+net.ec
+fin.ec
+k12.ec
+med.ec
+pro.ec
+org.ec
+edu.ec
+gov.ec
+gob.ec
+mil.ec
+
+// edu : http://en.wikipedia.org/wiki/.edu
+edu
+
+// ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B
+ee
+edu.ee
+gov.ee
+riik.ee
+lib.ee
+med.ee
+com.ee
+pri.ee
+aip.ee
+org.ee
+fie.ee
+
+// eg : http://en.wikipedia.org/wiki/.eg
+eg
+com.eg
+edu.eg
+eun.eg
+gov.eg
+mil.eg
+name.eg
+net.eg
+org.eg
+sci.eg
+
+// er : http://en.wikipedia.org/wiki/.er
+*.er
+
+// es : https://www.nic.es/site_ingles/ingles/dominios/index.html
+es
+com.es
+nom.es
+org.es
+gob.es
+edu.es
+
+// et : http://en.wikipedia.org/wiki/.et
+et
+com.et
+gov.et
+org.et
+edu.et
+biz.et
+name.et
+info.et
+
+// eu : http://en.wikipedia.org/wiki/.eu
+eu
+
+// fi : http://en.wikipedia.org/wiki/.fi
+fi
+// aland.fi : http://en.wikipedia.org/wiki/.ax
+// This domain is being phased out in favor of .ax. As there are still many
+// domains under aland.fi, we still keep it on the list until aland.fi is
+// completely removed.
+// TODO: Check for updates (expected to be phased out around Q1/2009)
+aland.fi
+
+// fj : http://en.wikipedia.org/wiki/.fj
+*.fj
+
+// fk : http://en.wikipedia.org/wiki/.fk
+*.fk
+
+// fm : http://en.wikipedia.org/wiki/.fm
+fm
+
+// fo : http://en.wikipedia.org/wiki/.fo
+fo
+
+// fr : http://www.afnic.fr/
+// domaines descriptifs : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-descriptifs
+fr
+com.fr
+asso.fr
+nom.fr
+prd.fr
+presse.fr
+tm.fr
+// domaines sectoriels : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-sectoriels
+aeroport.fr
+assedic.fr
+avocat.fr
+avoues.fr
+cci.fr
+chambagri.fr
+chirurgiens-dentistes.fr
+experts-comptables.fr
+geometre-expert.fr
+gouv.fr
+greta.fr
+huissier-justice.fr
+medecin.fr
+notaires.fr
+pharmacien.fr
+port.fr
+veterinaire.fr
+
+// ga : http://en.wikipedia.org/wiki/.ga
+ga
+
+// gb : This registry is effectively dormant
+// Submitted by registry <Damien.Shaw@ja.net> 2008-06-12
+gb
+
+// gd : http://en.wikipedia.org/wiki/.gd
+gd
+
+// ge : http://www.nic.net.ge/policy_en.pdf
+ge
+com.ge
+edu.ge
+gov.ge
+org.ge
+mil.ge
+net.ge
+pvt.ge
+
+// gf : http://en.wikipedia.org/wiki/.gf
+gf
+
+// gg : http://www.channelisles.net/register-domains/
+// Confirmed by registry <nigel@channelisles.net> 2013-11-28
+gg
+co.gg
+net.gg
+org.gg
+
+// gh : http://en.wikipedia.org/wiki/.gh
+// see also: http://www.nic.gh/reg_now.php
+// Although domains directly at second level are not possible at the moment,
+// they have been possible for some time and may come back.
+gh
+com.gh
+edu.gh
+gov.gh
+org.gh
+mil.gh
+
+// gi : http://www.nic.gi/rules.html
+gi
+com.gi
+ltd.gi
+gov.gi
+mod.gi
+edu.gi
+org.gi
+
+// gl : http://en.wikipedia.org/wiki/.gl
+// http://nic.gl
+gl
+
+// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm
+gm
+
+// gn : http://psg.com/dns/gn/gn.txt
+// Submitted by registry <randy@psg.com> 2008-06-17
+gn
+ac.gn
+com.gn
+edu.gn
+gov.gn
+org.gn
+net.gn
+
+// gov : http://en.wikipedia.org/wiki/.gov
+gov
+
+// gp : http://www.nic.gp/index.php?lang=en
+gp
+com.gp
+net.gp
+mobi.gp
+edu.gp
+org.gp
+asso.gp
+
+// gq : http://en.wikipedia.org/wiki/.gq
+gq
+
+// gr : https://grweb.ics.forth.gr/english/1617-B-2005.html
+// Submitted by registry <segred@ics.forth.gr> 2008-06-09
+gr
+com.gr
+edu.gr
+net.gr
+org.gr
+gov.gr
+
+// gs : http://en.wikipedia.org/wiki/.gs
+gs
+
+// gt : http://www.gt/politicas_de_registro.html
+gt
+com.gt
+edu.gt
+gob.gt
+ind.gt
+mil.gt
+net.gt
+org.gt
+
+// gu : http://gadao.gov.gu/registration.txt
+*.gu
+
+// gw : http://en.wikipedia.org/wiki/.gw
+gw
+
+// gy : http://en.wikipedia.org/wiki/.gy
+// http://registry.gy/
+gy
+co.gy
+com.gy
+net.gy
+
+// hk : https://www.hkdnr.hk
+// Submitted by registry <hk.tech@hkirc.hk> 2008-06-11
+hk
+com.hk
+edu.hk
+gov.hk
+idv.hk
+net.hk
+org.hk
+公司.hk
+xn--55qx5d.hk
+教育.hk
+xn--wcvs22d.hk
+敎育.hk
+xn--lcvr32d.hk
+政府.hk
+xn--mxtq1m.hk
+個人.hk
+xn--gmqw5a.hk
+个人.hk
+xn--ciqpn.hk
+箇人.hk
+xn--gmq050i.hk
+網络.hk
+xn--zf0avx.hk
+网络.hk
+xn--io0a7i.hk
+组織.hk
+xn--mk0axi.hk
+網絡.hk
+xn--od0alg.hk
+网絡.hk
+xn--od0aq3b.hk
+组织.hk
+xn--tn0ag.hk
+組織.hk
+xn--uc0atv.hk
+組织.hk
+xn--uc0ay4a.hk
+
+// hm : http://en.wikipedia.org/wiki/.hm
+hm
+
+// hn : http://www.nic.hn/politicas/ps02,,05.html
+hn
+com.hn
+edu.hn
+org.hn
+net.hn
+mil.hn
+gob.hn
+
+// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf
+hr
+iz.hr
+from.hr
+name.hr
+com.hr
+
+// ht : http://www.nic.ht/info/charte.cfm
+ht
+com.ht
+shop.ht
+firm.ht
+info.ht
+adult.ht
+net.ht
+pro.ht
+org.ht
+med.ht
+art.ht
+coop.ht
+pol.ht
+asso.ht
+edu.ht
+rel.ht
+gouv.ht
+perso.ht
+
+// hu : http://www.domain.hu/domain/English/sld.html
+// Confirmed by registry <pasztor@iszt.hu> 2008-06-12
+hu
+co.hu
+info.hu
+org.hu
+priv.hu
+sport.hu
+tm.hu
+2000.hu
+agrar.hu
+bolt.hu
+casino.hu
+city.hu
+erotica.hu
+erotika.hu
+film.hu
+forum.hu
+games.hu
+hotel.hu
+ingatlan.hu
+jogasz.hu
+konyvelo.hu
+lakas.hu
+media.hu
+news.hu
+reklam.hu
+sex.hu
+shop.hu
+suli.hu
+szex.hu
+tozsde.hu
+utazas.hu
+video.hu
+
+// id : https://register.pandi.or.id/
+id
+ac.id
+biz.id
+co.id
+desa.id
+go.id
+mil.id
+my.id
+net.id
+or.id
+sch.id
+web.id
+
+// ie : http://en.wikipedia.org/wiki/.ie
+ie
+gov.ie
+
+// il : http://en.wikipedia.org/wiki/.il
+*.il
+
+// im : https://www.nic.im/
+// Submitted by registry <info@nic.im> 2013-11-15
+im
+ac.im
+co.im
+com.im
+ltd.co.im
+net.im
+org.im
+plc.co.im
+tt.im
+tv.im
+
+// in : http://en.wikipedia.org/wiki/.in
+// see also: http://www.inregistry.in/policies/
+// Please note, that nic.in is not an offical eTLD, but used by most
+// government institutions.
+in
+co.in
+firm.in
+net.in
+org.in
+gen.in
+ind.in
+nic.in
+ac.in
+edu.in
+res.in
+gov.in
+mil.in
+
+// info : http://en.wikipedia.org/wiki/.info
+info
+
+// int : http://en.wikipedia.org/wiki/.int
+// Confirmed by registry <iana-questions@icann.org> 2008-06-18
+int
+eu.int
+
+// io : http://www.nic.io/rules.html
+// list of other 2nd level tlds ?
+io
+com.io
+
+// iq : http://www.cmc.iq/english/iq/iqregister1.htm
+iq
+gov.iq
+edu.iq
+mil.iq
+com.iq
+org.iq
+net.iq
+
+// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules
+// Also see http://www.nic.ir/Internationalized_Domain_Names
+// Two <iran>.ir entries added at request of <tech-team@nic.ir>, 2010-04-16
+ir
+ac.ir
+co.ir
+gov.ir
+id.ir
+net.ir
+org.ir
+sch.ir
+// xn--mgba3a4f16a.ir (<iran>.ir, Persian YEH)
+ایران.ir
+xn--mgba3a4f16a.ir
+// xn--mgba3a4fra.ir (<iran>.ir, Arabic YEH)
+ايران.ir
+xn--mgba3a4fra.ir
+
+// is : http://www.isnic.is/domain/rules.php
+// Confirmed by registry <marius@isgate.is> 2008-12-06
+is
+net.is
+com.is
+edu.is
+gov.is
+org.is
+int.is
+
+// it : http://en.wikipedia.org/wiki/.it
+it
+gov.it
+edu.it
+// Reserved geo-names:
+// http://www.nic.it/documenti/regolamenti-e-linee-guida/regolamento-assegnazione-versione-6.0.pdf
+// There is also a list of reserved geo-names corresponding to Italian municipalities
+// http://www.nic.it/documenti/appendice-c.pdf, but it is not included here.
+// Regions
+abr.it
+abruzzo.it
+aosta-valley.it
+aostavalley.it
+bas.it
+basilicata.it
+cal.it
+calabria.it
+cam.it
+campania.it
+emilia-romagna.it
+emiliaromagna.it
+emr.it
+friuli-v-giulia.it
+friuli-ve-giulia.it
+friuli-vegiulia.it
+friuli-venezia-giulia.it
+friuli-veneziagiulia.it
+friuli-vgiulia.it
+friuliv-giulia.it
+friulive-giulia.it
+friulivegiulia.it
+friulivenezia-giulia.it
+friuliveneziagiulia.it
+friulivgiulia.it
+fvg.it
+laz.it
+lazio.it
+lig.it
+liguria.it
+lom.it
+lombardia.it
+lombardy.it
+lucania.it
+mar.it
+marche.it
+mol.it
+molise.it
+piedmont.it
+piemonte.it
+pmn.it
+pug.it
+puglia.it
+sar.it
+sardegna.it
+sardinia.it
+sic.it
+sicilia.it
+sicily.it
+taa.it
+tos.it
+toscana.it
+trentino-a-adige.it
+trentino-aadige.it
+trentino-alto-adige.it
+trentino-altoadige.it
+trentino-s-tirol.it
+trentino-stirol.it
+trentino-sud-tirol.it
+trentino-sudtirol.it
+trentino-sued-tirol.it
+trentino-suedtirol.it
+trentinoa-adige.it
+trentinoaadige.it
+trentinoalto-adige.it
+trentinoaltoadige.it
+trentinos-tirol.it
+trentinostirol.it
+trentinosud-tirol.it
+trentinosudtirol.it
+trentinosued-tirol.it
+trentinosuedtirol.it
+tuscany.it
+umb.it
+umbria.it
+val-d-aosta.it
+val-daosta.it
+vald-aosta.it
+valdaosta.it
+valle-aosta.it
+valle-d-aosta.it
+valle-daosta.it
+valleaosta.it
+valled-aosta.it
+valledaosta.it
+vallee-aoste.it
+valleeaoste.it
+vao.it
+vda.it
+ven.it
+veneto.it
+// Provinces
+ag.it
+agrigento.it
+al.it
+alessandria.it
+alto-adige.it
+altoadige.it
+an.it
+ancona.it
+andria-barletta-trani.it
+andria-trani-barletta.it
+andriabarlettatrani.it
+andriatranibarletta.it
+ao.it
+aosta.it
+aoste.it
+ap.it
+aq.it
+aquila.it
+ar.it
+arezzo.it
+ascoli-piceno.it
+ascolipiceno.it
+asti.it
+at.it
+av.it
+avellino.it
+ba.it
+balsan.it
+bari.it
+barletta-trani-andria.it
+barlettatraniandria.it
+belluno.it
+benevento.it
+bergamo.it
+bg.it
+bi.it
+biella.it
+bl.it
+bn.it
+bo.it
+bologna.it
+bolzano.it
+bozen.it
+br.it
+brescia.it
+brindisi.it
+bs.it
+bt.it
+bz.it
+ca.it
+cagliari.it
+caltanissetta.it
+campidano-medio.it
+campidanomedio.it
+campobasso.it
+carbonia-iglesias.it
+carboniaiglesias.it
+carrara-massa.it
+carraramassa.it
+caserta.it
+catania.it
+catanzaro.it
+cb.it
+ce.it
+cesena-forli.it
+cesenaforli.it
+ch.it
+chieti.it
+ci.it
+cl.it
+cn.it
+co.it
+como.it
+cosenza.it
+cr.it
+cremona.it
+crotone.it
+cs.it
+ct.it
+cuneo.it
+cz.it
+dell-ogliastra.it
+dellogliastra.it
+en.it
+enna.it
+fc.it
+fe.it
+fermo.it
+ferrara.it
+fg.it
+fi.it
+firenze.it
+florence.it
+fm.it
+foggia.it
+forli-cesena.it
+forlicesena.it
+fr.it
+frosinone.it
+ge.it
+genoa.it
+genova.it
+go.it
+gorizia.it
+gr.it
+grosseto.it
+iglesias-carbonia.it
+iglesiascarbonia.it
+im.it
+imperia.it
+is.it
+isernia.it
+kr.it
+la-spezia.it
+laquila.it
+laspezia.it
+latina.it
+lc.it
+le.it
+lecce.it
+lecco.it
+li.it
+livorno.it
+lo.it
+lodi.it
+lt.it
+lu.it
+lucca.it
+macerata.it
+mantova.it
+massa-carrara.it
+massacarrara.it
+matera.it
+mb.it
+mc.it
+me.it
+medio-campidano.it
+mediocampidano.it
+messina.it
+mi.it
+milan.it
+milano.it
+mn.it
+mo.it
+modena.it
+monza-brianza.it
+monza-e-della-brianza.it
+monza.it
+monzabrianza.it
+monzaebrianza.it
+monzaedellabrianza.it
+ms.it
+mt.it
+na.it
+naples.it
+napoli.it
+no.it
+novara.it
+nu.it
+nuoro.it
+og.it
+ogliastra.it
+olbia-tempio.it
+olbiatempio.it
+or.it
+oristano.it
+ot.it
+pa.it
+padova.it
+padua.it
+palermo.it
+parma.it
+pavia.it
+pc.it
+pd.it
+pe.it
+perugia.it
+pesaro-urbino.it
+pesarourbino.it
+pescara.it
+pg.it
+pi.it
+piacenza.it
+pisa.it
+pistoia.it
+pn.it
+po.it
+pordenone.it
+potenza.it
+pr.it
+prato.it
+pt.it
+pu.it
+pv.it
+pz.it
+ra.it
+ragusa.it
+ravenna.it
+rc.it
+re.it
+reggio-calabria.it
+reggio-emilia.it
+reggiocalabria.it
+reggioemilia.it
+rg.it
+ri.it
+rieti.it
+rimini.it
+rm.it
+rn.it
+ro.it
+roma.it
+rome.it
+rovigo.it
+sa.it
+salerno.it
+sassari.it
+savona.it
+si.it
+siena.it
+siracusa.it
+so.it
+sondrio.it
+sp.it
+sr.it
+ss.it
+suedtirol.it
+sv.it
+ta.it
+taranto.it
+te.it
+tempio-olbia.it
+tempioolbia.it
+teramo.it
+terni.it
+tn.it
+to.it
+torino.it
+tp.it
+tr.it
+trani-andria-barletta.it
+trani-barletta-andria.it
+traniandriabarletta.it
+tranibarlettaandria.it
+trapani.it
+trentino.it
+trento.it
+treviso.it
+trieste.it
+ts.it
+turin.it
+tv.it
+ud.it
+udine.it
+urbino-pesaro.it
+urbinopesaro.it
+va.it
+varese.it
+vb.it
+vc.it
+ve.it
+venezia.it
+venice.it
+verbania.it
+vercelli.it
+verona.it
+vi.it
+vibo-valentia.it
+vibovalentia.it
+vicenza.it
+viterbo.it
+vr.it
+vs.it
+vt.it
+vv.it
+
+// je : http://www.channelisles.net/register-domains/
+// Confirmed by registry <nigel@channelisles.net> 2013-11-28
+je
+co.je
+net.je
+org.je
+
+// jm : http://www.com.jm/register.html
+*.jm
+
+// jo : http://www.dns.jo/Registration_policy.aspx
+jo
+com.jo
+org.jo
+net.jo
+edu.jo
+sch.jo
+gov.jo
+mil.jo
+name.jo
+
+// jobs : http://en.wikipedia.org/wiki/.jobs
+jobs
+
+// jp : http://en.wikipedia.org/wiki/.jp
+// http://jprs.co.jp/en/jpdomain.html
+// Submitted by registry <info@jprs.jp> 2014-10-30
+jp
+// jp organizational type names
+ac.jp
+ad.jp
+co.jp
+ed.jp
+go.jp
+gr.jp
+lg.jp
+ne.jp
+or.jp
+// jp prefecture type names
+aichi.jp
+akita.jp
+aomori.jp
+chiba.jp
+ehime.jp
+fukui.jp
+fukuoka.jp
+fukushima.jp
+gifu.jp
+gunma.jp
+hiroshima.jp
+hokkaido.jp
+hyogo.jp
+ibaraki.jp
+ishikawa.jp
+iwate.jp
+kagawa.jp
+kagoshima.jp
+kanagawa.jp
+kochi.jp
+kumamoto.jp
+kyoto.jp
+mie.jp
+miyagi.jp
+miyazaki.jp
+nagano.jp
+nagasaki.jp
+nara.jp
+niigata.jp
+oita.jp
+okayama.jp
+okinawa.jp
+osaka.jp
+saga.jp
+saitama.jp
+shiga.jp
+shimane.jp
+shizuoka.jp
+tochigi.jp
+tokushima.jp
+tokyo.jp
+tottori.jp
+toyama.jp
+wakayama.jp
+yamagata.jp
+yamaguchi.jp
+yamanashi.jp
+栃木.jp
+xn--4pvxs.jp
+愛知.jp
+xn--vgu402c.jp
+愛媛.jp
+xn--c3s14m.jp
+兵庫.jp
+xn--f6qx53a.jp
+熊本.jp
+xn--8pvr4u.jp
+茨城.jp
+xn--uist22h.jp
+北海道.jp
+xn--djrs72d6uy.jp
+千葉.jp
+xn--mkru45i.jp
+和歌山.jp
+xn--0trq7p7nn.jp
+長崎.jp
+xn--8ltr62k.jp
+長野.jp
+xn--2m4a15e.jp
+新潟.jp
+xn--efvn9s.jp
+青森.jp
+xn--32vp30h.jp
+静岡.jp
+xn--4it797k.jp
+東京.jp
+xn--1lqs71d.jp
+石川.jp
+xn--5rtp49c.jp
+埼玉.jp
+xn--5js045d.jp
+三重.jp
+xn--ehqz56n.jp
+京都.jp
+xn--1lqs03n.jp
+佐賀.jp
+xn--qqqt11m.jp
+大分.jp
+xn--kbrq7o.jp
+大阪.jp
+xn--pssu33l.jp
+奈良.jp
+xn--ntsq17g.jp
+宮城.jp
+xn--uisz3g.jp
+宮崎.jp
+xn--6btw5a.jp
+富山.jp
+xn--1ctwo.jp
+山口.jp
+xn--6orx2r.jp
+山形.jp
+xn--rht61e.jp
+山梨.jp
+xn--rht27z.jp
+岩手.jp
+xn--djty4k.jp
+岐阜.jp
+xn--nit225k.jp
+岡山.jp
+xn--rht3d.jp
+島根.jp
+xn--klty5x.jp
+広島.jp
+xn--kltx9a.jp
+徳島.jp
+xn--kltp7d.jp
+沖縄.jp
+xn--uuwu58a.jp
+滋賀.jp
+xn--zbx025d.jp
+神奈川.jp
+xn--ntso0iqx3a.jp
+福井.jp
+xn--elqq16h.jp
+福岡.jp
+xn--4it168d.jp
+福島.jp
+xn--klt787d.jp
+秋田.jp
+xn--rny31h.jp
+群馬.jp
+xn--7t0a264c.jp
+香川.jp
+xn--5rtq34k.jp
+高知.jp
+xn--k7yn95e.jp
+鳥取.jp
+xn--tor131o.jp
+鹿児島.jp
+xn--d5qv7z876c.jp
+// jp geographic type names
+// http://jprs.jp/doc/rule/saisoku-1.html
+*.kawasaki.jp
+*.kitakyushu.jp
+*.kobe.jp
+*.nagoya.jp
+*.sapporo.jp
+*.sendai.jp
+*.yokohama.jp
+!city.kawasaki.jp
+!city.kitakyushu.jp
+!city.kobe.jp
+!city.nagoya.jp
+!city.sapporo.jp
+!city.sendai.jp
+!city.yokohama.jp
+// 4th level registration
+aisai.aichi.jp
+ama.aichi.jp
+anjo.aichi.jp
+asuke.aichi.jp
+chiryu.aichi.jp
+chita.aichi.jp
+fuso.aichi.jp
+gamagori.aichi.jp
+handa.aichi.jp
+hazu.aichi.jp
+hekinan.aichi.jp
+higashiura.aichi.jp
+ichinomiya.aichi.jp
+inazawa.aichi.jp
+inuyama.aichi.jp
+isshiki.aichi.jp
+iwakura.aichi.jp
+kanie.aichi.jp
+kariya.aichi.jp
+kasugai.aichi.jp
+kira.aichi.jp
+kiyosu.aichi.jp
+komaki.aichi.jp
+konan.aichi.jp
+kota.aichi.jp
+mihama.aichi.jp
+miyoshi.aichi.jp
+nishio.aichi.jp
+nisshin.aichi.jp
+obu.aichi.jp
+oguchi.aichi.jp
+oharu.aichi.jp
+okazaki.aichi.jp
+owariasahi.aichi.jp
+seto.aichi.jp
+shikatsu.aichi.jp
+shinshiro.aichi.jp
+shitara.aichi.jp
+tahara.aichi.jp
+takahama.aichi.jp
+tobishima.aichi.jp
+toei.aichi.jp
+togo.aichi.jp
+tokai.aichi.jp
+tokoname.aichi.jp
+toyoake.aichi.jp
+toyohashi.aichi.jp
+toyokawa.aichi.jp
+toyone.aichi.jp
+toyota.aichi.jp
+tsushima.aichi.jp
+yatomi.aichi.jp
+akita.akita.jp
+daisen.akita.jp
+fujisato.akita.jp
+gojome.akita.jp
+hachirogata.akita.jp
+happou.akita.jp
+higashinaruse.akita.jp
+honjo.akita.jp
+honjyo.akita.jp
+ikawa.akita.jp
+kamikoani.akita.jp
+kamioka.akita.jp
+katagami.akita.jp
+kazuno.akita.jp
+kitaakita.akita.jp
+kosaka.akita.jp
+kyowa.akita.jp
+misato.akita.jp
+mitane.akita.jp
+moriyoshi.akita.jp
+nikaho.akita.jp
+noshiro.akita.jp
+odate.akita.jp
+oga.akita.jp
+ogata.akita.jp
+semboku.akita.jp
+yokote.akita.jp
+yurihonjo.akita.jp
+aomori.aomori.jp
+gonohe.aomori.jp
+hachinohe.aomori.jp
+hashikami.aomori.jp
+hiranai.aomori.jp
+hirosaki.aomori.jp
+itayanagi.aomori.jp
+kuroishi.aomori.jp
+misawa.aomori.jp
+mutsu.aomori.jp
+nakadomari.aomori.jp
+noheji.aomori.jp
+oirase.aomori.jp
+owani.aomori.jp
+rokunohe.aomori.jp
+sannohe.aomori.jp
+shichinohe.aomori.jp
+shingo.aomori.jp
+takko.aomori.jp
+towada.aomori.jp
+tsugaru.aomori.jp
+tsuruta.aomori.jp
+abiko.chiba.jp
+asahi.chiba.jp
+chonan.chiba.jp
+chosei.chiba.jp
+choshi.chiba.jp
+chuo.chiba.jp
+funabashi.chiba.jp
+futtsu.chiba.jp
+hanamigawa.chiba.jp
+ichihara.chiba.jp
+ichikawa.chiba.jp
+ichinomiya.chiba.jp
+inzai.chiba.jp
+isumi.chiba.jp
+kamagaya.chiba.jp
+kamogawa.chiba.jp
+kashiwa.chiba.jp
+katori.chiba.jp
+katsuura.chiba.jp
+kimitsu.chiba.jp
+kisarazu.chiba.jp
+kozaki.chiba.jp
+kujukuri.chiba.jp
+kyonan.chiba.jp
+matsudo.chiba.jp
+midori.chiba.jp
+mihama.chiba.jp
+minamiboso.chiba.jp
+mobara.chiba.jp
+mutsuzawa.chiba.jp
+nagara.chiba.jp
+nagareyama.chiba.jp
+narashino.chiba.jp
+narita.chiba.jp
+noda.chiba.jp
+oamishirasato.chiba.jp
+omigawa.chiba.jp
+onjuku.chiba.jp
+otaki.chiba.jp
+sakae.chiba.jp
+sakura.chiba.jp
+shimofusa.chiba.jp
+shirako.chiba.jp
+shiroi.chiba.jp
+shisui.chiba.jp
+sodegaura.chiba.jp
+sosa.chiba.jp
+tako.chiba.jp
+tateyama.chiba.jp
+togane.chiba.jp
+tohnosho.chiba.jp
+tomisato.chiba.jp
+urayasu.chiba.jp
+yachimata.chiba.jp
+yachiyo.chiba.jp
+yokaichiba.chiba.jp
+yokoshibahikari.chiba.jp
+yotsukaido.chiba.jp
+ainan.ehime.jp
+honai.ehime.jp
+ikata.ehime.jp
+imabari.ehime.jp
+iyo.ehime.jp
+kamijima.ehime.jp
+kihoku.ehime.jp
+kumakogen.ehime.jp
+masaki.ehime.jp
+matsuno.ehime.jp
+matsuyama.ehime.jp
+namikata.ehime.jp
+niihama.ehime.jp
+ozu.ehime.jp
+saijo.ehime.jp
+seiyo.ehime.jp
+shikokuchuo.ehime.jp
+tobe.ehime.jp
+toon.ehime.jp
+uchiko.ehime.jp
+uwajima.ehime.jp
+yawatahama.ehime.jp
+echizen.fukui.jp
+eiheiji.fukui.jp
+fukui.fukui.jp
+ikeda.fukui.jp
+katsuyama.fukui.jp
+mihama.fukui.jp
+minamiechizen.fukui.jp
+obama.fukui.jp
+ohi.fukui.jp
+ono.fukui.jp
+sabae.fukui.jp
+sakai.fukui.jp
+takahama.fukui.jp
+tsuruga.fukui.jp
+wakasa.fukui.jp
+ashiya.fukuoka.jp
+buzen.fukuoka.jp
+chikugo.fukuoka.jp
+chikuho.fukuoka.jp
+chikujo.fukuoka.jp
+chikushino.fukuoka.jp
+chikuzen.fukuoka.jp
+chuo.fukuoka.jp
+dazaifu.fukuoka.jp
+fukuchi.fukuoka.jp
+hakata.fukuoka.jp
+higashi.fukuoka.jp
+hirokawa.fukuoka.jp
+hisayama.fukuoka.jp
+iizuka.fukuoka.jp
+inatsuki.fukuoka.jp
+kaho.fukuoka.jp
+kasuga.fukuoka.jp
+kasuya.fukuoka.jp
+kawara.fukuoka.jp
+keisen.fukuoka.jp
+koga.fukuoka.jp
+kurate.fukuoka.jp
+kurogi.fukuoka.jp
+kurume.fukuoka.jp
+minami.fukuoka.jp
+miyako.fukuoka.jp
+miyama.fukuoka.jp
+miyawaka.fukuoka.jp
+mizumaki.fukuoka.jp
+munakata.fukuoka.jp
+nakagawa.fukuoka.jp
+nakama.fukuoka.jp
+nishi.fukuoka.jp
+nogata.fukuoka.jp
+ogori.fukuoka.jp
+okagaki.fukuoka.jp
+okawa.fukuoka.jp
+oki.fukuoka.jp
+omuta.fukuoka.jp
+onga.fukuoka.jp
+onojo.fukuoka.jp
+oto.fukuoka.jp
+saigawa.fukuoka.jp
+sasaguri.fukuoka.jp
+shingu.fukuoka.jp
+shinyoshitomi.fukuoka.jp
+shonai.fukuoka.jp
+soeda.fukuoka.jp
+sue.fukuoka.jp
+tachiarai.fukuoka.jp
+tagawa.fukuoka.jp
+takata.fukuoka.jp
+toho.fukuoka.jp
+toyotsu.fukuoka.jp
+tsuiki.fukuoka.jp
+ukiha.fukuoka.jp
+umi.fukuoka.jp
+usui.fukuoka.jp
+yamada.fukuoka.jp
+yame.fukuoka.jp
+yanagawa.fukuoka.jp
+yukuhashi.fukuoka.jp
+aizubange.fukushima.jp
+aizumisato.fukushima.jp
+aizuwakamatsu.fukushima.jp
+asakawa.fukushima.jp
+bandai.fukushima.jp
+date.fukushima.jp
+fukushima.fukushima.jp
+furudono.fukushima.jp
+futaba.fukushima.jp
+hanawa.fukushima.jp
+higashi.fukushima.jp
+hirata.fukushima.jp
+hirono.fukushima.jp
+iitate.fukushima.jp
+inawashiro.fukushima.jp
+ishikawa.fukushima.jp
+iwaki.fukushima.jp
+izumizaki.fukushima.jp
+kagamiishi.fukushima.jp
+kaneyama.fukushima.jp
+kawamata.fukushima.jp
+kitakata.fukushima.jp
+kitashiobara.fukushima.jp
+koori.fukushima.jp
+koriyama.fukushima.jp
+kunimi.fukushima.jp
+miharu.fukushima.jp
+mishima.fukushima.jp
+namie.fukushima.jp
+nango.fukushima.jp
+nishiaizu.fukushima.jp
+nishigo.fukushima.jp
+okuma.fukushima.jp
+omotego.fukushima.jp
+ono.fukushima.jp
+otama.fukushima.jp
+samegawa.fukushima.jp
+shimogo.fukushima.jp
+shirakawa.fukushima.jp
+showa.fukushima.jp
+soma.fukushima.jp
+sukagawa.fukushima.jp
+taishin.fukushima.jp
+tamakawa.fukushima.jp
+tanagura.fukushima.jp
+tenei.fukushima.jp
+yabuki.fukushima.jp
+yamato.fukushima.jp
+yamatsuri.fukushima.jp
+yanaizu.fukushima.jp
+yugawa.fukushima.jp
+anpachi.gifu.jp
+ena.gifu.jp
+gifu.gifu.jp
+ginan.gifu.jp
+godo.gifu.jp
+gujo.gifu.jp
+hashima.gifu.jp
+hichiso.gifu.jp
+hida.gifu.jp
+higashishirakawa.gifu.jp
+ibigawa.gifu.jp
+ikeda.gifu.jp
+kakamigahara.gifu.jp
+kani.gifu.jp
+kasahara.gifu.jp
+kasamatsu.gifu.jp
+kawaue.gifu.jp
+kitagata.gifu.jp
+mino.gifu.jp
+minokamo.gifu.jp
+mitake.gifu.jp
+mizunami.gifu.jp
+motosu.gifu.jp
+nakatsugawa.gifu.jp
+ogaki.gifu.jp
+sakahogi.gifu.jp
+seki.gifu.jp
+sekigahara.gifu.jp
+shirakawa.gifu.jp
+tajimi.gifu.jp
+takayama.gifu.jp
+tarui.gifu.jp
+toki.gifu.jp
+tomika.gifu.jp
+wanouchi.gifu.jp
+yamagata.gifu.jp
+yaotsu.gifu.jp
+yoro.gifu.jp
+annaka.gunma.jp
+chiyoda.gunma.jp
+fujioka.gunma.jp
+higashiagatsuma.gunma.jp
+isesaki.gunma.jp
+itakura.gunma.jp
+kanna.gunma.jp
+kanra.gunma.jp
+katashina.gunma.jp
+kawaba.gunma.jp
+kiryu.gunma.jp
+kusatsu.gunma.jp
+maebashi.gunma.jp
+meiwa.gunma.jp
+midori.gunma.jp
+minakami.gunma.jp
+naganohara.gunma.jp
+nakanojo.gunma.jp
+nanmoku.gunma.jp
+numata.gunma.jp
+oizumi.gunma.jp
+ora.gunma.jp
+ota.gunma.jp
+shibukawa.gunma.jp
+shimonita.gunma.jp
+shinto.gunma.jp
+showa.gunma.jp
+takasaki.gunma.jp
+takayama.gunma.jp
+tamamura.gunma.jp
+tatebayashi.gunma.jp
+tomioka.gunma.jp
+tsukiyono.gunma.jp
+tsumagoi.gunma.jp
+ueno.gunma.jp
+yoshioka.gunma.jp
+asaminami.hiroshima.jp
+daiwa.hiroshima.jp
+etajima.hiroshima.jp
+fuchu.hiroshima.jp
+fukuyama.hiroshima.jp
+hatsukaichi.hiroshima.jp
+higashihiroshima.hiroshima.jp
+hongo.hiroshima.jp
+jinsekikogen.hiroshima.jp
+kaita.hiroshima.jp
+kui.hiroshima.jp
+kumano.hiroshima.jp
+kure.hiroshima.jp
+mihara.hiroshima.jp
+miyoshi.hiroshima.jp
+naka.hiroshima.jp
+onomichi.hiroshima.jp
+osakikamijima.hiroshima.jp
+otake.hiroshima.jp
+saka.hiroshima.jp
+sera.hiroshima.jp
+seranishi.hiroshima.jp
+shinichi.hiroshima.jp
+shobara.hiroshima.jp
+takehara.hiroshima.jp
+abashiri.hokkaido.jp
+abira.hokkaido.jp
+aibetsu.hokkaido.jp
+akabira.hokkaido.jp
+akkeshi.hokkaido.jp
+asahikawa.hokkaido.jp
+ashibetsu.hokkaido.jp
+ashoro.hokkaido.jp
+assabu.hokkaido.jp
+atsuma.hokkaido.jp
+bibai.hokkaido.jp
+biei.hokkaido.jp
+bifuka.hokkaido.jp
+bihoro.hokkaido.jp
+biratori.hokkaido.jp
+chippubetsu.hokkaido.jp
+chitose.hokkaido.jp
+date.hokkaido.jp
+ebetsu.hokkaido.jp
+embetsu.hokkaido.jp
+eniwa.hokkaido.jp
+erimo.hokkaido.jp
+esan.hokkaido.jp
+esashi.hokkaido.jp
+fukagawa.hokkaido.jp
+fukushima.hokkaido.jp
+furano.hokkaido.jp
+furubira.hokkaido.jp
+haboro.hokkaido.jp
+hakodate.hokkaido.jp
+hamatonbetsu.hokkaido.jp
+hidaka.hokkaido.jp
+higashikagura.hokkaido.jp
+higashikawa.hokkaido.jp
+hiroo.hokkaido.jp
+hokuryu.hokkaido.jp
+hokuto.hokkaido.jp
+honbetsu.hokkaido.jp
+horokanai.hokkaido.jp
+horonobe.hokkaido.jp
+ikeda.hokkaido.jp
+imakane.hokkaido.jp
+ishikari.hokkaido.jp
+iwamizawa.hokkaido.jp
+iwanai.hokkaido.jp
+kamifurano.hokkaido.jp
+kamikawa.hokkaido.jp
+kamishihoro.hokkaido.jp
+kamisunagawa.hokkaido.jp
+kamoenai.hokkaido.jp
+kayabe.hokkaido.jp
+kembuchi.hokkaido.jp
+kikonai.hokkaido.jp
+kimobetsu.hokkaido.jp
+kitahiroshima.hokkaido.jp
+kitami.hokkaido.jp
+kiyosato.hokkaido.jp
+koshimizu.hokkaido.jp
+kunneppu.hokkaido.jp
+kuriyama.hokkaido.jp
+kuromatsunai.hokkaido.jp
+kushiro.hokkaido.jp
+kutchan.hokkaido.jp
+kyowa.hokkaido.jp
+mashike.hokkaido.jp
+matsumae.hokkaido.jp
+mikasa.hokkaido.jp
+minamifurano.hokkaido.jp
+mombetsu.hokkaido.jp
+moseushi.hokkaido.jp
+mukawa.hokkaido.jp
+muroran.hokkaido.jp
+naie.hokkaido.jp
+nakagawa.hokkaido.jp
+nakasatsunai.hokkaido.jp
+nakatombetsu.hokkaido.jp
+nanae.hokkaido.jp
+nanporo.hokkaido.jp
+nayoro.hokkaido.jp
+nemuro.hokkaido.jp
+niikappu.hokkaido.jp
+niki.hokkaido.jp
+nishiokoppe.hokkaido.jp
+noboribetsu.hokkaido.jp
+numata.hokkaido.jp
+obihiro.hokkaido.jp
+obira.hokkaido.jp
+oketo.hokkaido.jp
+okoppe.hokkaido.jp
+otaru.hokkaido.jp
+otobe.hokkaido.jp
+otofuke.hokkaido.jp
+otoineppu.hokkaido.jp
+oumu.hokkaido.jp
+ozora.hokkaido.jp
+pippu.hokkaido.jp
+rankoshi.hokkaido.jp
+rebun.hokkaido.jp
+rikubetsu.hokkaido.jp
+rishiri.hokkaido.jp
+rishirifuji.hokkaido.jp
+saroma.hokkaido.jp
+sarufutsu.hokkaido.jp
+shakotan.hokkaido.jp
+shari.hokkaido.jp
+shibecha.hokkaido.jp
+shibetsu.hokkaido.jp
+shikabe.hokkaido.jp
+shikaoi.hokkaido.jp
+shimamaki.hokkaido.jp
+shimizu.hokkaido.jp
+shimokawa.hokkaido.jp
+shinshinotsu.hokkaido.jp
+shintoku.hokkaido.jp
+shiranuka.hokkaido.jp
+shiraoi.hokkaido.jp
+shiriuchi.hokkaido.jp
+sobetsu.hokkaido.jp
+sunagawa.hokkaido.jp
+taiki.hokkaido.jp
+takasu.hokkaido.jp
+takikawa.hokkaido.jp
+takinoue.hokkaido.jp
+teshikaga.hokkaido.jp
+tobetsu.hokkaido.jp
+tohma.hokkaido.jp
+tomakomai.hokkaido.jp
+tomari.hokkaido.jp
+toya.hokkaido.jp
+toyako.hokkaido.jp
+toyotomi.hokkaido.jp
+toyoura.hokkaido.jp
+tsubetsu.hokkaido.jp
+tsukigata.hokkaido.jp
+urakawa.hokkaido.jp
+urausu.hokkaido.jp
+uryu.hokkaido.jp
+utashinai.hokkaido.jp
+wakkanai.hokkaido.jp
+wassamu.hokkaido.jp
+yakumo.hokkaido.jp
+yoichi.hokkaido.jp
+aioi.hyogo.jp
+akashi.hyogo.jp
+ako.hyogo.jp
+amagasaki.hyogo.jp
+aogaki.hyogo.jp
+asago.hyogo.jp
+ashiya.hyogo.jp
+awaji.hyogo.jp
+fukusaki.hyogo.jp
+goshiki.hyogo.jp
+harima.hyogo.jp
+himeji.hyogo.jp
+ichikawa.hyogo.jp
+inagawa.hyogo.jp
+itami.hyogo.jp
+kakogawa.hyogo.jp
+kamigori.hyogo.jp
+kamikawa.hyogo.jp
+kasai.hyogo.jp
+kasuga.hyogo.jp
+kawanishi.hyogo.jp
+miki.hyogo.jp
+minamiawaji.hyogo.jp
+nishinomiya.hyogo.jp
+nishiwaki.hyogo.jp
+ono.hyogo.jp
+sanda.hyogo.jp
+sannan.hyogo.jp
+sasayama.hyogo.jp
+sayo.hyogo.jp
+shingu.hyogo.jp
+shinonsen.hyogo.jp
+shiso.hyogo.jp
+sumoto.hyogo.jp
+taishi.hyogo.jp
+taka.hyogo.jp
+takarazuka.hyogo.jp
+takasago.hyogo.jp
+takino.hyogo.jp
+tamba.hyogo.jp
+tatsuno.hyogo.jp
+toyooka.hyogo.jp
+yabu.hyogo.jp
+yashiro.hyogo.jp
+yoka.hyogo.jp
+yokawa.hyogo.jp
+ami.ibaraki.jp
+asahi.ibaraki.jp
+bando.ibaraki.jp
+chikusei.ibaraki.jp
+daigo.ibaraki.jp
+fujishiro.ibaraki.jp
+hitachi.ibaraki.jp
+hitachinaka.ibaraki.jp
+hitachiomiya.ibaraki.jp
+hitachiota.ibaraki.jp
+ibaraki.ibaraki.jp
+ina.ibaraki.jp
+inashiki.ibaraki.jp
+itako.ibaraki.jp
+iwama.ibaraki.jp
+joso.ibaraki.jp
+kamisu.ibaraki.jp
+kasama.ibaraki.jp
+kashima.ibaraki.jp
+kasumigaura.ibaraki.jp
+koga.ibaraki.jp
+miho.ibaraki.jp
+mito.ibaraki.jp
+moriya.ibaraki.jp
+naka.ibaraki.jp
+namegata.ibaraki.jp
+oarai.ibaraki.jp
+ogawa.ibaraki.jp
+omitama.ibaraki.jp
+ryugasaki.ibaraki.jp
+sakai.ibaraki.jp
+sakuragawa.ibaraki.jp
+shimodate.ibaraki.jp
+shimotsuma.ibaraki.jp
+shirosato.ibaraki.jp
+sowa.ibaraki.jp
+suifu.ibaraki.jp
+takahagi.ibaraki.jp
+tamatsukuri.ibaraki.jp
+tokai.ibaraki.jp
+tomobe.ibaraki.jp
+tone.ibaraki.jp
+toride.ibaraki.jp
+tsuchiura.ibaraki.jp
+tsukuba.ibaraki.jp
+uchihara.ibaraki.jp
+ushiku.ibaraki.jp
+yachiyo.ibaraki.jp
+yamagata.ibaraki.jp
+yawara.ibaraki.jp
+yuki.ibaraki.jp
+anamizu.ishikawa.jp
+hakui.ishikawa.jp
+hakusan.ishikawa.jp
+kaga.ishikawa.jp
+kahoku.ishikawa.jp
+kanazawa.ishikawa.jp
+kawakita.ishikawa.jp
+komatsu.ishikawa.jp
+nakanoto.ishikawa.jp
+nanao.ishikawa.jp
+nomi.ishikawa.jp
+nonoichi.ishikawa.jp
+noto.ishikawa.jp
+shika.ishikawa.jp
+suzu.ishikawa.jp
+tsubata.ishikawa.jp
+tsurugi.ishikawa.jp
+uchinada.ishikawa.jp
+wajima.ishikawa.jp
+fudai.iwate.jp
+fujisawa.iwate.jp
+hanamaki.iwate.jp
+hiraizumi.iwate.jp
+hirono.iwate.jp
+ichinohe.iwate.jp
+ichinoseki.iwate.jp
+iwaizumi.iwate.jp
+iwate.iwate.jp
+joboji.iwate.jp
+kamaishi.iwate.jp
+kanegasaki.iwate.jp
+karumai.iwate.jp
+kawai.iwate.jp
+kitakami.iwate.jp
+kuji.iwate.jp
+kunohe.iwate.jp
+kuzumaki.iwate.jp
+miyako.iwate.jp
+mizusawa.iwate.jp
+morioka.iwate.jp
+ninohe.iwate.jp
+noda.iwate.jp
+ofunato.iwate.jp
+oshu.iwate.jp
+otsuchi.iwate.jp
+rikuzentakata.iwate.jp
+shiwa.iwate.jp
+shizukuishi.iwate.jp
+sumita.iwate.jp
+tanohata.iwate.jp
+tono.iwate.jp
+yahaba.iwate.jp
+yamada.iwate.jp
+ayagawa.kagawa.jp
+higashikagawa.kagawa.jp
+kanonji.kagawa.jp
+kotohira.kagawa.jp
+manno.kagawa.jp
+marugame.kagawa.jp
+mitoyo.kagawa.jp
+naoshima.kagawa.jp
+sanuki.kagawa.jp
+tadotsu.kagawa.jp
+takamatsu.kagawa.jp
+tonosho.kagawa.jp
+uchinomi.kagawa.jp
+utazu.kagawa.jp
+zentsuji.kagawa.jp
+akune.kagoshima.jp
+amami.kagoshima.jp
+hioki.kagoshima.jp
+isa.kagoshima.jp
+isen.kagoshima.jp
+izumi.kagoshima.jp
+kagoshima.kagoshima.jp
+kanoya.kagoshima.jp
+kawanabe.kagoshima.jp
+kinko.kagoshima.jp
+kouyama.kagoshima.jp
+makurazaki.kagoshima.jp
+matsumoto.kagoshima.jp
+minamitane.kagoshima.jp
+nakatane.kagoshima.jp
+nishinoomote.kagoshima.jp
+satsumasendai.kagoshima.jp
+soo.kagoshima.jp
+tarumizu.kagoshima.jp
+yusui.kagoshima.jp
+aikawa.kanagawa.jp
+atsugi.kanagawa.jp
+ayase.kanagawa.jp
+chigasaki.kanagawa.jp
+ebina.kanagawa.jp
+fujisawa.kanagawa.jp
+hadano.kanagawa.jp
+hakone.kanagawa.jp
+hiratsuka.kanagawa.jp
+isehara.kanagawa.jp
+kaisei.kanagawa.jp
+kamakura.kanagawa.jp
+kiyokawa.kanagawa.jp
+matsuda.kanagawa.jp
+minamiashigara.kanagawa.jp
+miura.kanagawa.jp
+nakai.kanagawa.jp
+ninomiya.kanagawa.jp
+odawara.kanagawa.jp
+oi.kanagawa.jp
+oiso.kanagawa.jp
+sagamihara.kanagawa.jp
+samukawa.kanagawa.jp
+tsukui.kanagawa.jp
+yamakita.kanagawa.jp
+yamato.kanagawa.jp
+yokosuka.kanagawa.jp
+yugawara.kanagawa.jp
+zama.kanagawa.jp
+zushi.kanagawa.jp
+aki.kochi.jp
+geisei.kochi.jp
+hidaka.kochi.jp
+higashitsuno.kochi.jp
+ino.kochi.jp
+kagami.kochi.jp
+kami.kochi.jp
+kitagawa.kochi.jp
+kochi.kochi.jp
+mihara.kochi.jp
+motoyama.kochi.jp
+muroto.kochi.jp
+nahari.kochi.jp
+nakamura.kochi.jp
+nankoku.kochi.jp
+nishitosa.kochi.jp
+niyodogawa.kochi.jp
+ochi.kochi.jp
+okawa.kochi.jp
+otoyo.kochi.jp
+otsuki.kochi.jp
+sakawa.kochi.jp
+sukumo.kochi.jp
+susaki.kochi.jp
+tosa.kochi.jp
+tosashimizu.kochi.jp
+toyo.kochi.jp
+tsuno.kochi.jp
+umaji.kochi.jp
+yasuda.kochi.jp
+yusuhara.kochi.jp
+amakusa.kumamoto.jp
+arao.kumamoto.jp
+aso.kumamoto.jp
+choyo.kumamoto.jp
+gyokuto.kumamoto.jp
+hitoyoshi.kumamoto.jp
+kamiamakusa.kumamoto.jp
+kashima.kumamoto.jp
+kikuchi.kumamoto.jp
+kosa.kumamoto.jp
+kumamoto.kumamoto.jp
+mashiki.kumamoto.jp
+mifune.kumamoto.jp
+minamata.kumamoto.jp
+minamioguni.kumamoto.jp
+nagasu.kumamoto.jp
+nishihara.kumamoto.jp
+oguni.kumamoto.jp
+ozu.kumamoto.jp
+sumoto.kumamoto.jp
+takamori.kumamoto.jp
+uki.kumamoto.jp
+uto.kumamoto.jp
+yamaga.kumamoto.jp
+yamato.kumamoto.jp
+yatsushiro.kumamoto.jp
+ayabe.kyoto.jp
+fukuchiyama.kyoto.jp
+higashiyama.kyoto.jp
+ide.kyoto.jp
+ine.kyoto.jp
+joyo.kyoto.jp
+kameoka.kyoto.jp
+kamo.kyoto.jp
+kita.kyoto.jp
+kizu.kyoto.jp
+kumiyama.kyoto.jp
+kyotamba.kyoto.jp
+kyotanabe.kyoto.jp
+kyotango.kyoto.jp
+maizuru.kyoto.jp
+minami.kyoto.jp
+minamiyamashiro.kyoto.jp
+miyazu.kyoto.jp
+muko.kyoto.jp
+nagaokakyo.kyoto.jp
+nakagyo.kyoto.jp
+nantan.kyoto.jp
+oyamazaki.kyoto.jp
+sakyo.kyoto.jp
+seika.kyoto.jp
+tanabe.kyoto.jp
+uji.kyoto.jp
+ujitawara.kyoto.jp
+wazuka.kyoto.jp
+yamashina.kyoto.jp
+yawata.kyoto.jp
+asahi.mie.jp
+inabe.mie.jp
+ise.mie.jp
+kameyama.mie.jp
+kawagoe.mie.jp
+kiho.mie.jp
+kisosaki.mie.jp
+kiwa.mie.jp
+komono.mie.jp
+kumano.mie.jp
+kuwana.mie.jp
+matsusaka.mie.jp
+meiwa.mie.jp
+mihama.mie.jp
+minamiise.mie.jp
+misugi.mie.jp
+miyama.mie.jp
+nabari.mie.jp
+shima.mie.jp
+suzuka.mie.jp
+tado.mie.jp
+taiki.mie.jp
+taki.mie.jp
+tamaki.mie.jp
+toba.mie.jp
+tsu.mie.jp
+udono.mie.jp
+ureshino.mie.jp
+watarai.mie.jp
+yokkaichi.mie.jp
+furukawa.miyagi.jp
+higashimatsushima.miyagi.jp
+ishinomaki.miyagi.jp
+iwanuma.miyagi.jp
+kakuda.miyagi.jp
+kami.miyagi.jp
+kawasaki.miyagi.jp
+kesennuma.miyagi.jp
+marumori.miyagi.jp
+matsushima.miyagi.jp
+minamisanriku.miyagi.jp
+misato.miyagi.jp
+murata.miyagi.jp
+natori.miyagi.jp
+ogawara.miyagi.jp
+ohira.miyagi.jp
+onagawa.miyagi.jp
+osaki.miyagi.jp
+rifu.miyagi.jp
+semine.miyagi.jp
+shibata.miyagi.jp
+shichikashuku.miyagi.jp
+shikama.miyagi.jp
+shiogama.miyagi.jp
+shiroishi.miyagi.jp
+tagajo.miyagi.jp
+taiwa.miyagi.jp
+tome.miyagi.jp
+tomiya.miyagi.jp
+wakuya.miyagi.jp
+watari.miyagi.jp
+yamamoto.miyagi.jp
+zao.miyagi.jp
+aya.miyazaki.jp
+ebino.miyazaki.jp
+gokase.miyazaki.jp
+hyuga.miyazaki.jp
+kadogawa.miyazaki.jp
+kawaminami.miyazaki.jp
+kijo.miyazaki.jp
+kitagawa.miyazaki.jp
+kitakata.miyazaki.jp
+kitaura.miyazaki.jp
+kobayashi.miyazaki.jp
+kunitomi.miyazaki.jp
+kushima.miyazaki.jp
+mimata.miyazaki.jp
+miyakonojo.miyazaki.jp
+miyazaki.miyazaki.jp
+morotsuka.miyazaki.jp
+nichinan.miyazaki.jp
+nishimera.miyazaki.jp
+nobeoka.miyazaki.jp
+saito.miyazaki.jp
+shiiba.miyazaki.jp
+shintomi.miyazaki.jp
+takaharu.miyazaki.jp
+takanabe.miyazaki.jp
+takazaki.miyazaki.jp
+tsuno.miyazaki.jp
+achi.nagano.jp
+agematsu.nagano.jp
+anan.nagano.jp
+aoki.nagano.jp
+asahi.nagano.jp
+azumino.nagano.jp
+chikuhoku.nagano.jp
+chikuma.nagano.jp
+chino.nagano.jp
+fujimi.nagano.jp
+hakuba.nagano.jp
+hara.nagano.jp
+hiraya.nagano.jp
+iida.nagano.jp
+iijima.nagano.jp
+iiyama.nagano.jp
+iizuna.nagano.jp
+ikeda.nagano.jp
+ikusaka.nagano.jp
+ina.nagano.jp
+karuizawa.nagano.jp
+kawakami.nagano.jp
+kiso.nagano.jp
+kisofukushima.nagano.jp
+kitaaiki.nagano.jp
+komagane.nagano.jp
+komoro.nagano.jp
+matsukawa.nagano.jp
+matsumoto.nagano.jp
+miasa.nagano.jp
+minamiaiki.nagano.jp
+minamimaki.nagano.jp
+minamiminowa.nagano.jp
+minowa.nagano.jp
+miyada.nagano.jp
+miyota.nagano.jp
+mochizuki.nagano.jp
+nagano.nagano.jp
+nagawa.nagano.jp
+nagiso.nagano.jp
+nakagawa.nagano.jp
+nakano.nagano.jp
+nozawaonsen.nagano.jp
+obuse.nagano.jp
+ogawa.nagano.jp
+okaya.nagano.jp
+omachi.nagano.jp
+omi.nagano.jp
+ookuwa.nagano.jp
+ooshika.nagano.jp
+otaki.nagano.jp
+otari.nagano.jp
+sakae.nagano.jp
+sakaki.nagano.jp
+saku.nagano.jp
+sakuho.nagano.jp
+shimosuwa.nagano.jp
+shinanomachi.nagano.jp
+shiojiri.nagano.jp
+suwa.nagano.jp
+suzaka.nagano.jp
+takagi.nagano.jp
+takamori.nagano.jp
+takayama.nagano.jp
+tateshina.nagano.jp
+tatsuno.nagano.jp
+togakushi.nagano.jp
+togura.nagano.jp
+tomi.nagano.jp
+ueda.nagano.jp
+wada.nagano.jp
+yamagata.nagano.jp
+yamanouchi.nagano.jp
+yasaka.nagano.jp
+yasuoka.nagano.jp
+chijiwa.nagasaki.jp
+futsu.nagasaki.jp
+goto.nagasaki.jp
+hasami.nagasaki.jp
+hirado.nagasaki.jp
+iki.nagasaki.jp
+isahaya.nagasaki.jp
+kawatana.nagasaki.jp
+kuchinotsu.nagasaki.jp
+matsuura.nagasaki.jp
+nagasaki.nagasaki.jp
+obama.nagasaki.jp
+omura.nagasaki.jp
+oseto.nagasaki.jp
+saikai.nagasaki.jp
+sasebo.nagasaki.jp
+seihi.nagasaki.jp
+shimabara.nagasaki.jp
+shinkamigoto.nagasaki.jp
+togitsu.nagasaki.jp
+tsushima.nagasaki.jp
+unzen.nagasaki.jp
+ando.nara.jp
+gose.nara.jp
+heguri.nara.jp
+higashiyoshino.nara.jp
+ikaruga.nara.jp
+ikoma.nara.jp
+kamikitayama.nara.jp
+kanmaki.nara.jp
+kashiba.nara.jp
+kashihara.nara.jp
+katsuragi.nara.jp
+kawai.nara.jp
+kawakami.nara.jp
+kawanishi.nara.jp
+koryo.nara.jp
+kurotaki.nara.jp
+mitsue.nara.jp
+miyake.nara.jp
+nara.nara.jp
+nosegawa.nara.jp
+oji.nara.jp
+ouda.nara.jp
+oyodo.nara.jp
+sakurai.nara.jp
+sango.nara.jp
+shimoichi.nara.jp
+shimokitayama.nara.jp
+shinjo.nara.jp
+soni.nara.jp
+takatori.nara.jp
+tawaramoto.nara.jp
+tenkawa.nara.jp
+tenri.nara.jp
+uda.nara.jp
+yamatokoriyama.nara.jp
+yamatotakada.nara.jp
+yamazoe.nara.jp
+yoshino.nara.jp
+aga.niigata.jp
+agano.niigata.jp
+gosen.niigata.jp
+itoigawa.niigata.jp
+izumozaki.niigata.jp
+joetsu.niigata.jp
+kamo.niigata.jp
+kariwa.niigata.jp
+kashiwazaki.niigata.jp
+minamiuonuma.niigata.jp
+mitsuke.niigata.jp
+muika.niigata.jp
+murakami.niigata.jp
+myoko.niigata.jp
+nagaoka.niigata.jp
+niigata.niigata.jp
+ojiya.niigata.jp
+omi.niigata.jp
+sado.niigata.jp
+sanjo.niigata.jp
+seiro.niigata.jp
+seirou.niigata.jp
+sekikawa.niigata.jp
+shibata.niigata.jp
+tagami.niigata.jp
+tainai.niigata.jp
+tochio.niigata.jp
+tokamachi.niigata.jp
+tsubame.niigata.jp
+tsunan.niigata.jp
+uonuma.niigata.jp
+yahiko.niigata.jp
+yoita.niigata.jp
+yuzawa.niigata.jp
+beppu.oita.jp
+bungoono.oita.jp
+bungotakada.oita.jp
+hasama.oita.jp
+hiji.oita.jp
+himeshima.oita.jp
+hita.oita.jp
+kamitsue.oita.jp
+kokonoe.oita.jp
+kuju.oita.jp
+kunisaki.oita.jp
+kusu.oita.jp
+oita.oita.jp
+saiki.oita.jp
+taketa.oita.jp
+tsukumi.oita.jp
+usa.oita.jp
+usuki.oita.jp
+yufu.oita.jp
+akaiwa.okayama.jp
+asakuchi.okayama.jp
+bizen.okayama.jp
+hayashima.okayama.jp
+ibara.okayama.jp
+kagamino.okayama.jp
+kasaoka.okayama.jp
+kibichuo.okayama.jp
+kumenan.okayama.jp
+kurashiki.okayama.jp
+maniwa.okayama.jp
+misaki.okayama.jp
+nagi.okayama.jp
+niimi.okayama.jp
+nishiawakura.okayama.jp
+okayama.okayama.jp
+satosho.okayama.jp
+setouchi.okayama.jp
+shinjo.okayama.jp
+shoo.okayama.jp
+soja.okayama.jp
+takahashi.okayama.jp
+tamano.okayama.jp
+tsuyama.okayama.jp
+wake.okayama.jp
+yakage.okayama.jp
+aguni.okinawa.jp
+ginowan.okinawa.jp
+ginoza.okinawa.jp
+gushikami.okinawa.jp
+haebaru.okinawa.jp
+higashi.okinawa.jp
+hirara.okinawa.jp
+iheya.okinawa.jp
+ishigaki.okinawa.jp
+ishikawa.okinawa.jp
+itoman.okinawa.jp
+izena.okinawa.jp
+kadena.okinawa.jp
+kin.okinawa.jp
+kitadaito.okinawa.jp
+kitanakagusuku.okinawa.jp
+kumejima.okinawa.jp
+kunigami.okinawa.jp
+minamidaito.okinawa.jp
+motobu.okinawa.jp
+nago.okinawa.jp
+naha.okinawa.jp
+nakagusuku.okinawa.jp
+nakijin.okinawa.jp
+nanjo.okinawa.jp
+nishihara.okinawa.jp
+ogimi.okinawa.jp
+okinawa.okinawa.jp
+onna.okinawa.jp
+shimoji.okinawa.jp
+taketomi.okinawa.jp
+tarama.okinawa.jp
+tokashiki.okinawa.jp
+tomigusuku.okinawa.jp
+tonaki.okinawa.jp
+urasoe.okinawa.jp
+uruma.okinawa.jp
+yaese.okinawa.jp
+yomitan.okinawa.jp
+yonabaru.okinawa.jp
+yonaguni.okinawa.jp
+zamami.okinawa.jp
+abeno.osaka.jp
+chihayaakasaka.osaka.jp
+chuo.osaka.jp
+daito.osaka.jp
+fujiidera.osaka.jp
+habikino.osaka.jp
+hannan.osaka.jp
+higashiosaka.osaka.jp
+higashisumiyoshi.osaka.jp
+higashiyodogawa.osaka.jp
+hirakata.osaka.jp
+ibaraki.osaka.jp
+ikeda.osaka.jp
+izumi.osaka.jp
+izumiotsu.osaka.jp
+izumisano.osaka.jp
+kadoma.osaka.jp
+kaizuka.osaka.jp
+kanan.osaka.jp
+kashiwara.osaka.jp
+katano.osaka.jp
+kawachinagano.osaka.jp
+kishiwada.osaka.jp
+kita.osaka.jp
+kumatori.osaka.jp
+matsubara.osaka.jp
+minato.osaka.jp
+minoh.osaka.jp
+misaki.osaka.jp
+moriguchi.osaka.jp
+neyagawa.osaka.jp
+nishi.osaka.jp
+nose.osaka.jp
+osakasayama.osaka.jp
+sakai.osaka.jp
+sayama.osaka.jp
+sennan.osaka.jp
+settsu.osaka.jp
+shijonawate.osaka.jp
+shimamoto.osaka.jp
+suita.osaka.jp
+tadaoka.osaka.jp
+taishi.osaka.jp
+tajiri.osaka.jp
+takaishi.osaka.jp
+takatsuki.osaka.jp
+tondabayashi.osaka.jp
+toyonaka.osaka.jp
+toyono.osaka.jp
+yao.osaka.jp
+ariake.saga.jp
+arita.saga.jp
+fukudomi.saga.jp
+genkai.saga.jp
+hamatama.saga.jp
+hizen.saga.jp
+imari.saga.jp
+kamimine.saga.jp
+kanzaki.saga.jp
+karatsu.saga.jp
+kashima.saga.jp
+kitagata.saga.jp
+kitahata.saga.jp
+kiyama.saga.jp
+kouhoku.saga.jp
+kyuragi.saga.jp
+nishiarita.saga.jp
+ogi.saga.jp
+omachi.saga.jp
+ouchi.saga.jp
+saga.saga.jp
+shiroishi.saga.jp
+taku.saga.jp
+tara.saga.jp
+tosu.saga.jp
+yoshinogari.saga.jp
+arakawa.saitama.jp
+asaka.saitama.jp
+chichibu.saitama.jp
+fujimi.saitama.jp
+fujimino.saitama.jp
+fukaya.saitama.jp
+hanno.saitama.jp
+hanyu.saitama.jp
+hasuda.saitama.jp
+hatogaya.saitama.jp
+hatoyama.saitama.jp
+hidaka.saitama.jp
+higashichichibu.saitama.jp
+higashimatsuyama.saitama.jp
+honjo.saitama.jp
+ina.saitama.jp
+iruma.saitama.jp
+iwatsuki.saitama.jp
+kamiizumi.saitama.jp
+kamikawa.saitama.jp
+kamisato.saitama.jp
+kasukabe.saitama.jp
+kawagoe.saitama.jp
+kawaguchi.saitama.jp
+kawajima.saitama.jp
+kazo.saitama.jp
+kitamoto.saitama.jp
+koshigaya.saitama.jp
+kounosu.saitama.jp
+kuki.saitama.jp
+kumagaya.saitama.jp
+matsubushi.saitama.jp
+minano.saitama.jp
+misato.saitama.jp
+miyashiro.saitama.jp
+miyoshi.saitama.jp
+moroyama.saitama.jp
+nagatoro.saitama.jp
+namegawa.saitama.jp
+niiza.saitama.jp
+ogano.saitama.jp
+ogawa.saitama.jp
+ogose.saitama.jp
+okegawa.saitama.jp
+omiya.saitama.jp
+otaki.saitama.jp
+ranzan.saitama.jp
+ryokami.saitama.jp
+saitama.saitama.jp
+sakado.saitama.jp
+satte.saitama.jp
+sayama.saitama.jp
+shiki.saitama.jp
+shiraoka.saitama.jp
+soka.saitama.jp
+sugito.saitama.jp
+toda.saitama.jp
+tokigawa.saitama.jp
+tokorozawa.saitama.jp
+tsurugashima.saitama.jp
+urawa.saitama.jp
+warabi.saitama.jp
+yashio.saitama.jp
+yokoze.saitama.jp
+yono.saitama.jp
+yorii.saitama.jp
+yoshida.saitama.jp
+yoshikawa.saitama.jp
+yoshimi.saitama.jp
+aisho.shiga.jp
+gamo.shiga.jp
+higashiomi.shiga.jp
+hikone.shiga.jp
+koka.shiga.jp
+konan.shiga.jp
+kosei.shiga.jp
+koto.shiga.jp
+kusatsu.shiga.jp
+maibara.shiga.jp
+moriyama.shiga.jp
+nagahama.shiga.jp
+nishiazai.shiga.jp
+notogawa.shiga.jp
+omihachiman.shiga.jp
+otsu.shiga.jp
+ritto.shiga.jp
+ryuoh.shiga.jp
+takashima.shiga.jp
+takatsuki.shiga.jp
+torahime.shiga.jp
+toyosato.shiga.jp
+yasu.shiga.jp
+akagi.shimane.jp
+ama.shimane.jp
+gotsu.shimane.jp
+hamada.shimane.jp
+higashiizumo.shimane.jp
+hikawa.shimane.jp
+hikimi.shimane.jp
+izumo.shimane.jp
+kakinoki.shimane.jp
+masuda.shimane.jp
+matsue.shimane.jp
+misato.shimane.jp
+nishinoshima.shimane.jp
+ohda.shimane.jp
+okinoshima.shimane.jp
+okuizumo.shimane.jp
+shimane.shimane.jp
+tamayu.shimane.jp
+tsuwano.shimane.jp
+unnan.shimane.jp
+yakumo.shimane.jp
+yasugi.shimane.jp
+yatsuka.shimane.jp
+arai.shizuoka.jp
+atami.shizuoka.jp
+fuji.shizuoka.jp
+fujieda.shizuoka.jp
+fujikawa.shizuoka.jp
+fujinomiya.shizuoka.jp
+fukuroi.shizuoka.jp
+gotemba.shizuoka.jp
+haibara.shizuoka.jp
+hamamatsu.shizuoka.jp
+higashiizu.shizuoka.jp
+ito.shizuoka.jp
+iwata.shizuoka.jp
+izu.shizuoka.jp
+izunokuni.shizuoka.jp
+kakegawa.shizuoka.jp
+kannami.shizuoka.jp
+kawanehon.shizuoka.jp
+kawazu.shizuoka.jp
+kikugawa.shizuoka.jp
+kosai.shizuoka.jp
+makinohara.shizuoka.jp
+matsuzaki.shizuoka.jp
+minamiizu.shizuoka.jp
+mishima.shizuoka.jp
+morimachi.shizuoka.jp
+nishiizu.shizuoka.jp
+numazu.shizuoka.jp
+omaezaki.shizuoka.jp
+shimada.shizuoka.jp
+shimizu.shizuoka.jp
+shimoda.shizuoka.jp
+shizuoka.shizuoka.jp
+susono.shizuoka.jp
+yaizu.shizuoka.jp
+yoshida.shizuoka.jp
+ashikaga.tochigi.jp
+bato.tochigi.jp
+haga.tochigi.jp
+ichikai.tochigi.jp
+iwafune.tochigi.jp
+kaminokawa.tochigi.jp
+kanuma.tochigi.jp
+karasuyama.tochigi.jp
+kuroiso.tochigi.jp
+mashiko.tochigi.jp
+mibu.tochigi.jp
+moka.tochigi.jp
+motegi.tochigi.jp
+nasu.tochigi.jp
+nasushiobara.tochigi.jp
+nikko.tochigi.jp
+nishikata.tochigi.jp
+nogi.tochigi.jp
+ohira.tochigi.jp
+ohtawara.tochigi.jp
+oyama.tochigi.jp
+sakura.tochigi.jp
+sano.tochigi.jp
+shimotsuke.tochigi.jp
+shioya.tochigi.jp
+takanezawa.tochigi.jp
+tochigi.tochigi.jp
+tsuga.tochigi.jp
+ujiie.tochigi.jp
+utsunomiya.tochigi.jp
+yaita.tochigi.jp
+aizumi.tokushima.jp
+anan.tokushima.jp
+ichiba.tokushima.jp
+itano.tokushima.jp
+kainan.tokushima.jp
+komatsushima.tokushima.jp
+matsushige.tokushima.jp
+mima.tokushima.jp
+minami.tokushima.jp
+miyoshi.tokushima.jp
+mugi.tokushima.jp
+nakagawa.tokushima.jp
+naruto.tokushima.jp
+sanagochi.tokushima.jp
+shishikui.tokushima.jp
+tokushima.tokushima.jp
+wajiki.tokushima.jp
+adachi.tokyo.jp
+akiruno.tokyo.jp
+akishima.tokyo.jp
+aogashima.tokyo.jp
+arakawa.tokyo.jp
+bunkyo.tokyo.jp
+chiyoda.tokyo.jp
+chofu.tokyo.jp
+chuo.tokyo.jp
+edogawa.tokyo.jp
+fuchu.tokyo.jp
+fussa.tokyo.jp
+hachijo.tokyo.jp
+hachioji.tokyo.jp
+hamura.tokyo.jp
+higashikurume.tokyo.jp
+higashimurayama.tokyo.jp
+higashiyamato.tokyo.jp
+hino.tokyo.jp
+hinode.tokyo.jp
+hinohara.tokyo.jp
+inagi.tokyo.jp
+itabashi.tokyo.jp
+katsushika.tokyo.jp
+kita.tokyo.jp
+kiyose.tokyo.jp
+kodaira.tokyo.jp
+koganei.tokyo.jp
+kokubunji.tokyo.jp
+komae.tokyo.jp
+koto.tokyo.jp
+kouzushima.tokyo.jp
+kunitachi.tokyo.jp
+machida.tokyo.jp
+meguro.tokyo.jp
+minato.tokyo.jp
+mitaka.tokyo.jp
+mizuho.tokyo.jp
+musashimurayama.tokyo.jp
+musashino.tokyo.jp
+nakano.tokyo.jp
+nerima.tokyo.jp
+ogasawara.tokyo.jp
+okutama.tokyo.jp
+ome.tokyo.jp
+oshima.tokyo.jp
+ota.tokyo.jp
+setagaya.tokyo.jp
+shibuya.tokyo.jp
+shinagawa.tokyo.jp
+shinjuku.tokyo.jp
+suginami.tokyo.jp
+sumida.tokyo.jp
+tachikawa.tokyo.jp
+taito.tokyo.jp
+tama.tokyo.jp
+toshima.tokyo.jp
+chizu.tottori.jp
+hino.tottori.jp
+kawahara.tottori.jp
+koge.tottori.jp
+kotoura.tottori.jp
+misasa.tottori.jp
+nanbu.tottori.jp
+nichinan.tottori.jp
+sakaiminato.tottori.jp
+tottori.tottori.jp
+wakasa.tottori.jp
+yazu.tottori.jp
+yonago.tottori.jp
+asahi.toyama.jp
+fuchu.toyama.jp
+fukumitsu.toyama.jp
+funahashi.toyama.jp
+himi.toyama.jp
+imizu.toyama.jp
+inami.toyama.jp
+johana.toyama.jp
+kamiichi.toyama.jp
+kurobe.toyama.jp
+nakaniikawa.toyama.jp
+namerikawa.toyama.jp
+nanto.toyama.jp
+nyuzen.toyama.jp
+oyabe.toyama.jp
+taira.toyama.jp
+takaoka.toyama.jp
+tateyama.toyama.jp
+toga.toyama.jp
+tonami.toyama.jp
+toyama.toyama.jp
+unazuki.toyama.jp
+uozu.toyama.jp
+yamada.toyama.jp
+arida.wakayama.jp
+aridagawa.wakayama.jp
+gobo.wakayama.jp
+hashimoto.wakayama.jp
+hidaka.wakayama.jp
+hirogawa.wakayama.jp
+inami.wakayama.jp
+iwade.wakayama.jp
+kainan.wakayama.jp
+kamitonda.wakayama.jp
+katsuragi.wakayama.jp
+kimino.wakayama.jp
+kinokawa.wakayama.jp
+kitayama.wakayama.jp
+koya.wakayama.jp
+koza.wakayama.jp
+kozagawa.wakayama.jp
+kudoyama.wakayama.jp
+kushimoto.wakayama.jp
+mihama.wakayama.jp
+misato.wakayama.jp
+nachikatsuura.wakayama.jp
+shingu.wakayama.jp
+shirahama.wakayama.jp
+taiji.wakayama.jp
+tanabe.wakayama.jp
+wakayama.wakayama.jp
+yuasa.wakayama.jp
+yura.wakayama.jp
+asahi.yamagata.jp
+funagata.yamagata.jp
+higashine.yamagata.jp
+iide.yamagata.jp
+kahoku.yamagata.jp
+kaminoyama.yamagata.jp
+kaneyama.yamagata.jp
+kawanishi.yamagata.jp
+mamurogawa.yamagata.jp
+mikawa.yamagata.jp
+murayama.yamagata.jp
+nagai.yamagata.jp
+nakayama.yamagata.jp
+nanyo.yamagata.jp
+nishikawa.yamagata.jp
+obanazawa.yamagata.jp
+oe.yamagata.jp
+oguni.yamagata.jp
+ohkura.yamagata.jp
+oishida.yamagata.jp
+sagae.yamagata.jp
+sakata.yamagata.jp
+sakegawa.yamagata.jp
+shinjo.yamagata.jp
+shirataka.yamagata.jp
+shonai.yamagata.jp
+takahata.yamagata.jp
+tendo.yamagata.jp
+tozawa.yamagata.jp
+tsuruoka.yamagata.jp
+yamagata.yamagata.jp
+yamanobe.yamagata.jp
+yonezawa.yamagata.jp
+yuza.yamagata.jp
+abu.yamaguchi.jp
+hagi.yamaguchi.jp
+hikari.yamaguchi.jp
+hofu.yamaguchi.jp
+iwakuni.yamaguchi.jp
+kudamatsu.yamaguchi.jp
+mitou.yamaguchi.jp
+nagato.yamaguchi.jp
+oshima.yamaguchi.jp
+shimonoseki.yamaguchi.jp
+shunan.yamaguchi.jp
+tabuse.yamaguchi.jp
+tokuyama.yamaguchi.jp
+toyota.yamaguchi.jp
+ube.yamaguchi.jp
+yuu.yamaguchi.jp
+chuo.yamanashi.jp
+doshi.yamanashi.jp
+fuefuki.yamanashi.jp
+fujikawa.yamanashi.jp
+fujikawaguchiko.yamanashi.jp
+fujiyoshida.yamanashi.jp
+hayakawa.yamanashi.jp
+hokuto.yamanashi.jp
+ichikawamisato.yamanashi.jp
+kai.yamanashi.jp
+kofu.yamanashi.jp
+koshu.yamanashi.jp
+kosuge.yamanashi.jp
+minami-alps.yamanashi.jp
+minobu.yamanashi.jp
+nakamichi.yamanashi.jp
+nanbu.yamanashi.jp
+narusawa.yamanashi.jp
+nirasaki.yamanashi.jp
+nishikatsura.yamanashi.jp
+oshino.yamanashi.jp
+otsuki.yamanashi.jp
+showa.yamanashi.jp
+tabayama.yamanashi.jp
+tsuru.yamanashi.jp
+uenohara.yamanashi.jp
+yamanakako.yamanashi.jp
+yamanashi.yamanashi.jp
+
+// ke : http://www.kenic.or.ke/index.php?option=com_content&task=view&id=117&Itemid=145
+*.ke
+
+// kg : http://www.domain.kg/dmn_n.html
+kg
+org.kg
+net.kg
+com.kg
+edu.kg
+gov.kg
+mil.kg
+
+// kh : http://www.mptc.gov.kh/dns_registration.htm
+*.kh
+
+// ki : http://www.ki/dns/index.html
+ki
+edu.ki
+biz.ki
+net.ki
+org.ki
+gov.ki
+info.ki
+com.ki
+
+// km : http://en.wikipedia.org/wiki/.km
+// http://www.domaine.km/documents/charte.doc
+km
+org.km
+nom.km
+gov.km
+prd.km
+tm.km
+edu.km
+mil.km
+ass.km
+com.km
+// These are only mentioned as proposed suggestions at domaine.km, but
+// http://en.wikipedia.org/wiki/.km says they're available for registration:
+coop.km
+asso.km
+presse.km
+medecin.km
+notaires.km
+pharmaciens.km
+veterinaire.km
+gouv.km
+
+// kn : http://en.wikipedia.org/wiki/.kn
+// http://www.dot.kn/domainRules.html
+kn
+net.kn
+org.kn
+edu.kn
+gov.kn
+
+// kp : http://www.kcce.kp/en_index.php
+kp
+com.kp
+edu.kp
+gov.kp
+org.kp
+rep.kp
+tra.kp
+
+// kr : http://en.wikipedia.org/wiki/.kr
+// see also: http://domain.nida.or.kr/eng/registration.jsp
+kr
+ac.kr
+co.kr
+es.kr
+go.kr
+hs.kr
+kg.kr
+mil.kr
+ms.kr
+ne.kr
+or.kr
+pe.kr
+re.kr
+sc.kr
+// kr geographical names
+busan.kr
+chungbuk.kr
+chungnam.kr
+daegu.kr
+daejeon.kr
+gangwon.kr
+gwangju.kr
+gyeongbuk.kr
+gyeonggi.kr
+gyeongnam.kr
+incheon.kr
+jeju.kr
+jeonbuk.kr
+jeonnam.kr
+seoul.kr
+ulsan.kr
+
+// kw : http://en.wikipedia.org/wiki/.kw
+*.kw
+
+// ky : http://www.icta.ky/da_ky_reg_dom.php
+// Confirmed by registry <kysupport@perimeterusa.com> 2008-06-17
+ky
+edu.ky
+gov.ky
+com.ky
+org.ky
+net.ky
+
+// kz : http://en.wikipedia.org/wiki/.kz
+// see also: http://www.nic.kz/rules/index.jsp
+kz
+org.kz
+edu.kz
+net.kz
+gov.kz
+mil.kz
+com.kz
+
+// la : http://en.wikipedia.org/wiki/.la
+// Submitted by registry <gavin.brown@nic.la> 2008-06-10
+la
+int.la
+net.la
+info.la
+edu.la
+gov.la
+per.la
+com.la
+org.la
+
+// lb : http://en.wikipedia.org/wiki/.lb
+// Submitted by registry <randy@psg.com> 2008-06-17
+lb
+com.lb
+edu.lb
+gov.lb
+net.lb
+org.lb
+
+// lc : http://en.wikipedia.org/wiki/.lc
+// see also: http://www.nic.lc/rules.htm
+lc
+com.lc
+net.lc
+co.lc
+org.lc
+edu.lc
+gov.lc
+
+// li : http://en.wikipedia.org/wiki/.li
+li
+
+// lk : http://www.nic.lk/seclevpr.html
+lk
+gov.lk
+sch.lk
+net.lk
+int.lk
+com.lk
+org.lk
+edu.lk
+ngo.lk
+soc.lk
+web.lk
+ltd.lk
+assn.lk
+grp.lk
+hotel.lk
+
+// lr : http://psg.com/dns/lr/lr.txt
+// Submitted by registry <randy@psg.com> 2008-06-17
+lr
+com.lr
+edu.lr
+gov.lr
+org.lr
+net.lr
+
+// ls : http://en.wikipedia.org/wiki/.ls
+ls
+co.ls
+org.ls
+
+// lt : http://en.wikipedia.org/wiki/.lt
+lt
+// gov.lt : http://www.gov.lt/index_en.php
+gov.lt
+
+// lu : http://www.dns.lu/en/
+lu
+
+// lv : http://www.nic.lv/DNS/En/generic.php
+lv
+com.lv
+edu.lv
+gov.lv
+org.lv
+mil.lv
+id.lv
+net.lv
+asn.lv
+conf.lv
+
+// ly : http://www.nic.ly/regulations.php
+ly
+com.ly
+net.ly
+gov.ly
+plc.ly
+edu.ly
+sch.ly
+med.ly
+org.ly
+id.ly
+
+// ma : http://en.wikipedia.org/wiki/.ma
+// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf
+ma
+co.ma
+net.ma
+gov.ma
+org.ma
+ac.ma
+press.ma
+
+// mc : http://www.nic.mc/
+mc
+tm.mc
+asso.mc
+
+// md : http://en.wikipedia.org/wiki/.md
+md
+
+// me : http://en.wikipedia.org/wiki/.me
+me
+co.me
+net.me
+org.me
+edu.me
+ac.me
+gov.me
+its.me
+priv.me
+
+// mg : http://www.nic.mg/tarif.htm
+mg
+org.mg
+nom.mg
+gov.mg
+prd.mg
+tm.mg
+edu.mg
+mil.mg
+com.mg
+
+// mh : http://en.wikipedia.org/wiki/.mh
+mh
+
+// mil : http://en.wikipedia.org/wiki/.mil
+mil
+
+// mk : http://en.wikipedia.org/wiki/.mk
+// see also: http://dns.marnet.net.mk/postapka.php
+mk
+com.mk
+org.mk
+net.mk
+edu.mk
+gov.mk
+inf.mk
+name.mk
+
+// ml : http://www.gobin.info/domainname/ml-template.doc
+// see also: http://en.wikipedia.org/wiki/.ml
+ml
+com.ml
+edu.ml
+gouv.ml
+gov.ml
+net.ml
+org.ml
+presse.ml
+
+// mm : http://en.wikipedia.org/wiki/.mm
+*.mm
+
+// mn : http://en.wikipedia.org/wiki/.mn
+mn
+gov.mn
+edu.mn
+org.mn
+
+// mo : http://www.monic.net.mo/
+mo
+com.mo
+net.mo
+org.mo
+edu.mo
+gov.mo
+
+// mobi : http://en.wikipedia.org/wiki/.mobi
+mobi
+
+// mp : http://www.dot.mp/
+// Confirmed by registry <dcamacho@saipan.com> 2008-06-17
+mp
+
+// mq : http://en.wikipedia.org/wiki/.mq
+mq
+
+// mr : http://en.wikipedia.org/wiki/.mr
+mr
+gov.mr
+
+// ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf
+ms
+com.ms
+edu.ms
+gov.ms
+net.ms
+org.ms
+
+// mt : https://www.nic.org.mt/go/policy
+// Submitted by registry <help@nic.org.mt> 2013-11-19
+mt
+com.mt
+edu.mt
+net.mt
+org.mt
+
+// mu : http://en.wikipedia.org/wiki/.mu
+mu
+com.mu
+net.mu
+org.mu
+gov.mu
+ac.mu
+co.mu
+or.mu
+
+// museum : http://about.museum/naming/
+// http://index.museum/
+museum
+academy.museum
+agriculture.museum
+air.museum
+airguard.museum
+alabama.museum
+alaska.museum
+amber.museum
+ambulance.museum
+american.museum
+americana.museum
+americanantiques.museum
+americanart.museum
+amsterdam.museum
+and.museum
+annefrank.museum
+anthro.museum
+anthropology.museum
+antiques.museum
+aquarium.museum
+arboretum.museum
+archaeological.museum
+archaeology.museum
+architecture.museum
+art.museum
+artanddesign.museum
+artcenter.museum
+artdeco.museum
+arteducation.museum
+artgallery.museum
+arts.museum
+artsandcrafts.museum
+asmatart.museum
+assassination.museum
+assisi.museum
+association.museum
+astronomy.museum
+atlanta.museum
+austin.museum
+australia.museum
+automotive.museum
+aviation.museum
+axis.museum
+badajoz.museum
+baghdad.museum
+bahn.museum
+bale.museum
+baltimore.museum
+barcelona.museum
+baseball.museum
+basel.museum
+baths.museum
+bauern.museum
+beauxarts.museum
+beeldengeluid.museum
+bellevue.museum
+bergbau.museum
+berkeley.museum
+berlin.museum
+bern.museum
+bible.museum
+bilbao.museum
+bill.museum
+birdart.museum
+birthplace.museum
+bonn.museum
+boston.museum
+botanical.museum
+botanicalgarden.museum
+botanicgarden.museum
+botany.museum
+brandywinevalley.museum
+brasil.museum
+bristol.museum
+british.museum
+britishcolumbia.museum
+broadcast.museum
+brunel.museum
+brussel.museum
+brussels.museum
+bruxelles.museum
+building.museum
+burghof.museum
+bus.museum
+bushey.museum
+cadaques.museum
+california.museum
+cambridge.museum
+can.museum
+canada.museum
+capebreton.museum
+carrier.museum
+cartoonart.museum
+casadelamoneda.museum
+castle.museum
+castres.museum
+celtic.museum
+center.museum
+chattanooga.museum
+cheltenham.museum
+chesapeakebay.museum
+chicago.museum
+children.museum
+childrens.museum
+childrensgarden.museum
+chiropractic.museum
+chocolate.museum
+christiansburg.museum
+cincinnati.museum
+cinema.museum
+circus.museum
+civilisation.museum
+civilization.museum
+civilwar.museum
+clinton.museum
+clock.museum
+coal.museum
+coastaldefence.museum
+cody.museum
+coldwar.museum
+collection.museum
+colonialwilliamsburg.museum
+coloradoplateau.museum
+columbia.museum
+columbus.museum
+communication.museum
+communications.museum
+community.museum
+computer.museum
+computerhistory.museum
+comunicações.museum
+xn--comunicaes-v6a2o.museum
+contemporary.museum
+contemporaryart.museum
+convent.museum
+copenhagen.museum
+corporation.museum
+correios-e-telecomunicações.museum
+xn--correios-e-telecomunicaes-ghc29a.museum
+corvette.museum
+costume.museum
+countryestate.museum
+county.museum
+crafts.museum
+cranbrook.museum
+creation.museum
+cultural.museum
+culturalcenter.museum
+culture.museum
+cyber.museum
+cymru.museum
+dali.museum
+dallas.museum
+database.museum
+ddr.museum
+decorativearts.museum
+delaware.museum
+delmenhorst.museum
+denmark.museum
+depot.museum
+design.museum
+detroit.museum
+dinosaur.museum
+discovery.museum
+dolls.museum
+donostia.museum
+durham.museum
+eastafrica.museum
+eastcoast.museum
+education.museum
+educational.museum
+egyptian.museum
+eisenbahn.museum
+elburg.museum
+elvendrell.museum
+embroidery.museum
+encyclopedic.museum
+england.museum
+entomology.museum
+environment.museum
+environmentalconservation.museum
+epilepsy.museum
+essex.museum
+estate.museum
+ethnology.museum
+exeter.museum
+exhibition.museum
+family.museum
+farm.museum
+farmequipment.museum
+farmers.museum
+farmstead.museum
+field.museum
+figueres.museum
+filatelia.museum
+film.museum
+fineart.museum
+finearts.museum
+finland.museum
+flanders.museum
+florida.museum
+force.museum
+fortmissoula.museum
+fortworth.museum
+foundation.museum
+francaise.museum
+frankfurt.museum
+franziskaner.museum
+freemasonry.museum
+freiburg.museum
+fribourg.museum
+frog.museum
+fundacio.museum
+furniture.museum
+gallery.museum
+garden.museum
+gateway.museum
+geelvinck.museum
+gemological.museum
+geology.museum
+georgia.museum
+giessen.museum
+glas.museum
+glass.museum
+gorge.museum
+grandrapids.museum
+graz.museum
+guernsey.museum
+halloffame.museum
+hamburg.museum
+handson.museum
+harvestcelebration.museum
+hawaii.museum
+health.museum
+heimatunduhren.museum
+hellas.museum
+helsinki.museum
+hembygdsforbund.museum
+heritage.museum
+histoire.museum
+historical.museum
+historicalsociety.museum
+historichouses.museum
+historisch.museum
+historisches.museum
+history.museum
+historyofscience.museum
+horology.museum
+house.museum
+humanities.museum
+illustration.museum
+imageandsound.museum
+indian.museum
+indiana.museum
+indianapolis.museum
+indianmarket.museum
+intelligence.museum
+interactive.museum
+iraq.museum
+iron.museum
+isleofman.museum
+jamison.museum
+jefferson.museum
+jerusalem.museum
+jewelry.museum
+jewish.museum
+jewishart.museum
+jfk.museum
+journalism.museum
+judaica.museum
+judygarland.museum
+juedisches.museum
+juif.museum
+karate.museum
+karikatur.museum
+kids.museum
+koebenhavn.museum
+koeln.museum
+kunst.museum
+kunstsammlung.museum
+kunstunddesign.museum
+labor.museum
+labour.museum
+lajolla.museum
+lancashire.museum
+landes.museum
+lans.museum
+läns.museum
+xn--lns-qla.museum
+larsson.museum
+lewismiller.museum
+lincoln.museum
+linz.museum
+living.museum
+livinghistory.museum
+localhistory.museum
+london.museum
+losangeles.museum
+louvre.museum
+loyalist.museum
+lucerne.museum
+luxembourg.museum
+luzern.museum
+mad.museum
+madrid.museum
+mallorca.museum
+manchester.museum
+mansion.museum
+mansions.museum
+manx.museum
+marburg.museum
+maritime.museum
+maritimo.museum
+maryland.museum
+marylhurst.museum
+media.museum
+medical.museum
+medizinhistorisches.museum
+meeres.museum
+memorial.museum
+mesaverde.museum
+michigan.museum
+midatlantic.museum
+military.museum
+mill.museum
+miners.museum
+mining.museum
+minnesota.museum
+missile.museum
+missoula.museum
+modern.museum
+moma.museum
+money.museum
+monmouth.museum
+monticello.museum
+montreal.museum
+moscow.museum
+motorcycle.museum
+muenchen.museum
+muenster.museum
+mulhouse.museum
+muncie.museum
+museet.museum
+museumcenter.museum
+museumvereniging.museum
+music.museum
+national.museum
+nationalfirearms.museum
+nationalheritage.museum
+nativeamerican.museum
+naturalhistory.museum
+naturalhistorymuseum.museum
+naturalsciences.museum
+nature.museum
+naturhistorisches.museum
+natuurwetenschappen.museum
+naumburg.museum
+naval.museum
+nebraska.museum
+neues.museum
+newhampshire.museum
+newjersey.museum
+newmexico.museum
+newport.museum
+newspaper.museum
+newyork.museum
+niepce.museum
+norfolk.museum
+north.museum
+nrw.museum
+nuernberg.museum
+nuremberg.museum
+nyc.museum
+nyny.museum
+oceanographic.museum
+oceanographique.museum
+omaha.museum
+online.museum
+ontario.museum
+openair.museum
+oregon.museum
+oregontrail.museum
+otago.museum
+oxford.museum
+pacific.museum
+paderborn.museum
+palace.museum
+paleo.museum
+palmsprings.museum
+panama.museum
+paris.museum
+pasadena.museum
+pharmacy.museum
+philadelphia.museum
+philadelphiaarea.museum
+philately.museum
+phoenix.museum
+photography.museum
+pilots.museum
+pittsburgh.museum
+planetarium.museum
+plantation.museum
+plants.museum
+plaza.museum
+portal.museum
+portland.museum
+portlligat.museum
+posts-and-telecommunications.museum
+preservation.museum
+presidio.museum
+press.museum
+project.museum
+public.museum
+pubol.museum
+quebec.museum
+railroad.museum
+railway.museum
+research.museum
+resistance.museum
+riodejaneiro.museum
+rochester.museum
+rockart.museum
+roma.museum
+russia.museum
+saintlouis.museum
+salem.museum
+salvadordali.museum
+salzburg.museum
+sandiego.museum
+sanfrancisco.museum
+santabarbara.museum
+santacruz.museum
+santafe.museum
+saskatchewan.museum
+satx.museum
+savannahga.museum
+schlesisches.museum
+schoenbrunn.museum
+schokoladen.museum
+school.museum
+schweiz.museum
+science.museum
+scienceandhistory.museum
+scienceandindustry.museum
+sciencecenter.museum
+sciencecenters.museum
+science-fiction.museum
+sciencehistory.museum
+sciences.museum
+sciencesnaturelles.museum
+scotland.museum
+seaport.museum
+settlement.museum
+settlers.museum
+shell.museum
+sherbrooke.museum
+sibenik.museum
+silk.museum
+ski.museum
+skole.museum
+society.museum
+sologne.museum
+soundandvision.museum
+southcarolina.museum
+southwest.museum
+space.museum
+spy.museum
+square.museum
+stadt.museum
+stalbans.museum
+starnberg.museum
+state.museum
+stateofdelaware.museum
+station.museum
+steam.museum
+steiermark.museum
+stjohn.museum
+stockholm.museum
+stpetersburg.museum
+stuttgart.museum
+suisse.museum
+surgeonshall.museum
+surrey.museum
+svizzera.museum
+sweden.museum
+sydney.museum
+tank.museum
+tcm.museum
+technology.museum
+telekommunikation.museum
+television.museum
+texas.museum
+textile.museum
+theater.museum
+time.museum
+timekeeping.museum
+topology.museum
+torino.museum
+touch.museum
+town.museum
+transport.museum
+tree.museum
+trolley.museum
+trust.museum
+trustee.museum
+uhren.museum
+ulm.museum
+undersea.museum
+university.museum
+usa.museum
+usantiques.museum
+usarts.museum
+uscountryestate.museum
+usculture.museum
+usdecorativearts.museum
+usgarden.museum
+ushistory.museum
+ushuaia.museum
+uslivinghistory.museum
+utah.museum
+uvic.museum
+valley.museum
+vantaa.museum
+versailles.museum
+viking.museum
+village.museum
+virginia.museum
+virtual.museum
+virtuel.museum
+vlaanderen.museum
+volkenkunde.museum
+wales.museum
+wallonie.museum
+war.museum
+washingtondc.museum
+watchandclock.museum
+watch-and-clock.museum
+western.museum
+westfalen.museum
+whaling.museum
+wildlife.museum
+williamsburg.museum
+windmill.museum
+workshop.museum
+york.museum
+yorkshire.museum
+yosemite.museum
+youth.museum
+zoological.museum
+zoology.museum
+ירושלים.museum
+xn--9dbhblg6di.museum
+иком.museum
+xn--h1aegh.museum
+
+// mv : http://en.wikipedia.org/wiki/.mv
+// "mv" included because, contra Wikipedia, google.mv exists.
+mv
+aero.mv
+biz.mv
+com.mv
+coop.mv
+edu.mv
+gov.mv
+info.mv
+int.mv
+mil.mv
+museum.mv
+name.mv
+net.mv
+org.mv
+pro.mv
+
+// mw : http://www.registrar.mw/
+mw
+ac.mw
+biz.mw
+co.mw
+com.mw
+coop.mw
+edu.mw
+gov.mw
+int.mw
+museum.mw
+net.mw
+org.mw
+
+// mx : http://www.nic.mx/
+// Submitted by registry <farias@nic.mx> 2008-06-19
+mx
+com.mx
+org.mx
+gob.mx
+edu.mx
+net.mx
+
+// my : http://www.mynic.net.my/
+my
+com.my
+net.my
+org.my
+gov.my
+edu.my
+mil.my
+name.my
+
+// mz : http://www.gobin.info/domainname/mz-template.doc
+*.mz
+!teledata.mz
+
+// na : http://www.na-nic.com.na/
+// http://www.info.na/domain/
+na
+info.na
+pro.na
+name.na
+school.na
+or.na
+dr.na
+us.na
+mx.na
+ca.na
+in.na
+cc.na
+tv.na
+ws.na
+mobi.na
+co.na
+com.na
+org.na
+
+// name : has 2nd-level tlds, but there's no list of them
+name
+
+// nc : http://www.cctld.nc/
+nc
+asso.nc
+
+// ne : http://en.wikipedia.org/wiki/.ne
+ne
+
+// net : http://en.wikipedia.org/wiki/.net
+net
+
+// nf : http://en.wikipedia.org/wiki/.nf
+nf
+com.nf
+net.nf
+per.nf
+rec.nf
+web.nf
+arts.nf
+firm.nf
+info.nf
+other.nf
+store.nf
+
+// ng : http://psg.com/dns/ng/
+ng
+com.ng
+edu.ng
+name.ng
+net.ng
+org.ng
+sch.ng
+gov.ng
+mil.ng
+mobi.ng
+
+// ni : http://www.nic.ni/dominios.htm
+*.ni
+
+// nl : http://www.domain-registry.nl/ace.php/c,728,122,,,,Home.html
+// Confirmed by registry <Antoin.Verschuren@sidn.nl> (with technical
+// reservations) 2008-06-08
+nl
+
+// BV.nl will be a registry for dutch BV's (besloten vennootschap)
+bv.nl
+
+// no : http://www.norid.no/regelverk/index.en.html
+// The Norwegian registry has declined to notify us of updates. The web pages
+// referenced below are the official source of the data. There is also an
+// announce mailing list:
+// https://postlister.uninett.no/sympa/info/norid-diskusjon
+no
+// Norid generic domains : http://www.norid.no/regelverk/vedlegg-c.en.html
+fhs.no
+vgs.no
+fylkesbibl.no
+folkebibl.no
+museum.no
+idrett.no
+priv.no
+// Non-Norid generic domains : http://www.norid.no/regelverk/vedlegg-d.en.html
+mil.no
+stat.no
+dep.no
+kommune.no
+herad.no
+// no geographical names : http://www.norid.no/regelverk/vedlegg-b.en.html
+// counties
+aa.no
+ah.no
+bu.no
+fm.no
+hl.no
+hm.no
+jan-mayen.no
+mr.no
+nl.no
+nt.no
+of.no
+ol.no
+oslo.no
+rl.no
+sf.no
+st.no
+svalbard.no
+tm.no
+tr.no
+va.no
+vf.no
+// primary and lower secondary schools per county
+gs.aa.no
+gs.ah.no
+gs.bu.no
+gs.fm.no
+gs.hl.no
+gs.hm.no
+gs.jan-mayen.no
+gs.mr.no
+gs.nl.no
+gs.nt.no
+gs.of.no
+gs.ol.no
+gs.oslo.no
+gs.rl.no
+gs.sf.no
+gs.st.no
+gs.svalbard.no
+gs.tm.no
+gs.tr.no
+gs.va.no
+gs.vf.no
+// cities
+akrehamn.no
+åkrehamn.no
+xn--krehamn-dxa.no
+algard.no
+ålgård.no
+xn--lgrd-poac.no
+arna.no
+brumunddal.no
+bryne.no
+bronnoysund.no
+brønnøysund.no
+xn--brnnysund-m8ac.no
+drobak.no
+drøbak.no
+xn--drbak-wua.no
+egersund.no
+fetsund.no
+floro.no
+florø.no
+xn--flor-jra.no
+fredrikstad.no
+hokksund.no
+honefoss.no
+hønefoss.no
+xn--hnefoss-q1a.no
+jessheim.no
+jorpeland.no
+jørpeland.no
+xn--jrpeland-54a.no
+kirkenes.no
+kopervik.no
+krokstadelva.no
+langevag.no
+langevåg.no
+xn--langevg-jxa.no
+leirvik.no
+mjondalen.no
+mjøndalen.no
+xn--mjndalen-64a.no
+mo-i-rana.no
+mosjoen.no
+mosjøen.no
+xn--mosjen-eya.no
+nesoddtangen.no
+orkanger.no
+osoyro.no
+osøyro.no
+xn--osyro-wua.no
+raholt.no
+råholt.no
+xn--rholt-mra.no
+sandnessjoen.no
+sandnessjøen.no
+xn--sandnessjen-ogb.no
+skedsmokorset.no
+slattum.no
+spjelkavik.no
+stathelle.no
+stavern.no
+stjordalshalsen.no
+stjørdalshalsen.no
+xn--stjrdalshalsen-sqb.no
+tananger.no
+tranby.no
+vossevangen.no
+// communities
+afjord.no
+åfjord.no
+xn--fjord-lra.no
+agdenes.no
+al.no
+ål.no
+xn--l-1fa.no
+alesund.no
+ålesund.no
+xn--lesund-hua.no
+alstahaug.no
+alta.no
+áltá.no
+xn--lt-liac.no
+alaheadju.no
+álaheadju.no
+xn--laheadju-7ya.no
+alvdal.no
+amli.no
+åmli.no
+xn--mli-tla.no
+amot.no
+åmot.no
+xn--mot-tla.no
+andebu.no
+andoy.no
+andøy.no
+xn--andy-ira.no
+andasuolo.no
+ardal.no
+årdal.no
+xn--rdal-poa.no
+aremark.no
+arendal.no
+ås.no
+xn--s-1fa.no
+aseral.no
+åseral.no
+xn--seral-lra.no
+asker.no
+askim.no
+askvoll.no
+askoy.no
+askøy.no
+xn--asky-ira.no
+asnes.no
+åsnes.no
+xn--snes-poa.no
+audnedaln.no
+aukra.no
+aure.no
+aurland.no
+aurskog-holand.no
+aurskog-høland.no
+xn--aurskog-hland-jnb.no
+austevoll.no
+austrheim.no
+averoy.no
+averøy.no
+xn--avery-yua.no
+balestrand.no
+ballangen.no
+balat.no
+bálát.no
+xn--blt-elab.no
+balsfjord.no
+bahccavuotna.no
+báhccavuotna.no
+xn--bhccavuotna-k7a.no
+bamble.no
+bardu.no
+beardu.no
+beiarn.no
+bajddar.no
+bájddar.no
+xn--bjddar-pta.no
+baidar.no
+báidár.no
+xn--bidr-5nac.no
+berg.no
+bergen.no
+berlevag.no
+berlevåg.no
+xn--berlevg-jxa.no
+bearalvahki.no
+bearalváhki.no
+xn--bearalvhki-y4a.no
+bindal.no
+birkenes.no
+bjarkoy.no
+bjarkøy.no
+xn--bjarky-fya.no
+bjerkreim.no
+bjugn.no
+bodo.no
+bodø.no
+xn--bod-2na.no
+badaddja.no
+bådåddjå.no
+xn--bdddj-mrabd.no
+budejju.no
+bokn.no
+bremanger.no
+bronnoy.no
+brønnøy.no
+xn--brnny-wuac.no
+bygland.no
+bykle.no
+barum.no
+bærum.no
+xn--brum-voa.no
+bo.telemark.no
+bø.telemark.no
+xn--b-5ga.telemark.no
+bo.nordland.no
+bø.nordland.no
+xn--b-5ga.nordland.no
+bievat.no
+bievát.no
+xn--bievt-0qa.no
+bomlo.no
+bømlo.no
+xn--bmlo-gra.no
+batsfjord.no
+båtsfjord.no
+xn--btsfjord-9za.no
+bahcavuotna.no
+báhcavuotna.no
+xn--bhcavuotna-s4a.no
+dovre.no
+drammen.no
+drangedal.no
+dyroy.no
+dyrøy.no
+xn--dyry-ira.no
+donna.no
+dønna.no
+xn--dnna-gra.no
+eid.no
+eidfjord.no
+eidsberg.no
+eidskog.no
+eidsvoll.no
+eigersund.no
+elverum.no
+enebakk.no
+engerdal.no
+etne.no
+etnedal.no
+evenes.no
+evenassi.no
+evenášši.no
+xn--eveni-0qa01ga.no
+evje-og-hornnes.no
+farsund.no
+fauske.no
+fuossko.no
+fuoisku.no
+fedje.no
+fet.no
+finnoy.no
+finnøy.no
+xn--finny-yua.no
+fitjar.no
+fjaler.no
+fjell.no
+flakstad.no
+flatanger.no
+flekkefjord.no
+flesberg.no
+flora.no
+fla.no
+flå.no
+xn--fl-zia.no
+folldal.no
+forsand.no
+fosnes.no
+frei.no
+frogn.no
+froland.no
+frosta.no
+frana.no
+fræna.no
+xn--frna-woa.no
+froya.no
+frøya.no
+xn--frya-hra.no
+fusa.no
+fyresdal.no
+forde.no
+førde.no
+xn--frde-gra.no
+gamvik.no
+gangaviika.no
+gáŋgaviika.no
+xn--ggaviika-8ya47h.no
+gaular.no
+gausdal.no
+gildeskal.no
+gildeskål.no
+xn--gildeskl-g0a.no
+giske.no
+gjemnes.no
+gjerdrum.no
+gjerstad.no
+gjesdal.no
+gjovik.no
+gjøvik.no
+xn--gjvik-wua.no
+gloppen.no
+gol.no
+gran.no
+grane.no
+granvin.no
+gratangen.no
+grimstad.no
+grong.no
+kraanghke.no
+kråanghke.no
+xn--kranghke-b0a.no
+grue.no
+gulen.no
+hadsel.no
+halden.no
+halsa.no
+hamar.no
+hamaroy.no
+habmer.no
+hábmer.no
+xn--hbmer-xqa.no
+hapmir.no
+hápmir.no
+xn--hpmir-xqa.no
+hammerfest.no
+hammarfeasta.no
+hámmárfeasta.no
+xn--hmmrfeasta-s4ac.no
+haram.no
+hareid.no
+harstad.no
+hasvik.no
+aknoluokta.no
+ákŋoluokta.no
+xn--koluokta-7ya57h.no
+hattfjelldal.no
+aarborte.no
+haugesund.no
+hemne.no
+hemnes.no
+hemsedal.no
+heroy.more-og-romsdal.no
+herøy.møre-og-romsdal.no
+xn--hery-ira.xn--mre-og-romsdal-qqb.no
+heroy.nordland.no
+herøy.nordland.no
+xn--hery-ira.nordland.no
+hitra.no
+hjartdal.no
+hjelmeland.no
+hobol.no
+hobøl.no
+xn--hobl-ira.no
+hof.no
+hol.no
+hole.no
+holmestrand.no
+holtalen.no
+holtålen.no
+xn--holtlen-hxa.no
+hornindal.no
+horten.no
+hurdal.no
+hurum.no
+hvaler.no
+hyllestad.no
+hagebostad.no
+hægebostad.no
+xn--hgebostad-g3a.no
+hoyanger.no
+høyanger.no
+xn--hyanger-q1a.no
+hoylandet.no
+høylandet.no
+xn--hylandet-54a.no
+ha.no
+hå.no
+xn--h-2fa.no
+ibestad.no
+inderoy.no
+inderøy.no
+xn--indery-fya.no
+iveland.no
+jevnaker.no
+jondal.no
+jolster.no
+jølster.no
+xn--jlster-bya.no
+karasjok.no
+karasjohka.no
+kárášjohka.no
+xn--krjohka-hwab49j.no
+karlsoy.no
+galsa.no
+gálsá.no
+xn--gls-elac.no
+karmoy.no
+karmøy.no
+xn--karmy-yua.no
+kautokeino.no
+guovdageaidnu.no
+klepp.no
+klabu.no
+klæbu.no
+xn--klbu-woa.no
+kongsberg.no
+kongsvinger.no
+kragero.no
+kragerø.no
+xn--krager-gya.no
+kristiansand.no
+kristiansund.no
+krodsherad.no
+krødsherad.no
+xn--krdsherad-m8a.no
+kvalsund.no
+rahkkeravju.no
+ráhkkerávju.no
+xn--rhkkervju-01af.no
+kvam.no
+kvinesdal.no
+kvinnherad.no
+kviteseid.no
+kvitsoy.no
+kvitsøy.no
+xn--kvitsy-fya.no
+kvafjord.no
+kvæfjord.no
+xn--kvfjord-nxa.no
+giehtavuoatna.no
+kvanangen.no
+kvænangen.no
+xn--kvnangen-k0a.no
+navuotna.no
+návuotna.no
+xn--nvuotna-hwa.no
+kafjord.no
+kåfjord.no
+xn--kfjord-iua.no
+gaivuotna.no
+gáivuotna.no
+xn--givuotna-8ya.no
+larvik.no
+lavangen.no
+lavagis.no
+loabat.no
+loabát.no
+xn--loabt-0qa.no
+lebesby.no
+davvesiida.no
+leikanger.no
+leirfjord.no
+leka.no
+leksvik.no
+lenvik.no
+leangaviika.no
+leaŋgaviika.no
+xn--leagaviika-52b.no
+lesja.no
+levanger.no
+lier.no
+lierne.no
+lillehammer.no
+lillesand.no
+lindesnes.no
+lindas.no
+lindås.no
+xn--linds-pra.no
+lom.no
+loppa.no
+lahppi.no
+láhppi.no
+xn--lhppi-xqa.no
+lund.no
+lunner.no
+luroy.no
+lurøy.no
+xn--lury-ira.no
+luster.no
+lyngdal.no
+lyngen.no
+ivgu.no
+lardal.no
+lerdal.no
+lærdal.no
+xn--lrdal-sra.no
+lodingen.no
+lødingen.no
+xn--ldingen-q1a.no
+lorenskog.no
+lørenskog.no
+xn--lrenskog-54a.no
+loten.no
+løten.no
+xn--lten-gra.no
+malvik.no
+masoy.no
+måsøy.no
+xn--msy-ula0h.no
+muosat.no
+muosát.no
+xn--muost-0qa.no
+mandal.no
+marker.no
+marnardal.no
+masfjorden.no
+meland.no
+meldal.no
+melhus.no
+meloy.no
+meløy.no
+xn--mely-ira.no
+meraker.no
+meråker.no
+xn--merker-kua.no
+moareke.no
+moåreke.no
+xn--moreke-jua.no
+midsund.no
+midtre-gauldal.no
+modalen.no
+modum.no
+molde.no
+moskenes.no
+moss.no
+mosvik.no
+malselv.no
+målselv.no
+xn--mlselv-iua.no
+malatvuopmi.no
+málatvuopmi.no
+xn--mlatvuopmi-s4a.no
+namdalseid.no
+aejrie.no
+namsos.no
+namsskogan.no
+naamesjevuemie.no
+nååmesjevuemie.no
+xn--nmesjevuemie-tcba.no
+laakesvuemie.no
+nannestad.no
+narvik.no
+narviika.no
+naustdal.no
+nedre-eiker.no
+nes.akershus.no
+nes.buskerud.no
+nesna.no
+nesodden.no
+nesseby.no
+unjarga.no
+unjárga.no
+xn--unjrga-rta.no
+nesset.no
+nissedal.no
+nittedal.no
+nord-aurdal.no
+nord-fron.no
+nord-odal.no
+norddal.no
+nordkapp.no
+davvenjarga.no
+davvenjárga.no
+xn--davvenjrga-y4a.no
+nordre-land.no
+nordreisa.no
+raisa.no
+ráisa.no
+xn--risa-5na.no
+nore-og-uvdal.no
+notodden.no
+naroy.no
+nærøy.no
+xn--nry-yla5g.no
+notteroy.no
+nøtterøy.no
+xn--nttery-byae.no
+odda.no
+oksnes.no
+øksnes.no
+xn--ksnes-uua.no
+oppdal.no
+oppegard.no
+oppegård.no
+xn--oppegrd-ixa.no
+orkdal.no
+orland.no
+ørland.no
+xn--rland-uua.no
+orskog.no
+ørskog.no
+xn--rskog-uua.no
+orsta.no
+ørsta.no
+xn--rsta-fra.no
+os.hedmark.no
+os.hordaland.no
+osen.no
+osteroy.no
+osterøy.no
+xn--ostery-fya.no
+ostre-toten.no
+østre-toten.no
+xn--stre-toten-zcb.no
+overhalla.no
+ovre-eiker.no
+øvre-eiker.no
+xn--vre-eiker-k8a.no
+oyer.no
+øyer.no
+xn--yer-zna.no
+oygarden.no
+øygarden.no
+xn--ygarden-p1a.no
+oystre-slidre.no
+øystre-slidre.no
+xn--ystre-slidre-ujb.no
+porsanger.no
+porsangu.no
+porsáŋgu.no
+xn--porsgu-sta26f.no
+porsgrunn.no
+radoy.no
+radøy.no
+xn--rady-ira.no
+rakkestad.no
+rana.no
+ruovat.no
+randaberg.no
+rauma.no
+rendalen.no
+rennebu.no
+rennesoy.no
+rennesøy.no
+xn--rennesy-v1a.no
+rindal.no
+ringebu.no
+ringerike.no
+ringsaker.no
+rissa.no
+risor.no
+risør.no
+xn--risr-ira.no
+roan.no
+rollag.no
+rygge.no
+ralingen.no
+rælingen.no
+xn--rlingen-mxa.no
+rodoy.no
+rødøy.no
+xn--rdy-0nab.no
+romskog.no
+rømskog.no
+xn--rmskog-bya.no
+roros.no
+røros.no
+xn--rros-gra.no
+rost.no
+røst.no
+xn--rst-0na.no
+royken.no
+røyken.no
+xn--ryken-vua.no
+royrvik.no
+røyrvik.no
+xn--ryrvik-bya.no
+rade.no
+råde.no
+xn--rde-ula.no
+salangen.no
+siellak.no
+saltdal.no
+salat.no
+sálát.no
+xn--slt-elab.no
+sálat.no
+xn--slat-5na.no
+samnanger.no
+sande.more-og-romsdal.no
+sande.møre-og-romsdal.no
+sande.xn--mre-og-romsdal-qqb.no
+sande.vestfold.no
+sandefjord.no
+sandnes.no
+sandoy.no
+sandøy.no
+xn--sandy-yua.no
+sarpsborg.no
+sauda.no
+sauherad.no
+sel.no
+selbu.no
+selje.no
+seljord.no
+sigdal.no
+siljan.no
+sirdal.no
+skaun.no
+skedsmo.no
+ski.no
+skien.no
+skiptvet.no
+skjervoy.no
+skjervøy.no
+xn--skjervy-v1a.no
+skierva.no
+skiervá.no
+xn--skierv-uta.no
+skjak.no
+skjåk.no
+xn--skjk-soa.no
+skodje.no
+skanland.no
+skånland.no
+xn--sknland-fxa.no
+skanit.no
+skánit.no
+xn--sknit-yqa.no
+smola.no
+smøla.no
+xn--smla-hra.no
+snillfjord.no
+snasa.no
+snåsa.no
+xn--snsa-roa.no
+snoasa.no
+snaase.no
+snåase.no
+xn--snase-nra.no
+sogndal.no
+sokndal.no
+sola.no
+solund.no
+songdalen.no
+sortland.no
+spydeberg.no
+stange.no
+stavanger.no
+steigen.no
+steinkjer.no
+stjordal.no
+stjørdal.no
+xn--stjrdal-s1a.no
+stokke.no
+stor-elvdal.no
+stord.no
+stordal.no
+storfjord.no
+omasvuotna.no
+strand.no
+stranda.no
+stryn.no
+sula.no
+suldal.no
+sund.no
+sunndal.no
+surnadal.no
+sveio.no
+svelvik.no
+sykkylven.no
+sogne.no
+søgne.no
+xn--sgne-gra.no
+somna.no
+sømna.no
+xn--smna-gra.no
+sondre-land.no
+søndre-land.no
+xn--sndre-land-0cb.no
+sor-aurdal.no
+sør-aurdal.no
+xn--sr-aurdal-l8a.no
+sor-fron.no
+sør-fron.no
+xn--sr-fron-q1a.no
+sor-odal.no
+sør-odal.no
+xn--sr-odal-q1a.no
+sor-varanger.no
+sør-varanger.no
+xn--sr-varanger-ggb.no
+matta-varjjat.no
+mátta-várjjat.no
+xn--mtta-vrjjat-k7af.no
+sorfold.no
+sørfold.no
+xn--srfold-bya.no
+sorreisa.no
+sørreisa.no
+xn--srreisa-q1a.no
+sorum.no
+sørum.no
+xn--srum-gra.no
+tana.no
+deatnu.no
+time.no
+tingvoll.no
+tinn.no
+tjeldsund.no
+dielddanuorri.no
+tjome.no
+tjøme.no
+xn--tjme-hra.no
+tokke.no
+tolga.no
+torsken.no
+tranoy.no
+tranøy.no
+xn--trany-yua.no
+tromso.no
+tromsø.no
+xn--troms-zua.no
+tromsa.no
+romsa.no
+trondheim.no
+troandin.no
+trysil.no
+trana.no
+træna.no
+xn--trna-woa.no
+trogstad.no
+trøgstad.no
+xn--trgstad-r1a.no
+tvedestrand.no
+tydal.no
+tynset.no
+tysfjord.no
+divtasvuodna.no
+divttasvuotna.no
+tysnes.no
+tysvar.no
+tysvær.no
+xn--tysvr-vra.no
+tonsberg.no
+tønsberg.no
+xn--tnsberg-q1a.no
+ullensaker.no
+ullensvang.no
+ulvik.no
+utsira.no
+vadso.no
+vadsø.no
+xn--vads-jra.no
+cahcesuolo.no
+čáhcesuolo.no
+xn--hcesuolo-7ya35b.no
+vaksdal.no
+valle.no
+vang.no
+vanylven.no
+vardo.no
+vardø.no
+xn--vard-jra.no
+varggat.no
+várggát.no
+xn--vrggt-xqad.no
+vefsn.no
+vaapste.no
+vega.no
+vegarshei.no
+vegårshei.no
+xn--vegrshei-c0a.no
+vennesla.no
+verdal.no
+verran.no
+vestby.no
+vestnes.no
+vestre-slidre.no
+vestre-toten.no
+vestvagoy.no
+vestvågøy.no
+xn--vestvgy-ixa6o.no
+vevelstad.no
+vik.no
+vikna.no
+vindafjord.no
+volda.no
+voss.no
+varoy.no
+værøy.no
+xn--vry-yla5g.no
+vagan.no
+vågan.no
+xn--vgan-qoa.no
+voagat.no
+vagsoy.no
+vågsøy.no
+xn--vgsy-qoa0j.no
+vaga.no
+vågå.no
+xn--vg-yiab.no
+valer.ostfold.no
+våler.østfold.no
+xn--vler-qoa.xn--stfold-9xa.no
+valer.hedmark.no
+våler.hedmark.no
+xn--vler-qoa.hedmark.no
+
+// np : http://www.mos.com.np/register.html
+*.np
+
+// nr : http://cenpac.net.nr/dns/index.html
+// Confirmed by registry <technician@cenpac.net.nr> 2008-06-17
+nr
+biz.nr
+info.nr
+gov.nr
+edu.nr
+org.nr
+net.nr
+com.nr
+
+// nu : http://en.wikipedia.org/wiki/.nu
+nu
+
+// nz : http://en.wikipedia.org/wiki/.nz
+// Confirmed by registry <jay@nzrs.net.nz> 2014-05-19
+nz
+ac.nz
+co.nz
+cri.nz
+geek.nz
+gen.nz
+govt.nz
+health.nz
+iwi.nz
+kiwi.nz
+maori.nz
+mil.nz
+māori.nz
+xn--mori-qsa.nz
+net.nz
+org.nz
+parliament.nz
+school.nz
+
+// om : http://en.wikipedia.org/wiki/.om
+om
+co.om
+com.om
+edu.om
+gov.om
+med.om
+museum.om
+net.om
+org.om
+pro.om
+
+// org : http://en.wikipedia.org/wiki/.org
+org
+
+// pa : http://www.nic.pa/
+// Some additional second level "domains" resolve directly as hostnames, such as
+// pannet.pa, so we add a rule for "pa".
+pa
+ac.pa
+gob.pa
+com.pa
+org.pa
+sld.pa
+edu.pa
+net.pa
+ing.pa
+abo.pa
+med.pa
+nom.pa
+
+// pe : https://www.nic.pe/InformeFinalComision.pdf
+pe
+edu.pe
+gob.pe
+nom.pe
+mil.pe
+org.pe
+com.pe
+net.pe
+
+// pf : http://www.gobin.info/domainname/formulaire-pf.pdf
+pf
+com.pf
+org.pf
+edu.pf
+
+// pg : http://en.wikipedia.org/wiki/.pg
+*.pg
+
+// ph : http://www.domains.ph/FAQ2.asp
+// Submitted by registry <jed@email.com.ph> 2008-06-13
+ph
+com.ph
+net.ph
+org.ph
+gov.ph
+edu.ph
+ngo.ph
+mil.ph
+i.ph
+
+// pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK
+pk
+com.pk
+net.pk
+edu.pk
+org.pk
+fam.pk
+biz.pk
+web.pk
+gov.pk
+gob.pk
+gok.pk
+gon.pk
+gop.pk
+gos.pk
+info.pk
+
+// pl http://www.dns.pl/english/index.html
+// confirmed on 26.09.2014 from Bogna Tchórzewska <partner@dns.pl>
+pl
+com.pl
+net.pl
+org.pl
+info.pl
+waw.pl
+gov.pl
+// pl functional domains (http://www.dns.pl/english/index.html)
+aid.pl
+agro.pl
+atm.pl
+auto.pl
+biz.pl
+edu.pl
+gmina.pl
+gsm.pl
+mail.pl
+miasta.pl
+media.pl
+mil.pl
+nieruchomosci.pl
+nom.pl
+pc.pl
+powiat.pl
+priv.pl
+realestate.pl
+rel.pl
+sex.pl
+shop.pl
+sklep.pl
+sos.pl
+szkola.pl
+targi.pl
+tm.pl
+tourism.pl
+travel.pl
+turystyka.pl
+// Government domains (administred by ippt.gov.pl)
+uw.gov.pl
+um.gov.pl
+ug.gov.pl
+upow.gov.pl
+starostwo.gov.pl
+so.gov.pl
+sr.gov.pl
+po.gov.pl
+pa.gov.pl
+// pl regional domains (http://www.dns.pl/english/index.html)
+augustow.pl
+babia-gora.pl
+bedzin.pl
+beskidy.pl
+bialowieza.pl
+bialystok.pl
+bielawa.pl
+bieszczady.pl
+boleslawiec.pl
+bydgoszcz.pl
+bytom.pl
+cieszyn.pl
+czeladz.pl
+czest.pl
+dlugoleka.pl
+elblag.pl
+elk.pl
+glogow.pl
+gniezno.pl
+gorlice.pl
+grajewo.pl
+ilawa.pl
+jaworzno.pl
+jelenia-gora.pl
+jgora.pl
+kalisz.pl
+kazimierz-dolny.pl
+karpacz.pl
+kartuzy.pl
+kaszuby.pl
+katowice.pl
+kepno.pl
+ketrzyn.pl
+klodzko.pl
+kobierzyce.pl
+kolobrzeg.pl
+konin.pl
+konskowola.pl
+kutno.pl
+lapy.pl
+lebork.pl
+legnica.pl
+lezajsk.pl
+limanowa.pl
+lomza.pl
+lowicz.pl
+lubin.pl
+lukow.pl
+malbork.pl
+malopolska.pl
+mazowsze.pl
+mazury.pl
+mielec.pl
+mielno.pl
+mragowo.pl
+naklo.pl
+nowaruda.pl
+nysa.pl
+olawa.pl
+olecko.pl
+olkusz.pl
+olsztyn.pl
+opoczno.pl
+opole.pl
+ostroda.pl
+ostroleka.pl
+ostrowiec.pl
+ostrowwlkp.pl
+pila.pl
+pisz.pl
+podhale.pl
+podlasie.pl
+polkowice.pl
+pomorze.pl
+pomorskie.pl
+prochowice.pl
+pruszkow.pl
+przeworsk.pl
+pulawy.pl
+radom.pl
+rawa-maz.pl
+rybnik.pl
+rzeszow.pl
+sanok.pl
+sejny.pl
+slask.pl
+slupsk.pl
+sosnowiec.pl
+stalowa-wola.pl
+skoczow.pl
+starachowice.pl
+stargard.pl
+suwalki.pl
+swidnica.pl
+swiebodzin.pl
+swinoujscie.pl
+szczecin.pl
+szczytno.pl
+tarnobrzeg.pl
+tgory.pl
+turek.pl
+tychy.pl
+ustka.pl
+walbrzych.pl
+warmia.pl
+warszawa.pl
+wegrow.pl
+wielun.pl
+wlocl.pl
+wloclawek.pl
+wodzislaw.pl
+wolomin.pl
+wroclaw.pl
+zachpomor.pl
+zagan.pl
+zarow.pl
+zgora.pl
+zgorzelec.pl
+
+// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+pm
+
+// pn : http://www.government.pn/PnRegistry/policies.htm
+pn
+gov.pn
+co.pn
+org.pn
+edu.pn
+net.pn
+
+// post : http://en.wikipedia.org/wiki/.post
+post
+
+// pr : http://www.nic.pr/index.asp?f=1
+pr
+com.pr
+net.pr
+org.pr
+gov.pr
+edu.pr
+isla.pr
+pro.pr
+biz.pr
+info.pr
+name.pr
+// these aren't mentioned on nic.pr, but on http://en.wikipedia.org/wiki/.pr
+est.pr
+prof.pr
+ac.pr
+
+// pro : http://www.nic.pro/support_faq.htm
+pro
+aca.pro
+bar.pro
+cpa.pro
+jur.pro
+law.pro
+med.pro
+eng.pro
+
+// ps : http://en.wikipedia.org/wiki/.ps
+// http://www.nic.ps/registration/policy.html#reg
+ps
+edu.ps
+gov.ps
+sec.ps
+plo.ps
+com.ps
+org.ps
+net.ps
+
+// pt : http://online.dns.pt/dns/start_dns
+pt
+net.pt
+gov.pt
+org.pt
+edu.pt
+int.pt
+publ.pt
+com.pt
+nome.pt
+
+// pw : http://en.wikipedia.org/wiki/.pw
+pw
+co.pw
+ne.pw
+or.pw
+ed.pw
+go.pw
+belau.pw
+
+// py : http://www.nic.py/pautas.html#seccion_9
+// Confirmed by registry 2012-10-03
+py
+com.py
+coop.py
+edu.py
+gov.py
+mil.py
+net.py
+org.py
+
+// qa : http://domains.qa/en/
+qa
+com.qa
+edu.qa
+gov.qa
+mil.qa
+name.qa
+net.qa
+org.qa
+sch.qa
+
+// re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs
+re
+com.re
+asso.re
+nom.re
+
+// ro : http://www.rotld.ro/
+ro
+com.ro
+org.ro
+tm.ro
+nt.ro
+nom.ro
+info.ro
+rec.ro
+arts.ro
+firm.ro
+store.ro
+www.ro
+
+// rs : http://en.wikipedia.org/wiki/.rs
+rs
+co.rs
+org.rs
+edu.rs
+ac.rs
+gov.rs
+in.rs
+
+// ru : http://www.cctld.ru/ru/docs/aktiv_8.php
+// Industry domains
+ru
+ac.ru
+com.ru
+edu.ru
+int.ru
+net.ru
+org.ru
+pp.ru
+// Geographical domains
+adygeya.ru
+altai.ru
+amur.ru
+arkhangelsk.ru
+astrakhan.ru
+bashkiria.ru
+belgorod.ru
+bir.ru
+bryansk.ru
+buryatia.ru
+cbg.ru
+chel.ru
+chelyabinsk.ru
+chita.ru
+chukotka.ru
+chuvashia.ru
+dagestan.ru
+dudinka.ru
+e-burg.ru
+grozny.ru
+irkutsk.ru
+ivanovo.ru
+izhevsk.ru
+jar.ru
+joshkar-ola.ru
+kalmykia.ru
+kaluga.ru
+kamchatka.ru
+karelia.ru
+kazan.ru
+kchr.ru
+kemerovo.ru
+khabarovsk.ru
+khakassia.ru
+khv.ru
+kirov.ru
+koenig.ru
+komi.ru
+kostroma.ru
+krasnoyarsk.ru
+kuban.ru
+kurgan.ru
+kursk.ru
+lipetsk.ru
+magadan.ru
+mari.ru
+mari-el.ru
+marine.ru
+mordovia.ru
+// mosreg.ru Bug 1090800 - removed at request of Aleksey Konstantinov <konstantinovav@mosreg.ru>
+msk.ru
+murmansk.ru
+nalchik.ru
+nnov.ru
+nov.ru
+novosibirsk.ru
+nsk.ru
+omsk.ru
+orenburg.ru
+oryol.ru
+palana.ru
+penza.ru
+perm.ru
+ptz.ru
+rnd.ru
+ryazan.ru
+sakhalin.ru
+samara.ru
+saratov.ru
+simbirsk.ru
+smolensk.ru
+spb.ru
+stavropol.ru
+stv.ru
+surgut.ru
+tambov.ru
+tatarstan.ru
+tom.ru
+tomsk.ru
+tsaritsyn.ru
+tsk.ru
+tula.ru
+tuva.ru
+tver.ru
+tyumen.ru
+udm.ru
+udmurtia.ru
+ulan-ude.ru
+vladikavkaz.ru
+vladimir.ru
+vladivostok.ru
+volgograd.ru
+vologda.ru
+voronezh.ru
+vrn.ru
+vyatka.ru
+yakutia.ru
+yamal.ru
+yaroslavl.ru
+yekaterinburg.ru
+yuzhno-sakhalinsk.ru
+// More geographical domains
+amursk.ru
+baikal.ru
+cmw.ru
+fareast.ru
+jamal.ru
+kms.ru
+k-uralsk.ru
+kustanai.ru
+kuzbass.ru
+magnitka.ru
+mytis.ru
+nakhodka.ru
+nkz.ru
+norilsk.ru
+oskol.ru
+pyatigorsk.ru
+rubtsovsk.ru
+snz.ru
+syzran.ru
+vdonsk.ru
+zgrad.ru
+// State domains
+gov.ru
+mil.ru
+// Technical domains
+test.ru
+
+// rw : http://www.nic.rw/cgi-bin/policy.pl
+rw
+gov.rw
+net.rw
+edu.rw
+ac.rw
+com.rw
+co.rw
+int.rw
+mil.rw
+gouv.rw
+
+// sa : http://www.nic.net.sa/
+sa
+com.sa
+net.sa
+org.sa
+gov.sa
+med.sa
+pub.sa
+edu.sa
+sch.sa
+
+// sb : http://www.sbnic.net.sb/
+// Submitted by registry <lee.humphries@telekom.com.sb> 2008-06-08
+sb
+com.sb
+edu.sb
+gov.sb
+net.sb
+org.sb
+
+// sc : http://www.nic.sc/
+sc
+com.sc
+gov.sc
+net.sc
+org.sc
+edu.sc
+
+// sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm
+// Submitted by registry <admin@isoc.sd> 2008-06-17
+sd
+com.sd
+net.sd
+org.sd
+edu.sd
+med.sd
+tv.sd
+gov.sd
+info.sd
+
+// se : http://en.wikipedia.org/wiki/.se
+// Submitted by registry <patrik.wallstrom@iis.se> 2014-03-18
+se
+a.se
+ac.se
+b.se
+bd.se
+brand.se
+c.se
+d.se
+e.se
+f.se
+fh.se
+fhsk.se
+fhv.se
+g.se
+h.se
+i.se
+k.se
+komforb.se
+kommunalforbund.se
+komvux.se
+l.se
+lanbib.se
+m.se
+n.se
+naturbruksgymn.se
+o.se
+org.se
+p.se
+parti.se
+pp.se
+press.se
+r.se
+s.se
+t.se
+tm.se
+u.se
+w.se
+x.se
+y.se
+z.se
+
+// sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines
+sg
+com.sg
+net.sg
+org.sg
+gov.sg
+edu.sg
+per.sg
+
+// sh : http://www.nic.sh/registrar.html
+sh
+com.sh
+net.sh
+gov.sh
+org.sh
+mil.sh
+
+// si : http://en.wikipedia.org/wiki/.si
+si
+
+// sj : No registrations at this time.
+// Submitted by registry <jarle@uninett.no> 2008-06-16
+sj
+
+// sk : http://en.wikipedia.org/wiki/.sk
+// list of 2nd level domains ?
+sk
+
+// sl : http://www.nic.sl
+// Submitted by registry <adam@neoip.com> 2008-06-12
+sl
+com.sl
+net.sl
+edu.sl
+gov.sl
+org.sl
+
+// sm : http://en.wikipedia.org/wiki/.sm
+sm
+
+// sn : http://en.wikipedia.org/wiki/.sn
+sn
+art.sn
+com.sn
+edu.sn
+gouv.sn
+org.sn
+perso.sn
+univ.sn
+
+// so : http://www.soregistry.com/
+so
+com.so
+net.so
+org.so
+
+// sr : http://en.wikipedia.org/wiki/.sr
+sr
+
+// st : http://www.nic.st/html/policyrules/
+st
+co.st
+com.st
+consulado.st
+edu.st
+embaixada.st
+gov.st
+mil.st
+net.st
+org.st
+principe.st
+saotome.st
+store.st
+
+// su : http://en.wikipedia.org/wiki/.su
+su
+
+// sv : http://www.svnet.org.sv/niveldos.pdf
+sv
+com.sv
+edu.sv
+gob.sv
+org.sv
+red.sv
+
+// sx : http://en.wikipedia.org/wiki/.sx
+// Confirmed by registry <jcvignes@openregistry.com> 2012-05-31
+sx
+gov.sx
+
+// sy : http://en.wikipedia.org/wiki/.sy
+// see also: http://www.gobin.info/domainname/sy.doc
+sy
+edu.sy
+gov.sy
+net.sy
+mil.sy
+com.sy
+org.sy
+
+// sz : http://en.wikipedia.org/wiki/.sz
+// http://www.sispa.org.sz/
+sz
+co.sz
+ac.sz
+org.sz
+
+// tc : http://en.wikipedia.org/wiki/.tc
+tc
+
+// td : http://en.wikipedia.org/wiki/.td
+td
+
+// tel: http://en.wikipedia.org/wiki/.tel
+// http://www.telnic.org/
+tel
+
+// tf : http://en.wikipedia.org/wiki/.tf
+tf
+
+// tg : http://en.wikipedia.org/wiki/.tg
+// http://www.nic.tg/
+tg
+
+// th : http://en.wikipedia.org/wiki/.th
+// Submitted by registry <krit@thains.co.th> 2008-06-17
+th
+ac.th
+co.th
+go.th
+in.th
+mi.th
+net.th
+or.th
+
+// tj : http://www.nic.tj/policy.html
+tj
+ac.tj
+biz.tj
+co.tj
+com.tj
+edu.tj
+go.tj
+gov.tj
+int.tj
+mil.tj
+name.tj
+net.tj
+nic.tj
+org.tj
+test.tj
+web.tj
+
+// tk : http://en.wikipedia.org/wiki/.tk
+tk
+
+// tl : http://en.wikipedia.org/wiki/.tl
+tl
+gov.tl
+
+// tm : http://www.nic.tm/local.html
+tm
+com.tm
+co.tm
+org.tm
+net.tm
+nom.tm
+gov.tm
+mil.tm
+edu.tm
+
+// tn : http://en.wikipedia.org/wiki/.tn
+// http://whois.ati.tn/
+tn
+com.tn
+ens.tn
+fin.tn
+gov.tn
+ind.tn
+intl.tn
+nat.tn
+net.tn
+org.tn
+info.tn
+perso.tn
+tourism.tn
+edunet.tn
+rnrt.tn
+rns.tn
+rnu.tn
+mincom.tn
+agrinet.tn
+defense.tn
+turen.tn
+
+// to : http://en.wikipedia.org/wiki/.to
+// Submitted by registry <egullich@colo.to> 2008-06-17
+to
+com.to
+gov.to
+net.to
+org.to
+edu.to
+mil.to
+
+// tp : No registrations at this time.
+// Submitted by Ryan Sleevi <ryan.sleevi@gmail.com> 2014-01-03
+tp
+
+// subTLDs: https://www.nic.tr/forms/eng/policies.pdf
+// and: https://www.nic.tr/forms/politikalar.pdf
+// Submitted by <mehmetgurevin@gmail.com> 2014-07-19
+tr
+com.tr
+info.tr
+biz.tr
+net.tr
+org.tr
+web.tr
+gen.tr
+tv.tr
+av.tr
+dr.tr
+bbs.tr
+name.tr
+tel.tr
+gov.tr
+bel.tr
+pol.tr
+mil.tr
+k12.tr
+edu.tr
+kep.tr
+
+// Used by Northern Cyprus
+nc.tr
+
+// Used by government agencies of Northern Cyprus
+gov.nc.tr
+
+// travel : http://en.wikipedia.org/wiki/.travel
+travel
+
+// tt : http://www.nic.tt/
+tt
+co.tt
+com.tt
+org.tt
+net.tt
+biz.tt
+info.tt
+pro.tt
+int.tt
+coop.tt
+jobs.tt
+mobi.tt
+travel.tt
+museum.tt
+aero.tt
+name.tt
+gov.tt
+edu.tt
+
+// tv : http://en.wikipedia.org/wiki/.tv
+// Not listing any 2LDs as reserved since none seem to exist in practice,
+// Wikipedia notwithstanding.
+tv
+
+// tw : http://en.wikipedia.org/wiki/.tw
+tw
+edu.tw
+gov.tw
+mil.tw
+com.tw
+net.tw
+org.tw
+idv.tw
+game.tw
+ebiz.tw
+club.tw
+網路.tw
+xn--zf0ao64a.tw
+組織.tw
+xn--uc0atv.tw
+商業.tw
+xn--czrw28b.tw
+
+// tz : http://www.tznic.or.tz/index.php/domains
+// Confirmed by registry <manager@tznic.or.tz> 2013-01-22
+tz
+ac.tz
+co.tz
+go.tz
+hotel.tz
+info.tz
+me.tz
+mil.tz
+mobi.tz
+ne.tz
+or.tz
+sc.tz
+tv.tz
+
+// ua : https://hostmaster.ua/policy/?ua
+// Submitted by registry <dk@cctld.ua> 2012-04-27
+ua
+// ua 2LD
+com.ua
+edu.ua
+gov.ua
+in.ua
+net.ua
+org.ua
+// ua geographic names
+// https://hostmaster.ua/2ld/
+cherkassy.ua
+cherkasy.ua
+chernigov.ua
+chernihiv.ua
+chernivtsi.ua
+chernovtsy.ua
+ck.ua
+cn.ua
+cr.ua
+crimea.ua
+cv.ua
+dn.ua
+dnepropetrovsk.ua
+dnipropetrovsk.ua
+dominic.ua
+donetsk.ua
+dp.ua
+if.ua
+ivano-frankivsk.ua
+kh.ua
+kharkiv.ua
+kharkov.ua
+kherson.ua
+khmelnitskiy.ua
+khmelnytskyi.ua
+kiev.ua
+kirovograd.ua
+km.ua
+kr.ua
+krym.ua
+ks.ua
+kv.ua
+kyiv.ua
+lg.ua
+lt.ua
+lugansk.ua
+lutsk.ua
+lv.ua
+lviv.ua
+mk.ua
+mykolaiv.ua
+nikolaev.ua
+od.ua
+odesa.ua
+odessa.ua
+pl.ua
+poltava.ua
+rivne.ua
+rovno.ua
+rv.ua
+sb.ua
+sebastopol.ua
+sevastopol.ua
+sm.ua
+sumy.ua
+te.ua
+ternopil.ua
+uz.ua
+uzhgorod.ua
+vinnica.ua
+vinnytsia.ua
+vn.ua
+volyn.ua
+yalta.ua
+zaporizhzhe.ua
+zaporizhzhia.ua
+zhitomir.ua
+zhytomyr.ua
+zp.ua
+zt.ua
+
+// Private registries in .ua
+co.ua
+pp.ua
+
+// ug : https://www.registry.co.ug/
+ug
+co.ug
+or.ug
+ac.ug
+sc.ug
+go.ug
+ne.ug
+com.ug
+org.ug
+
+// uk : http://en.wikipedia.org/wiki/.uk
+// Submitted by registry <Michael.Daly@nominet.org.uk>
+uk
+ac.uk
+co.uk
+gov.uk
+ltd.uk
+me.uk
+net.uk
+nhs.uk
+org.uk
+plc.uk
+police.uk
+*.sch.uk
+
+// us : http://en.wikipedia.org/wiki/.us
+us
+dni.us
+fed.us
+isa.us
+kids.us
+nsn.us
+// us geographic names
+ak.us
+al.us
+ar.us
+as.us
+az.us
+ca.us
+co.us
+ct.us
+dc.us
+de.us
+fl.us
+ga.us
+gu.us
+hi.us
+ia.us
+id.us
+il.us
+in.us
+ks.us
+ky.us
+la.us
+ma.us
+md.us
+me.us
+mi.us
+mn.us
+mo.us
+ms.us
+mt.us
+nc.us
+nd.us
+ne.us
+nh.us
+nj.us
+nm.us
+nv.us
+ny.us
+oh.us
+ok.us
+or.us
+pa.us
+pr.us
+ri.us
+sc.us
+sd.us
+tn.us
+tx.us
+ut.us
+vi.us
+vt.us
+va.us
+wa.us
+wi.us
+wv.us
+wy.us
+// The registrar notes several more specific domains available in each state,
+// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat
+// haphazard; in some states these domains resolve as addresses, while in others
+// only subdomains are available, or even nothing at all. We include the
+// most common ones where it's clear that different sites are different
+// entities.
+k12.ak.us
+k12.al.us
+k12.ar.us
+k12.as.us
+k12.az.us
+k12.ca.us
+k12.co.us
+k12.ct.us
+k12.dc.us
+k12.de.us
+k12.fl.us
+k12.ga.us
+k12.gu.us
+// k12.hi.us Bug 614565 - Hawaii has a state-wide DOE login
+k12.ia.us
+k12.id.us
+k12.il.us
+k12.in.us
+k12.ks.us
+k12.ky.us
+k12.la.us
+k12.ma.us
+k12.md.us
+k12.me.us
+k12.mi.us
+k12.mn.us
+k12.mo.us
+k12.ms.us
+k12.mt.us
+k12.nc.us
+// k12.nd.us Bug 1028347 - Removed at request of Travis Rosso <trossow@nd.gov>
+k12.ne.us
+k12.nh.us
+k12.nj.us
+k12.nm.us
+k12.nv.us
+k12.ny.us
+k12.oh.us
+k12.ok.us
+k12.or.us
+k12.pa.us
+k12.pr.us
+k12.ri.us
+k12.sc.us
+// k12.sd.us Bug 934131 - Removed at request of James Booze <James.Booze@k12.sd.us>
+k12.tn.us
+k12.tx.us
+k12.ut.us
+k12.vi.us
+k12.vt.us
+k12.va.us
+k12.wa.us
+k12.wi.us
+// k12.wv.us Bug 947705 - Removed at request of Verne Britton <verne@wvnet.edu>
+k12.wy.us
+cc.ak.us
+cc.al.us
+cc.ar.us
+cc.as.us
+cc.az.us
+cc.ca.us
+cc.co.us
+cc.ct.us
+cc.dc.us
+cc.de.us
+cc.fl.us
+cc.ga.us
+cc.gu.us
+cc.hi.us
+cc.ia.us
+cc.id.us
+cc.il.us
+cc.in.us
+cc.ks.us
+cc.ky.us
+cc.la.us
+cc.ma.us
+cc.md.us
+cc.me.us
+cc.mi.us
+cc.mn.us
+cc.mo.us
+cc.ms.us
+cc.mt.us
+cc.nc.us
+cc.nd.us
+cc.ne.us
+cc.nh.us
+cc.nj.us
+cc.nm.us
+cc.nv.us
+cc.ny.us
+cc.oh.us
+cc.ok.us
+cc.or.us
+cc.pa.us
+cc.pr.us
+cc.ri.us
+cc.sc.us
+cc.sd.us
+cc.tn.us
+cc.tx.us
+cc.ut.us
+cc.vi.us
+cc.vt.us
+cc.va.us
+cc.wa.us
+cc.wi.us
+cc.wv.us
+cc.wy.us
+lib.ak.us
+lib.al.us
+lib.ar.us
+lib.as.us
+lib.az.us
+lib.ca.us
+lib.co.us
+lib.ct.us
+lib.dc.us
+lib.de.us
+lib.fl.us
+lib.ga.us
+lib.gu.us
+lib.hi.us
+lib.ia.us
+lib.id.us
+lib.il.us
+lib.in.us
+lib.ks.us
+lib.ky.us
+lib.la.us
+lib.ma.us
+lib.md.us
+lib.me.us
+lib.mi.us
+lib.mn.us
+lib.mo.us
+lib.ms.us
+lib.mt.us
+lib.nc.us
+lib.nd.us
+lib.ne.us
+lib.nh.us
+lib.nj.us
+lib.nm.us
+lib.nv.us
+lib.ny.us
+lib.oh.us
+lib.ok.us
+lib.or.us
+lib.pa.us
+lib.pr.us
+lib.ri.us
+lib.sc.us
+lib.sd.us
+lib.tn.us
+lib.tx.us
+lib.ut.us
+lib.vi.us
+lib.vt.us
+lib.va.us
+lib.wa.us
+lib.wi.us
+// lib.wv.us Bug 941670 - Removed at request of Larry W Arnold <arnold@wvlc.lib.wv.us>
+lib.wy.us
+// k12.ma.us contains school districts in Massachusetts. The 4LDs are
+// managed indepedently except for private (PVT), charter (CHTR) and
+// parochial (PAROCH) schools. Those are delegated dorectly to the
+// 5LD operators. <k12-ma-hostmaster _ at _ rsuc.gweep.net>
+pvt.k12.ma.us
+chtr.k12.ma.us
+paroch.k12.ma.us
+
+// uy : http://www.nic.org.uy/
+uy
+com.uy
+edu.uy
+gub.uy
+mil.uy
+net.uy
+org.uy
+
+// uz : http://www.reg.uz/
+uz
+co.uz
+com.uz
+net.uz
+org.uz
+
+// va : http://en.wikipedia.org/wiki/.va
+va
+
+// vc : http://en.wikipedia.org/wiki/.vc
+// Submitted by registry <kshah@ca.afilias.info> 2008-06-13
+vc
+com.vc
+net.vc
+org.vc
+gov.vc
+mil.vc
+edu.vc
+
+// ve : https://registro.nic.ve/
+// Confirmed by registry 2012-10-04
+// Updated 2014-05-20 - Bug 940478
+ve
+arts.ve
+co.ve
+com.ve
+e12.ve
+edu.ve
+firm.ve
+gob.ve
+gov.ve
+info.ve
+int.ve
+mil.ve
+net.ve
+org.ve
+rec.ve
+store.ve
+tec.ve
+web.ve
+
+// vg : http://en.wikipedia.org/wiki/.vg
+vg
+
+// vi : http://www.nic.vi/newdomainform.htm
+// http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other
+// TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they
+// are available for registration (which they do not seem to be).
+vi
+co.vi
+com.vi
+k12.vi
+net.vi
+org.vi
+
+// vn : https://www.dot.vn/vnnic/vnnic/domainregistration.jsp
+vn
+com.vn
+net.vn
+org.vn
+edu.vn
+gov.vn
+int.vn
+ac.vn
+biz.vn
+info.vn
+name.vn
+pro.vn
+health.vn
+
+// vu : http://en.wikipedia.org/wiki/.vu
+// http://www.vunic.vu/
+vu
+com.vu
+edu.vu
+net.vu
+org.vu
+
+// wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+wf
+
+// ws : http://en.wikipedia.org/wiki/.ws
+// http://samoanic.ws/index.dhtml
+ws
+com.ws
+net.ws
+org.ws
+gov.ws
+edu.ws
+
+// yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf
+yt
+
+// IDN ccTLDs
+// Please sort by ISO 3166 ccTLD, then punicode string
+// when submitting patches and follow this format:
+// <Punicode> ("<english word>" <language>) : <ISO 3166 ccTLD>
+// [optional sponsoring org]
+// <URL>
+
+// xn--mgbaam7a8h ("Emerat" Arabic) : AE
+// http://nic.ae/english/arabicdomain/rules.jsp
+امارات
+xn--mgbaam7a8h
+
+// xn--54b7fta0cc ("Bangla" Bangla) : BD
+বাংলা
+xn--54b7fta0cc
+
+// xn--fiqs8s ("China" Chinese-Han-Simplified <.Zhongguo>) : CN
+// CNNIC
+// http://cnnic.cn/html/Dir/2005/10/11/3218.htm
+中国
+xn--fiqs8s
+
+// xn--fiqz9s ("China" Chinese-Han-Traditional <.Zhongguo>) : CN
+// CNNIC
+// http://cnnic.cn/html/Dir/2005/10/11/3218.htm
+中國
+xn--fiqz9s
+
+// xn--lgbbat1ad8j ("Algeria / Al Jazair" Arabic) : DZ
+الجزائر
+xn--lgbbat1ad8j
+
+// xn--wgbh1c ("Egypt" Arabic .masr) : EG
+// http://www.dotmasr.eg/
+مصر
+xn--wgbh1c
+
+// xn--node ("ge" Georgian (Mkhedruli)) : GE
+გე
+xn--node
+
+// xn--j6w193g ("Hong Kong" Chinese-Han) : HK
+// https://www2.hkirc.hk/register/rules.jsp
+香港
+xn--j6w193g
+
+// xn--h2brj9c ("Bharat" Devanagari) : IN
+// India
+भारत
+xn--h2brj9c
+
+// xn--mgbbh1a71e ("Bharat" Arabic) : IN
+// India
+بھارت
+xn--mgbbh1a71e
+
+// xn--fpcrj9c3d ("Bharat" Telugu) : IN
+// India
+భారత్
+xn--fpcrj9c3d
+
+// xn--gecrj9c ("Bharat" Gujarati) : IN
+// India
+ભારત
+xn--gecrj9c
+
+// xn--s9brj9c ("Bharat" Gurmukhi) : IN
+// India
+ਭਾਰਤ
+xn--s9brj9c
+
+// xn--45brj9c ("Bharat" Bengali) : IN
+// India
+ভারত
+xn--45brj9c
+
+// xn--xkc2dl3a5ee0h ("India" Tamil) : IN
+// India
+இந்தியா
+xn--xkc2dl3a5ee0h
+
+// xn--mgba3a4f16a ("Iran" Persian) : IR
+ایران
+xn--mgba3a4f16a
+
+// xn--mgba3a4fra ("Iran" Arabic) : IR
+ايران
+xn--mgba3a4fra
+
+// xn--mgbayh7gpa ("al-Ordon" Arabic) : JO
+// National Information Technology Center (NITC)
+// Royal Scientific Society, Al-Jubeiha
+الاردن
+xn--mgbayh7gpa
+
+// xn--3e0b707e ("Republic of Korea" Hangul) : KR
+한국
+xn--3e0b707e
+
+// xn--80ao21a ("Kaz" Kazakh) : KZ
+қаз
+xn--80ao21a
+
+// xn--fzc2c9e2c ("Lanka" Sinhalese-Sinhala) : LK
+// http://nic.lk
+ලංකා
+xn--fzc2c9e2c
+
+// xn--xkc2al3hye2a ("Ilangai" Tamil) : LK
+// http://nic.lk
+இலங்கை
+xn--xkc2al3hye2a
+
+// xn--mgbc0a9azcg ("Morocco / al-Maghrib" Arabic) : MA
+المغرب
+xn--mgbc0a9azcg
+
+// xn--l1acc ("mon" Mongolian) : MN
+мон
+xn--l1acc
+
+// xn--mgbx4cd0ab ("Malaysia" Malay) : MY
+مليسيا
+xn--mgbx4cd0ab
+
+// xn--mgb9awbf ("Oman" Arabic) : OM
+عمان
+xn--mgb9awbf
+
+// xn--ygbi2ammx ("Falasteen" Arabic) : PS
+// The Palestinian National Internet Naming Authority (PNINA)
+// http://www.pnina.ps
+فلسطين
+xn--ygbi2ammx
+
+// xn--90a3ac ("srb" Cyrillic) : RS
+// http://www.rnids.rs/en/the-.срб-domain
+срб
+xn--90a3ac
+пр.срб
+xn--o1ac.xn--90a3ac
+орг.срб
+xn--c1avg.xn--90a3ac
+обр.срб
+xn--90azh.xn--90a3ac
+од.срб
+xn--d1at.xn--90a3ac
+упр.срб
+xn--o1ach.xn--90a3ac
+ак.срб
+xn--80au.xn--90a3ac
+
+// xn--p1ai ("rf" Russian-Cyrillic) : RU
+// http://www.cctld.ru/en/docs/rulesrf.php
+рф
+xn--p1ai
+
+// xn--wgbl6a ("Qatar" Arabic) : QA
+// http://www.ict.gov.qa/
+قطر
+xn--wgbl6a
+
+// xn--mgberp4a5d4ar ("AlSaudiah" Arabic) : SA
+// http://www.nic.net.sa/
+السعودية
+xn--mgberp4a5d4ar
+
+// xn--mgberp4a5d4a87g ("AlSaudiah" Arabic) variant : SA
+السعودیة
+xn--mgberp4a5d4a87g
+
+// xn--mgbqly7c0a67fbc ("AlSaudiah" Arabic) variant : SA
+السعودیۃ
+xn--mgbqly7c0a67fbc
+
+// xn--mgbqly7cvafr ("AlSaudiah" Arabic) variant : SA
+السعوديه
+xn--mgbqly7cvafr
+
+// xn--ogbpf8fl ("Syria" Arabic) : SY
+سورية
+xn--ogbpf8fl
+
+// xn--mgbtf8fl ("Syria" Arabic) variant : SY
+سوريا
+xn--mgbtf8fl
+
+// xn--yfro4i67o Singapore ("Singapore" Chinese-Han) : SG
+新加坡
+xn--yfro4i67o
+
+// xn--clchc0ea0b2g2a9gcd ("Singapore" Tamil) : SG
+சிங்கப்பூர்
+xn--clchc0ea0b2g2a9gcd
+
+// xn--o3cw4h ("Thai" Thai) : TH
+// http://www.thnic.co.th
+ไทย
+xn--o3cw4h
+
+// xn--pgbs0dh ("Tunis") : TN
+// http://nic.tn
+تونس
+xn--pgbs0dh
+
+// xn--kpry57d ("Taiwan" Chinese-Han-Traditional) : TW
+// http://www.twnic.net/english/dn/dn_07a.htm
+台灣
+xn--kpry57d
+
+// xn--kprw13d ("Taiwan" Chinese-Han-Simplified) : TW
+// http://www.twnic.net/english/dn/dn_07a.htm
+台湾
+xn--kprw13d
+
+// xn--nnx388a ("Taiwan") variant : TW
+臺灣
+xn--nnx388a
+
+// xn--j1amh ("ukr" Cyrillic) : UA
+укр
+xn--j1amh
+
+// xn--mgb2ddes ("AlYemen" Arabic) : YE
+اليمن
+xn--mgb2ddes
+
+// xxx : http://icmregistry.com
+xxx
+
+// ye : http://www.y.net.ye/services/domain_name.htm
+*.ye
+
+// za : http://www.zadna.org.za/slds.html
+*.za
+
+// zm : http://en.wikipedia.org/wiki/.zm
+*.zm
+
+// zw : http://en.wikipedia.org/wiki/.zw
+*.zw
+
+
+// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2014-12-22T18:02:07Z
+
+// abb : 2014-10-24 ABB Ltd
+abb
+
+// abbott : 2014-07-24 Abbott Laboratories, Inc.
+abbott
+
+// abogado : 2014-04-24 Top Level Domain Holdings Limited
+abogado
+
+// academy : 2013-11-07 Half Oaks, LLC
+academy
+
+// accenture : 2014-08-15 Accenture plc
+accenture
+
+// accountant : 2014-11-20 dot Accountant Limited
+accountant
+
+// accountants : 2014-03-20 Knob Town, LLC
+accountants
+
+// active : 2014-05-01 The Active Network, Inc
+active
+
+// actor : 2013-12-12 United TLD Holdco Ltd.
+actor
+
+// ads : 2014-12-04 Charleston Road Registry Inc.
+ads
+
+// adult : 2014-10-16 ICM Registry AD LLC
+adult
+
+// afl : 2014-10-02 Australian Football League
+afl
+
+// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
+africa
+
+// agency : 2013-11-14 Steel Falls, LLC
+agency
+
+// aig : 2014-12-18 American International Group, Inc.
+aig
+
+// airforce : 2014-03-06 United TLD Holdco Ltd.
+airforce
+
+// airtel : 2014-10-24 Bharti Airtel Limited
+airtel
+
+// allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
+allfinanz
+
+// alsace : 2014-07-02 REGION D ALSACE
+alsace
+
+// amsterdam : 2014-07-24 Gemeente Amsterdam
+amsterdam
+
+// analytics : 2014-12-18 Campus IP LLC
+analytics
+
+// android : 2014-08-07 Charleston Road Registry Inc.
+android
+
+// apartments : 2014-12-11 June Maple, LLC
+apartments
+
+// aquarelle : 2014-07-24 Aquarelle.com
+aquarelle
+
+// aramco : 2014-11-20 Aramco Services Company
+aramco
+
+// archi : 2014-02-06 STARTING DOT LIMITED
+archi
+
+// army : 2014-03-06 United TLD Holdco Ltd.
+army
+
+// arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E.
+arte
+
+// associates : 2014-03-06 Baxter Hill, LLC
+associates
+
+// attorney : 2014-03-20
+attorney
+
+// auction : 2014-03-20
+auction
+
+// audio : 2014-03-20 Uniregistry, Corp.
+audio
+
+// author : 2014-12-18 Amazon EU S.à r.l.
+author
+
+// auto : 2014-11-13 Uniregistry, Corp.
+auto
+
+// autos : 2014-01-09 DERAutos, LLC
+autos
+
+// axa : 2013-12-19 AXA SA
+axa
+
+// azure : 2014-12-18 Microsoft Corporation
+azure
+
+// band : 2014-06-12
+band
+
+// bank : 2014-09-25 fTLD Registry Services LLC
+bank
+
+// bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+bar
+
+// barcelona : 2014-07-24 Municipi de Barcelona
+barcelona
+
+// barclaycard : 2014-11-20 Barclays Bank PLC
+barclaycard
+
+// barclays : 2014-11-20 Barclays Bank PLC
+barclays
+
+// bargains : 2013-11-14 Half Hallow, LLC
+bargains
+
+// bauhaus : 2014-04-17 Werkhaus GmbH
+bauhaus
+
+// bayern : 2014-01-23 Bayern Connect GmbH
+bayern
+
+// bbc : 2014-12-18 British Broadcasting Corporation
+bbc
+
+// bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
+bbva
+
+// bcn : 2014-07-24 Municipi de Barcelona
+bcn
+
+// beer : 2014-01-09 Top Level Domain Holdings Limited
+beer
+
+// bentley : 2014-12-18 Bentley Motors Limited
+bentley
+
+// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
+berlin
+
+// best : 2013-12-19 BestTLD Pty Ltd
+best
+
+// bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited
+bharti
+
+// bible : 2014-06-19 American Bible Society
+bible
+
+// bid : 2013-12-19 dot Bid Limited
+bid
+
+// bike : 2013-08-27 Grand Hollow, LLC
+bike
+
+// bing : 2014-12-18 Microsoft Corporation
+bing
+
+// bingo : 2014-12-04 Sand Cedar, LLC
+bingo
+
+// bio : 2014-03-06 STARTING DOT LIMITED
+bio
+
+// black : 2014-01-16 Afilias Limited
+black
+
+// blackfriday : 2014-01-16 Uniregistry, Corp.
+blackfriday
+
+// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC
+bloomberg
+
+// blue : 2013-11-07 Afilias Limited
+blue
+
+// bms : 2014-10-30 Bristol-Myers Squibb Company
+bms
+
+// bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+bmw
+
+// bnl : 2014-07-24 Banca Nazionale del Lavoro
+bnl
+
+// bnpparibas : 2014-05-29 BNP Paribas
+bnpparibas
+
+// boats : 2014-12-04 DERBoats, LLC
+boats
+
+// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+bom
+
+// bond : 2014-06-05 Bond University Limited
+bond
+
+// boo : 2014-01-30 Charleston Road Registry Inc.
+boo
+
+// bot : 2014-12-18 Amazon EU S.à r.l.
+bot
+
+// boutique : 2013-11-14 Over Galley, LLC
+boutique
+
+// bradesco : 2014-12-18 Banco Bradesco S.A.
+bradesco
+
+// bridgestone : 2014-12-18 Bridgestone Corporation
+bridgestone
+
+// broker : 2014-12-11 IG Group Holdings PLC
+broker
+
+// brussels : 2014-02-06 DNS.be vzw
+brussels
+
+// budapest : 2013-11-21 Top Level Domain Holdings Limited
+budapest
+
+// build : 2013-11-07 Plan Bee LLC
+build
+
+// builders : 2013-11-07 Atomic Madison, LLC
+builders
+
+// business : 2013-11-07 Spring Cross, LLC
+business
+
+// buy : 2014-12-18 Amazon EU S.à r.l.
+buy
+
+// buzz : 2013-10-02 DOTSTRATEGY CO.
+buzz
+
+// bzh : 2014-02-27 Association www.bzh
+bzh
+
+// cab : 2013-10-24 Half Sunset, LLC
+cab
+
+// cal : 2014-07-24 Charleston Road Registry Inc.
+cal
+
+// call : 2014-12-18 Amazon EU S.à r.l.
+call
+
+// camera : 2013-08-27 Atomic Maple, LLC
+camera
+
+// camp : 2013-11-07 Delta Dynamite, LLC
+camp
+
+// cancerresearch : 2014-05-15 Australian Cancer Research Foundation
+cancerresearch
+
+// canon : 2014-09-12 Canon Inc.
+canon
+
+// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+capetown
+
+// capital : 2014-03-06 Delta Mill, LLC
+capital
+
+// caravan : 2013-12-12 Caravan International, Inc.
+caravan
+
+// cards : 2013-12-05 Foggy Hollow, LLC
+cards
+
+// care : 2014-03-06 Goose Cross
+care
+
+// career : 2013-10-09 dotCareer LLC
+career
+
+// careers : 2013-10-02 Wild Corner, LLC
+careers
+
+// cars : 2014-11-13 Uniregistry, Corp.
+cars
+
+// cartier : 2014-06-23 Richemont DNS Inc.
+cartier
+
+// casa : 2013-11-21 Top Level Domain Holdings Limited
+casa
+
+// cash : 2014-03-06 Delta Lake, LLC
+cash
+
+// casino : 2014-12-18 Binky Sky, LLC
+casino
+
+// catering : 2013-12-05 New Falls. LLC
+catering
+
+// cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+cba
+
+// cbn : 2014-08-22 The Christian Broadcasting Network, Inc.
+cbn
+
+// center : 2013-11-07 Tin Mill, LLC
+center
+
+// ceo : 2013-11-07 CEOTLD Pty Ltd
+ceo
+
+// cern : 2014-06-05 European Organization for Nuclear Research (
+cern
+
+// cfa : 2014-08-28 CFA Institute
+cfa
+
+// cfd : 2014-12-11 IG Group Holdings PLC
+cfd
+
+// channel : 2014-05-08 Charleston Road Registry Inc.
+channel
+
+// chat : 2014-12-04 Sand Fields, LLC
+chat
+
+// cheap : 2013-11-14 Sand Cover, LLC
+cheap
+
+// chloe : 2014-10-16 Richemont DNS Inc.
+chloe
+
+// christmas : 2013-11-21 Uniregistry, Corp.
+christmas
+
+// chrome : 2014-07-24 Charleston Road Registry Inc.
+chrome
+
+// church : 2014-02-06 Holly Fileds, LLC
+church
+
+// circle : 2014-12-18 Amazon EU S.à r.l.
+circle
+
+// citic : 2014-01-09 CITIC Group Corporation
+citic
+
+// city : 2014-05-29 Snow Sky, LLC
+city
+
+// cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc.
+cityeats
+
+// claims : 2014-03-20 Black Corner, LLC
+claims
+
+// cleaning : 2013-12-05 Fox Shadow, LLC
+cleaning
+
+// click : 2014-06-05 Uniregistry, Corp.
+click
+
+// clinic : 2014-03-20 Goose Park, LLC
+clinic
+
+// clothing : 2013-08-27 Steel Lake, LLC
+clothing
+
+// club : 2013-11-08 .CLUB DOMAINS, LLC
+club
+
+// coach : 2014-10-09 Koko Island, LLC
+coach
+
+// codes : 2013-10-31 Puff Willow, LLC
+codes
+
+// coffee : 2013-10-17 Trixy Cover, LLC
+coffee
+
+// college : 2014-01-16 XYZ.COM LLC
+college
+
+// cologne : 2014-02-05 NetCologne Gesellschaft für Telekommunikation mbH
+cologne
+
+// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+commbank
+
+// community : 2013-12-05 Fox Orchard, LLC
+community
+
+// company : 2013-11-07 Silver Avenue, LLC
+company
+
+// computer : 2013-10-24 Pine Mill, LLC
+computer
+
+// condos : 2013-12-05 Pine House, LLC
+condos
+
+// construction : 2013-09-16 Fox Dynamite, LLC
+construction
+
+// consulting : 2013-12-05
+consulting
+
+// contractors : 2013-09-10 Magic Woods, LLC
+contractors
+
+// cooking : 2013-11-21 Top Level Domain Holdings Limited
+cooking
+
+// cool : 2013-11-14 Koko Lake, LLC
+cool
+
+// corsica : 2014-09-25 Collectivité Territoriale de Corse
+corsica
+
+// country : 2013-12-19 Top Level Domain Holdings Limited
+country
+
+// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD
+courses
+
+// credit : 2014-03-20 Snow Shadow, LLC
+credit
+
+// creditcard : 2014-03-20 Binky Frostbite, LLC
+creditcard
+
+// cricket : 2014-10-09 dot Cricket Limited
+cricket
+
+// crown : 2014-10-24 Crown Equipment Corporation
+crown
+
+// crs : 2014-04-03 Federated Co-operatives Limited
+crs
+
+// cruises : 2013-12-05 Spring Way, LLC
+cruises
+
+// csc : 2014-09-25 Alliance-One Services, Inc.
+csc
+
+// cuisinella : 2014-04-03 SALM S.A.S.
+cuisinella
+
+// cymru : 2014-05-08 Nominet UK
+cymru
+
+// dabur : 2014-02-06 Dabur India Limited
+dabur
+
+// dad : 2014-01-23 Charleston Road Registry Inc.
+dad
+
+// dance : 2013-10-24 United TLD Holdco Ltd.
+dance
+
+// date : 2014-11-20 dot Date Limited
+date
+
+// dating : 2013-12-05 Pine Fest, LLC
+dating
+
+// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
+datsun
+
+// day : 2014-01-30 Charleston Road Registry Inc.
+day
+
+// dclk : 2014-11-20 Charleston Road Registry Inc.
+dclk
+
+// deals : 2014-05-22 Sand Sunset, LLC
+deals
+
+// degree : 2014-03-06
+degree
+
+// delivery : 2014-09-11 Steel Station, LLC
+delivery
+
+// dell : 2014-10-24 Dell Inc.
+dell
+
+// democrat : 2013-10-24 United TLD Holdco Ltd.
+democrat
+
+// dental : 2014-03-20 Tin Birch, LLC
+dental
+
+// dentist : 2014-03-20
+dentist
+
+// desi : 2013-11-14 Desi Networks LLC
+desi
+
+// design : 2014-11-07 Top Level Design, LLC
+design
+
+// dev : 2014-10-16 Charleston Road Registry Inc.
+dev
+
+// diamonds : 2013-09-22 John Edge, LLC
+diamonds
+
+// diet : 2014-06-26 Uniregistry, Corp.
+diet
+
+// digital : 2014-03-06 Dash Park, LLC
+digital
+
+// direct : 2014-04-10 Half Trail, LLC
+direct
+
+// directory : 2013-09-20 Extra Madison, LLC
+directory
+
+// discount : 2014-03-06 Holly Hill, LLC
+discount
+
+// dnp : 2013-12-13 Dai Nippon Printing Co., Ltd.
+dnp
+
+// docs : 2014-10-16 Charleston Road Registry Inc.
+docs
+
+// dog : 2014-12-04 Koko Mill, LLC
+dog
+
+// doha : 2014-09-18 Communications Regulatory Authority (CRA)
+doha
+
+// domains : 2013-10-17 Sugar Cross, LLC
+domains
+
+// doosan : 2014-04-03 Doosan Corporation
+doosan
+
+// download : 2014-11-20 dot Support Limited
+download
+
+// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+durban
+
+// dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+dvag
+
+// earth : 2014-12-04 Interlink Co., Ltd.
+earth
+
+// eat : 2014-01-23 Charleston Road Registry Inc.
+eat
+
+// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V.
+edeka
+
+// education : 2013-11-07 Brice Way, LLC
+education
+
+// email : 2013-10-31 Spring Madison, LLC
+email
+
+// emerck : 2014-04-03 Merck KGaA
+emerck
+
+// energy : 2014-09-11 Binky Birch, LLC
+energy
+
+// engineer : 2014-03-06 United TLD Holdco Ltd.
+engineer
+
+// engineering : 2014-03-06 Romeo Canyon
+engineering
+
+// enterprises : 2013-09-20 Snow Oaks, LLC
+enterprises
+
+// epson : 2014-12-04 Seiko Epson Corporation
+epson
+
+// equipment : 2013-08-27 Corn Station, LLC
+equipment
+
+// erni : 2014-04-03 ERNI Group Holding AG
+erni
+
+// esq : 2014-05-08 Charleston Road Registry Inc.
+esq
+
+// estate : 2013-08-27 Trixy Park, LLC
+estate
+
+// eurovision : 2014-04-24 European Broadcasting Union (EBU)
+eurovision
+
+// eus : 2013-12-12 Puntueus Fundazioa
+eus
+
+// events : 2013-12-05 Pioneer Maple, LLC
+events
+
+// everbank : 2014-05-15 EverBank
+everbank
+
+// exchange : 2014-03-06 Spring Falls, LLC
+exchange
+
+// expert : 2013-11-21 Magic Pass, LLC
+expert
+
+// exposed : 2013-12-05 Victor Beach, LLC
+exposed
+
+// fage : 2014-12-18 Fage International S.A.
+fage
+
+// fail : 2014-03-06 Atomic Pipe, LLC
+fail
+
+// fairwinds : 2014-11-13 FairWinds Partners, LLC
+fairwinds
+
+// faith : 2014-11-20 dot Faith Limited
+faith
+
+// fan : 2014-03-06
+fan
+
+// fans : 2014-11-07 Asiamix Digital Limited
+fans
+
+// farm : 2013-11-07 Just Maple, LLC
+farm
+
+// fashion : 2014-07-03 Top Level Domain Holdings Limited
+fashion
+
+// fast : 2014-12-18 Amazon EU S.à r.l.
+fast
+
+// feedback : 2013-12-19 Top Level Spectrum, Inc.
+feedback
+
+// ferrero : 2014-12-18 Ferrero Trading Lux S.A.
+ferrero
+
+// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+final
+
+// finance : 2014-03-20 Cotton Cypress, LLC
+finance
+
+// financial : 2014-03-06 Just Cover, LLC
+financial
+
+// firestone : 2014-12-18 Bridgestone Corporation
+firestone
+
+// firmdale : 2014-03-27 Firmdale Holdings Limited
+firmdale
+
+// fish : 2013-12-12 Fox Woods, LLC
+fish
+
+// fishing : 2013-11-21 Top Level Domain Holdings Limited
+fishing
+
+// fit : 2014-11-07 Top Level Domain Holdings Limited
+fit
+
+// fitness : 2014-03-06 Brice Orchard, LLC
+fitness
+
+// flights : 2013-12-05 Fox Station, LLC
+flights
+
+// florist : 2013-11-07 Half Cypress, LLC
+florist
+
+// flowers : 2014-10-09 Uniregistry, Corp.
+flowers
+
+// flsmidth : 2014-07-24 FLSmidth A/S
+flsmidth
+
+// fly : 2014-05-08 Charleston Road Registry Inc.
+fly
+
+// foo : 2014-01-23 Charleston Road Registry Inc.
+foo
+
+// football : 2014-12-18 Foggy Farms, LLC
+football
+
+// ford : 2014-11-13 Ford Motor Company
+ford
+
+// forex : 2014-12-11 IG Group Holdings PLC
+forex
+
+// forsale : 2014-05-22
+forsale
+
+// foundation : 2013-12-05 John Dale, LLC
+foundation
+
+// frl : 2014-05-15 FRLregistry B.V.
+frl
+
+// frogans : 2013-12-19 OP3FT
+frogans
+
+// fund : 2014-03-20 John Castle, LLC
+fund
+
+// furniture : 2014-03-20 Lone Fields, LLC
+furniture
+
+// futbol : 2013-09-20
+futbol
+
+// gal : 2013-11-07 Asociación puntoGAL
+gal
+
+// gallery : 2013-09-13 Sugar House, LLC
+gallery
+
+// garden : 2014-06-26 Top Level Domain Holdings Limited
+garden
+
+// gbiz : 2014-07-17 Charleston Road Registry Inc.
+gbiz
+
+// gdn : 2014-07-31 Joint Stock Company
+gdn
+
+// gea : 2014-12-04 GEA Group Aktiengesellschaft
+gea
+
+// gent : 2014-01-23 COMBELL GROUP NV/SA
+gent
+
+// ggee : 2014-01-09 GMO Internet, Inc.
+ggee
+
+// gift : 2013-10-17 Uniregistry, Corp.
+gift
+
+// gifts : 2014-07-03 Goose Sky, LLC
+gifts
+
+// gives : 2014-03-06 United TLD Holdco Ltd.
+gives
+
+// giving : 2014-11-13 Giving Limited
+giving
+
+// glass : 2013-11-07 Black Cover, LLC
+glass
+
+// gle : 2014-07-24 Charleston Road Registry Inc.
+gle
+
+// global : 2014-04-17 Dot GLOBAL AS
+global
+
+// globo : 2013-12-19 Globo Comunicação e Participações S.A
+globo
+
+// gmail : 2014-05-01 Charleston Road Registry Inc.
+gmail
+
+// gmo : 2014-01-09 GMO Internet, Inc.
+gmo
+
+// gmx : 2014-04-24 1&1 Mail & Media GmbH
+gmx
+
+// goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+goldpoint
+
+// golf : 2014-12-18 Lone falls, LLC
+golf
+
+// goo : 2014-12-18 NTT Resonant Inc.
+goo
+
+// goog : 2014-11-20 Charleston Road Registry Inc.
+goog
+
+// google : 2014-07-24 Charleston Road Registry Inc.
+google
+
+// gop : 2014-01-16 Republican State Leadership Committee, Inc.
+gop
+
+// got : 2014-12-18 Amazon EU S.à r.l.
+got
+
+// graphics : 2013-09-13 Over Madison, LLC
+graphics
+
+// gratis : 2014-03-20 Pioneer Tigers, LLC
+gratis
+
+// green : 2014-05-08 Afilias Limited
+green
+
+// gripe : 2014-03-06 Corn Sunset, LLC
+gripe
+
+// group : 2014-08-15 Romeo Town, LLC
+group
+
+// gucci : 2014-11-13 Guccio Gucci S.p.a.
+gucci
+
+// guge : 2014-08-28 Charleston Road Registry Inc.
+guge
+
+// guide : 2013-09-13 Snow Moon, LLC
+guide
+
+// guitars : 2013-11-14 Uniregistry, Corp.
+guitars
+
+// guru : 2013-08-27 Pioneer Cypress, LLC
+guru
+
+// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
+hamburg
+
+// hangout : 2014-11-13 Charleston Road Registry Inc.
+hangout
+
+// haus : 2013-12-05
+haus
+
+// healthcare : 2014-06-12 Silver Glen, LLC
+healthcare
+
+// help : 2014-06-26 Uniregistry, Corp.
+help
+
+// here : 2014-02-06 Charleston Road Registry Inc.
+here
+
+// hermes : 2014-07-10 HERMES INTERNATIONAL
+hermes
+
+// hiphop : 2014-03-06 Uniregistry, Corp.
+hiphop
+
+// hitachi : 2014-10-31 Hitachi, Ltd.
+hitachi
+
+// hiv : 2014-03-13 dotHIV gemeinnuetziger e.V.
+hiv
+
+// holdings : 2013-08-27 John Madison, LLC
+holdings
+
+// holiday : 2013-11-07 Goose Woods, LLC
+holiday
+
+// homes : 2014-01-09 DERHomes, LLC
+homes
+
+// honda : 2014-12-18 Honda Motor Co., Ltd.
+honda
+
+// horse : 2013-11-21 Top Level Domain Holdings Limited
+horse
+
+// host : 2014-04-17 DotHost Inc.
+host
+
+// hosting : 2014-05-29 Uniregistry, Corp.
+hosting
+
+// hotmail : 2014-12-18 Microsoft Corporation
+hotmail
+
+// house : 2013-11-07 Sugar Park, LLC
+house
+
+// how : 2014-01-23 Charleston Road Registry Inc.
+how
+
+// hsbc : 2014-10-24 HSBC Holdings PLC
+hsbc
+
+// ibm : 2014-07-31 International Business Machines Corporation
+ibm
+
+// ice : 2014-10-30 IntercontinentalExchange, Inc.
+ice
+
+// ifm : 2014-01-30 ifm electronic gmbh
+ifm
+
+// iinet : 2014-07-03 Connect West Pty. Ltd.
+iinet
+
+// immo : 2014-07-10 Auburn Bloom, LLC
+immo
+
+// immobilien : 2013-11-07 United TLD Holdco Ltd.
+immobilien
+
+// industries : 2013-12-05 Outer House, LLC
+industries
+
+// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
+infiniti
+
+// ing : 2014-01-23 Charleston Road Registry Inc.
+ing
+
+// ink : 2013-12-05 Top Level Design, LLC
+ink
+
+// institute : 2013-11-07 Outer Maple, LLC
+institute
+
+// insure : 2014-03-20 Pioneer Willow, LLC
+insure
+
+// international : 2013-11-07 Wild Way, LLC
+international
+
+// investments : 2014-03-20 Holly Glen, LLC
+investments
+
+// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A.
+ipiranga
+
+// irish : 2014-08-07 Dot-Irish LLC
+irish
+
+// ist : 2014-08-28 Istanbul Metropolitan Municipality
+ist
+
+// istanbul : 2014-08-28 Istanbul Metropolitan Municipality
+istanbul
+
+// itau : 2014-10-02 Itau Unibanco Holding S.A.
+itau
+
+// iwc : 2014-06-23 Richemont DNS Inc.
+iwc
+
+// jaguar : 2014-11-13 Jaguar Land Rover Ltd
+jaguar
+
+// java : 2014-06-19 Oracle Corporation
+java
+
+// jcb : 2014-11-20 JCB Co., Ltd.
+jcb
+
+// jetzt : 2014-01-09 New TLD Company AB
+jetzt
+
+// jlc : 2014-12-04 Richemont DNS Inc.
+jlc
+
+// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+joburg
+
+// jot : 2014-12-18 Amazon EU S.à r.l.
+jot
+
+// joy : 2014-12-18 Amazon EU S.à r.l.
+joy
+
+// jprs : 2014-09-18 Japan Registry Services Co., Ltd.
+jprs
+
+// juegos : 2014-03-20 Uniregistry, Corp.
+juegos
+
+// kaufen : 2013-11-07 United TLD Holdco Ltd.
+kaufen
+
+// kddi : 2014-09-12 KDDI CORPORATION
+kddi
+
+// kfh : 2014-12-04 Kuwait Finance House
+kfh
+
+// kim : 2013-09-23 Afilias Limited
+kim
+
+// kinder : 2014-11-07 Ferrero Trading Lux S.A.
+kinder
+
+// kitchen : 2013-09-20 Just Goodbye, LLC
+kitchen
+
+// kiwi : 2013-09-20 DOT KIWI LIMITED
+kiwi
+
+// koeln : 2014-01-09 NetCologne Gesellschaft für Telekommunikation mbH
+koeln
+
+// krd : 2013-12-05 KRG Department of Information Technology
+krd
+
+// kred : 2013-12-19 KredTLD Pty Ltd
+kred
+
+// kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen
+kyoto
+
+// lacaixa : 2014-01-09 CAIXA D'ESTALVIS I PENSIONS DE BARCELONA
+lacaixa
+
+// land : 2013-09-10 Pine Moon, LLC
+land
+
+// landrover : 2014-11-13 Jaguar Land Rover Ltd
+landrover
+
+// lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico
+lat
+
+// latrobe : 2014-06-16 La Trobe University
+latrobe
+
+// lawyer : 2014-03-20
+lawyer
+
+// lds : 2014-03-20 IRI Domain Management, LLC (
+lds
+
+// lease : 2014-03-06 Victor Trail, LLC
+lease
+
+// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
+leclerc
+
+// legal : 2014-10-16 Blue Falls, LLC
+legal
+
+// lgbt : 2014-05-08 Afilias Limited
+lgbt
+
+// liaison : 2014-10-02 Liaison Technologies, Incorporated
+liaison
+
+// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+lidl
+
+// life : 2014-02-06 Trixy Oaks, LLC
+life
+
+// lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc.
+lifestyle
+
+// lighting : 2013-08-27 John McCook, LLC
+lighting
+
+// like : 2014-12-18 Amazon EU S.à r.l.
+like
+
+// limited : 2014-03-06 Big Fest, LLC
+limited
+
+// limo : 2013-10-17 Hidden Frostbite, LLC
+limo
+
+// lincoln : 2014-11-13 Ford Motor Company
+lincoln
+
+// linde : 2014-12-04 Linde Aktiengesellschaft
+linde
+
+// link : 2013-11-14 Uniregistry, Corp.
+link
+
+// live : 2014-12-04 Half Woods, LLC
+live
+
+// loan : 2014-11-20 dot Loan Limited
+loan
+
+// loans : 2014-03-20 June Woods, LLC
+loans
+
+// london : 2013-11-14 Dot London Domains Limited
+london
+
+// lotte : 2014-11-07 Lotte Holdings Co., Ltd.
+lotte
+
+// lotto : 2014-04-10 Afilias Limited
+lotto
+
+// ltd : 2014-09-25 Over Corner, LLC
+ltd
+
+// ltda : 2014-04-17 DOMAIN ROBOT SERVICOS DE HOSPEDAGEM NA INTERNET LTDA
+ltda
+
+// lupin : 2014-11-07 LUPIN LIMITED
+lupin
+
+// luxe : 2014-01-09 Top Level Domain Holdings Limited
+luxe
+
+// luxury : 2013-10-17 Luxury Partners, LLC
+luxury
+
+// madrid : 2014-05-01 Comunidad de Madrid
+madrid
+
+// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF)
+maif
+
+// maison : 2013-12-05 Victor Frostbite, LLC
+maison
+
+// man : 2014-12-04 MAN SE
+man
+
+// management : 2013-11-07 John Goodbye, LLC
+management
+
+// mango : 2013-10-24 PUNTO FA S.L.
+mango
+
+// market : 2014-03-06
+market
+
+// marketing : 2013-11-07 Fern Pass, LLC
+marketing
+
+// markets : 2014-12-11 IG Group Holdings PLC
+markets
+
+// marriott : 2014-10-09 Marriott Worldwide Corporation
+marriott
+
+// media : 2014-03-06 Grand Glen, LLC
+media
+
+// meet : 2014-01-16 Afilias Limited
+meet
+
+// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
+melbourne
+
+// meme : 2014-01-30 Charleston Road Registry Inc.
+meme
+
+// memorial : 2014-10-16 Dog Beach, LLC
+memorial
+
+// menu : 2013-09-11 Wedding TLD2, LLC
+menu
+
+// meo : 2014-11-07 PT Comunicacoes S.A.
+meo
+
+// miami : 2013-12-19 Top Level Domain Holdings Limited
+miami
+
+// microsoft : 2014-12-18 Microsoft Corporation
+microsoft
+
+// mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+mini
+
+// mma : 2014-11-07 MMA IARD
+mma
+
+// mobily : 2014-12-18 GreenTech Consultancy Company W.L.L.
+mobily
+
+// moda : 2013-11-07 United TLD Holdco Ltd.
+moda
+
+// moe : 2013-11-13 Interlink Co., Ltd.
+moe
+
+// moi : 2014-12-18 Amazon EU S.à r.l.
+moi
+
+// monash : 2013-09-30 Monash University
+monash
+
+// money : 2014-10-16 Outer McCook, LLC
+money
+
+// montblanc : 2014-06-23 Richemont DNS Inc.
+montblanc
+
+// mormon : 2013-12-05 IRI Domain Management, LLC (
+mormon
+
+// mortgage : 2014-03-20
+mortgage
+
+// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+moscow
+
+// motorcycles : 2014-01-09 DERMotorcycles, LLC
+motorcycles
+
+// mov : 2014-01-30 Charleston Road Registry Inc.
+mov
+
+// movistar : 2014-10-16 Telefónica S.A.
+movistar
+
+// mtn : 2014-12-04 MTN Dubai Limited
+mtn
+
+// mtpc : 2014-11-20 Mitsubishi Tanabe Pharma Corporation
+mtpc
+
+// nadex : 2014-12-11 IG Group Holdings PLC
+nadex
+
+// nagoya : 2013-10-24 GMO Registry, Inc.
+nagoya
+
+// navy : 2014-03-06 United TLD Holdco Ltd.
+navy
+
+// netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+netbank
+
+// network : 2013-11-14 Trixy Manor, LLC
+network
+
+// neustar : 2013-12-05 NeuStar, Inc.
+neustar
+
+// new : 2014-01-30 Charleston Road Registry Inc.
+new
+
+// news : 2014-12-18 Hidden Bloom, LLC
+news
+
+// nexus : 2014-07-24 Charleston Road Registry Inc.
+nexus
+
+// ngo : 2014-03-06 Public Interest Registry
+ngo
+
+// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
+nhk
+
+// nico : 2014-12-04 DWANGO Co., Ltd.
+nico
+
+// ninja : 2013-11-07 United TLD Holdco Ltd.
+ninja
+
+// nissan : 2014-03-27 NISSAN MOTOR CO., LTD.
+nissan
+
+// norton : 2014-12-04 Symantec Corporation
+norton
+
+// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+nowruz
+
+// nra : 2014-05-22 NRA Holdings Company, INC.
+nra
+
+// nrw : 2013-11-21 Minds + Machines GmbH
+nrw
+
+// ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ntt
+
+// nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications
+nyc
+
+// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
+obi
+
+// okinawa : 2013-12-05 BusinessRalliart Inc.
+okinawa
+
+// one : 2014-11-07 One.com A/S
+one
+
+// ong : 2014-03-06 Public Interest Registry
+ong
+
+// onl : 2013-09-16 I-Registry Ltd.
+onl
+
+// ooo : 2014-01-09 INFIBEAM INCORPORATION LIMITED
+ooo
+
+// oracle : 2014-06-19 Oracle Corporation
+oracle
+
+// organic : 2014-03-27 Afilias Limited
+organic
+
+// osaka : 2014-09-04 Interlink Co., Ltd.
+osaka
+
+// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd.
+otsuka
+
+// ovh : 2014-01-16 OVH SAS
+ovh
+
+// page : 2014-12-04 Charleston Road Registry Inc.
+page
+
+// panerai : 2014-11-07 Richemont DNS Inc.
+panerai
+
+// paris : 2014-01-30 City of Paris
+paris
+
+// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+pars
+
+// partners : 2013-12-05 Magic Glen, LLC
+partners
+
+// parts : 2013-12-05 Sea Goodbye, LLC
+parts
+
+// party : 2014-09-11 Blue Sky Registry Limited
+party
+
+// pharmacy : 2014-06-19 National Association of Boards of Pharmacy
+pharmacy
+
+// philips : 2014-11-07 Koninklijke Philips N.V.
+philips
+
+// photo : 2013-11-14 Uniregistry, Corp.
+photo
+
+// photography : 2013-09-20 Sugar Glen, LLC
+photography
+
+// photos : 2013-10-17 Sea Corner, LLC
+photos
+
+// physio : 2014-05-01 PhysBiz Pty Ltd
+physio
+
+// piaget : 2014-10-16 Richemont DNS Inc.
+piaget
+
+// pics : 2013-11-14 Uniregistry, Corp.
+pics
+
+// pictet : 2014-06-26 Pictet Europe S.A.
+pictet
+
+// pictures : 2014-03-06 Foggy Sky, LLC
+pictures
+
+// pin : 2014-12-18 Amazon EU S.à r.l.
+pin
+
+// pink : 2013-10-01 Afilias Limited
+pink
+
+// pizza : 2014-06-26 Foggy Moon, LLC
+pizza
+
+// place : 2014-04-24 Snow Galley, LLC
+place
+
+// plumbing : 2013-09-10 Spring Tigers, LLC
+plumbing
+
+// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+pohl
+
+// poker : 2014-07-03 Afilias Domains No. 5 Limited
+poker
+
+// porn : 2014-10-16 ICM Registry PN LLC
+porn
+
+// praxi : 2013-12-05 Praxi S.p.A.
+praxi
+
+// press : 2014-04-03 DotPress Inc.
+press
+
+// prod : 2014-01-23 Charleston Road Registry Inc.
+prod
+
+// productions : 2013-12-05 Magic Birch, LLC
+productions
+
+// prof : 2014-07-24 Charleston Road Registry Inc.
+prof
+
+// promo : 2014-12-18 Play.PROMO Oy
+promo
+
+// properties : 2013-12-05 Big Pass, LLC
+properties
+
+// property : 2014-05-22 Uniregistry, Corp.
+property
+
+// pub : 2013-12-12 United TLD Holdco Ltd.
+pub
+
+// qpon : 2013-11-14 dotCOOL, Inc.
+qpon
+
+// quebec : 2013-12-19 PointQuébec Inc
+quebec
+
+// racing : 2014-12-04 Premier Registry Limited
+racing
+
+// read : 2014-12-18 Amazon EU S.à r.l.
+read
+
+// realtor : 2014-05-29 Real Estate Domains LLC
+realtor
+
+// recipes : 2013-10-17 Grand Island, LLC
+recipes
+
+// red : 2013-11-07 Afilias Limited
+red
+
+// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd.
+redstone
+
+// rehab : 2014-03-06 United TLD Holdco Ltd.
+rehab
+
+// reise : 2014-03-13 dotreise GmbH
+reise
+
+// reisen : 2014-03-06 New Cypress, LLC
+reisen
+
+// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc.
+reit
+
+// ren : 2013-12-12 Beijing Qianxiang Wangjing Technology Development Co., Ltd.
+ren
+
+// rent : 2014-12-04 DERRent, LLC
+rent
+
+// rentals : 2013-12-05 Big Hollow,LLC
+rentals
+
+// repair : 2013-11-07 Lone Sunset, LLC
+repair
+
+// report : 2013-12-05 Binky Glen, LLC
+report
+
+// republican : 2014-03-20 United TLD Holdco Ltd.
+republican
+
+// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+rest
+
+// restaurant : 2014-07-03 Snow Avenue, LLC
+restaurant
+
+// review : 2014-11-20 dot Review Limited
+review
+
+// reviews : 2013-09-13
+reviews
+
+// rich : 2013-11-21 I-Registry Ltd.
+rich
+
+// ricoh : 2014-11-20 Ricoh Company, Ltd.
+ricoh
+
+// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
+rio
+
+// rip : 2014-07-10 United TLD Holdco Ltd.
+rip
+
+// rocher : 2014-12-18 Ferrero Trading Lux S.A.
+rocher
+
+// rocks : 2013-11-14
+rocks
+
+// rodeo : 2013-12-19 Top Level Domain Holdings Limited
+rodeo
+
+// room : 2014-12-18 Amazon EU S.à r.l.
+room
+
+// rsvp : 2014-05-08 Charleston Road Registry Inc.
+rsvp
+
+// ruhr : 2013-10-02 regiodot GmbH & Co. KG
+ruhr
+
+// ryukyu : 2014-01-09 BusinessRalliart Inc.
+ryukyu
+
+// saarland : 2013-12-12 dotSaarland GmbH
+saarland
+
+// safe : 2014-12-18 Amazon EU S.à r.l.
+safe
+
+// sakura : 2014-12-18 SAKURA Internet Inc.
+sakura
+
+// sale : 2014-10-16
+sale
+
+// salon : 2014-12-11 Outer Orchard, LLC
+salon
+
+// samsung : 2014-04-03 SAMSUNG SDS CO., LTD
+samsung
+
+// sandvik : 2014-11-13 Sandvik AB
+sandvik
+
+// sandvikcoromant : 2014-11-07 Sandvik AB
+sandvikcoromant
+
+// sanofi : 2014-10-09 Sanofi
+sanofi
+
+// sap : 2014-03-27 SAP AG
+sap
+
+// sapo : 2014-11-07 PT Comunicacoes S.A.
+sapo
+
+// sarl : 2014-07-03 Delta Orchard, LLC
+sarl
+
+// saxo : 2014-10-31 Saxo Bank A/S
+saxo
+
+// sbs : 2014-11-07 SPECIAL BROADCASTING SERVICE CORPORATION
+sbs
+
+// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
+sca
+
+// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited (
+scb
+
+// schmidt : 2014-04-03 SALM S.A.S.
+schmidt
+
+// scholarships : 2014-04-24 Scholarships.com, LLC
+scholarships
+
+// school : 2014-12-18 Little Galley, LLC
+school
+
+// schule : 2014-03-06 Outer Moon, LLC
+schule
+
+// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+schwarz
+
+// science : 2014-09-11 dot Science Limited
+science
+
+// scor : 2014-10-31 SCOR SE
+scor
+
+// scot : 2014-01-23 Dot Scot Registry Limited
+scot
+
+// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
+seat
+
+// seek : 2014-12-04 Seek Limited
+seek
+
+// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A.
+sener
+
+// services : 2014-02-27 Fox Castle, LLC
+services
+
+// sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG
+sew
+
+// sex : 2014-11-13 ICM Registry SX LLC
+sex
+
+// sexy : 2013-09-11 Uniregistry, Corp.
+sexy
+
+// sharp : 2014-05-01 Sharp Corporation
+sharp
+
+// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+shia
+
+// shiksha : 2013-11-14 Afilias Limited
+shiksha
+
+// shoes : 2013-10-02 Binky Galley, LLC
+shoes
+
+// shriram : 2014-01-23 Shriram Capital Ltd.
+shriram
+
+// singles : 2013-08-27 Fern Madison, LLC
+singles
+
+// sky : 2014-06-19 Sky IP International Ltd, a company incorporated in England and Wales, operating via its registered Swiss branch
+sky
+
+// skype : 2014-12-18 Microsoft Corporation
+skype
+
+// smile : 2014-12-18 Amazon EU S.à r.l.
+smile
+
+// social : 2013-11-07 United TLD Holdco Ltd.
+social
+
+// software : 2014-03-20
+software
+
+// sohu : 2013-12-19 Sohu.com Limited
+sohu
+
+// solar : 2013-11-07 Ruby Town, LLC
+solar
+
+// solutions : 2013-11-07 Silver Cover, LLC
+solutions
+
+// soy : 2014-01-23 Charleston Road Registry Inc.
+soy
+
+// space : 2014-04-03 DotSpace Inc.
+space
+
+// spiegel : 2014-02-05 SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG
+spiegel
+
+// spreadbetting : 2014-12-11 IG Group Holdings PLC
+spreadbetting
+
+// stada : 2014-11-13 STADA Arzneimittel AG
+stada
+
+// statoil : 2014-12-04 Statoil ASA
+statoil
+
+// stc : 2014-10-09 Saudi Telecom Company
+stc
+
+// stcgroup : 2014-10-09 Saudi Telecom Company
+stcgroup
+
+// stockholm : 2014-12-18 Stockholms kommun
+stockholm
+
+// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD
+study
+
+// style : 2014-12-04 Binky Moon, LLC
+style
+
+// supplies : 2013-12-19 Atomic Fields, LLC
+supplies
+
+// supply : 2013-12-19 Half Falls, LLC
+supply
+
+// support : 2013-10-24 Grand Orchard, LLC
+support
+
+// surf : 2014-01-09 Top Level Domain Holdings Limited
+surf
+
+// surgery : 2014-03-20 Tin Avenue, LLC
+surgery
+
+// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
+suzuki
+
+// swiss : 2014-10-16 Swiss Confederation
+swiss
+
+// sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet
+sydney
+
+// symantec : 2014-12-04 Symantec Corporation
+symantec
+
+// systems : 2013-11-07 Dash Cypress, LLC
+systems
+
+// tab : 2014-12-04 Tabcorp Holdings Limited
+tab
+
+// taipei : 2014-07-10 Taipei City Government
+taipei
+
+// tatar : 2014-04-24 Limited Liability Company
+tatar
+
+// tattoo : 2013-08-30 Uniregistry, Corp.
+tattoo
+
+// tax : 2014-03-20 Storm Orchard, LLC
+tax
+
+// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+tci
+
+// technology : 2013-09-13 Auburn Falls
+technology
+
+// telefonica : 2014-10-16 Telefónica S.A.
+telefonica
+
+// temasek : 2014-08-07 Temasek Holdings (Private) Limited
+temasek
+
+// tennis : 2014-12-04 Cotton Bloom, LLC
+tennis
+
+// tienda : 2013-11-14 Victor Manor, LLC
+tienda
+
+// tips : 2013-09-20 Corn Willow, LLC
+tips
+
+// tires : 2014-11-07 Dog Edge, LLC
+tires
+
+// tirol : 2014-04-24 punkt Tirol GmbH
+tirol
+
+// today : 2013-09-20 Pearl Woods, LLC
+today
+
+// tokyo : 2013-11-13 GMO Registry, Inc.
+tokyo
+
+// tools : 2013-11-21 Pioneer North, LLC
+tools
+
+// top : 2014-03-20 Jiangsu Bangning Science & Technology Co.,Ltd.
+top
+
+// toray : 2014-12-18 Toray Industries, Inc.
+toray
+
+// toshiba : 2014-04-10 TOSHIBA Corporation
+toshiba
+
+// town : 2014-03-06 Koko Moon, LLC
+town
+
+// toys : 2014-03-06 Pioneer Orchard, LLC
+toys
+
+// trade : 2014-01-23 Elite Registry Limited
+trade
+
+// trading : 2014-12-11 IG Group Holdings PLC
+trading
+
+// training : 2013-11-07 Wild Willow, LLC
+training
+
+// trust : 2014-10-16
+trust
+
+// tui : 2014-07-03 TUI AG
+tui
+
+// tushu : 2014-12-18 Amazon EU S.à r.l.
+tushu
+
+// ubs : 2014-12-11 UBS AG
+ubs
+
+// university : 2014-03-06 Little Station, LLC
+university
+
+// uno : 2013-09-11 Dot Latin LLC
+uno
+
+// uol : 2014-05-01 UBN INTERNET LTDA.
+uol
+
+// vacations : 2013-12-05 Atomic Tigers, LLC
+vacations
+
+// vana : 2014-12-11 Lifestyle Domain Holdings, Inc.
+vana
+
+// vegas : 2014-01-16 Dot Vegas, Inc.
+vegas
+
+// ventures : 2013-08-27 Binky Lake, LLC
+ventures
+
+// versicherung : 2014-03-20 dotversicherung-registry GmbH
+versicherung
+
+// vet : 2014-03-06
+vet
+
+// viajes : 2013-10-17 Black Madison, LLC
+viajes
+
+// video : 2014-10-16
+video
+
+// villas : 2013-12-05 New Sky, LLC
+villas
+
+// virgin : 2014-09-25 Virgin Enterprises Limited
+virgin
+
+// vision : 2013-12-05 Koko Station, LLC
+vision
+
+// vista : 2014-09-18 Vistaprint Limited
+vista
+
+// vistaprint : 2014-09-18 Vistaprint Limited
+vistaprint
+
+// viva : 2014-11-07 Saudi Telecom Company
+viva
+
+// vlaanderen : 2014-02-06 DNS.be vzw
+vlaanderen
+
+// vodka : 2013-12-19 Top Level Domain Holdings Limited
+vodka
+
+// vote : 2013-11-21 Monolith Registry LLC
+vote
+
+// voting : 2013-11-13 Valuetainment Corp.
+voting
+
+// voto : 2013-11-21 Monolith Registry LLC
+voto
+
+// voyage : 2013-08-27 Ruby House, LLC
+voyage
+
+// wales : 2014-05-08 Nominet UK
+wales
+
+// walter : 2014-11-13 Sandvik AB
+walter
+
+// wang : 2013-10-24 Zodiac Leo Limited
+wang
+
+// wanggou : 2014-12-18 Amazon EU S.à r.l.
+wanggou
+
+// watch : 2013-11-14 Sand Shadow, LLC
+watch
+
+// webcam : 2014-01-23 dot Webcam Limited
+webcam
+
+// website : 2014-04-03 DotWebsite Inc.
+website
+
+// wed : 2013-10-01 Atgron, Inc.
+wed
+
+// wedding : 2014-04-24 Top Level Domain Holdings Limited
+wedding
+
+// whoswho : 2014-02-20 Who's Who Registry
+whoswho
+
+// wien : 2013-10-28 punkt.wien GmbH
+wien
+
+// wiki : 2013-11-07 Top Level Design, LLC
+wiki
+
+// williamhill : 2014-03-13 William Hill Organization Limited
+williamhill
+
+// win : 2014-11-20 First Registry Limited
+win
+
+// windows : 2014-12-18 Microsoft Corporation
+windows
+
+// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
+wme
+
+// work : 2013-12-19 Top Level Domain Holdings Limited
+work
+
+// works : 2013-11-14 Little Dynamite, LLC
+works
+
+// world : 2014-06-12 Bitter Fields, LLC
+world
+
+// wtc : 2013-12-19 World Trade Centers Association, Inc.
+wtc
+
+// wtf : 2014-03-06 Hidden Way, LLC
+wtf
+
+// xbox : 2014-12-18 Microsoft Corporation
+xbox
+
+// xerox : 2014-10-24 Xerox DNHC LLC
+xerox
+
+// xin : 2014-12-11 Elegant Leader Limited
+xin
+
+// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
+佛山
+xn--1qqw23a
+
+// xn--30rr7y : 2014-06-12 Excellent First Limited
+慈善
+xn--30rr7y
+
+// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
+集团
+xn--3bst00m
+
+// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED
+在线
+xn--3ds443g
+
+// xn--45q11c : 2013-11-21 Zodiac Scorpio Limited
+八卦
+xn--45q11c
+
+// xn--4gbrim : 2013-10-04 Suhub Electronic Establishment
+موقع
+xn--4gbrim
+
+// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
+公益
+xn--55qw42g
+
+// xn--55qx5d : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+公司
+xn--55qx5d
+
+// xn--6frz82g : 2013-09-23 Afilias Limited
+移动
+xn--6frz82g
+
+// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited
+我爱你
+xn--6qq986b3xl
+
+// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+москва
+xn--80adxhks
+
+// xn--80asehdb : 2013-07-14 CORE Association
+онлайн
+xn--80asehdb
+
+// xn--80aswg : 2013-07-14 CORE Association
+сайт
+xn--80aswg
+
+// xn--9et52u : 2014-06-12 RISE VICTORY LIMITED
+时尚
+xn--9et52u
+
+// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited
+淡马锡
+xn--b4w605ferd
+
+// xn--c1avg : 2013-11-14 Public Interest Registry
+орг
+xn--c1avg
+
+// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD
+삼성
+xn--cg4bki
+
+// xn--czr694b : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES(HOLDING) COMPANY.HONGKONG LIMITED
+商标
+xn--czr694b
+
+// xn--czrs0t : 2013-12-19 Wild Island, LLC
+商店
+xn--czrs0t
+
+// xn--czru2d : 2013-11-21 Zodiac Capricorn Limited
+商城
+xn--czru2d
+
+// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
+дети
+xn--d1acj3b
+
+// xn--eckvdtc9d : 2014-12-18 Amazon EU S.à r.l.
+ポイント
+xn--eckvdtc9d
+
+// xn--efvy88h : 2014-08-22 Xinhua News Agency Guangdong Branch 新华通讯社广东分社
+新闻
+xn--efvy88h
+
+// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED
+中文网
+xn--fiq228c5hs
+
+// xn--fiq64b : 2013-10-14 CITIC Group Corporation
+中信
+xn--fiq64b
+
+// xn--fjq720a : 2014-05-22 Will Bloom, LLC
+娱乐
+xn--fjq720a
+
+// xn--flw351e : 2014-07-31 Charleston Road Registry Inc.
+谷歌
+xn--flw351e
+
+// xn--hxt814e : 2014-05-15 Zodiac Libra Limited
+网店
+xn--hxt814e
+
+// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
+संगठन
+xn--i1b6b1a6a2e
+
+// xn--imr513n : 2014-12-11 HU YI GLOBAL INFORMATION RESOURCES (HOLDING) COMPANY. HONGKONG LIMITED
+餐厅
+xn--imr513n
+
+// xn--io0a7i : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+网络
+xn--io0a7i
+
+// xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V.
+飞利浦
+xn--kcrx77d1x4a
+
+// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd
+手机
+xn--kput3i
+
+// xn--mgba3a3ejt : 2014-11-20 Aramco Services Company
+ارامكو
+xn--mgba3a3ejt
+
+// xn--mgbab2bd : 2013-10-31 CORE Association
+بازار
+xn--mgbab2bd
+
+// xn--mgbb9fbpob : 2014-12-18 GreenTech Consultancy Company W.L.L.
+موبايلي
+xn--mgbb9fbpob
+
+// xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+همراه
+xn--mgbt3dhd
+
+// xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd.
+政府
+xn--mxtq1m
+
+// xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd.
+شبكة
+xn--ngbc5azd
+
+// xn--ngbe9e0a : 2014-12-04 Kuwait Finance House
+بيتك
+xn--ngbe9e0a
+
+// xn--nqv7f : 2013-11-14 Public Interest Registry
+机构
+xn--nqv7f
+
+// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry
+组织机构
+xn--nqv7fs00ema
+
+// xn--nyqy26a : 2014-11-07 Stable Tone Limited
+健康
+xn--nyqy26a
+
+// xn--p1acf : 2013-12-12 Rusnames Limited
+рус
+xn--p1acf
+
+// xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc.
+みんな
+xn--q9jyb4c
+
+// xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc.
+グーグル
+xn--qcka1pmc
+
+// xn--rhqv96g : 2013-09-11 Stable Tone Limited
+世界
+xn--rhqv96g
+
+// xn--ses554g : 2014-01-16 HU YI GLOBAL INFORMATION RESOURCES (HOLDING) COMPANY. HONGKONG LIMITED
+网址
+xn--ses554g
+
+// xn--unup4y : 2013-07-14 Spring Fields, LLC
+游戏
+xn--unup4y
+
+// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberater
+xn--vermgensberater-ctb
+
+// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+vermögensberatung
+xn--vermgensberatung-pwb
+
+// xn--vhquv : 2013-08-27 Dash McCook, LLC
+企业
+xn--vhquv
+
+// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd.
+信息
+xn--vuq861b
+
+// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd.
+广东
+xn--xhq521b
+
+// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center
+政务
+xn--zfr164b
+
+// xyz : 2013-12-05 XYZ.COM LLC
+xyz
+
+// yachts : 2014-01-09 DERYachts, LLC
+yachts
+
+// yamaxun : 2014-12-18 Amazon EU S.à r.l.
+yamaxun
+
+// yandex : 2014-04-10 YANDEX, LLC
+yandex
+
+// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+yodobashi
+
+// yoga : 2014-05-29 Top Level Domain Holdings Limited
+yoga
+
+// yokohama : 2013-12-12 GMO Registry, Inc.
+yokohama
+
+// youtube : 2014-05-01 Charleston Road Registry Inc.
+youtube
+
+// zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.)
+zara
+
+// zero : 2014-12-18 Amazon EU S.à r.l.
+zero
+
+// zip : 2014-05-08 Charleston Road Registry Inc.
+zip
+
+// zone : 2013-11-14 Outer Falls, LLC
+zone
+
+// zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich)
+zuerich
+
+// ===END ICANN DOMAINS===
+// ===BEGIN PRIVATE DOMAINS===
+
+// Amazon CloudFront : https://aws.amazon.com/cloudfront/
+// Submitted by Donavan Miller <donavanm@amazon.com> 2013-03-22
+cloudfront.net
+
+// Amazon Elastic Compute Cloud: https://aws.amazon.com/ec2/
+// Submitted by Osman Surkatty <osmans@amazon.com> 2014-12-16
+ap-northeast-1.compute.amazonaws.com
+ap-southeast-1.compute.amazonaws.com
+ap-southeast-2.compute.amazonaws.com
+cn-north-1.compute.amazonaws.cn
+compute.amazonaws.cn
+compute.amazonaws.com
+compute-1.amazonaws.com
+eu-west-1.compute.amazonaws.com
+eu-central-1.compute.amazonaws.com
+sa-east-1.compute.amazonaws.com
+us-east-1.amazonaws.com
+us-gov-west-1.compute.amazonaws.com
+us-west-1.compute.amazonaws.com
+us-west-2.compute.amazonaws.com
+z-1.compute-1.amazonaws.com
+z-2.compute-1.amazonaws.com
+
+// Amazon Elastic Beanstalk : https://aws.amazon.com/elasticbeanstalk/
+// Submitted by Adam Stein <astein@amazon.com> 2013-04-02
+elasticbeanstalk.com
+
+// Amazon Elastic Load Balancing : https://aws.amazon.com/elasticloadbalancing/
+// Submitted by Scott Vidmar <svidmar@amazon.com> 2013-03-27
+elb.amazonaws.com
+
+// Amazon S3 : https://aws.amazon.com/s3/
+// Submitted by Courtney Eckhardt <coec@amazon.com> 2013-03-22
+s3.amazonaws.com
+s3-us-west-2.amazonaws.com
+s3-us-west-1.amazonaws.com
+s3-eu-west-1.amazonaws.com
+s3-ap-southeast-1.amazonaws.com
+s3-ap-southeast-2.amazonaws.com
+s3-ap-northeast-1.amazonaws.com
+s3-sa-east-1.amazonaws.com
+s3-us-gov-west-1.amazonaws.com
+s3-fips-us-gov-west-1.amazonaws.com
+s3-website-us-east-1.amazonaws.com
+s3-website-us-west-2.amazonaws.com
+s3-website-us-west-1.amazonaws.com
+s3-website-eu-west-1.amazonaws.com
+s3-website-ap-southeast-1.amazonaws.com
+s3-website-ap-southeast-2.amazonaws.com
+s3-website-ap-northeast-1.amazonaws.com
+s3-website-sa-east-1.amazonaws.com
+s3-website-us-gov-west-1.amazonaws.com
+
+// BetaInABox
+// Submitted by adrian@betainabox.com 2012-09-13
+betainabox.com
+
+// CentralNic : http://www.centralnic.com/names/domains
+// Submitted by registry <gavin.brown@centralnic.com> 2012-09-27
+ae.org
+ar.com
+br.com
+cn.com
+com.de
+com.se
+de.com
+eu.com
+gb.com
+gb.net
+hu.com
+hu.net
+jp.net
+jpn.com
+kr.com
+mex.com
+no.com
+qc.com
+ru.com
+sa.com
+se.com
+se.net
+uk.com
+uk.net
+us.com
+uy.com
+za.bz
+za.com
+
+// Africa.com Web Solutions Ltd : https://registry.africa.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+africa.com
+
+// iDOT Services Limited : http://www.domain.gr.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+gr.com
+
+// Radix FZC : http://domains.in.net
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+in.net
+
+// US REGISTRY LLC : http://us.org
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+us.org
+
+// co.com Registry, LLC : https://registry.co.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+co.com
+
+// c.la : http://www.c.la/
+c.la
+
+// cloudControl : https://www.cloudcontrol.com/
+// Submitted by Tobias Wilken <tw@cloudcontrol.com> 2013-07-23
+cloudcontrolled.com
+cloudcontrolapp.com
+
+// co.ca : http://registry.co.ca/
+co.ca
+
+// CoDNS B.V.
+co.nl
+co.no
+
+// Cupcake : https://cupcake.io/
+// Submitted by Jonathan Rudenberg <jonathan@cupcake.io> 2013-10-08
+cupcake.is
+
+// DreamHost : http://www.dreamhost.com/
+// Submitted by Andrew Farmer <andrew.farmer@dreamhost.com> 2012-10-02
+dreamhosters.com
+
+// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/
+dyndns-at-home.com
+dyndns-at-work.com
+dyndns-blog.com
+dyndns-free.com
+dyndns-home.com
+dyndns-ip.com
+dyndns-mail.com
+dyndns-office.com
+dyndns-pics.com
+dyndns-remote.com
+dyndns-server.com
+dyndns-web.com
+dyndns-wiki.com
+dyndns-work.com
+dyndns.biz
+dyndns.info
+dyndns.org
+dyndns.tv
+at-band-camp.net
+ath.cx
+barrel-of-knowledge.info
+barrell-of-knowledge.info
+better-than.tv
+blogdns.com
+blogdns.net
+blogdns.org
+blogsite.org
+boldlygoingnowhere.org
+broke-it.net
+buyshouses.net
+cechire.com
+dnsalias.com
+dnsalias.net
+dnsalias.org
+dnsdojo.com
+dnsdojo.net
+dnsdojo.org
+does-it.net
+doesntexist.com
+doesntexist.org
+dontexist.com
+dontexist.net
+dontexist.org
+doomdns.com
+doomdns.org
+dvrdns.org
+dyn-o-saur.com
+dynalias.com
+dynalias.net
+dynalias.org
+dynathome.net
+dyndns.ws
+endofinternet.net
+endofinternet.org
+endoftheinternet.org
+est-a-la-maison.com
+est-a-la-masion.com
+est-le-patron.com
+est-mon-blogueur.com
+for-better.biz
+for-more.biz
+for-our.info
+for-some.biz
+for-the.biz
+forgot.her.name
+forgot.his.name
+from-ak.com
+from-al.com
+from-ar.com
+from-az.net
+from-ca.com
+from-co.net
+from-ct.com
+from-dc.com
+from-de.com
+from-fl.com
+from-ga.com
+from-hi.com
+from-ia.com
+from-id.com
+from-il.com
+from-in.com
+from-ks.com
+from-ky.com
+from-la.net
+from-ma.com
+from-md.com
+from-me.org
+from-mi.com
+from-mn.com
+from-mo.com
+from-ms.com
+from-mt.com
+from-nc.com
+from-nd.com
+from-ne.com
+from-nh.com
+from-nj.com
+from-nm.com
+from-nv.com
+from-ny.net
+from-oh.com
+from-ok.com
+from-or.com
+from-pa.com
+from-pr.com
+from-ri.com
+from-sc.com
+from-sd.com
+from-tn.com
+from-tx.com
+from-ut.com
+from-va.com
+from-vt.com
+from-wa.com
+from-wi.com
+from-wv.com
+from-wy.com
+ftpaccess.cc
+fuettertdasnetz.de
+game-host.org
+game-server.cc
+getmyip.com
+gets-it.net
+go.dyndns.org
+gotdns.com
+gotdns.org
+groks-the.info
+groks-this.info
+ham-radio-op.net
+here-for-more.info
+hobby-site.com
+hobby-site.org
+home.dyndns.org
+homedns.org
+homeftp.net
+homeftp.org
+homeip.net
+homelinux.com
+homelinux.net
+homelinux.org
+homeunix.com
+homeunix.net
+homeunix.org
+iamallama.com
+in-the-band.net
+is-a-anarchist.com
+is-a-blogger.com
+is-a-bookkeeper.com
+is-a-bruinsfan.org
+is-a-bulls-fan.com
+is-a-candidate.org
+is-a-caterer.com
+is-a-celticsfan.org
+is-a-chef.com
+is-a-chef.net
+is-a-chef.org
+is-a-conservative.com
+is-a-cpa.com
+is-a-cubicle-slave.com
+is-a-democrat.com
+is-a-designer.com
+is-a-doctor.com
+is-a-financialadvisor.com
+is-a-geek.com
+is-a-geek.net
+is-a-geek.org
+is-a-green.com
+is-a-guru.com
+is-a-hard-worker.com
+is-a-hunter.com
+is-a-knight.org
+is-a-landscaper.com
+is-a-lawyer.com
+is-a-liberal.com
+is-a-libertarian.com
+is-a-linux-user.org
+is-a-llama.com
+is-a-musician.com
+is-a-nascarfan.com
+is-a-nurse.com
+is-a-painter.com
+is-a-patsfan.org
+is-a-personaltrainer.com
+is-a-photographer.com
+is-a-player.com
+is-a-republican.com
+is-a-rockstar.com
+is-a-socialist.com
+is-a-soxfan.org
+is-a-student.com
+is-a-teacher.com
+is-a-techie.com
+is-a-therapist.com
+is-an-accountant.com
+is-an-actor.com
+is-an-actress.com
+is-an-anarchist.com
+is-an-artist.com
+is-an-engineer.com
+is-an-entertainer.com
+is-by.us
+is-certified.com
+is-found.org
+is-gone.com
+is-into-anime.com
+is-into-cars.com
+is-into-cartoons.com
+is-into-games.com
+is-leet.com
+is-lost.org
+is-not-certified.com
+is-saved.org
+is-slick.com
+is-uberleet.com
+is-very-bad.org
+is-very-evil.org
+is-very-good.org
+is-very-nice.org
+is-very-sweet.org
+is-with-theband.com
+isa-geek.com
+isa-geek.net
+isa-geek.org
+isa-hockeynut.com
+issmarterthanyou.com
+isteingeek.de
+istmein.de
+kicks-ass.net
+kicks-ass.org
+knowsitall.info
+land-4-sale.us
+lebtimnetz.de
+leitungsen.de
+likes-pie.com
+likescandy.com
+merseine.nu
+mine.nu
+misconfused.org
+mypets.ws
+myphotos.cc
+neat-url.com
+office-on-the.net
+on-the-web.tv
+podzone.net
+podzone.org
+readmyblog.org
+saves-the-whales.com
+scrapper-site.net
+scrapping.cc
+selfip.biz
+selfip.com
+selfip.info
+selfip.net
+selfip.org
+sells-for-less.com
+sells-for-u.com
+sells-it.net
+sellsyourhome.org
+servebbs.com
+servebbs.net
+servebbs.org
+serveftp.net
+serveftp.org
+servegame.org
+shacknet.nu
+simple-url.com
+space-to-rent.com
+stuff-4-sale.org
+stuff-4-sale.us
+teaches-yoga.com
+thruhere.net
+traeumtgerade.de
+webhop.biz
+webhop.info
+webhop.net
+webhop.org
+worse-than.tv
+writesthisblog.com
+
+// Fastly Inc. http://www.fastly.com/
+// Submitted by Vladimir Vuksan <vladimir@fastly.com> 2013-05-31
+a.ssl.fastly.net
+b.ssl.fastly.net
+global.ssl.fastly.net
+a.prod.fastly.net
+global.prod.fastly.net
+
+// Firebase, Inc.
+// Submitted by Chris Raynor <chris@firebase.com> 2014-01-21
+firebaseapp.com
+
+// Flynn : https://flynn.io
+// Submitted by Jonathan Rudenberg <jonathan@flynn.io> 2014-07-12
+flynnhub.com
+
+// GitHub, Inc.
+// Submitted by Ben Toews <btoews@github.com> 2014-02-06
+github.io
+githubusercontent.com
+
+// GlobeHosting, Inc.
+// Submitted by Zoltan Egresi <egresi@globehosting.com> 2013-07-12
+ro.com
+
+// Google, Inc.
+// Submitted by Eduardo Vela <evn@google.com> 2014-12-19
+appspot.com
+blogspot.ae
+blogspot.be
+blogspot.bj
+blogspot.ca
+blogspot.cf
+blogspot.ch
+blogspot.co.at
+blogspot.co.il
+blogspot.co.nz
+blogspot.co.uk
+blogspot.com
+blogspot.com.ar
+blogspot.com.au
+blogspot.com.br
+blogspot.com.es
+blogspot.com.tr
+blogspot.cv
+blogspot.cz
+blogspot.de
+blogspot.dk
+blogspot.fi
+blogspot.fr
+blogspot.gr
+blogspot.hk
+blogspot.hu
+blogspot.ie
+blogspot.in
+blogspot.it
+blogspot.jp
+blogspot.kr
+blogspot.mr
+blogspot.mx
+blogspot.nl
+blogspot.no
+blogspot.pt
+blogspot.re
+blogspot.ro
+blogspot.ru
+blogspot.se
+blogspot.sg
+blogspot.sk
+blogspot.td
+blogspot.tw
+codespot.com
+googleapis.com
+googlecode.com
+pagespeedmobilizer.com
+withgoogle.com
+
+// Heroku : https://www.heroku.com/
+// Submitted by Tom Maher <tmaher@heroku.com> 2013-05-02
+herokuapp.com
+herokussl.com
+
+// iki.fi
+// Submitted by Hannu Aronsson <haa@iki.fi> 2009-11-05
+iki.fi
+
+// info.at : http://www.info.at/
+biz.at
+info.at
+
+// Michau Enterprises Limited : http://www.co.pl/
+co.pl
+
+// Microsoft : http://microsoft.com
+// Submitted by Barry Dorrans <bdorrans@microsoft.com> 2014-01-24
+azurewebsites.net
+azure-mobile.net
+cloudapp.net
+
+// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/
+// Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net> 2014-02-02
+nfshost.com
+
+// NYC.mn : http://www.information.nyc.mn
+// Submitted by Matthew Brown <mattbrown@nyc.mn> 2013-03-11
+nyc.mn
+
+// One Fold Media : http://www.onefoldmedia.com/
+// Submitted by Eddie Jones <eddie@onefoldmedia.com> 2014-06-10
+nid.io
+
+// Opera Software, A.S.A.
+// Submitted by Yngve Pettersen <yngve@opera.com> 2009-11-26
+operaunite.com
+
+// OutSystems
+// Submitted by Duarte Santos <domain-admin@outsystemscloud.com> 2014-03-11
+outsystemscloud.com
+
+// .pl domains (grandfathered)
+art.pl
+gliwice.pl
+krakow.pl
+poznan.pl
+wroc.pl
+zakopane.pl
+
+// Red Hat, Inc. OpenShift : https://openshift.redhat.com/
+// Submitted by Tim Kramer <tkramer@rhcloud.com> 2012-10-24
+rhcloud.com
+
+// GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains
+// Submitted by David Illsley <david.illsley@digital.cabinet-office.gov.uk> 2014-08-28
+service.gov.uk
+
+// priv.at : http://www.nic.priv.at/
+// Submitted by registry <lendl@nic.at> 2008-06-09
+priv.at
+
+// TASK geographical domains (www.task.gda.pl/uslugi/dns)
+gda.pl
+gdansk.pl
+gdynia.pl
+med.pl
+sopot.pl
+
+// UDR Limited : http://www.udr.hk.com
+// Submitted by registry <hostmaster@udr.hk.com> 2014-11-07
+hk.com
+hk.org
+ltd.hk
+inc.hk
+
+// Yola : https://www.yola.com/
+// Submitted by Stefano Rivera <stefano@yola.com> 2014-07-09
+yolasite.com
+
+// ZaNiC : http://www.za.net/
+// Submitted by registry <hostmaster@nic.za.net> 2009-10-03
+za.net
+za.org
+
+// ===END PRIVATE DOMAINS===
diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_cloudflare.sh b/net/ddns-scripts/files/usr/lib/ddns/update_cloudflare.sh
new file mode 100644 (file)
index 0000000..93098bc
--- /dev/null
@@ -0,0 +1,140 @@
+#
+# script for sending updates to cloudflare.com
+# 2014-2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+# many thanks to Paul for testing and feedback during development
+#
+# This script is parsed by dynamic_dns_functions.sh inside send_update() function
+#
+# using following options from /etc/config/ddns
+# option username - your cloudflare e-mail
+# option password - cloudflare api key, you can get it from cloudflare.com/my-account/
+# option domain   - your full hostname to update, in cloudflare its subdomain.domain
+#                      i.e. myhost.example.com where myhost is the subdomain and example.com is your domain
+#
+# variable __IP already defined with the ip-address to use for update
+#
+[ $use_https -eq 0 ] && write_log 14 "Cloudflare only support updates via Secure HTTP (HTTPS). Please correct configuration!"
+[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
+[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
+
+local __RECID __URL __KEY __KEYS __FOUND __SUBDOM __DOMAIN __TLD
+
+# split given Host/Domain into TLD, registrable domain, and subdomain
+split_FQDN $domain __TLD __DOMAIN __SUBDOM
+[ $? -ne 0 -o -z "$__DOMAIN" ] && \
+       write_log 14 "Wrong Host/Domain configuration ($domain). Please correct configuration!"
+
+# put together what we need
+__DOMAIN="$__DOMAIN.$__TLD"
+
+# parse OpenWrt script with
+# functions for parsing and generating json
+. /usr/share/libubox/jshn.sh
+
+# function copied from /usr/share/libubox/jshn.sh
+# from BB14.09 for backward compatibility to AA12.09
+grep -i "json_get_keys" /usr/share/libubox/jshn.sh >/dev/null 2>&1 || json_get_keys() {
+               local __dest="$1"
+               local _tbl_cur
+
+               if [ -n "$2" ]; then
+                       json_get_var _tbl_cur "$2"
+               else
+                       _json_get_var _tbl_cur JSON_CUR
+               fi
+               local __var="${JSON_PREFIX}KEYS_${_tbl_cur}"
+               eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
+}
+
+# function to "sed" unwanted string parts from DATFILE
+cleanup() {
+       # based on the sample output on cloudflare.com homepage we need to do some cleanup
+       sed -i 's/^[ \t]*//;s/[ \t]*$//' $DATFILE       # remove invisible chars at beginning and end of lines
+       sed -i '/^-$/d' $DATFILE                        # remove lines with "-" (dash)
+       sed -i '/^$/d' $DATFILE                         # remove empty lines
+       sed -i "#'##g" $DATFILE                         # remove "'" (single quote)
+}
+
+# build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html
+# to "rec_load_all" to detect rec_id needed for update
+__URL="https://www.cloudflare.com/api_json.html"       # https://www.cloudflare.com/api_json.html
+__URL="${__URL}?a=rec_load_all"                                #  -d 'a=rec_load_all'
+__URL="${__URL}&tkn=$password"                         #  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25'
+__URL="${__URL}&email=$username"                       #  -d 'email=sample@example.com'
+__URL="${__URL}&z=$__DOMAIN"                           #  -d 'z=example.com'
+
+# lets request the data
+do_transfer "$__URL" || return 1
+
+cleanup                                # cleanup dat file
+json_load "$(cat $DATFILE)"    # lets extract data
+__FOUND=0                      # found record indicator
+json_get_var __RES "result"    # cloudflare result of last request
+json_get_var __MSG "msg"       # cloudflare error message
+[ "$__RES" != "success" ] && {
+       write_log 4 "'rec_load_all' failed with error: \n$__MSG"
+       return 1
+}
+
+json_select "response"
+json_select "recs"
+json_select "objs"
+json_get_keys __KEYS
+for __KEY in $__KEYS; do
+       local __ZONE __DISPLAY __NAME __TYPE
+       json_select "$__KEY"
+#      json_get_var __ZONE "zone_name"         # for debugging
+#      json_get_var __DISPLAY "display_name"   # for debugging
+       json_get_var __NAME "name"
+       json_get_var __TYPE "type"
+       if [ "$__NAME" = "$domain" ]; then
+               # we must verify IPv4 and IPv6 because there might be both for the same host
+               [ \( $use_ipv6 -eq 0 -a "$__TYPE" = "A" \) -o \( $use_ipv6 -eq 1 -a "$__TYPE" = "AAAA" \) ] && {
+                       __FOUND=1       # mark found
+                       break           # found leave for loop
+               }
+       fi
+       json_select ..
+done
+[ $__FOUND -eq 0 ] && {
+       # we don't need to continue trying to update cloudflare because record to update does not exist
+       # user has to setup record first outside ddns-scripts
+       write_log 14 "No valid record found at Cloudflare setup. Please create first!"
+}
+json_get_var __RECID "rec_id"  # last thing to do get rec_id
+json_cleanup                   # cleanup
+write_log 7 "rec_id '$__RECID' detected for host/domain '$domain'"
+
+# build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html
+# for "rec_edit" to update IP address
+__URL="https://www.cloudflare.com/api_json.html"       # https://www.cloudflare.com/api_json.html
+__URL="${__URL}?a=rec_edit"                            #  -d 'a=rec_edit'
+__URL="${__URL}&tkn=$password"                         #  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25'
+__URL="${__URL}&id=$__RECID"                           #  -d 'id=9001'
+__URL="${__URL}&email=$username"                       #  -d 'email=sample@example.com'
+__URL="${__URL}&z=$__DOMAIN"                           #  -d 'z=example.com'
+
+[ $use_ipv6 -eq 0 ] && __URL="${__URL}&type=A"         #  -d 'type=A'          (IPv4)
+[ $use_ipv6 -eq 1 ] && __URL="${__URL}&type=AAAA"      #  -d 'type=AAAA'       (IPv6)
+
+# handle subdomain or domain record
+[ -n "$__SUBDOM" ] && __URL="${__URL}&name=$__SUBDOM"  #  -d 'name=sub'        (HOST/SUBDOMAIN)
+[ -z "$__SUBDOM" ] && __URL="${__URL}&name=$__DOMAIN"  #  -d 'name=example.com'(DOMAIN)
+
+__URL="${__URL}&content=$__IP"                         #  -d 'content=1.2.3.4'
+__URL="${__URL}&service_mode=0"                                #  -d 'service_mode=0'
+__URL="${__URL}&ttl=1"                                 #  -d 'ttl=1'
+
+# lets do the update
+do_transfer "$__URL" || return 1
+
+cleanup                                # cleanup tmp file
+json_load "$(cat $DATFILE)"    # lets extract data
+json_get_var __RES "result"    # cloudflare result of last request
+json_get_var __MSG "msg"       # cloudflare error message
+[ "$__RES" != "success" ] && {
+       write_log 4 "'rec_edit' failed with error:\n$__MSG"
+       return 1
+}
+write_log 7 "Update of rec_id '$__RECID' successful"
+return 0
diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_no-ip.sh b/net/ddns-scripts/files/usr/lib/ddns/update_no-ip.sh
new file mode 100644 (file)
index 0000000..4fefb96
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# script for sending updates to no-ip.com / noip.com
+# 2014-2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+#
+# This script is parsed by dynamic_dns_functions.sh inside send_update() function
+#
+# provider did not reactivate records, if no IP change was recognized
+# so we send a dummy (localhost) and a seconds later we send the correct IP addr
+#
+local __DUMMY
+local __UPDURL="http://[USERNAME]:[PASSWORD]@dynupdate.no-ip.com/nic/update?hostname=[DOMAIN]&myip=[IP]"
+# inside url we need username and password
+[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
+[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
+
+# set IP version dependend dummy (localhost)
+[ $use_ipv6 -eq 0 ] && __DUMMY="127.0.0.1" || __DUMMY="::1"
+
+# lets do DUMMY transfer
+write_log 7 "sending dummy IP to 'no-ip.com'"
+__URL=$(echo $__UPDURL | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
+                              -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__DUMMY#g")
+[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
+
+do_transfer "$__URL" || return 1
+
+write_log 7 "'no-ip.com' answered:\n$(cat $DATFILE)"
+# analyse provider answers
+# "good [IP_ADR]"      = successful
+# "nochg [IP_ADR]"     = no change but OK
+grep -E "good|nochg" $DATFILE >/dev/null 2>&1 || return 1
+
+# lets wait a seconds
+sleep 1
+
+# now send the correct data
+write_log 7 "sending real IP to 'no-ip.com'"
+__URL=$(echo $__UPDURL | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
+                              -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
+[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
+
+do_transfer "$__URL" || return 1
+
+write_log 7 "'no-ip.com' answered:\n$(cat $DATFILE)"
+# analyse provider answers
+# "good [IP_ADR]"      = successful
+# "nochg [IP_ADR]"     = no change but OK
+grep -E "good|nochg" $DATFILE >/dev/null 2>&1
+return $?      # "0" if "good" or "nochg" found
+
index fb69081ac557b1eb35f5be15306a9120edc56c06..1799d229f15f12d8ca90eff2b3b209d33719d15a 100644 (file)
@@ -1,37 +1,39 @@
-# sample script for sending user defined updates 
-# 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+# sample script for sending user defined updates
+# 2014-2015 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
 #
 # activated inside /etc/config/ddns by setting
 #
-# option update_script '/usr/lib/ddns/update_sample.sh' 
+# option update_script '/usr/lib/ddns/update_sample.sh'
 #
 # the script is parsed (not executed) inside send_update() function
 # of /usr/lib/ddns/dynamic_dns_functions.sh
 # so you can use all available functions and global variables inside this script
 # already defined in dynamic_dns_updater.sh and dynamic_dns_functions.sh
 #
-# It make sence to define the update url ONLY inside this script 
+# It make sence to define the update url ONLY inside this script
 # because it's anyway unique to the update script
 # otherwise it should work with the default scripts
 #
 # the code here is the copy of the default used inside send_update()
 #
-local __USER __PASS __ANSWER
 # tested with spdns.de
 local __URL="http://[USERNAME]:[PASSWORD]@update.spdns.de/nic/update?hostname=[DOMAIN]&myip=[IP]"
+# inside url we need username and password
+[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'"
+[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'"
 
 # do replaces in URL
-__urlencode __USER "$username" # encode username, might be email or something like this
-__urlencode __PASS "$password" # encode password, might have special chars for security reason
-__URL=$(echo $__URL | sed -e "s#\[USERNAME\]#$__USER#g" -e "s#\[PASSWORD\]#$__PASS#g" \
+__URL=$(echo $__URL | sed -e "s#\[USERNAME\]#$URL_USER#g" -e "s#\[PASSWORD\]#$URL_PASS#g" \
                               -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
 [ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')
 
-__do_transfer __ANSWER "$__URL"
-__ERR=$?
-[ $__ERR -gt 0 ] && {
-       verbose_echo "\n!!!!!!!!! ERROR =: Error sending update to DDNS Provider\n"
-       return 1
-}
-verbose_echo "   update send =: DDNS Provider answered\n$__ANSWER"
-return 0
+do_transfer "$__URL" || return 1
+
+write_log 7 "DDNS Provider answered:\n$(cat $DATFILE)"
+
+# analyse provider answers
+# "good [IP_ADR]"      = successful
+# "nochg [IP_ADR]"     = no change but OK
+grep -E "good|nochg" $DATFILE >/dev/null 2>&1
+return $?      # "0" if "good" or "nochg" found
+
index ca53f6bce60af78205d4a13797c8df65ee5d90fb..f69622e9c9c06ffdaa656f482b1bc83fd4047881 100644 (file)
@@ -14,7 +14,7 @@ PKG_RELEASE:=1
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
 PKG_LICENSE:=GPLv2
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.flyn.org/projects/dmapd
@@ -32,6 +32,7 @@ define Package/dmapd
   DEPENDS:=+libdmapsharing +libdb47 +vips
   TITLE:= dmapd
   URL:=http://www.flyn.org/projects/dmapd/
+  USERID:=dmapd=56:dmapd=56
 endef
 
 define Package/dmapd/decription
index 2d9e9aadff479a972d18d2a5cfabc3643ab3b37e..76ecd501fac19364f058d2b9b9836408ef7278b8 100644 (file)
@@ -4,8 +4,6 @@
 START=60
 
 start() {
-       user_exists dmapd 56 || user_add dmapd 56
-       group_exists dmapd 56 || group_add dmapd 56
        [ -d /var/run/dmapd ] || {
                mkdir -m 0755 -p /var/run/dmapd
                chown dmapd:dmapd /var/run/dmapd
index b0e1e69affc85ce79b0d0336def4522232e4f3d2..2b4c2c6522782bf13772e3a7bc5a8d5671066ec6 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=dnscrypt-proxy
-PKG_VERSION:=1.4.1
+PKG_VERSION:=1.4.3
 PKG_RELEASE:=1
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://download.dnscrypt.org/dnscrypt-proxy
-PKG_MD5SUM:=f2bf4195b7264813138e3c6c8da86190
+PKG_MD5SUM:=54d172236a8f321fb5689ff81767f1ba
 PKG_CAT:=zcat
 
 PKG_FIXUP:=autoreconf
diff --git a/net/e2guardian/Makefile b/net/e2guardian/Makefile
new file mode 100644 (file)
index 0000000..0823d95
--- /dev/null
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=e2guardian
+PKG_VERSION:=3.0.4
+PKG_RELEASE:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+PKG_SOURCE:=v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/e2guardian/e2guardian/archive/
+PKG_MD5SUM:=f8ffac7ac4f040b672cc4e62121bf4c5
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/e2guardian
+  SECTION:=net
+  DEPENDS:=+libpthread $(CXX_DEPENDS) +zlib +libpcre
+  CATEGORY:=Network
+  SUBMENU:=Web Servers/Proxies
+  TITLE:=E2Guardian
+  URL:=http://e2guardian.org/cms/
+endef
+
+define Package/e2guardian/conffiles
+/etc/e2guardian/e2guardianf1.conf
+/etc/config/e2guardian
+endef
+
+CONFIGURE_VARS += \
+       INCLUDES="" \
+       CXXFLAGS="$$$$CXXFLAGS -fno-rtti" \
+       LIBS="-lpthread"
+
+CONFIGURE_ARGS += \
+               --with-sysconfsubdir=e2guardian \
+               --with-proxyuser=root \
+               --with-proxygroup=root \
+               --enable-pcre=yes
+
+define Build/Configure
+       $(call Build/Configure/Default,$CONFIGURE_ARGS)
+endef
+
+define Package/e2guardian/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/e2guardian $(1)/usr/sbin/
+
+       $(INSTALL_DIR) $(1)/etc
+       $(CP) $(PKG_INSTALL_DIR)/etc/e2guardian $(1)/etc/
+       $(INSTALL_CONF) ./files/e2guardianf1.conf $(1)/etc/e2guardian/e2guardianf1.conf
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/e2guardian.config $(1)/etc/config/e2guardian
+
+       $(INSTALL_DIR) $(1)/usr/share/e2guardian
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/e2guardian/transparent1x1.gif $(1)/usr/share/e2guardian/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/e2guardian/blockedflash.swf $(1)/usr/share/e2guardian/
+
+       $(INSTALL_DIR) $(1)/usr/share/e2guardian/languages/ukenglish
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/e2guardian/languages/ukenglish/* $(1)/usr/share/e2guardian/languages/ukenglish/
+
+       $(INSTALL_DIR) $(1)/etc/init.d/
+       $(INSTALL_BIN) ./files/e2guardian.init $(1)/etc/init.d/e2guardian
+endef
+
+$(eval $(call BuildPackage,e2guardian))
diff --git a/net/e2guardian/files/e2guardian.config b/net/e2guardian/files/e2guardian.config
new file mode 100644 (file)
index 0000000..2b46f20
--- /dev/null
@@ -0,0 +1,70 @@
+config e2guardian 'e2guardian'
+       option config_file '/etc/e2guardian/e2guardianf1.conf'
+       option languagedir '/usr/share/e2guardian/languages'
+       option language 'ukenglish'
+       option loglevel '2'
+       option logexceptionhits '2'
+       option logfileformat '1'
+       option loglocation '/dev/null'
+       option maxuploadsize '-1'
+       option filterip ''
+       option filterports '8080'
+       option proxyip '127.0.0.1'
+       option proxyport '3128'
+       option proxytimeout '20'
+       option proxyexchange '20'
+       option pcontimeout '55'
+       option accessdeniedaddress 'http://YOURSERVER.YOURDOMAIN/cgi-bin/e2guardian.pl'
+       option usecustombannedimage 'on'
+       option custombannedimagefile '/usr/share/e2guardian/transparent1x1.gif'
+       option usecustombannedflash 'on'
+       option custombannedflashfile '/usr/share/e2guardian/blockedflash.swf'
+       option filtergroups '1'
+       option filtergroupslist '/etc/e2guardian/lists/filtergroupslist'
+       option bannediplist '/etc/e2guardian/lists/bannediplist'
+       option exceptioniplist '/etc/e2guardian/lists/exceptioniplist'
+       option perroomdirectory '/etc/e2guardian/lists/bannedrooms/'
+       option showweightedfound 'on'
+       option weightedphrasemode '2'
+       option urlcachenumber '1000'
+       option urlcacheage '900'
+       option scancleancache 'on'
+       option phrasefiltermode '2'
+       option preservecase '0'
+       option hexdecodecontent 'off'
+       option forcequicksearch 'off'
+       option reverseaddresslookups 'off'
+       option reverseclientiplookups 'off'
+       option logclienthostnames 'off'
+       option createlistcachefiles 'on'
+       option prefercachedlists 'off'
+       option maxcontentfiltersize '256'
+       option maxcontentramcachescansize '2000'
+       option maxcontentfilecachescansize '20000'
+       option filecachedir '/tmp'
+       option deletedownloadedtempfiles 'on'
+       option initialtrickledelay '20'
+       option trickledelay '10'
+       option downloadmanager '/etc/e2guardian/downloadmanagers/default.conf'
+       option contentscannertimeout '60'
+       option contentscanexceptions 'off'
+       option recheckreplacedurls 'off'
+       option forwardedfor 'off'
+       option usexforwardedfor 'off'
+       option logconnectionhandlingerrors 'on'
+       option logchildprocesshandling 'off'
+       option maxchildren '180'
+       option minchildren '20'
+       option minsparechildren '16'
+       option preforkchildren '10'
+       option maxsparechildren '32'
+       option maxagechildren '500'
+       option maxips '0'
+       option ipcfilename '/tmp/.dguardianipc'
+       option urlipcfilename '/tmp/.dguardianurlipc'
+       option ipipcfilename '/tmp/.dguardianipipc'
+       option nodaemon 'off'
+       option nologger 'off'
+       option logadblocks 'off'
+       option loguseragent 'off'
+       option softrestart 'off'
diff --git a/net/e2guardian/files/e2guardian.init b/net/e2guardian/files/e2guardian.init
new file mode 100644 (file)
index 0000000..132b61f
--- /dev/null
@@ -0,0 +1,192 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/sbin/e2guardian
+CONFIGFILE="/tmp/e2guardian/e2guardian.conf"
+
+validate_e2guardian_section() {
+       uci_validate_section e2guardian e2guardian "${1}" \
+               'config_file:string' \
+               'accessdeniedaddress:string' \
+               'bannediplist:string' \
+               'contentscanexceptions:string' \
+               'contentscannertimeout:uinteger' \
+               'createlistcachefiles:string' \
+               'custombannedflashfile:string' \
+               'custombannedimagefile:string' \
+               'deletedownloadedtempfiles:string' \
+               'downloadmanager:string' \
+               'exceptioniplist:string' \
+               'filecachedir:string' \
+               'filtergroups:uinteger' \
+               'filtergroupslist:string' \
+               'filterip:ipaddr' \
+               'filterports:port:8080' \
+               'forcequicksearch:string' \
+               'forwardedfor:string' \
+               'hexdecodecontent:string' \
+               'initialtrickledelay:uinteger' \
+               'ipcfilename:string' \
+               'ipipcfilename:string' \
+               'languagedir:string' \
+               'language:string' \
+               'logadblocks:string' \
+               'logchildprocesshandling:string' \
+               'logclienthostnames:string' \
+               'logconnectionhandlingerrors:string' \
+               'logexceptionhits:range(0,2)' \
+               'logfileformat:range(1,6)' \
+               'loglevel:range(0,3)' \
+               'loglocation:string' \
+               'loguseragent:string' \
+               'maxagechildren:uinteger' \
+               'maxchildren:uinteger' \
+               'maxcontentfilecachescansize:uinteger' \
+               'maxcontentfiltersize:uinteger' \
+               'maxcontentramcachescansize:uinteger' \
+               'maxips:uinteger' \
+               'maxsparechildren:uinteger' \
+               'maxuploadsize:integer' \
+               'minchildren:uinteger' \
+               'minsparechildren:uinteger' \
+               'nodaemon:string' \
+               'nologger:string' \
+               'pcontimeout:range(5,300)' \
+               'perroomdirectory:string' \
+               'phrasefiltermode:range(0,3)' \
+               'prefercachedlists:string' \
+               'preforkchildren:uinteger' \
+               'preservecase:range(0,2)' \
+               'proxyexchange:range(20,300)' \
+               'proxyip:ipaddr' \
+               'proxyport:port:3128' \
+               'proxytimeout:range(5,100)' \
+               'recheckreplacedurls:string' \
+               'reverseaddresslookups:string' \
+               'reverseclientiplookups:string' \
+               'scancleancache:string' \
+               'showweightedfound:string' \
+               'softrestart:string' \
+               'trickledelay:uinteger' \
+               'urlcacheage:uinteger' \
+               'urlcachenumber:uinteger' \
+               'urlipcfilename:string' \
+               'usecustombannedflash:string' \
+               'usecustombannedimage:string' \
+               'usexforwardedfor:string' \
+               'weightedphrasemode:range(0,2)'
+}
+
+start_service() {
+
+       local config_file accessdeniedaddress bannediplist contentscanexceptions contentscannertimeout \
+               createlistcachefiles custombannedflashfile custombannedimagefile deletedownloadedtempfiles \
+               downloadmanager exceptioniplist filecachedir loglocation \
+               filtergroups filtergroupslist filterip filterports forcequicksearch forwardedfor hexdecodecontent \
+               initialtrickledelay ipcfilename ipipcfilename language languagedir logadblocks logchildprocesshandling \
+               logclienthostnames logconnectionhandlingerrors logexceptionhits logfileformat loglevel loguseragent \
+               maxagechildren maxchildren maxcontentfilecachescansize maxcontentfiltersize maxcontentramcachescansize \
+               maxips maxsparechildren maxuploadsize minchildren minsparechildren nodaemon nologger \
+               pcontimeout perroomdirectory phrasefiltermode prefercachedlists preforkchildren preservecase proxyexchange \
+               proxyip proxyport proxytimeout recheckreplacedurls reverseaddresslookups reverseclientiplookups scancleancache \
+               showweightedfound softrestart trickledelay urlcacheage urlcachenumber urlipcfilename usecustombannedflash \
+               usecustombannedimage usexforwardedfor weightedphrasemode
+
+       validate_e2guardian_section e2guardian || {
+               echo "validation failed"
+               return 1
+       }
+
+       mkdir -p $(dirname $CONFIGFILE)
+       ln -sf $config_file $(dirname $CONFIGFILE)
+
+       echo "accessdeniedaddress = " $accessdeniedaddress > $CONFIGFILE
+       echo "bannediplist = " $bannediplist >> $CONFIGFILE
+       echo "contentscanexceptions = " $contentscanexceptions >> $CONFIGFILE
+       echo "contentscannertimeout = " $contentscannertimeout >> $CONFIGFILE
+       echo "createlistcachefiles = " $createlistcachefiles >> $CONFIGFILE
+       echo "custombannedflashfile = " $custombannedflashfile >> $CONFIGFILE
+       echo "custombannedimagefile = " $custombannedimagefile >> $CONFIGFILE
+       echo "deletedownloadedtempfiles = " $deletedownloadedtempfiles >> $CONFIGFILE
+       echo "downloadmanager = " $downloadmanager >> $CONFIGFILE
+       echo "exceptioniplist = " $exceptioniplist >> $CONFIGFILE
+       echo "filecachedir = " $filecachedir >> $CONFIGFILE
+       echo "filtergroups = " $filtergroups >> $CONFIGFILE
+       echo "filtergroupslist = " $filtergroupslist >> $CONFIGFILE
+       echo "filterip = " $filterip >> $CONFIGFILE
+       echo "filterports = " $filterports >> $CONFIGFILE
+       echo "forcequicksearch = " $forcequicksearch >> $CONFIGFILE
+       echo "forwardedfor = " $forwardedfor >> $CONFIGFILE
+       echo "hexdecodecontent = " $hexdecodecontent >> $CONFIGFILE
+       echo "initialtrickledelay = " $initialtrickledelay >> $CONFIGFILE
+       echo "ipcfilename = " $ipcfilename >> $CONFIGFILE
+       echo "ipipcfilename = " $ipipcfilename >> $CONFIGFILE
+       echo "language = " $language >> $CONFIGFILE
+       echo "languagedir = " $languagedir >> $CONFIGFILE
+       echo "logadblocks = " $logadblocks >> $CONFIGFILE
+       echo "logchildprocesshandling = " $logchildprocesshandling >> $CONFIGFILE
+       echo "logclienthostnames = " $logclienthostnames >> $CONFIGFILE
+       echo "logconnectionhandlingerrors = " $logconnectionhandlingerrors >> $CONFIGFILE
+       echo "logexceptionhits = " $logexceptionhits >> $CONFIGFILE
+       echo "logfileformat = " $logfileformat >> $CONFIGFILE
+       echo "loglevel = " $loglevel >> $CONFIGFILE
+       echo "loglocation = " $loglocation >> $CONFIGFILE
+       echo "loguseragent = " $loguseragent >> $CONFIGFILE
+       echo "maxagechildren = " $maxagechildren >> $CONFIGFILE
+       echo "maxchildren = " $maxchildren >> $CONFIGFILE
+       echo "maxcontentfilecachescansize = " $maxcontentfilecachescansize >> $CONFIGFILE
+       echo "maxcontentfiltersize = " $maxcontentfiltersize >> $CONFIGFILE
+       echo "maxcontentramcachescansize = " $maxcontentramcachescansize >> $CONFIGFILE
+       echo "maxips = " $maxips >> $CONFIGFILE
+       echo "maxsparechildren = " $maxsparechildren >> $CONFIGFILE
+       echo "maxuploadsize = " $maxuploadsize >> $CONFIGFILE
+       echo "minchildren = " $minchildren >> $CONFIGFILE
+       echo "minsparechildren = " $minsparechildren >> $CONFIGFILE
+       echo "nodaemon = " $nodaemon >> $CONFIGFILE
+       echo "nologger = " $nologger >> $CONFIGFILE
+       echo "pcontimeout = " $pcontimeout >> $CONFIGFILE
+       echo "perroomdirectory = " $perroomdirectory >> $CONFIGFILE
+       echo "phrasefiltermode = " $phrasefiltermode >> $CONFIGFILE
+       echo "prefercachedlists = " $prefercachedlists >> $CONFIGFILE
+       echo "preforkchildren = " $preforkchildren >> $CONFIGFILE
+       echo "preservecase = " $preservecase >> $CONFIGFILE
+       echo "proxyexchange = " $proxyexchange >> $CONFIGFILE
+       echo "proxyip = " $proxyip >> $CONFIGFILE
+       echo "proxyport = " $proxyport >> $CONFIGFILE
+       echo "proxytimeout = " $proxytimeout >> $CONFIGFILE
+       echo "recheckreplacedurls = " $recheckreplacedurls >> $CONFIGFILE
+       echo "reverseaddresslookups = " $reverseaddresslookups >> $CONFIGFILE
+       echo "reverseclientiplookups = " $reverseclientiplookups >> $CONFIGFILE
+       echo "scancleancache = " $scancleancache >> $CONFIGFILE
+       echo "showweightedfound = " $showweightedfound >> $CONFIGFILE
+       echo "softrestart = " $softrestart >> $CONFIGFILE
+       echo "trickledelay = " $trickledelay >> $CONFIGFILE
+       echo "urlcacheage = " $urlcacheage >> $CONFIGFILE
+       echo "urlcachenumber = " $urlcachenumber >> $CONFIGFILE
+       echo "urlipcfilename = " $urlipcfilename >> $CONFIGFILE
+       echo "usecustombannedflash = " $usecustombannedflash >> $CONFIGFILE
+       echo "usecustombannedimage = " $usecustombannedimage >> $CONFIGFILE
+       echo "usexforwardedfor = " $usexforwardedfor >> $CONFIGFILE
+       echo "weightedphrasemode = " $weightedphrasemode >> $CONFIGFILE
+
+       procd_open_instance
+       procd_set_param command $PROG -N -c "$CONFIGFILE"
+       procd_set_param file $CONFIGFILE
+       procd_set_param respawn
+       procd_close_instance
+}
+
+stop_service()
+{
+       e2guardian -s | awk -F':' '{ print $2}' | xargs kill -9
+}
+
+service_triggers()
+{
+       procd_add_reload_trigger "e2guardian"
+       procd_add_validation validate_e2guardian_section
+}
diff --git a/net/e2guardian/files/e2guardianf1.conf b/net/e2guardian/files/e2guardianf1.conf
new file mode 100644 (file)
index 0000000..21a145a
--- /dev/null
@@ -0,0 +1,426 @@
+# e2guardian filter group config file for version 3.0.4
+
+
+# Filter group mode
+# This option determines whether members of this group have their web access
+# unfiltered, filtered, or banned.
+#
+# 0 = banned
+# 1 = filtered
+# 2 = unfiltered (exception)
+#
+# Only filter groups with a mode of 1 need to define phrase, URL, site, extension,
+# mimetype and PICS lists; in other modes, these options are ignored to conserve
+# memory.
+#
+# Defaults to 0 if unspecified.
+# Unauthenticated users are treated as being in the first filter group.
+groupmode = 1
+
+# Filter group name
+# Used to fill in the -FILTERGROUP- placeholder in the HTML template file, and to
+# name the group in the access logs
+# Defaults to empty string
+#groupname = ''
+groupname = ''
+
+# Content filtering files location
+bannedphraselist = 'etc/e2guardian/lists/bannedphraselist'
+weightedphraselist = 'etc/e2guardian/lists/weightedphraselist'
+exceptionphraselist = 'etc/e2guardian/lists/exceptionphraselist'
+bannedsitelist = 'etc/e2guardian/lists/bannedsitelist'
+greysitelist = 'etc/e2guardian/lists/greysitelist'
+bannedsslsitelist = 'etc/e2guardian/lists/bannedsslsitelist'
+greysslsitelist = 'etc/e2guardian/lists/greysslsitelist'
+exceptionsitelist = 'etc/e2guardian/lists/exceptionsitelist'
+bannedurllist = 'etc/e2guardian/lists/bannedurllist'
+greyurllist = 'etc/e2guardian/lists/greyurllist'
+exceptionurllist = 'etc/e2guardian/lists/exceptionurllist'
+exceptionregexpurllist = 'etc/e2guardian/lists/exceptionregexpurllist'
+bannedregexpurllist = 'etc/e2guardian/lists/bannedregexpurllist'
+picsfile = 'etc/e2guardian/lists/pics'
+contentregexplist = 'etc/e2guardian/lists/contentregexplist'
+urlregexplist = 'etc/e2guardian/lists/urlregexplist'
+refererexceptionsitelist = 'etc/e2guardian/lists/refererexceptionsitelist'
+refererexceptionurllist = 'etc/e2guardian/lists/refererexceptionurllist'
+embededreferersitelist = 'etc/e2guardian/lists/embededreferersitelist'
+embededrefererurllist = 'etc/e2guardian/lists/embededrefererurllist'
+urlredirectregexplist = 'etc/e2guardian/lists/urlredirectregexplist'
+
+# local versions of lists (where LOCAL_LISTS enabled)
+#localbannedsitelist = 'etc/e2guardian/lists/localbannedsitelist'
+#localgreysitelist = 'etc/e2guardian/lists/localgreysitelist'
+#localexceptionsitelist = 'etc/e2guardian/lists/localexceptionsitelist'
+#localbannedurllist = 'etc/e2guardian/lists/localbannedurllist'
+#localgreyurllist = 'etc/e2guardian/lists/localgreyurllist'
+#localexceptionurllist = 'etc/e2guardian/lists/localexceptionurllist'
+#localbannedsslsitelist = 'etc/e2guardian/lists/localbannedsslsitelist'
+#localgreysslsitelist = 'etc/e2guardian/lists/localgreysslsitelist'
+#localbannedsearchlist = 'etc/e2guardian/lists/localbannedsearchlist'
+
+!! Not compiled !! authexceptionsitelist = 'etc/e2guardian/lists/authexceptionsitelist'
+!! Not compiled !! authexceptionurllist = 'etc/e2guardian/lists/authexceptionurllist'
+
+# Filetype filtering
+#
+# Allow bannedregexpurllist with grey list mode
+# bannedregexpheaderlist and bannedregexpurllist
+#
+# bannedregexwithblanketblock = off
+#
+# Blanket download blocking
+# If enabled, all files will be blocked, unless they match the
+# exceptionextensionlist or exceptionmimetypelist.
+# These lists do not override virus scanning.
+# Exception lists defined above override all types of filtering, including
+# the blanket download block.
+# Defaults to disabled.
+# (on | off)
+#
+blockdownloads = off
+exceptionextensionlist = 'etc/e2guardian/lists/exceptionextensionlist'
+exceptionmimetypelist = 'etc/e2guardian/lists/exceptionmimetypelist'
+#
+# Use the following lists to block specific kinds of file downloads.
+# The two exception lists above can be used to override these.
+#
+bannedextensionlist = 'etc/e2guardian/lists/bannedextensionlist'
+bannedmimetypelist = 'etc/e2guardian/lists/bannedmimetypelist'
+#
+# In either file filtering mode, the following list can be used to override
+# MIME type & extension blocks for particular domains & URLs (trusted download sites).
+#
+exceptionfilesitelist = 'etc/e2guardian/lists/exceptionfilesitelist'
+exceptionfileurllist = 'etc/e2guardian/lists/exceptionfileurllist'
+
+# POST protection (web upload and forms)
+# does not block forms without any file upload, i.e. this is just for
+# blocking or limiting uploads
+# measured in kibibytes after MIME encoding and header bumph
+# use 0 for a complete block
+# use higher (e.g. 512 = 512Kbytes) for limiting
+# use -1 for no blocking
+#maxuploadsize = 512
+#maxuploadsize = 0
+maxuploadsize = -1
+
+# Categorise without blocking:
+# Supply categorised lists here and the category string shall be logged against
+# matching requests, but matching these lists does not perform any filtering
+# action.
+#logsitelist = 'etc/e2guardian/lists/logsitelist'
+#logurllist = 'etc/e2guardian/lists/logurllist'
+#logregexpurllist = 'etc/e2guardian/lists/logregexpurllist'
+
+# Outgoing HTTP header rules:
+# Optional lists for blocking based on, and modification of, outgoing HTTP
+# request headers.  Format for headerregexplist is one modification rule per
+# line, similar to content/URL modifications.  Format for
+# bannedregexpheaderlist is one regular expression per line, with matching
+# headers causing a request to be blocked.
+# Headers are matched/replaced on a line-by-line basis, not as a contiguous
+# block.
+# Use for example, to remove cookies or prevent certain user-agents.
+headerregexplist = 'etc/e2guardian/lists/headerregexplist'
+bannedregexpheaderlist = 'etc/e2guardian/lists/bannedregexpheaderlist'
+addheaderregexplist = 'etc/e2guardian/lists/addheaderregexplist'
+
+# Weighted phrase mode
+# Optional; overrides the weightedphrasemode option in e2guardian.conf
+# for this particular group.  See documentation for supported values in
+# that file.
+#weightedphrasemode = 0
+
+# Naughtiness limit
+# This the limit over which the page will be blocked.  Each weighted phrase is given
+# a value either positive or negative and the values added up.  Phrases to do with
+# good subjects will have negative values, and bad subjects will have positive
+# values.  See the weightedphraselist file for examples.
+# As a guide:
+# 50 is for young children,  100 for old children,  160 for young adults.
+naughtynesslimit = 50
+
+# Search term blocking
+# Search terms can be extracted from search URLs and filtered using one or
+# both of two different methods.
+
+# Method 1 is that developed by Protex where specific
+# search terms are contained in a bannedsearchlist.
+# (localbannedsearchlist and bannedsearchoveridelist can be used to suppliment
+# and overide this list as required.)
+# These lists contain banned search words combinations on each line.
+# Words are separated by '+' and must be in sorted order within a line.
+#    so to block 'sexy girl' then the list must contain the line
+#      girl+sexy
+#    and this will block both 'sexy girl' and 'girl sexy'
+# To use this method, the searchregexplist must be enabled and the bannedsearchlist(s) defined
+
+# Method 2 is uses the
+# bannedphraselist, weightedphraselist and exceptionphraselist, with a separate
+# threshold for blocking than that used for normal page content.
+# To do this, the searchregexplist must be enabled and searchtermlimit
+# must be grater than 0.
+
+#
+# Search engine regular expression list (need for both options)
+# List of regular expressions for matching search engine URLs.  It is assumed
+# that the search terms themselves will be contained in the
+# of output of each expression.
+#searchregexplist = 'etc/e2guardian/lists/searchregexplist'
+#
+# Banned Search Term list(s) for option 1
+#bannedsearchlist = 'etc/e2guardian/lists/bannedsearchlist'
+#bannedsearchoveridelist = 'etc/e2guardian/lists/bannedsearchoveridelist'
+
+
+# Search term limit (for Option 2)
+# The limit over which requests will be blocked for containing search terms
+# which match the weightedphraselist.  This should usually be lower than the
+# 'naughtynesslimit' value above, because the amount of text being filtered
+# is only a few words, rather than a whole page.
+# This option must be uncommented if searchregexplist is uncommented.
+# A value of 0 here indicates that search terms should be extracted,
+# but no phrase filtering should be performed on the resulting text.
+#searchtermlimit = 0
+#
+# Search term phrase lists (for Option 2)
+# If the three lines below are uncommented, search term blocking will use
+# the banned, weighted & exception phrases from these lists, instead of using
+# the same phrase lists as for page content.  This is optional but recommended,
+# as weights for individual phrases in the "normal" lists may not be
+# appropriate for blocking when those phrases appear in a much smaller block
+# of text.
+# Please note that all or none of the below should be uncommented, not a
+# mixture.
+#bannedsearchtermlist = 'etc/e2guardian/lists/bannedsearchtermlist'
+#weightedsearchtermlist = 'etc/e2guardian/lists/weightedsearchtermlist'
+#exceptionsearchtermlist = 'etc/e2guardian/lists/exceptionsearchtermlist'
+
+# Category display threshold
+# This option only applies to pages blocked by weighted phrase filtering.
+# Defines the minimum score that must be accumulated within a particular
+# category in order for it to show up on the block pages' category list.
+# All categories under which the page scores positively will be logged; those
+# that were not displayed to the user appear in brackets.
+#
+# -1 = display only the highest scoring category
+# 0 = display all categories (default)
+# > 0 = minimum score for a category to be displayed
+categorydisplaythreshold = 0
+
+# Embedded URL weighting
+# When set to something greater than zero, this option causes URLs embedded within a
+# page's HTML (from links, image tags, etc.) to be extracted and checked against the
+# bannedsitelist and bannedurllist. Each link to a banned page causes the amount set
+# here to be added to the page's weighting.
+# The behaviour of this option with regards to multiple occurrences of a site/URL is
+# affected by the weightedphrasemode setting.
+#
+# NB: Currently, this feature uses regular expressions that require the PCRE library.
+# As such, it is only available if you compiled DansGuardian with '--enable-pcre=yes'.
+# You can check compile-time options by running 'e2guardian -v'.
+#
+# Set to 0 to disable.
+# Defaults to 0.
+# WARNING: This option is highly CPU intensive!
+embeddedurlweight = 0
+
+# Enable PICS rating support
+#
+# Defaults to disabled
+# (on | off)
+enablepics = off
+
+# Temporary Denied Page Bypass
+# This provides a link on the denied page to bypass the ban for a few minutes.  To be
+# secure it uses a random hashed secret generated at daemon startup.  You define the
+# number of seconds the bypass will function for before the deny will appear again.
+# To allow the link on the denied page to appear you will need to edit the template.html
+# or e2guardian.pl file for your language.
+# 300 = enable for 5 minutes
+# 0 = disable ( defaults to 0 )
+# -1 = enable but you require a separate program/CGI to generate a valid link
+bypass = 0
+
+# Temporary Denied Page Bypass Secret Key
+# Rather than generating a random key you can specify one.  It must be more than 8 chars.
+# '' = generate a random one (recommended and default)
+# 'Mary had a little lamb.' = an example
+# '76b42abc1cd0fdcaf6e943dcbc93b826' = an example
+bypasskey = ''
+
+# Infection/Scan Error Bypass
+# Similar to the 'bypass' setting, but specifically for bypassing files scanned and found
+# to be infected, or files that trigger scanner errors - for example, archive types with
+# recognised but unsupported compression schemes, or corrupt archives.
+# The option specifies the number of seconds for which the bypass link will be valid.
+# 300 = enable for 5 minutes
+# 0 = disable (default)
+# -1 = enable, but require a separate program/CGI to generate a valid link
+infectionbypass = 0
+
+# Infection/Scan Error Bypass Secret Key
+# Same as the 'bypasskey' option, but used for infection bypass mode.
+infectionbypasskey = ''
+
+# Infection/Scan Error Bypass on Scan Errors Only
+# Enable this option to allow infectionbypass links only when virus scanning fails,
+# not when a file is found to contain a virus.
+# on = enable (default and highly recommended)
+# off = disable
+infectionbypasserrorsonly = on
+
+# Disable content scanning
+# If you enable this option you will disable content scanning for this group.
+# Content scanning primarily is AV scanning (if enabled) but could include
+# other types.
+# (on|off) default = off.
+disablecontentscan = off
+
+# Enable Deep URL Analysis
+# When enabled, DG looks for URLs within URLs, checking against the bannedsitelist and
+# bannedurllist. This can be used, for example, to block images originating from banned
+# sites from appearing in Google Images search results, as the original URLs are
+# embedded in the thumbnail GET requests.
+# (on|off) default = off
+deepurlanalysis = off
+
+# reportinglevel
+#
+# -1 = log, but do not block - Stealth mode
+#  0 = just say 'Access Denied'
+#  1 = report why but not what denied phrase
+#  2 = report fully
+#  3 = use HTML template file (accessdeniedaddress ignored) - recommended
+#
+# If defined, this overrides the global setting in e2guardian.conf for
+# members of this filter group.
+#
+reportinglevel = 3
+
+# accessdeniedaddress is the address of your web server to which the cgi
+# e2guardian reporting script was copied. Only used in reporting levels
+# 1 and 2.
+#
+# This webserver must be either:
+#  1. Non-proxied. Either a machine on the local network, or listed as an
+#     exception in your browser's proxy configuration.
+#  2. Added to the exceptionsitelist. Option 1 is preferable; this option is
+#     only for users using both transparent proxying and a non-local server
+#     to host this script.
+#
+# If defined, this overrides the global setting in e2guardian.conf for
+# members of this filter group.
+#
+#accessdeniedaddress = 'http://YOURSERVER.YOURDOMAIN/cgi-bin/e2guardian.pl'
+
+# sslaccessdeniedaddress is the address of your web server to which the static page
+# e2guardian reporting was copied. Only used in reporting levels 3 (avoid blank page)
+# Work only in firefox with ssldeniedrewrite off
+
+# sslaccessdeniedaddress = 'http://YOURSERVER.YOURDOMAIN/denyssl.htm'
+
+# Break SSL protocol and redirect to another HTTPS website for denied page (sslaccessdeniedaddress url)
+
+#ssldeniedrewrite = 'on'
+
+# HTML Template override
+# If defined, this specifies a custom HTML template file for members of this
+# filter group, overriding the global setting in e2guardian.conf. This is
+# only used in reporting level 3.
+#
+# The default template file path is <languagedir>/<language>/template.h
+# e.g. share/e2guardian/languages/ukenglish/template.html when using 'ukenglish'
+# language.
+#
+# This option generates a file path of the form:
+# <languagedir>/<language>/<htmltemplate>
+# e.g. share/e2guardian/languages/ukenglish/custom.html
+#
+#htmltemplate = 'custom.html'
+
+# Non standard delimiter (only used with accessdeniedaddress)
+# To help preserve the full banned URL, including parameters, the variables
+# passed into the access denied CGI are separated using non-standard
+# delimiters. This can be useful to ensure correct operation of the filter
+# bypass modes. Parameters are split using "::" in place of "&", and "==" in
+# place of "=".
+# Default is enabled, but to go back to the standard mode, disable it.
+
+#nonstandarddelimiter = off
+
+# Email reporting - original patch by J. Gauthier
+
+# Use SMTP
+# If on, will enable system wide events to be reported by email.
+# need to configure mail program (see 'mailer' in global config)
+# and email recipients
+# default usesmtp = off
+#!! Not compiled !!usesmtp = off
+
+# mailfrom
+# who the email would come from
+# example: mailfrom = 'e2guardian@mycompany.com'
+#!! Not compiled !!mailfrom = ''
+
+# avadmin
+# who the virus emails go to (if notify av is on)
+# example: avadmin = 'admin@mycompany.com'
+#!! Not compiled !!avadmin = ''
+
+# contentdmin
+# who the content emails go to (when thresholds are exceeded)
+# and contentnotify is on
+# example: contentadmin = 'admin@mycompany.com'
+#!! Not compiled !!contentadmin = ''
+
+# avsubject
+# Subject of the email sent when a virus is caught.
+# only applicable if notifyav is on
+# default avsubject = 'e2guardian virus block'
+#!! Not compiled !!avsubject = 'e2guardian virus block'
+
+# content
+# Subject of the email sent when violation thresholds are exceeded
+# default contentsubject = 'e2guardian violation'
+#!! Not compiled !!contentsubject = 'e2guardian violation'
+
+# notifyAV
+# This will send a notification, if usesmtp/notifyav is on, any time an
+# infection is found.
+# Important: If this option is off, viruses will still be recorded like a
+# content infraction.
+#!! Not compiled !!notifyav = off
+
+# notifycontent
+# This will send a notification, if usesmtp is on, based on thresholds
+# below
+#!! Not compiled !!notifycontent = off
+
+# thresholdbyuser
+# results are only predictable with user authenticated configs
+# if enabled the violation/threshold count is kept track of by the user
+#!! Not compiled !!thresholdbyuser = off
+
+#violations
+# number of violations before notification
+# setting to 0 will never trigger a notification
+#!! Not compiled !!violations = 0
+
+#threshold
+# this is in seconds. If 'violations' occur in 'threshold' seconds, then
+# a notification is made.
+# if this is set to 0, then whenever the set number of violations are made a
+# notifaction will be sent.
+#!! Not compiled !!threshold = 0
+
+#SSL certificate checking
+# Check that ssl certificates for servers on https connections are valid
+# and signed by a ca in the configured path
+sslcertcheck = off
+
+#SSL man in the middle
+# Forge ssl certificates for all sites, decrypt the data then re encrypt it
+# using a different private key. Used to filter ssl sites
+sslmitm = off
+
index 7fa772aeda982a5afaec80b86f88f6aef371cd44..5ffb8253c3167a3474bfb8961d33f38bc442abf5 100644 (file)
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ethtool
-PKG_VERSION:=3.15
+PKG_VERSION:=3.18
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@KERNEL/software/network/ethtool
-PKG_MD5SUM:=e7bf0c355d2bf6ee281ebc713c5fb987
+PKG_MD5SUM:=fbf1a167b88a5966a2c56a2483af68c6
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
index ca4045c5c572f4e5a76be05f14de4c561f7cc318..5820b9796562cd11826f8bbefbb02806fe516c61 100644 (file)
@@ -11,6 +11,11 @@ config FASTD_ENABLE_METHOD_COMPOSED_GMAC
        depends on PACKAGE_fastd
        default y
 
+config FASTD_ENABLE_METHOD_COMPOSED_UMAC
+       bool "Enable composed-umac method provider"
+       depends on PACKAGE_fastd
+       default y
+
 config FASTD_ENABLE_METHOD_GENERIC_GMAC
        bool "Enable generic-gmac method provider"
        depends on PACKAGE_fastd
@@ -21,6 +26,11 @@ config FASTD_ENABLE_METHOD_GENERIC_POLY1305
        depends on PACKAGE_fastd
        default n
 
+config FASTD_ENABLE_METHOD_GENERIC_UMAC
+       bool "Enable generic-umac method provider"
+       depends on PACKAGE_fastd
+       default y
+
 config FASTD_ENABLE_METHOD_NULL
        bool "Enable null method"
        depends on PACKAGE_fastd
@@ -58,6 +68,11 @@ config FASTD_ENABLE_MAC_GHASH
        depends on PACKAGE_fastd
        default y
 
+config FASTD_ENABLE_MAC_UHASH
+       bool "Enable the UHASH message authentication code"
+       depends on PACKAGE_fastd
+       default y
+
 
 config FASTD_WITH_CMDLINE_USER
        bool "Include support for setting user/group related options on the command line"
@@ -79,9 +94,15 @@ config FASTD_WITH_CMDLINE_COMMANDS
        depends on PACKAGE_fastd
        default n
 
-config FASTD_WITH_VERIFY
-        bool "Include support for on-verify handlers"
-        depends on PACKAGE_fastd
-        default n
+config FASTD_WITH_DYNAMIC_PEERS
+       bool "Include support for on-verify handlers"
+       depends on PACKAGE_fastd
+       default n
+
+config FASTD_WITH_STATUS_SOCKET
+       bool "Include support for status sockets"
+       depends on PACKAGE_fastd
+       default y
+
 
 endmenu
index e2fca698e194b618822eb3c421cefa67b7614aad..027f5491d2f6b066affe08e846b1967900c391e1 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 OpenWrt.org
+# Copyright (C) 2012-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,22 +8,24 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=fastd
-PKG_VERSION:=14
+PKG_VERSION:=17
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/75
-PKG_MD5SUM:=34f6bdebd0410a1fba7c8fd06fff7a05
+PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/81
+PKG_MD5SUM:=bad4f1948702f418b799578f83a0edb8
 
 PKG_LICENSE:=BSD-2-Clause
-PKG_LICENSE_FILE:=COPYRIGHT
+PKG_LICENSE_FILES:=COPYRIGHT
 
 PKG_CONFIG_DEPENDS:=\
        CONFIG_FASTD_ENABLE_METHOD_CIPHER_TEST \
        CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC \
+       CONFIG_FASTD_ENABLE_METHOD_COMPOSED_UMAC \
        CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC \
        CONFIG_FASTD_ENABLE_METHOD_GENERIC_POLY1305 \
+       CONFIG_FASTD_ENABLE_METHOD_GENERIC_UMAC \
        CONFIG_FASTD_ENABLE_METHOD_NULL \
        CONFIG_FASTD_ENABLE_METHOD_XSALSA20_POLY1305 \
        CONFIG_FASTD_ENABLE_CIPHER_AES128_CTR \
@@ -31,11 +33,13 @@ PKG_CONFIG_DEPENDS:=\
        CONFIG_FASTD_ENABLE_CIPHER_SALSA20 \
        CONFIG_FASTD_ENABLE_CIPHER_SALSA2012 \
        CONFIG_FASTD_ENABLE_MAC_GHASH \
+       CONFIG_FASTD_ENABLE_MAC_UHASH \
        CONFIG_FASTD_WITH_CMDLINE_USER \
        CONFIG_FASTD_WITH_CMDLINE_LOGGING \
        CONFIG_FASTD_WITH_CMDLINE_OPERATION \
        CONFIG_FASTD_WITH_CMDLINE_COMMANDS \
-       CONFIG_FASTD_WITH_VERIFY
+       CONFIG_FASTD_WITH_DYNAMIC_PEERS \
+       CONFIG_FASTD_WITH_STATUS_SOCKET
 
 
 PKG_BUILD_DEPENDS:=nacl libuecc
@@ -46,7 +50,7 @@ include $(INCLUDE_DIR)/cmake.mk
 define Package/fastd
   SECTION:=net
   CATEGORY:=Network
-  DEPENDS:=+kmod-tun +librt +libpthread
+  DEPENDS:=+kmod-tun +librt +libpthread +FASTD_WITH_STATUS_SOCKET:libjson-c
   TITLE:=Fast and Secure Tunneling Daemon
   URL:=https://projects.universe-factory.net/projects/fastd
   SUBMENU:=VPN
@@ -63,8 +67,10 @@ CMAKE_OPTIONS += \
        -DCMAKE_BUILD_TYPE:STRING=MINSIZEREL \
        -DWITH_METHOD_CIPHER_TEST:BOOL=FALSE \
        -DWITH_METHOD_COMPOSED_GMAC:BOOL=FALSE \
+       -DWITH_METHOD_COMPOSED_UMAC:BOOL=FALSE \
        -DWITH_METHOD_GENERIC_GMAC:BOOL=FALSE \
        -DWITH_METHOD_GENERIC_POLY1305:BOOL=FALSE \
+       -DWITH_METHOD_GENERIC_UMAC:BOOL=FALSE \
        -DWITH_METHOD_NULL:BOOL=FALSE \
        -DWITH_METHOD_XSALSA20_POLY1305:BOOL=FALSE \
        -DWITH_CIPHER_AES128_CTR:BOOL=FALSE \
@@ -72,11 +78,13 @@ CMAKE_OPTIONS += \
        -DWITH_CIPHER_SALSA20:BOOL=FALSE \
        -DWITH_CIPHER_SALSA2012:BOOL=FALSE \
        -DWITH_MAC_GHASH:BOOL=FALSE \
+       -DWITH_MAC_UHASH:BOOL=FALSE \
        -DWITH_CMDLINE_USER:BOOL=FALSE \
        -DWITH_CMDLINE_LOGGING:BOOL=FALSE \
        -DWITH_CMDLINE_OPERATION:BOOL=FALSE \
        -DWITH_CMDLINE_COMMANDS:BOOL=FALSE \
-       -DWITH_VERIFY:BOOL=FALSE \
+       -DWITH_DYNAMIC_PEERS:BOOL=FALSE \
+       -DWITH_STATUS_SOCKET:BOOL=FALSE \
        -DWITH_CAPABILITIES:BOOL=FALSE \
        -DENABLE_SYSTEMD:BOOL=FALSE \
        -DENABLE_LIBSODIUM:BOOL=FALSE \
@@ -91,6 +99,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC),y)
 CMAKE_OPTIONS += -DWITH_METHOD_COMPOSED_GMAC:BOOL=TRUE
 endif
 
+ifeq ($(CONFIG_FASTD_ENABLE_METHOD_COMPOSED_UMAC),y)
+CMAKE_OPTIONS += -DWITH_METHOD_COMPOSED_UMAC:BOOL=TRUE
+endif
+
 ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC),y)
 CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_GMAC:BOOL=TRUE
 endif
@@ -99,6 +111,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_POLY1305),y)
 CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_POLY1305:BOOL=TRUE
 endif
 
+ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_UMAC),y)
+CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_UMAC:BOOL=TRUE
+endif
+
 ifeq ($(CONFIG_FASTD_ENABLE_METHOD_NULL),y)
 CMAKE_OPTIONS += -DWITH_METHOD_NULL:BOOL=TRUE
 endif
@@ -129,6 +145,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_MAC_GHASH),y)
 CMAKE_OPTIONS += -DWITH_MAC_GHASH:BOOL=TRUE
 endif
 
+ifeq ($(CONFIG_FASTD_ENABLE_MAC_UHASH),y)
+CMAKE_OPTIONS += -DWITH_MAC_UHASH:BOOL=TRUE
+endif
+
 
 ifeq ($(CONFIG_FASTD_WITH_CMDLINE_USER),y)
 CMAKE_OPTIONS += -DWITH_CMDLINE_USER:BOOL=TRUE
@@ -146,8 +166,12 @@ ifeq ($(CONFIG_FASTD_WITH_CMDLINE_COMMANDS),y)
 CMAKE_OPTIONS += -DWITH_CMDLINE_COMMANDS:BOOL=TRUE
 endif
 
-ifeq ($(CONFIG_FASTD_WITH_VERIFY),y)
-CMAKE_OPTIONS += -DWITH_VERIFY:BOOL=TRUE
+ifeq ($(CONFIG_FASTD_WITH_DYNAMIC_PEERS),y)
+CMAKE_OPTIONS += -DWITH_DYNAMIC_PEERS:BOOL=TRUE
+endif
+
+ifeq ($(CONFIG_FASTD_WITH_STATUS_SOCKET),y)
+CMAKE_OPTIONS += -DWITH_STATUS_SOCKET:BOOL=TRUE
 endif
 
 
@@ -164,9 +188,9 @@ define Package/fastd/install
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/fastd $(1)/usr/bin/
 
        $(INSTALL_DIR) $(1)/etc/init.d/
-       $(INSTALL_BIN) files/fastd.init $(1)/etc/init.d/fastd
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/doc/examples/openwrt/fastd.init $(1)/etc/init.d/fastd
        $(INSTALL_DIR) $(1)/etc/config
-       $(INSTALL_CONF) files/fastd.config $(1)/etc/config/fastd
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/examples/openwrt/fastd.config $(1)/etc/config/fastd
        $(INSTALL_DIR) $(1)/etc/fastd
        $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
        $(INSTALL_DATA) files/fastd.upgrade $(1)/lib/upgrade/keep.d/fastd
diff --git a/net/fastd/files/fastd.config b/net/fastd/files/fastd.config
deleted file mode 100644 (file)
index b47cc65..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package fastd
-
-config fastd sample_config
-
-       # Set to 1 to enable this instance:
-       option enabled 0
-
-       # Sets a static config file, optional
-       # Options set via UCI have higher priority that statically configured ones
-#      list config '/etc/fastd/sample_config/fastd.conf'
-
-       # Configures a single static peer from a configuration file
-#      list config_peer '/etc/fastd/sample_config/sample_peer.conf'
-
-       # Sets an additional directory from which peers configurations are read
-       # The peer list can be reloaded without restarting fastd
-       # Peer can either be configured via UCI (see examples below) or via peer dirs
-       # Can't be used in tun mode
-#      list config_peer_dir '/etc/fastd/sample_config/peers'
-
-       # Sets the log level
-       # Possible values: error, warn, info, verbose, debug
-       # Default: info
-       option syslog_level 'info'
-
-       # IP address and port of the local end, optional
-       # 'any' can be used to bind to both IPv4 and IPv6
-       # If no port is given fastd will bind to a random port
-#      list bind 'any:1337'
-#      list bind '0.0.0.0:1337'
-#      list bind '[::]:1337'
-
-       # "method null" uses no encryption or MAC
-       # "method xsalsa20-poly1305" uses the XSalsa20 encryption ad the Poly1305 MAC
-       list method 'xsalsa20-poly1305'
-
-       # "mode tap" will create an ethernet tunnel (tap device),
-       # "mode tun" will create an IP tunnel (tun device).
-       option mode 'tap'
-
-       # Set the name of the tunnel interface to use
-       option interface 'tap0'
-#      option interface 'tun0'
-#      option interface 'fastd0'
-
-       # Sets the MTU of the tunnel interface, default is 1500
-       # 1426 is a good value that avoids fragmentation for the xsalsa20-poly1305 method
-       # when the tunnel uses an IPv4 connection on a line with an MTU of 1492 or higher
-       option mtu 1426
-
-       # Enables direct forwaring of packets between peers
-       # WARNING: Only enable this if you know what you are doing, as this can lead to forwarding loops!
-       option forward 0
-
-       # Disable for compatiblity with fastd v10 and older
-       option secure_handshakes 1
-
-       # Set a packet mark to filter for with iptables or ip rules
-#      option packet_mark 42
-
-       # Limits the maximum number of connections, optional
-#      option peer_limit 5
-
-       # The secret key
-       # A keypair can be generated with `fastd --generate-key`
-       # When the corresponding public key is lost it can be recovered with `/etc/init.d/fastd show-key <config name>`
-#      option secret '0000000000000000000000000000000000000000000000000000000000000000'
-
-       # Sets the user to run fastd as. Defaults to root
-#      option user 'daemon'
-
-       # Sets the group to run fastd as. Defaults to the user's primary group
-#      option group 'daemon'
-
-       # If set to 1, the logs won't contain peers' IP addresses
-#      option hide_ip_addresses '0'
-
-       # If set to 1, the logs won't contain peers' MAC addresses
-#      option hide_mac_addresses '0'
-
-       # Read the documentation about this one. Only ever useful in severly broken networks.
-#      option pmtu ''
-
-       # command to configure IP addresses etc. after the tunnel interface is up; $1 will be the interface name (optional)
-#      option up ''
-
-       # command to execute before the tunnel interface is set down; $1 will be the interface name (optional)
-#      option down ''
-
-
-config peer sample_peer
-
-       # Set to 1 to enable this peer
-       # In tap mode peers can be reloaded dynamically
-       option enabled 0
-
-       # Controls which instance this peer is associated with
-       option net 'sample_config'
-
-       # Controls which peer group this peer belongs to, optional
-       # For most use cases peer groups aren't necessary
-#      option group 'sample_group'
-
-       # The peer's public key
-       option key '0000000000000000000000000000000000000000000000000000000000000000'
-
-       # A remote specification consists of an address or a hostname, and a port
-       # When a hostname is given, it is recommended to specify the address family to use
-       # It is possible to specify no, one or multiple remotes
-       # (but all entries must designate the same host as the public key must be unique)
-#      list remote '192.0.2.1:1337'
-#      list remote '[2001:db8::1]:1337'
-#      list remote '"example.com" port 1337'
-#      list remote 'ipv4 "example.com" port 1337'
-#      list remote 'ipv6 "example.com" port 1337'
-
-       # Setting float to 1 allow incoming connections with this key from other addresses/hostnames/ports than the specified remotes
-#      option float 0
-
-
-config peer_group sample_group
-
-       # Set to 1 to enable this peer group
-       option enabled 0
-
-       # Controls which instance this peer group is associated with
-       # Peer groups can't be used in tun mode
-       option net 'sample_config'
-
-       # Allows configuring nested groups
-#      option parent 'other_group'
-
-       # Includes another config file inside the peer group definition
-#      list config '/etc/fastd/sample_config/sample_group.conf'
-
-       # Configures a single static peer from a configuration file
-#      list config_peer '/etc/fastd/sample_config/sample_peer.conf'
-
-       # Configures an additional peer directory for this group
-#      list config_peer_dir '/etc/fastd/sample_config/peers2'
-
-       # Limits the maximum number of connections to peers in this group (optional)
-#      option peer_limit 5
diff --git a/net/fastd/files/fastd.init b/net/fastd/files/fastd.init
deleted file mode 100644 (file)
index 3a20922..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2012-2013 OpenWrt.org
-
-START=95
-
-SERVICE_USE_PID=1
-
-EXTRA_COMMANDS="up down show_key generate_key"
-
-LIST_SEP="
-"
-TMP_FASTD=/tmp/fastd
-FASTD_COMMAND=/usr/bin/fastd
-
-
-section_enabled() {
-       config_get_bool enabled "$1" 'enabled' 0
-       [ $enabled -gt 0 ]
-}
-
-error() {
-       echo "${initscript}:" "$@" 1>&2
-}
-
-get_key_instance() {
-       local s="$1"
-
-       config_get secret "$s" secret
-       if [ "$secret" = 'generate' ]; then
-               secret=`"$FASTD_COMMAND" --generate-key --machine-readable`
-               uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
-       fi
-
-       echo "$secret"
-}
-
-
-escape_string() {
-       local t=${1//\\/\\\\}
-       echo -n "\"${t//\"/\\\"}\""
-}
-
-guard_value() {
-       local t=${1//[^-a-z0-9\[\].:]/}
-       echo -n "$t"
-}
-
-guard_remote() {
-       local t=${1//[^-a-zA-Z0-9\[\].:\"% ]/}
-       local quotes=${t//[^\"]/}
-       if [ "${#quotes}" = 0 -o "${#quotes}" = 2 ]; then
-               echo -n "$t"
-       fi
-}
-
-yes_no() {
-       case "$1" in
-               0|no|off|false|disabled) echo -n no;;
-               *) echo -n yes;;
-       esac
-}
-
-config_string_config='include $(escape_string "$value");'
-config_string_config_peer='include peer $(escape_string "$value");'
-config_string_config_peer_dir='include peers from $(escape_string "$value");'
-config_string_bind='bind $(guard_value "$value");'
-config_string_method='method $(escape_string "$value");'
-config_string_syslog_level='log to syslog level $(guard_value "$value");'
-config_string_mode='mode $(guard_value "$value");'
-config_string_interface='interface $(escape_string "$value");'
-config_string_mtu='mtu $(guard_value "$value");'
-config_string_peer_limit='peer limit $(guard_value "$value");'
-config_string_user='user $(escape_string "$value");'
-config_string_group='group $(escape_string "$value");'
-config_string_pmtu='pmtu $(yes_no "$value");'
-config_string_forward='forward $(yes_no "$value");'
-config_string_hide_ip_addresses='hide ip addresses $(yes_no "$value");'
-config_string_hide_mac_addresses='hide mac addresses $(yes_no "$value");'
-config_string_secure_handshakes='secure handshakes $(yes_no "$value");'
-config_string_packet_mark='packet mark $(guard_value "$value");'
-
-config_string_peer='peer $(escape_string "$value") {'
-config_string_peer_group='peer group $(escape_string "$value") {'
-
-peer_string_key='key $(escape_string "$value");'
-peer_string_float='float $(yes_no "$value");'
-peer_string_remote='remote $(guard_remote "$value");'
-
-generate_option() {
-       local __string=$(eval echo \"\$$2\")
-       local value="$1";
-       eval echo "\"$__string\""
-}
-
-append_option() {
-       local v; local len; local s="$1"; local prefix="$2"; local p="$3"
-
-       config_get len "$s" "${p}_LENGTH"
-
-       if [ -z "$len" ]; then
-               config_get v "$s" "$p"
-               [ -n "$v" ] && generate_option "$v" "${prefix}_string_${p}"
-       else
-               config_list_foreach "$s" "$p" generate_option "${prefix}_string_${p}"
-       fi
-}
-
-append_options() {
-       local p; local s="$1"; local prefix="$2"; shift; shift
-       for p in $*; do
-               append_option "$s" "$prefix" "$p"
-       done
-}
-
-
-generate_config_secret() {
-       echo "secret $(escape_string "$1");"
-}
-
-
-generate_peer_config() {
-       local peer="$1"
-
-       # These options are deprecated
-       config_get address "$peer" address
-       config_get hostname "$peer" hostname
-       config_get address_family "$peer" address_family
-       config_get port "$peer" port
-
-       if [ "$address" -o "$hostname" ]; then
-               if [ -z "$port" ]; then
-                       error "peer $peer: address or hostname, but no port given"
-                       return 1
-               fi
-
-               if [ "$hostname" ]; then
-                       generate_option peer_string_remote "$address_family \"$hostname\" port $port"
-               fi
-
-               if [ "$address" ]; then
-                       generate_option peer_string_remote "$address port $port"
-               fi
-       fi
-
-       append_options "$peer" peer \
-               key float remote
-}
-
-generate_single_peer_config() {
-       local peer="$1"; local net="$2"
-
-       config_get peer_net "$peer" net
-       config_get peer_group "$peer" group
-       [ "$net" = "$peer_net" -a "$peer_group" = '' ] || return 0
-
-       section_enabled "$peer" || return 0
-
-       generate_option "$peer" config_string_peer
-       generate_peer_config "$peer"
-       echo '}'
-}
-
-create_peer_config() {
-       local peer="$1"; local net="$2"; local group="$3"; local path="$4"
-
-       config_get peer_net "$peer" net
-       config_get peer_group "$peer" group
-       [ "$group" = "$peer_group" ] || return 0
-
-       if [ "$net" != "$peer_net" ]; then
-               [ -z "$group" ] || error "warning: the peer group of peer '$peer' doesn't match its net, the peer will be ignored"
-               return 0
-       fi
-
-       section_enabled "$peer" || return 0
-
-       generate_peer_config "$peer" >"$path/$peer"
-}
-
-update_peer_group() {
-       local net="$1"; local group_dir="$2"; local group="$3"; local update_only="$4"
-       local path="$TMP_FASTD/fastd.$net/$group_dir"
-
-       rm -rf "$path"
-       mkdir -p "$path"
-
-       config_foreach create_peer_config 'peer' "$net" "$group" "$path"
-
-       if [ -z "$update_only" ]; then
-               generate_option "$path" config_string_config_peer_dir
-       fi
-
-       config_foreach generate_peer_group_config 'peer_group' "$net" "$group_dir" "$update_only" "$group"
-}
-
-generate_peer_group_config() {
-       local group="$1"; local net="$2"; local group_dir="$3%$group"; local update_only="$4"; local parent="$5"
-
-       config_get group_net "$group" net
-       config_get group_parent "$group" parent
-       [ "$parent" = "$group_parent" ] || return 0
-
-       if [ "$net" != "$peer_net" ]; then
-               [ -z "$parent" ] || error "warning: the parent of peer group '$group' doesn't match its net, the peer group will be ignored"
-               return 0
-       fi
-
-       section_enabled "$group" || return 0
-
-       if [ -z "$update_only" ]; then
-               generate_option "$group" config_string_peer_group
-               append_options "$group" config \
-                       config config_peer config_peer_dir peer_limit
-       fi
-
-       update_peer_group "$net" "$group_dir" "$group" "$update_only"
-
-       if [ -z "$update_only" ]; then
-               echo '}'
-       fi
-}
-
-update_peer_groups() {
-       local net="$1"; local update_only="$2"
-
-       update_peer_group "$net" 'peers' '' "$update_only"
-}
-
-generate_config() {
-       local s="$1"
-
-       generate_option 'info' config_string_syslog_level
-
-       append_options "$s" config \
-               config config_peer config_peer_dir bind method syslog_level mode interface mtu peer_limit \
-               user group pmtu forward hide_ip_addresses hide_mac_addresses secure_handshakes packet_mark
-
-       config_get mode "$s" mode
-
-       if [ "$mode" = "tun" ]; then
-               config_foreach generate_single_peer_config 'peer' "$s"
-       else
-               update_peer_groups "$s"
-       fi
-}
-
-
-generate_key_instance() {
-       local s="$1"
-
-       config_get secret "$s" secret
-       if [ -z "$secret" -o "$secret" = 'generate' ]; then
-               secret=`fastd --generate-key --machine-readable`
-               uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
-       fi
-
-       generate_config_secret "$secret" | "$FASTD_COMMAND" --config - --show-key --machine-readable
-}
-
-show_key_instance() {
-       local s="$1"
-
-       local secret=`get_key_instance "$s"`
-       if [ -z "$secret" ]; then
-               error "$s: secret is not set"
-               return 1
-       fi
-
-       generate_config_secret "$secret" | "$FASTD_COMMAND" --config - --show-key --machine-readable
-}
-
-start_instance() {
-       local s="$1"
-
-       section_enabled "$s" || return 1
-
-       SERVICE_PID_FILE="/var/run/fastd.$s.pid"
-
-       config_get interface "$s" interface
-       if [ -z "$interface" ]; then
-               error "$s: interface is not set"
-               return 1
-       fi
-
-       if ifconfig "$interface" &>/dev/null; then
-               error "$s: interface '$interface' is already in use"
-               return 1
-       fi
-
-       config_get mode "$s" mode
-       if [ -z "$mode" ]; then
-               error "$s: mode is not set"
-               return 1
-       fi
-
-       local secret=`get_key_instance "$s"`
-       if [ -z "$secret" ]; then
-               error "$s: secret is not set"
-               return 1
-       fi
-
-       rm -f "$SERVICE_PID_FILE"
-       touch "$SERVICE_PID_FILE"
-
-       config_get user "$s" user
-       if [ "$user" ]; then
-               chown "$user" "$SERVICE_PID_FILE"
-       fi
-
-       (generate_config_secret "$secret"; generate_config "$s") | service_start "$FASTD_COMMAND" --config - --daemon --pid-file "$SERVICE_PID_FILE"
-
-       if ! ifconfig "$interface" >/dev/null 2>&1; then
-               error "$s: startup failed"
-               return 1
-       fi
-
-       config_get up "$s" up
-       [ -n "$up" ] && sh -c "$up" - "$interface"
-}
-
-stop_instance() {
-       local s="$1"
-
-       section_enabled "$s" || return 1
-
-       SERVICE_PID_FILE="/var/run/fastd.$s.pid"
-
-       config_get interface "$s" interface
-       if [ -z "$interface" ]; then
-               error "$s: interface is not set"
-               return 1
-       fi
-
-       if ! ifconfig "$interface" &>/dev/null; then
-               error "$s: interface '$interface' does not exist"
-               return 1
-       fi
-
-       config_get down "$s" down
-       [ -n "$down" ] && sh -c "$down" - "$interface"
-
-       service_stop "$FASTD_COMMAND"
-
-       rm -rf "$TMP_FASTD/fastd.$s"
-}
-
-reload_instance() {
-       local s="$1"
-
-       section_enabled "$s" || return 1
-
-       config_get mode "$s" mode
-       [ "$mode" = "tun" ] && return 1
-
-       update_peer_groups "$s" true
-
-       SERVICE_PID_FILE="/var/run/fastd.$s.pid"
-       service_reload "$FASTD_COMMAND"
-}
-
-start() {
-       config_load 'fastd'
-       config_foreach start_instance 'fastd'
-       return 0
-}
-
-stop() {
-       config_load 'fastd'
-       config_foreach stop_instance 'fastd'
-       return 0
-}
-
-reload() {
-       config_load 'fastd'
-       config_foreach reload_instance 'fastd'
-       return 0
-}
-
-up() {
-       local exists
-       local instance
-       config_load 'fastd'
-       for instance in "$@"; do
-               config_get exists "$instance" 'TYPE'
-               if [ "$exists" = 'fastd' ]; then
-                       start_instance "$instance"
-               fi
-       done
-}
-
-down() {
-       local exists
-       local instance
-       config_load 'fastd'
-       for instance in "$@"; do
-               config_get exists "$instance" 'TYPE'
-               if [ "$exists" = 'fastd' ]; then
-                       stop_instance "$instance"
-               fi
-       done
-}
-
-show_key() {
-       local exists
-       local instance
-       config_load 'fastd'
-       for instance in "$@"; do
-               config_get exists "$instance" 'TYPE'
-               if [ "$exists" = 'fastd' ]; then
-                       show_key_instance "$instance"
-               fi
-       done
-}
-
-generate_key() {
-       local exists
-       local instance
-       config_load 'fastd'
-       for instance in "$@"; do
-               config_get exists "$instance" 'TYPE'
-               if [ "$exists" = 'fastd' ]; then
-                       generate_key_instance "$instance"
-               fi
-       done
-}
index f2d821efee91b2bbf98f6ffbaa1bfc8ed684f67e..1f1d86dce6320128de503892fc467e261d8aa4d1 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=freeradius2
-PKG_VERSION:=2.2.5
+PKG_VERSION:=2.2.6
 PKG_RELEASE:=1
 
 PKG_SOURCE:=freeradius-server-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=ftp://ftp.freeradius.org/pub/freeradius/
-PKG_MD5SUM:=40535bace507d7a3134c3d858f3cbc5a
+PKG_MD5SUM:=e9a6f9bbee9706b008b924061ab3f915
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=GPL-2.0
 PKG_LICENSE_FILES:=COPYRIGHT LICENSE
@@ -26,6 +26,7 @@ PKG_CONFIG_DEPENDS := \
   FREERADIUS_OPENSSL \
   FREERADIUS_NOSSL
 
+PKG_CHECK_FORMAT_SECURITY:=0
 include $(INCLUDE_DIR)/package.mk
 
 define Package/freeradius2/config
index 4bf225276ef4a5f781e4f8c04e3c22dc93b57e18..c254912d46a9313d32070166825148f5b4c79cda 100644 (file)
@@ -1,6 +1,6 @@
 --- a/configure.in
 +++ b/configure.in
-@@ -832,35 +832,6 @@ if test "x$WITH_OPENSSL" = xyes; then
+@@ -796,35 +796,6 @@ if test "x$WITH_OPENSSL" = xyes; then
      OPENSSL_INCLUDE="-DOPENSSL_NO_KRB5"
    fi
  
index bf60dcbdf95900152edf7879b40c4bf6eae9ebd7..df16e15f4f57e4b55df362cbca2471c5a8634558 100644 (file)
@@ -8,13 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=fwknop
-PKG_VERSION:=2.6.3
+PKG_VERSION:=2.6.5
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://www.cipherdyne.org/fwknop/download
-PKG_MD5SUM:=79e8a2feff54b429503bc7cade3bc32e
+PKG_MD5SUM:=1ae000a499bf604a2aeef4d0a7a178c8
 PKG_MAINTAINER:=Jonathan Bennett <JBennett@incomsystems.biz>
+PKG_LICENSE:=GPLv2
 PKG_INSTALL:=1
 
 include $(INCLUDE_DIR)/package.mk
index 9362df99a98b77e9a17165baf4ecc78e13e1bc5a..8e5e59088d46f9eb92b2bde8513df205456124f6 100644 (file)
@@ -1,6 +1,6 @@
 --- a/server/fwknopd.conf.inst
 +++ b/server/fwknopd.conf.inst
-@@ -284,8 +284,13 @@
+@@ -402,8 +402,13 @@
  # The IPT_FORWARD_ACCESS variable is only used if ENABLE_IPT_FORWARDING is
  # enabled.
  #
index e36790ece207fa1dc29d11c524fb70b0ce3d6989..1be8a01f78eb6427c0b84c36bedf6ba41c75c0ad 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=git
-PKG_VERSION:=2.1.0
-PKG_RELEASE:=2
+PKG_VERSION:=2.2.2
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@KERNEL/software/scm/git/
-PKG_MD5SUM:=47b1f55d9a16be112f7ae2c778a9b30c
+PKG_MD5SUM:=f694e8c911a6f7cfd7aec7b99454ed1f
 
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
index e883921e54a0b6597c6a00216dd543d058d191b2..7cc0dfbca4800adf1c8ebf8bb6102fcc017ae958 100644 (file)
@@ -1,6 +1,6 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -533,16 +533,7 @@ EXTRA_PROGRAMS =
+@@ -529,16 +529,7 @@ EXTRA_PROGRAMS =
  # ... and all the rest that could be moved out of bindir to gitexecdir
  PROGRAMS += $(EXTRA_PROGRAMS)
  
@@ -18,7 +18,7 @@
  
  # Binary suffix, set to .exe for Windows builds
  X =
-@@ -1007,6 +998,12 @@ BUILTIN_OBJS += builtin/verify-commit.o
+@@ -887,6 +878,12 @@ BUILTIN_OBJS += builtin/verify-commit.o
  BUILTIN_OBJS += builtin/verify-pack.o
  BUILTIN_OBJS += builtin/verify-tag.o
  BUILTIN_OBJS += builtin/write-tree.o
@@ -31,7 +31,7 @@
  
  GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
  EXTLIBS =
-@@ -1174,7 +1171,7 @@ endif
+@@ -1049,7 +1046,7 @@ endif
  EXTLIBS += -lz
  
  ifndef NO_OPENSSL
@@ -40,7 +40,7 @@
        ifdef OPENSSLDIR
                BASIC_CFLAGS += -I$(OPENSSLDIR)/include
                OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib)
-@@ -2067,10 +2064,6 @@ endif
+@@ -1901,10 +1898,6 @@ endif
  git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
  
@@ -51,7 +51,7 @@
  git-http-fetch$X: http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
                $(LIBS) $(CURL_LIBCURL)
-@@ -2388,24 +2381,22 @@ endif
+@@ -2222,24 +2215,22 @@ endif
        bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
        execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
        { test "$$bindir/" = "$$execdir/" || \
@@ -80,7 +80,7 @@
        done && \
 --- a/builtin.h
 +++ b/builtin.h
-@@ -137,5 +137,11 @@ extern int cmd_verify_pack(int argc, con
+@@ -138,5 +138,11 @@ extern int cmd_verify_pack(int argc, con
  extern int cmd_show_ref(int argc, const char **argv, const char *prefix);
  extern int cmd_pack_refs(int argc, const char **argv, const char *prefix);
  extern int cmd_replace(int argc, const char **argv, const char *prefix);
 +#include "../upload-pack.c"
 --- a/daemon.c
 +++ b/daemon.c
-@@ -1119,7 +1119,7 @@ static int serve(struct string_list *lis
+@@ -1096,7 +1096,7 @@ static int serve(struct string_list *lis
        return service_loop(&socklist);
  }
  
  {
        int listen_port = 0;
        struct string_list listen_addr = STRING_LIST_INIT_NODUP;
-@@ -1315,12 +1315,13 @@
+@@ -1292,12 +1292,13 @@ int main(int argc, char **argv)
                store_pid(pid_file);
  
        /* prepare argv for serving-processes */
  }
 --- a/fast-import.c
 +++ b/fast-import.c
-@@ -3343,7 +3343,7 @@ static void parse_argv(void)
+@@ -3350,7 +3350,7 @@ static void parse_argv(void)
                read_marks();
  }
  
        { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
        { "init", cmd_init_db, NO_SETUP },
        { "init-db", cmd_init_db, NO_SETUP },
-@@ -461,6 +464,7 @@ static struct cmd_struct commands[] = {
+@@ -462,6 +465,7 @@ static struct cmd_struct commands[] = {
        { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
        { "rm", cmd_rm, RUN_SETUP },
        { "send-pack", cmd_send_pack, RUN_SETUP },
        { "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
        { "show", cmd_show, RUN_SETUP },
        { "show-branch", cmd_show_branch, RUN_SETUP },
-@@ -477,6 +481,7 @@ static struct cmd_struct commands[] = {
+@@ -478,6 +482,7 @@ static struct cmd_struct commands[] = {
        { "update-server-info", cmd_update_server_info, RUN_SETUP },
        { "upload-archive", cmd_upload_archive },
        { "upload-archive--writer", cmd_upload_archive_writer },
        { "verify-pack", cmd_verify_pack },
 --- a/http-backend.c
 +++ b/http-backend.c
-@@ -566,7 +566,7 @@ static struct service_cmd {
+@@ -557,7 +557,7 @@ static struct service_cmd {
        {"POST", "/git-receive-pack$", service_rpc}
  };
  
        char *dir;
 --- a/imap-send.c
 +++ b/imap-send.c
-@@ -1365,7 +1365,7 @@ static int git_imap_config(const char *k
-       return 0;
+@@ -1338,7 +1338,7 @@ static void git_imap_config(void)
+       git_config_get_string("imap.authmethod", &server.auth_method);
  }
  
 -int main(int argc, char **argv)
        const char **user_argv;
 --- a/upload-pack.c
 +++ b/upload-pack.c
-@@ -790,7 +790,7 @@ static int upload_pack_config(const char
+@@ -791,7 +791,7 @@ static int upload_pack_config(const char
        return parse_hide_refs_config(var, value, "uploadpack");
  }
  
index 4a9f8330767d55ae3f0f0dc5aaad8a5f0b15e601..77bf9f230bea7d43466b1e2c5437c18fe79ce533 100644 (file)
@@ -9,12 +9,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=haproxy
-PKG_VERSION:=1.5.4
-PKG_RELEASE:=20
+PKG_VERSION:=1.5.10
+PKG_RELEASE:=00
 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
-PKG_MD5SUM:=b027035bfd8f28326634f802c3447a34
+PKG_MD5SUM:=5631457ea1f84b3c0d8e5bc8015ed329
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
 PKG_LICENSE:=GPL-2.0
 
diff --git a/net/haproxy/patches/0001-DOC-clearly-state-that-the-show-sess-output-format-i.patch b/net/haproxy/patches/0001-DOC-clearly-state-that-the-show-sess-output-format-i.patch
deleted file mode 100644 (file)
index ff17cb7..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From e99d44d4bc3423b721c7f654fd1778b9822a94e3 Mon Sep 17 00:00:00 2001
-From: Olivier <webmaster@ajeux.com>
-Date: Fri, 5 Sep 2014 18:49:10 +0200
-Subject: [PATCH 01/13] DOC: clearly state that the "show sess" output format
- is not fixed
-
-It requires to look at the code (src/dumpstats.c) since the format may
-change at any moment.
-(cherry picked from commit ce31e6e3baebe75a2e6f6b5c66553db8d76dff0c)
----
- doc/configuration.txt | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/doc/configuration.txt b/doc/configuration.txt
-index 19df5ae..1ecf15a 100644
---- a/doc/configuration.txt
-+++ b/doc/configuration.txt
-@@ -13734,9 +13734,11 @@ show sess <id>
-   of "show sess" (it corresponds to the session pointer). Those information are
-   useless to most users but may be used by haproxy developers to troubleshoot a
-   complex bug. The output format is intentionally not documented so that it can
--  freely evolve depending on demands. The special id "all" dumps the states of
--  all sessions, which can be avoided as much as possible as it is highly CPU
--  intensive and can take a lot of time.
-+  freely evolve depending on demands. You may find a description of all fields
-+  returned in src/dumpstats.c
-+
-+  The special id "all" dumps the states of all sessions, which must be avoided
-+  as much as possible as it is highly CPU intensive and can take a lot of time.
- show stat [<iid> <type> <sid>]
-   Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0002-MINOR-stats-fix-minor-typo-fix-in-stats_dump_errors_.patch b/net/haproxy/patches/0002-MINOR-stats-fix-minor-typo-fix-in-stats_dump_errors_.patch
deleted file mode 100644 (file)
index 47542d2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 815d7d5c348575181874429b93b0ebdb0cf873c2 Mon Sep 17 00:00:00 2001
-From: Olivier Doucet <webmaster@ajeux.com>
-Date: Mon, 8 Sep 2014 11:23:00 +0200
-Subject: [PATCH 02/13] MINOR: stats: fix minor typo fix in
- stats_dump_errors_to_buffer()
-
-Remove the space before the colon to match the format used in the frontend.
-(cherry picked from commit 08afdcb47bc39c071787f8fc2066776e1c5e8607)
----
- src/dumpstats.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/dumpstats.c b/src/dumpstats.c
-index 5365042..09bc7f6 100644
---- a/src/dumpstats.c
-+++ b/src/dumpstats.c
-@@ -6045,7 +6045,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
-                               break;
-                       case 1:
-                               chunk_appendf(&trash,
--                                           " backend %s (#%d) : invalid response\n"
-+                                           " backend %s (#%d): invalid response\n"
-                                            "  frontend %s (#%d)",
-                                            appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
-                                            es->oe->id, es->oe->uuid);
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch b/net/haproxy/patches/0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch
deleted file mode 100644 (file)
index b745406..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From 62c8565cd5bbda6ac0dd818fa26922eeaef1605c Mon Sep 17 00:00:00 2001
-From: Conrad Hoffmann <conrad@soundcloud.com>
-Date: Mon, 28 Jul 2014 23:52:20 +0200
-Subject: [PATCH 03/13] MEDIUM: Improve signal handling in systemd wrapper.
-
-Move all code out of the signal handlers, since this is potentially
-dangerous. To make sure the signal handlers behave as expected, use
-sigaction() instead of signal(). That also obsoletes messing with
-the signal mask after restart.
-
-Signed-off-by: Conrad Hoffmann <conrad@soundcloud.com>
-(cherry picked from commit 5b5ea9c93384da49eea0f67ebed0966d4167b17a)
----
- src/haproxy-systemd-wrapper.c | 37 ++++++++++++++++++++++++-------------
- 1 file changed, 24 insertions(+), 13 deletions(-)
-
-diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
-index 529b213..90a94ce 100644
---- a/src/haproxy-systemd-wrapper.c
-+++ b/src/haproxy-systemd-wrapper.c
-@@ -22,6 +22,8 @@
- #define SD_DEBUG "<7>"
- #define SD_NOTICE "<5>"
-+static volatile sig_atomic_t caught_signal;
-+
- static char *pid_file = "/run/haproxy.pid";
- static int wrapper_argc;
- static char **wrapper_argv;
-@@ -103,7 +105,12 @@ static int read_pids(char ***pid_strv)
-       return read;
- }
--static void sigusr2_handler(int signum __attribute__((unused)))
-+static void signal_handler(int signum)
-+{
-+      caught_signal = signum;
-+}
-+
-+static void do_restart(void)
- {
-       setenv(REEXEC_FLAG, "1", 1);
-       fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing\n");
-@@ -111,7 +118,7 @@ static void sigusr2_handler(int signum __attribute__((unused)))
-       execv(wrapper_argv[0], wrapper_argv);
- }
--static void sigint_handler(int signum __attribute__((unused)))
-+static void do_shutdown(void)
- {
-       int i, pid;
-       char **pid_strv = NULL;
-@@ -147,25 +154,21 @@ int main(int argc, char **argv)
-       --argc; ++argv;
-       init(argc, argv);
--      signal(SIGINT, &sigint_handler);
--      signal(SIGUSR2, &sigusr2_handler);
-+      struct sigaction sa;
-+      memset(&sa, 0, sizeof(struct sigaction));
-+      sa.sa_handler = &signal_handler;
-+      sigaction(SIGUSR2, &sa, NULL);
-+      sigaction(SIGINT, &sa, NULL);
-       if (getenv(REEXEC_FLAG) != NULL) {
-               /* We are being re-executed: restart HAProxy gracefully */
-               int i;
-               char **pid_strv = NULL;
-               int nb_pid = read_pids(&pid_strv);
--              sigset_t sigs;
-               unsetenv(REEXEC_FLAG);
-               spawn_haproxy(pid_strv, nb_pid);
--              /* Unblock SIGUSR2 which was blocked by the signal handler
--               * before re-exec */
--              sigprocmask(SIG_BLOCK, NULL, &sigs);
--              sigdelset(&sigs, SIGUSR2);
--              sigprocmask(SIG_SETMASK, &sigs, NULL);
--
-               for (i = 0; i < nb_pid; ++i)
-                       free(pid_strv[i]);
-               free(pid_strv);
-@@ -176,8 +179,16 @@ int main(int argc, char **argv)
-       }
-       status = -1;
--      while (-1 != wait(&status) || errno == EINTR)
--              ;
-+      while (-1 != wait(&status) || errno == EINTR) {
-+              if (caught_signal == SIGUSR2) {
-+                      caught_signal = 0;
-+                      do_restart();
-+              }
-+              else if (caught_signal == SIGINT) {
-+                      caught_signal = 0;
-+                      do_shutdown();
-+              }
-+      }
-       fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n",
-                       status);
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0004-MINOR-Also-accept-SIGHUP-SIGTERM-in-systemd-wrapper.patch b/net/haproxy/patches/0004-MINOR-Also-accept-SIGHUP-SIGTERM-in-systemd-wrapper.patch
deleted file mode 100644 (file)
index bbda7d8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From 6bb7bf7949dd019403b65f400c4b3d0d8589327b Mon Sep 17 00:00:00 2001
-From: Matt Robenolt <matt@ydekproductions.com>
-Date: Thu, 11 Sep 2014 05:19:30 +0000
-Subject: [PATCH 04/13] MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper
-
-My proposal is to let haproxy-systemd-wrapper also accept normal
-SIGHUP/SIGTERM signals to play nicely with other process managers
-besides just systemd. In my use case, this will be for using with
-runit which has to ability to change the signal used for a
-"reload" or "stop" command. It also might be worth renaming this
-bin to just haproxy-wrapper or something of that sort to separate
-itself away from systemd. But that's a different discussion. :)
-(cherry picked from commit c54bdd2a118161b4dc36963b4201edfa7341dadb)
----
- src/haproxy-systemd-wrapper.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
-index 90a94ce..cc8baa8 100644
---- a/src/haproxy-systemd-wrapper.c
-+++ b/src/haproxy-systemd-wrapper.c
-@@ -158,7 +158,9 @@ int main(int argc, char **argv)
-       memset(&sa, 0, sizeof(struct sigaction));
-       sa.sa_handler = &signal_handler;
-       sigaction(SIGUSR2, &sa, NULL);
-+      sigaction(SIGHUP, &sa, NULL);
-       sigaction(SIGINT, &sa, NULL);
-+      sigaction(SIGTERM, &sa, NULL);
-       if (getenv(REEXEC_FLAG) != NULL) {
-               /* We are being re-executed: restart HAProxy gracefully */
-@@ -180,11 +182,11 @@ int main(int argc, char **argv)
-       status = -1;
-       while (-1 != wait(&status) || errno == EINTR) {
--              if (caught_signal == SIGUSR2) {
-+              if (caught_signal == SIGUSR2 || caught_signal == SIGHUP) {
-                       caught_signal = 0;
-                       do_restart();
-               }
--              else if (caught_signal == SIGINT) {
-+              else if (caught_signal == SIGINT || caught_signal == SIGTERM) {
-                       caught_signal = 0;
-                       do_shutdown();
-               }
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0005-DOC-indicate-in-the-doc-that-track-sc-can-wait-if-da.patch b/net/haproxy/patches/0005-DOC-indicate-in-the-doc-that-track-sc-can-wait-if-da.patch
deleted file mode 100644 (file)
index d34b7ca..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 531485c08ffb15b939a28ecf47090e4c93341d1b Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 15:48:15 +0200
-Subject: [PATCH 05/13] DOC: indicate in the doc that track-sc* can wait if
- data are missing
-
-Since commit 1b71eb5 ("BUG/MEDIUM: counters: fix track-sc* to wait on
-unstable contents"), we don't need the "if HTTP" anymore. But the doc
-was not updated to reflect this.
-
-Since this change was backported to 1.5, this doc update should be
-backported as well.
-(cherry picked from commit 4d54c7ca0286588de5060acce9aff8aa9645bb98)
----
- doc/configuration.txt | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/doc/configuration.txt b/doc/configuration.txt
-index 1ecf15a..3c75c92 100644
---- a/doc/configuration.txt
-+++ b/doc/configuration.txt
-@@ -7470,9 +7470,9 @@ tcp-request content <action> [{if | unless} <condition>]
-   contents will always be immediately present when the rule is evaluated first.
-   Tracking layer7 information is also possible provided that the information
--  are present when the rule is processed. The current solution for making the
--  rule engine wait for such information is to set an inspect delay and to
--  condition its execution with an ACL relying on such information.
-+  are present when the rule is processed. The rule processing engine is able to
-+  wait until the inspect delay expires when the data to be tracked is not yet
-+  available.
-   Example:
-         # Accept HTTP requests containing a Host header saying "example.com"
-@@ -7497,12 +7497,12 @@ tcp-request content <action> [{if | unless} <condition>]
-   Example:
-         # Track the last IP from X-Forwarded-For
-         tcp-request inspect-delay 10s
--        tcp-request content track-sc0 hdr(x-forwarded-for,-1) if HTTP
-+        tcp-request content track-sc0 hdr(x-forwarded-for,-1)
-   Example:
-         # track request counts per "base" (concatenation of Host+URL)
-         tcp-request inspect-delay 10s
--        tcp-request content track-sc0 base table req-rate if HTTP
-+        tcp-request content track-sc0 base table req-rate
-   Example: track per-frontend and per-backend counters, block abusers at the
-            frontend when the backend detects abuse.
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0006-MEDIUM-http-enable-header-manipulation-for-101-respo.patch b/net/haproxy/patches/0006-MEDIUM-http-enable-header-manipulation-for-101-respo.patch
deleted file mode 100644 (file)
index b189db7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-From 0cb4b899d370b9d04b3457a1d75dbd658c1a1646 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 10:40:38 +0200
-Subject: [PATCH 06/13] MEDIUM: http: enable header manipulation for 101
- responses
-
-Ryan Brock reported that server stickiness did not work for WebSocket
-because the cookies and headers are not modified on 1xx responses. He
-found that his browser correctly presents the cookies learned on 101
-responses, which was not specifically defined in the WebSocket spec,
-nor in the cookie spec. 101 is a very special case. Being part of 1xx,
-it's an interim response. But within 1xx, it's special because it's
-the last HTTP/1 response that transits on the wire, which is different
-from 100 or 102 which may appear multiple times. So in that sense, we
-can consider it as a final response regarding HTTP/1, and it makes
-sense to allow header processing there. Note that we still ensure not
-to mangle the Connection header, which is critical for HTTP upgrade to
-continue to work smoothly with agents that are a bit picky about what
-tokens are found there.
-
-The rspadd rules are now processed for 101 responses as well, but the
-cache-control checks are not performed (since no body is delivered).
-
-Ryan confirmed that this patch works for him.
-
-It would make sense to backport it to 1.5 given that it improves end
-user experience on WebSocket servers.
-(cherry picked from commit ce730de86719d0b5079dd8b0843559e4ff0a1ecc)
----
- src/proto_http.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
-diff --git a/src/proto_http.c b/src/proto_http.c
-index 4d27b2c..7e35c8b 100644
---- a/src/proto_http.c
-+++ b/src/proto_http.c
-@@ -6249,7 +6249,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
-               /* add response headers from the rule sets in the same order */
-               list_for_each_entry(wl, &rule_set->rsp_add, list) {
--                      if (txn->status < 200)
-+                      if (txn->status < 200 && txn->status != 101)
-                               break;
-                       if (wl->cond) {
-                               int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
-@@ -6270,7 +6270,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
-       }
-       /* OK that's all we can do for 1xx responses */
--      if (unlikely(txn->status < 200))
-+      if (unlikely(txn->status < 200 && txn->status != 101))
-               goto skip_header_mangling;
-       /*
-@@ -6283,7 +6283,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
-       /*
-        * Check for cache-control or pragma headers if required.
-        */
--      if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
-+      if (((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC)) && txn->status != 101)
-               check_response_for_cacheability(s, rep);
-       /*
-@@ -6399,9 +6399,11 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
-        * Adjust "Connection: close" or "Connection: keep-alive" if needed.
-        * If an "Upgrade" token is found, the header is left untouched in order
-        * not to have to deal with some client bugs : some of them fail an upgrade
--       * if anything but "Upgrade" is present in the Connection header.
-+       * if anything but "Upgrade" is present in the Connection header. We don't
-+       * want to touch any 101 response either since it's switching to another
-+       * protocol.
-        */
--      if (!(txn->flags & TX_HDR_CONN_UPG) &&
-+      if ((txn->status != 101) && !(txn->flags & TX_HDR_CONN_UPG) &&
-           (((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
-            ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
-             (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0007-BUG-MEDIUM-config-propagate-frontend-to-backend-proc.patch b/net/haproxy/patches/0007-BUG-MEDIUM-config-propagate-frontend-to-backend-proc.patch
deleted file mode 100644 (file)
index c4fe96a..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From b53934eec71ab34eb3762a89cec326360a5b0bc5 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 11:31:31 +0200
-Subject: [PATCH 07/13] BUG/MEDIUM: config: propagate frontend to backend
- process binding again.
-
-This basically reverts 3507d5d ("MEDIUM: proxy: only adjust the backend's
-bind-process when already set"). It was needed during the transition to
-the new process binding method but is causing trouble now because frontend
-to backend binding is not properly propagated.
-
-This fix should be backported to 1.5.
-(cherry picked from commit 8a3478ed31a16904f45178c153f4649faf6de675)
----
- src/cfgparse.c | 15 ++++++---------
- 1 file changed, 6 insertions(+), 9 deletions(-)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index 943eba0..5288600 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -6165,9 +6165,8 @@ int check_config_validity()
-                               /* we force the backend to be present on at least all of
-                                * the frontend's processes.
-                                */
--                              if (target->bind_proc)
--                                      target->bind_proc = curproxy->bind_proc ?
--                                              (target->bind_proc | curproxy->bind_proc) : 0;
-+                              target->bind_proc = curproxy->bind_proc ?
-+                                      (target->bind_proc | curproxy->bind_proc) : 0;
-                               /* Emit a warning if this proxy also has some servers */
-                               if (curproxy->srv) {
-@@ -6203,9 +6202,8 @@ int check_config_validity()
-                                       /* we force the backend to be present on at least all of
-                                        * the frontend's processes.
-                                        */
--                                      if (target->bind_proc)
--                                              target->bind_proc = curproxy->bind_proc ?
--                                                      (target->bind_proc | curproxy->bind_proc) : 0;
-+                                      target->bind_proc = curproxy->bind_proc ?
-+                                              (target->bind_proc | curproxy->bind_proc) : 0;
-                               }
-                       }
-               }
-@@ -6257,9 +6255,8 @@ int check_config_validity()
-                               /* we force the backend to be present on at least all of
-                                * the frontend's processes.
-                                */
--                              if (target->bind_proc)
--                                      target->bind_proc = curproxy->bind_proc ?
--                                              (target->bind_proc | curproxy->bind_proc) : 0;
-+                              target->bind_proc = curproxy->bind_proc ?
-+                                      (target->bind_proc | curproxy->bind_proc) : 0;
-                       }
-               }
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0008-MEDIUM-config-properly-propagate-process-binding-bet.patch b/net/haproxy/patches/0008-MEDIUM-config-properly-propagate-process-binding-bet.patch
deleted file mode 100644 (file)
index add6b6f..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-From 5436afc9488531a5e2adff3a1a766af375e0922c Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 12:17:36 +0200
-Subject: [PATCH 08/13] MEDIUM: config: properly propagate process binding
- between proxies
-
-We now recursively propagate the bind-process values between frontends
-and backends instead of doing it during name resolving. This ensures
-that we're able to properly propagate all the bind-process directives
-even across "listen" instances, which are not perfectly covered at the
-moment, depending on the declaration order.
-(cherry picked from commit 64ab6077b768ee02b04a36b30ee195639a2fabc1)
----
- src/cfgparse.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++------------
- 1 file changed, 65 insertions(+), 16 deletions(-)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index 5288600..b9853ef 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -5932,6 +5932,64 @@ int readcfgfile(const char *file)
-       return err_code;
- }
-+/* This function propagates processes from frontend <from> to backend <to> so
-+ * that it is always guaranteed that a backend pointed to by a frontend is
-+ * bound to all of its processes. After that, if the target is a "listen"
-+ * instance, the function recursively descends the target's own targets along
-+ * default_backend, use_backend rules, and reqsetbe rules. Since the bits are
-+ * checked first to ensure that <to> is already bound to all processes of
-+ * <from>, there is no risk of looping and we ensure to follow the shortest
-+ * path to the destination.
-+ *
-+ * It is possible to set <to> to NULL for the first call so that the function
-+ * takes care of visiting the initial frontend in <from>.
-+ *
-+ * It is important to note that the function relies on the fact that all names
-+ * have already been resolved.
-+ */
-+void propagate_processes(struct proxy *from, struct proxy *to)
-+{
-+      struct switching_rule *rule;
-+      struct hdr_exp *exp;
-+
-+      if (to) {
-+              /* check whether we need to go down */
-+              if (from->bind_proc &&
-+                  (from->bind_proc & to->bind_proc) == from->bind_proc)
-+                      return;
-+
-+              if (!from->bind_proc && !to->bind_proc)
-+                      return;
-+
-+              to->bind_proc = from->bind_proc ?
-+                      (to->bind_proc | from->bind_proc) : 0;
-+
-+              /* now propagate down */
-+              from = to;
-+      }
-+
-+      if (!from->cap & PR_CAP_FE)
-+              return;
-+
-+      /* default_backend */
-+      if (from->defbe.be)
-+              propagate_processes(from, from->defbe.be);
-+
-+      /* use_backend */
-+      list_for_each_entry(rule, &from->switching_rules, list) {
-+              to = rule->be.backend;
-+              propagate_processes(from, to);
-+      }
-+
-+      /* reqsetbe */
-+      for (exp = from->req_exp; exp != NULL; exp = exp->next) {
-+              if (exp->action != ACT_SETBE)
-+                      continue;
-+              to = (struct proxy *)exp->replace;
-+              propagate_processes(from, to);
-+      }
-+}
-+
- /*
-  * Returns the error code, 0 if OK, or any combination of :
-  *  - ERR_ABORT: must abort ASAP
-@@ -6162,11 +6220,6 @@ int check_config_validity()
-                       } else {
-                               free(curproxy->defbe.name);
-                               curproxy->defbe.be = target;
--                              /* we force the backend to be present on at least all of
--                               * the frontend's processes.
--                               */
--                              target->bind_proc = curproxy->bind_proc ?
--                                      (target->bind_proc | curproxy->bind_proc) : 0;
-                               /* Emit a warning if this proxy also has some servers */
-                               if (curproxy->srv) {
-@@ -6199,11 +6252,6 @@ int check_config_validity()
-                               } else {
-                                       free((void *)exp->replace);
-                                       exp->replace = (const char *)target;
--                                      /* we force the backend to be present on at least all of
--                                       * the frontend's processes.
--                                       */
--                                      target->bind_proc = curproxy->bind_proc ?
--                                              (target->bind_proc | curproxy->bind_proc) : 0;
-                               }
-                       }
-               }
-@@ -6252,15 +6300,10 @@ int check_config_validity()
-                       } else {
-                               free((void *)rule->be.name);
-                               rule->be.backend = target;
--                              /* we force the backend to be present on at least all of
--                               * the frontend's processes.
--                               */
--                              target->bind_proc = curproxy->bind_proc ?
--                                      (target->bind_proc | curproxy->bind_proc) : 0;
-                       }
-               }
--              /* find the target proxy for 'use_backend' rules */
-+              /* find the target server for 'use_server' rules */
-               list_for_each_entry(srule, &curproxy->server_rules, list) {
-                       struct server *target = findserver(curproxy, srule->srv.name);
-@@ -7131,6 +7174,12 @@ out_uri_auth_compat:
-               }
-       }
-+      /* At this point, target names have already been resolved */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->cap & PR_CAP_FE)
-+                      propagate_processes(curproxy, NULL);
-+      }
-+
-       /* automatically compute fullconn if not set. We must not do it in the
-        * loop above because cross-references are not yet fully resolved.
-        */
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0009-MEDIUM-config-make-the-frontends-automatically-bind-.patch b/net/haproxy/patches/0009-MEDIUM-config-make-the-frontends-automatically-bind-.patch
deleted file mode 100644 (file)
index 1d83add..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-From e56c4f1f76c6731a5a0f4b128540071cffeb1951 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 13:21:03 +0200
-Subject: [PATCH 09/13] MEDIUM: config: make the frontends automatically bind
- to the listeners' processes
-
-When a frontend does not have any bind-process directive, make it
-automatically bind to the union of all of its listeners' processes
-instead of binding to all processes. That will make it possible to
-have the expected behaviour without having to explicitly specify a
-bind-process directive.
-
-Note that if the listeners are not bound to a specific process, the
-default is still to bind to all processes.
-
-This change could be backported to 1.5 as it simplifies process
-management, and was planned to be done during the 1.5 development phase.
-(cherry picked from commit b369a045d545b41ef2b250bf747caf83c97e0ca8)
----
- doc/configuration.txt |  4 ++++
- src/cfgparse.c        | 36 ++++++++++++++++++++++++++++++++++++
- 2 files changed, 40 insertions(+)
-
-diff --git a/doc/configuration.txt b/doc/configuration.txt
-index 3c75c92..1e32057 100644
---- a/doc/configuration.txt
-+++ b/doc/configuration.txt
-@@ -1905,6 +1905,10 @@ bind-process [ all | odd | even | <number 1-64>[-<number 1-64>] ] ...
-   Each "bind" line may further be limited to a subset of the proxy's processes,
-   please consult the "process" bind keyword in section 5.1.
-+  When a frontend has no explicit "bind-process" line, it tries to bind to all
-+  the processes referenced by its "bind" lines. That means that frontends can
-+  easily adapt to their listeners' processes.
-+
-   If some backends are referenced by frontends bound to other processes, the
-   backend automatically inherits the frontend's processes.
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index b9853ef..d53f69e 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -7175,11 +7175,47 @@ out_uri_auth_compat:
-       }
-       /* At this point, target names have already been resolved */
-+
-+      /* Make each frontend inherit bind-process from its listeners when not specified. */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->bind_proc)
-+                      continue;
-+
-+              list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
-+                      unsigned long mask;
-+
-+                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
-+                      curproxy->bind_proc |= mask;
-+              }
-+
-+              if (!curproxy->bind_proc)
-+                      curproxy->bind_proc = ~0UL;
-+      }
-+
-+      if (global.stats_fe) {
-+              list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
-+                      unsigned long mask;
-+
-+                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
-+                      global.stats_fe->bind_proc |= mask;
-+              }
-+              if (!global.stats_fe->bind_proc)
-+                      global.stats_fe->bind_proc = ~0UL;
-+      }
-+
-+      /* propagate bindings from frontends to backends */
-       for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-               if (curproxy->cap & PR_CAP_FE)
-                       propagate_processes(curproxy, NULL);
-       }
-+      /* Bind each unbound backend to all processes when not specified. */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->bind_proc)
-+                      continue;
-+              curproxy->bind_proc = ~0UL;
-+      }
-+
-       /* automatically compute fullconn if not set. We must not do it in the
-        * loop above because cross-references are not yet fully resolved.
-        */
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch b/net/haproxy/patches/0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch
deleted file mode 100644 (file)
index 4701df6..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-From 91b00c2194b728ccd61133cca83f03de3650b674 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 13:41:21 +0200
-Subject: [PATCH 10/13] MEDIUM: config: compute the exact bind-process before
- listener's maxaccept
-
-This is a continuation of previous patch, the listener's maxaccept is divided
-by the number of processes, so it's best if we can swap the two blocks so that
-the number of processes is already known when computing the maxaccept value.
-(cherry picked from commit 419ead8eca9237f9cc2ec32630d96fde333282ee)
----
- src/cfgparse.c | 156 ++++++++++++++++++++++++++++++---------------------------
- 1 file changed, 81 insertions(+), 75 deletions(-)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index d53f69e..f3907bf 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -6042,12 +6042,11 @@ int check_config_validity()
-               proxy = next;
-       }
--      while (curproxy != NULL) {
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-               struct switching_rule *rule;
-               struct server_rule *srule;
-               struct sticking_rule *mrule;
-               struct tcp_rule *trule;
--              struct listener *listener;
-               unsigned int next_id;
-               int nbproc;
-@@ -6115,14 +6114,6 @@ int check_config_validity()
-                       }
-               }
--              /* here, if bind_proc is null, it means no limit, otherwise it's explicit.
--               * We now check how many processes the proxy will effectively run on.
--               */
--
--              nbproc = global.nbproc;
--              if (curproxy->bind_proc)
--                      nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
--
-               if (global.nbproc > 1 && curproxy->table.peers.name) {
-                       Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n",
-                             curproxy->id);
-@@ -7005,6 +6996,86 @@ out_uri_auth_compat:
-                       if (curproxy->options2 & PR_O2_RDPC_PRST)
-                               curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
-               }
-+      }
-+
-+      /***********************************************************/
-+      /* At this point, target names have already been resolved. */
-+      /***********************************************************/
-+
-+      /* Check multi-process mode compatibility */
-+
-+      if (global.nbproc > 1 && global.stats_fe) {
-+              list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
-+                      unsigned long mask;
-+
-+                      mask = nbits(global.nbproc);
-+                      if (global.stats_fe->bind_proc)
-+                              mask &= global.stats_fe->bind_proc;
-+
-+                      if (bind_conf->bind_proc)
-+                              mask &= bind_conf->bind_proc;
-+
-+                      /* stop here if more than one process is used */
-+                      if (popcount(mask) > 1)
-+                              break;
-+              }
-+              if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
-+                      Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
-+              }
-+      }
-+
-+      /* Make each frontend inherit bind-process from its listeners when not specified. */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->bind_proc)
-+                      continue;
-+
-+              list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
-+                      unsigned long mask;
-+
-+                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
-+                      curproxy->bind_proc |= mask;
-+              }
-+
-+              if (!curproxy->bind_proc)
-+                      curproxy->bind_proc = ~0UL;
-+      }
-+
-+      if (global.stats_fe) {
-+              list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
-+                      unsigned long mask;
-+
-+                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
-+                      global.stats_fe->bind_proc |= mask;
-+              }
-+              if (!global.stats_fe->bind_proc)
-+                      global.stats_fe->bind_proc = ~0UL;
-+      }
-+
-+      /* propagate bindings from frontends to backends */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->cap & PR_CAP_FE)
-+                      propagate_processes(curproxy, NULL);
-+      }
-+
-+      /* Bind each unbound backend to all processes when not specified. */
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              if (curproxy->bind_proc)
-+                      continue;
-+              curproxy->bind_proc = ~0UL;
-+      }
-+
-+      /*******************************************************/
-+      /* At this step, all proxies have a non-null bind_proc */
-+      /*******************************************************/
-+
-+      /* perform the final checks before creating tasks */
-+
-+      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+              struct listener *listener;
-+              unsigned int next_id;
-+              int nbproc;
-+
-+              nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
- #ifdef USE_OPENSSL
-               /* Configure SSL for each bind line.
-@@ -7149,71 +7220,6 @@ out_uri_auth_compat:
-                             curproxy->id);
-                       cfgerr++;
-               }
--
--              curproxy = curproxy->next;
--      }
--
--      /* Check multi-process mode compatibility */
--      if (global.nbproc > 1 && global.stats_fe) {
--              list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
--                      unsigned long mask;
--
--                      mask = nbits(global.nbproc);
--                      if (global.stats_fe->bind_proc)
--                              mask &= global.stats_fe->bind_proc;
--
--                      if (bind_conf->bind_proc)
--                              mask &= bind_conf->bind_proc;
--
--                      /* stop here if more than one process is used */
--                      if (popcount(mask) > 1)
--                              break;
--              }
--              if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
--                      Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
--              }
--      }
--
--      /* At this point, target names have already been resolved */
--
--      /* Make each frontend inherit bind-process from its listeners when not specified. */
--      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
--              if (curproxy->bind_proc)
--                      continue;
--
--              list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
--                      unsigned long mask;
--
--                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
--                      curproxy->bind_proc |= mask;
--              }
--
--              if (!curproxy->bind_proc)
--                      curproxy->bind_proc = ~0UL;
--      }
--
--      if (global.stats_fe) {
--              list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
--                      unsigned long mask;
--
--                      mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
--                      global.stats_fe->bind_proc |= mask;
--              }
--              if (!global.stats_fe->bind_proc)
--                      global.stats_fe->bind_proc = ~0UL;
--      }
--
--      /* propagate bindings from frontends to backends */
--      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
--              if (curproxy->cap & PR_CAP_FE)
--                      propagate_processes(curproxy, NULL);
--      }
--
--      /* Bind each unbound backend to all processes when not specified. */
--      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
--              if (curproxy->bind_proc)
--                      continue;
--              curproxy->bind_proc = ~0UL;
-       }
-       /* automatically compute fullconn if not set. We must not do it in the
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0011-MEDIUM-config-only-warn-if-stats-are-attached-to-mul.patch b/net/haproxy/patches/0011-MEDIUM-config-only-warn-if-stats-are-attached-to-mul.patch
deleted file mode 100644 (file)
index 1d5527a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From 036a83e9c300a42386cd378022420e52a43b314f Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 15:11:04 +0200
-Subject: [PATCH 11/13] MEDIUM: config: only warn if stats are attached to
- multi-process bind directives
-
-Some users want to have a stats frontend with one line per process, but while
-100% valid and safe, the config parser emits a warning. Relax this check to
-ensure that the warning is only emitted if at least one of the listeners is
-bound to multiple processes, or if the directive is placed in a backend called
-from multiple processes (since in this case we don't know if it's safe).
-(cherry picked from commit eb791e03b5c5abfddb24a439fa6434788db026b7)
----
- src/cfgparse.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index f3907bf..5668393 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -7189,8 +7189,19 @@ out_uri_auth_compat:
-               if (nbproc > 1) {
-                       if (curproxy->uri_auth) {
--                              Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n",
--                                      curproxy->id);
-+                              int count, maxproc = 0;
-+
-+                              list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
-+                                      count = popcount(bind_conf->bind_proc);
-+                                      if (count > maxproc)
-+                                              maxproc = count;
-+                              }
-+                              /* backends have 0, frontends have 1 or more */
-+                              if (maxproc != 1)
-+                                      Warning("Proxy '%s': in multi-process mode, stats will be"
-+                                              " limited to process assigned to the current request.\n",
-+                                              curproxy->id);
-+
-                               if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
-                                       Warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
-                                               curproxy->id);
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch b/net/haproxy/patches/0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch
deleted file mode 100644 (file)
index ffd6cb4..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-From 8b3c808c37dd5672f87e7b61085295e1316a6694 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 15:39:51 +0200
-Subject: [PATCH 12/13] MEDIUM: config: report it when tcp-request rules are
- misplaced
-
-A config where a tcp-request rule appears after an http-request rule
-might seem valid but it is not. So let's report a warning about this
-since this case is hard to detect by the naked eye.
-(cherry picked from commit 3986b9c14037f446f5f5bec6207a39e1bd753fae)
----
- include/common/cfgparse.h |  2 ++
- src/cfgparse.c            | 38 ++++++++++++++++++++++++++++++++++++++
- src/proto_tcp.c           |  4 ++++
- 3 files changed, 44 insertions(+)
-
-diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h
-index 80310ae..86a0035 100644
---- a/include/common/cfgparse.h
-+++ b/include/common/cfgparse.h
-@@ -73,6 +73,8 @@ int check_config_validity();
- int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err);
- int cfg_register_section(char *section_name,
-                          int (*section_parser)(const char *, int, char **, int));
-+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg);
-+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg);
- /*
-  * Sends a warning if proxy <proxy> does not have at least one of the
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index 5668393..9ff44e9 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -317,6 +317,19 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
-       return 0;
- }
-+/* Report a warning if a rule is placed after a 'tcp-request content' rule.
-+ * Return 1 if the warning has been emitted, otherwise 0.
-+ */
-+int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
-+{
-+      if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
-+              Warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
-+                      file, line, arg);
-+              return 1;
-+      }
-+      return 0;
-+}
-+
- /* Report a warning if a rule is placed after a 'block' rule.
-  * Return 1 if the warning has been emitted, otherwise 0.
-  */
-@@ -408,6 +421,31 @@ int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line
-       return 0;
- }
-+/* report a warning if a "tcp request connection" rule is dangerously placed */
-+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
-+{
-+      return  warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
-+              warnif_rule_after_block(proxy, file, line, arg) ||
-+              warnif_rule_after_http_req(proxy, file, line, arg) ||
-+              warnif_rule_after_reqxxx(proxy, file, line, arg) ||
-+              warnif_rule_after_reqadd(proxy, file, line, arg) ||
-+              warnif_rule_after_redirect(proxy, file, line, arg) ||
-+              warnif_rule_after_use_backend(proxy, file, line, arg) ||
-+              warnif_rule_after_use_server(proxy, file, line, arg);
-+}
-+
-+/* report a warning if a "tcp request content" rule is dangerously placed */
-+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
-+{
-+      return  warnif_rule_after_block(proxy, file, line, arg) ||
-+              warnif_rule_after_http_req(proxy, file, line, arg) ||
-+              warnif_rule_after_reqxxx(proxy, file, line, arg) ||
-+              warnif_rule_after_reqadd(proxy, file, line, arg) ||
-+              warnif_rule_after_redirect(proxy, file, line, arg) ||
-+              warnif_rule_after_use_backend(proxy, file, line, arg) ||
-+              warnif_rule_after_use_server(proxy, file, line, arg);
-+}
-+
- /* report a warning if a block rule is dangerously placed */
- int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
- {
-diff --git a/src/proto_tcp.c b/src/proto_tcp.c
-index 72dc92b..940c3f1 100644
---- a/src/proto_tcp.c
-+++ b/src/proto_tcp.c
-@@ -1711,6 +1711,8 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
-                       warn++;
-               }
-+              /* the following function directly emits the warning */
-+              warnif_misplaced_tcp_cont(curpx, file, line, args[0]);
-               LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
-       }
-       else if (strcmp(args[1], "connection") == 0) {
-@@ -1754,6 +1756,8 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
-                       warn++;
-               }
-+              /* the following function directly emits the warning */
-+              warnif_misplaced_tcp_conn(curpx, file, line, args[0]);
-               LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list);
-       }
-       else {
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0013-MINOR-config-detect-the-case-where-a-tcp-request-con.patch b/net/haproxy/patches/0013-MINOR-config-detect-the-case-where-a-tcp-request-con.patch
deleted file mode 100644 (file)
index 4d70d2b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 7fc7ebd5785629074297ee324b22e0aee9ad00f9 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 16 Sep 2014 16:21:19 +0200
-Subject: [PATCH 13/13] MINOR: config: detect the case where a tcp-request
- content rule has no inspect-delay
-
-If a frontend has any tcp-request content rule relying on request contents
-without any inspect delay, we now emit a warning as this will randomly match.
-
-This can be backported to 1.5 as it reduces the support effort.
-(cherry picked from commit e42bd96d0acc38ea7c546c8de8115ffd1dd6c3f3)
----
- src/cfgparse.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index 9ff44e9..f723a3a 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -6998,6 +6998,29 @@ out_uri_auth_compat:
-                       newsrv = newsrv->next;
-               }
-+              /* check if we have a frontend with "tcp-request content" looking at L7
-+               * with no inspect-delay
-+               */
-+              if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
-+                      list_for_each_entry(trule, &curproxy->tcp_req.inspect_rules, list) {
-+                              if (trule->action == TCP_ACT_CAPTURE &&
-+                                  !(trule->act_prm.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
-+                                      break;
-+                              if  ((trule->action >= TCP_ACT_TRK_SC0 && trule->action <= TCP_ACT_TRK_SCMAX) &&
-+                                   !(trule->act_prm.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
-+                                      break;
-+                      }
-+
-+                      if (&trule->list != &curproxy->tcp_req.inspect_rules) {
-+                              Warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
-+                                      " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
-+                                      " This means that these rules will randomly find their contents. This can be fixed by"
-+                                      " setting the tcp-request inspect-delay.\n",
-+                                      proxy_type_str(curproxy), curproxy->id);
-+                              err_code |= ERR_WARN;
-+                      }
-+              }
-+
-               if (curproxy->cap & PR_CAP_FE) {
-                       if (!curproxy->accept)
-                               curproxy->accept = frontend_accept;
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0014-MEDIUM-systemd-wrapper-support-multiple-executable-v.patch b/net/haproxy/patches/0014-MEDIUM-systemd-wrapper-support-multiple-executable-v.patch
deleted file mode 100644 (file)
index cc152de..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-From afbfc27c0f2cac29e18f87b36335ea821c633b9d Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Fri, 19 Sep 2014 15:42:30 +0200
-Subject: [PATCH 14/14] MEDIUM: systemd-wrapper: support multiple executable
- versions and names
-
-Having to use a hard-coded "haproxy" executable name next to the systemd
-wrapper is not always convenient, as it's sometimes desirable to run with
-multiple versions in parallel.
-
-Thus this patch performs a minor change to the wrapper : if the name ends
-with "-systemd-wrapper", then it trims that part off and what remains
-becomes the target haproxy executable. That makes it easy to have for
-example :
-
-     haproxy-1.5.4-systemd-wrapper      haproxy-1.5.4
-     haproxy-1.5.3-systemd-wrapper      haproxy-1.5.3
-
-and so on, in a same directory.
-
-This patch also fixes a rare bug caused by readlink() not adding the
-trailing zero and leaving possible existing contents, including possibly
-a randomly placed "/" which would make it unable to locate the correct
-binary. This case is not totally unlikely as I got a \177 a few times
-at the end of the executable names, so I could have got a '/' as well.
-
-Back-porting to 1.5 is desirable.
-(cherry picked from commit ceaf2aec1ec1612da461c61798e944693144bee9)
----
- src/haproxy-systemd-wrapper.c | 27 ++++++++++++++++++++++-----
- 1 file changed, 22 insertions(+), 5 deletions(-)
-
-diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
-index cc8baa8..446f28f 100644
---- a/src/haproxy-systemd-wrapper.c
-+++ b/src/haproxy-systemd-wrapper.c
-@@ -28,20 +28,36 @@ static char *pid_file = "/run/haproxy.pid";
- static int wrapper_argc;
- static char **wrapper_argv;
-+/* returns the path to the haproxy binary into <buffer>, whose size indicated
-+ * in <buffer_size> must be at least 1 byte long.
-+ */
- static void locate_haproxy(char *buffer, size_t buffer_size)
- {
-       char *end = NULL;
-+      int len;
-+
-+      len = readlink("/proc/self/exe", buffer, buffer_size - 1);
-+      if (len == -1)
-+              goto fail;
--      if (readlink("/proc/self/exe", buffer, buffer_size) > 0)
--              end = strrchr(buffer, '/');
-+      buffer[len] = 0;
-+      end = strrchr(buffer, '/');
-+      if (end == NULL)
-+              goto fail;
--      if (end == NULL) {
--              strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
-+      if (strcmp(end + strlen(end) - 16, "-systemd-wrapper") == 0) {
-+              end[strlen(end) - 16] = '\0';
-               return;
-       }
-+
-       end[1] = '\0';
-       strncpy(end + 1, "haproxy", buffer + buffer_size - (end + 1));
-       buffer[buffer_size - 1] = '\0';
-+      return;
-+ fail:
-+      strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
-+      buffer[buffer_size - 1] = '\0';
-+      return;
- }
- static void spawn_haproxy(char **pid_strv, int nb_pid)
-@@ -54,7 +70,8 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
-       main_argc = wrapper_argc - 1;
-       main_argv = wrapper_argv + 1;
--      pid = fork();
-+      //pid = fork();
-+      pid=0;
-       if (!pid) {
-               /* 3 for "haproxy -Ds -sf" */
-               char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
--- 
-1.8.5.5
-
diff --git a/net/haproxy/patches/0015-BUG-MEDIUM-remove-debugging-code-from-systemd-wrappe.patch b/net/haproxy/patches/0015-BUG-MEDIUM-remove-debugging-code-from-systemd-wrappe.patch
deleted file mode 100644 (file)
index 3accdc4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From 575e299cc07f5f2b314d91dfac8671834cbdd2a7 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Wed, 24 Sep 2014 12:59:25 +0200
-Subject: [PATCH 15/20] BUG/MEDIUM: remove debugging code from systemd-wrapper
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Kristoffer Grönlund reported that after my recent update to the
-systemd-wrapper, I accidentely left the debugging code which
-consists in disabling the fork :-(
-
-The fix needs to be backported to 1.5 as well since I pushed it
-there as well.
-(cherry picked from commit a55bbc64d8272e4066a67b6d190ffebaff2b300a)
----
- src/haproxy-systemd-wrapper.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
-index 446f28f..8602881 100644
---- a/src/haproxy-systemd-wrapper.c
-+++ b/src/haproxy-systemd-wrapper.c
-@@ -70,8 +70,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
-       main_argc = wrapper_argc - 1;
-       main_argv = wrapper_argv + 1;
--      //pid = fork();
--      pid=0;
-+      pid = fork();
-       if (!pid) {
-               /* 3 for "haproxy -Ds -sf" */
-               char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
--- 
-2.0.4
-
diff --git a/net/haproxy/patches/0016-BUG-MEDIUM-http-adjust-close-mode-when-switching-to-.patch b/net/haproxy/patches/0016-BUG-MEDIUM-http-adjust-close-mode-when-switching-to-.patch
deleted file mode 100644 (file)
index 6f1b2c7..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From 2e47a3ab11188239abadb6bba7bd901d764aa4fb Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Tue, 30 Sep 2014 18:44:22 +0200
-Subject: [PATCH 16/20] BUG/MEDIUM: http: adjust close mode when switching to
- backend
-
-Commit 179085c ("MEDIUM: http: move Connection header processing earlier")
-introduced a regression : the backend's HTTP mode is not considered anymore
-when setting the session's HTTP mode, because wait_for_request() is only
-called once, when the frontend receives the request (or when the frontend
-is in TCP mode, when the backend receives the request).
-
-The net effect is that in some situations when the frontend and the backend
-do not work in the same mode (eg: keep-alive vs close), the backend's mode
-is ignored.
-
-This patch moves all that processing to a dedicated function, which is
-called from the original place, as well as from session_set_backend()
-when switching from an HTTP frontend to an HTTP backend in different
-modes.
-
-This fix must be backported to 1.5.
-(cherry picked from commit 4e21ff9244aefa56bcf0793a9e07edba2c3c1960)
----
- include/proto/proto_http.h |   1 +
- src/proto_http.c           | 107 +++++++++++++++++++++++----------------------
- src/proxy.c                |   8 ++++
- 3 files changed, 64 insertions(+), 52 deletions(-)
-
-diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
-index e898ca8..8014310 100644
---- a/include/proto/proto_http.h
-+++ b/include/proto/proto_http.h
-@@ -112,6 +112,7 @@ unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hle
- void http_init_txn(struct session *s);
- void http_end_txn(struct session *s);
- void http_reset_txn(struct session *s);
-+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg);
- struct http_req_rule *parse_http_req_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
- struct http_res_rule *parse_http_res_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
-diff --git a/src/proto_http.c b/src/proto_http.c
-index 7e35c8b..20e7088 100644
---- a/src/proto_http.c
-+++ b/src/proto_http.c
-@@ -2393,6 +2393,59 @@ fail:
-       return 0;
- }
-+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg)
-+{
-+      int tmp = TX_CON_WANT_KAL;
-+
-+      if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) {
-+              if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN ||
-+                  (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
-+                      tmp = TX_CON_WANT_TUN;
-+
-+              if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
-+                  (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
-+                      tmp = TX_CON_WANT_TUN;
-+      }
-+
-+      if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL ||
-+          (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) {
-+              /* option httpclose + server_close => forceclose */
-+              if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
-+                  (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
-+                      tmp = TX_CON_WANT_CLO;
-+              else
-+                      tmp = TX_CON_WANT_SCL;
-+      }
-+
-+      if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL ||
-+          (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
-+              tmp = TX_CON_WANT_CLO;
-+
-+      if ((txn->flags & TX_CON_WANT_MSK) < tmp)
-+              txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
-+
-+      if (!(txn->flags & TX_HDR_CONN_PRS) &&
-+          (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) {
-+              /* parse the Connection header and possibly clean it */
-+              int to_del = 0;
-+              if ((msg->flags & HTTP_MSGF_VER_11) ||
-+                  ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL &&
-+                   !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)))
-+                      to_del |= 2; /* remove "keep-alive" */
-+              if (!(msg->flags & HTTP_MSGF_VER_11))
-+                      to_del |= 1; /* remove "close" */
-+              http_parse_connection_header(txn, msg, to_del);
-+      }
-+
-+      /* check if client or config asks for explicit close in KAL/SCL */
-+      if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
-+           (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) &&
-+          ((txn->flags & TX_HDR_CONN_CLO) ||                         /* "connection: close" */
-+           (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */
-+           !(msg->flags & HTTP_MSGF_XFER_LEN) ||                     /* no length known => close */
-+           s->fe->state == PR_STSTOPPED))                            /* frontend is stopping */
-+              txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
-+}
- /* This stream analyser waits for a complete HTTP request. It returns 1 if the
-  * processing can continue on next analysers, or zero if it either needs more
-@@ -2929,58 +2982,8 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
-        * time.
-        */
-       if (!(txn->flags & TX_HDR_CONN_PRS) ||
--          ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE))) {
--              int tmp = TX_CON_WANT_KAL;
--
--              if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) {
--                      if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN ||
--                          (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
--                              tmp = TX_CON_WANT_TUN;
--
--                      if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
--                          (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
--                              tmp = TX_CON_WANT_TUN;
--              }
--
--              if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL ||
--                  (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) {
--                      /* option httpclose + server_close => forceclose */
--                      if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
--                          (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
--                              tmp = TX_CON_WANT_CLO;
--                      else
--                              tmp = TX_CON_WANT_SCL;
--              }
--
--              if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL ||
--                  (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
--                      tmp = TX_CON_WANT_CLO;
--
--              if ((txn->flags & TX_CON_WANT_MSK) < tmp)
--                      txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
--
--              if (!(txn->flags & TX_HDR_CONN_PRS) &&
--                  (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) {
--                      /* parse the Connection header and possibly clean it */
--                      int to_del = 0;
--                      if ((msg->flags & HTTP_MSGF_VER_11) ||
--                          ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL &&
--                           !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)))
--                              to_del |= 2; /* remove "keep-alive" */
--                      if (!(msg->flags & HTTP_MSGF_VER_11))
--                              to_del |= 1; /* remove "close" */
--                      http_parse_connection_header(txn, msg, to_del);
--              }
--
--              /* check if client or config asks for explicit close in KAL/SCL */
--              if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
--                   (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) &&
--                  ((txn->flags & TX_HDR_CONN_CLO) ||                         /* "connection: close" */
--                   (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */
--                   !(msg->flags & HTTP_MSGF_XFER_LEN) ||                     /* no length known => close */
--                   s->fe->state == PR_STSTOPPED))                            /* frontend is stopping */
--                  txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
--      }
-+          ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE)))
-+              http_adjust_conn_mode(s, txn, msg);
-       /* end of job, return OK */
-       req->analysers &= ~an_bit;
-diff --git a/src/proxy.c b/src/proxy.c
-index 02103ee..405c4c4 100644
---- a/src/proxy.c
-+++ b/src/proxy.c
-@@ -955,6 +955,14 @@ int session_set_backend(struct session *s, struct proxy *be)
-               http_init_txn(s);
-       }
-+      /* If we chain to an HTTP backend running a different HTTP mode, we
-+       * have to re-adjust the desired keep-alive/close mode to accommodate
-+       * both the frontend's and the backend's modes.
-+       */
-+      if (s->fe->mode == PR_MODE_HTTP && be->mode == PR_MODE_HTTP &&
-+          ((s->fe->options & PR_O_HTTP_MODE) != (be->options & PR_O_HTTP_MODE)))
-+              http_adjust_conn_mode(s, &s->txn, &s->txn.req);
-+
-       /* If an LB algorithm needs to access some pre-parsed body contents,
-        * we must not start to forward anything until the connection is
-        * confirmed otherwise we'll lose the pointer to these data and
--- 
-2.0.4
-
diff --git a/net/haproxy/patches/0017-BUG-MINOR-config-don-t-propagate-process-binding-on-.patch b/net/haproxy/patches/0017-BUG-MINOR-config-don-t-propagate-process-binding-on-.patch
deleted file mode 100644 (file)
index 50c25c8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From b3228c83e320ad168f5b3e6884e771530a68a449 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Wed, 1 Oct 2014 20:50:17 +0200
-Subject: [PATCH 17/20] BUG/MINOR: config: don't propagate process binding on
- fatal errors.
-
-propagate_processes() must not be called with unresolved proxies, but
-nothing prevents it from being called in check_config_validity(). The
-resulting effect is that an unresolved proxy can cause a recursion
-loop if called in such a situation, ending with a segfault after the
-fatal error report. There's no side effect beyond this.
-
-This patch refrains from calling the function when any error was met.
-
-This bug also affects 1.5, it should be backported.
-(cherry picked from commit acbe8ab38a638a076f8cf9fe2635db0e729d6a1f)
----
- src/cfgparse.c | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index f723a3a..6e962c8 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -7112,10 +7112,14 @@ out_uri_auth_compat:
-                       global.stats_fe->bind_proc = ~0UL;
-       }
--      /* propagate bindings from frontends to backends */
--      for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
--              if (curproxy->cap & PR_CAP_FE)
--                      propagate_processes(curproxy, NULL);
-+      /* propagate bindings from frontends to backends. Don't do it if there
-+       * are any fatal errors as we must not call it with unresolved proxies.
-+       */
-+      if (!cfgerr) {
-+              for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
-+                      if (curproxy->cap & PR_CAP_FE)
-+                              propagate_processes(curproxy, NULL);
-+              }
-       }
-       /* Bind each unbound backend to all processes when not specified. */
--- 
-2.0.4
-
diff --git a/net/haproxy/patches/0018-BUG-MEDIUM-check-rule-less-tcp-check-must-detect-con.patch b/net/haproxy/patches/0018-BUG-MEDIUM-check-rule-less-tcp-check-must-detect-con.patch
deleted file mode 100644 (file)
index 3d4b18f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-From e61737a721c3b91c79484e51fc1789293b269f9f Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Thu, 2 Oct 2014 14:30:14 +0200
-Subject: [PATCH 18/20] BUG/MEDIUM: check: rule-less tcp-check must detect
- connect failures
-
-When "option tcp-check" is specified without any tcp-check rules, the
-documentation says that it's the same as the default check method. But
-the code path is a bit different, and we used to consider that since
-the end of rules was reached, the check is always successful regardless
-of the connection status.
-
-This patch reorganizes the error detection, and considers the special
-case where there's no tcp-check rule as a real L4 check. It also avoids
-dereferencing the rule list head as a rule by itself.
-
-While fixing this bug, another one related to the output messages'
-accuracy was noticed, it will be fixed in a separate commit and is
-much less important.
-
-This bug is also present in 1.5, so this fix must be backported.
-(cherry picked from commit ef953953e7f33c6a72c432fce8d47c2d84c69512)
----
- src/checks.c | 40 +++++++++++++++++++++++++---------------
- 1 file changed, 25 insertions(+), 15 deletions(-)
-
-diff --git a/src/checks.c b/src/checks.c
-index f3b2b54..9c1a866 100644
---- a/src/checks.c
-+++ b/src/checks.c
-@@ -1837,20 +1837,34 @@ static int tcpcheck_get_step_id(struct server *s)
- static void tcpcheck_main(struct connection *conn)
- {
-       char *contentptr;
--      struct list *head = NULL;
-       struct tcpcheck_rule *cur = NULL;
-       int done = 0, ret = 0;
--
-       struct check *check = conn->owner;
-       struct server *s = check->server;
-       struct task *t = check->task;
-+      struct list *head = &s->proxy->tcpcheck_rules;
--      /*
--       * don't do anything until the connection is established but if we're running
--       * first step which must be a connect
-+      /* here, we know that the check is complete or that it failed */
-+      if (check->result != CHK_RES_UNKNOWN)
-+              goto out_end_tcpcheck;
-+
-+      /* We have 4 possibilities here :
-+       *   1. we've not yet attempted step 1, and step 1 is a connect, so no
-+       *      connection attempt was made yet ;
-+       *   2. we've not yet attempted step 1, and step 1 is a not connect or
-+       *      does not exist (no rule), so a connection attempt was made
-+       *      before coming here.
-+       *   3. we're coming back after having started with step 1, so we may
-+       *      be waiting for a connection attempt to complete.
-+       *   4. the connection + handshake are complete
-+       *
-+       * #2 and #3 are quite similar, we want both the connection and the
-+       * handshake to complete before going any further. Thus we must always
-+       * wait for a connection to complete unless we're before and existing
-+       * step 1.
-        */
--      if (check->current_step && (!(conn->flags & CO_FL_CONNECTED))) {
--              /* update expire time, should be done by process_chk */
-+      if ((!(conn->flags & CO_FL_CONNECTED) || (conn->flags & CO_FL_HANDSHAKE)) &&
-+          (check->current_step || LIST_ISEMPTY(head))) {
-               /* we allow up to min(inter, timeout.connect) for a connection
-                * to establish but only when timeout.check is set
-                * as it may be to short for a full check otherwise
-@@ -1867,12 +1881,11 @@ static void tcpcheck_main(struct connection *conn)
-               return;
-       }
--      /* here, we know that the connection is established */
--      if (check->result != CHK_RES_UNKNOWN)
-+      /* special case: option tcp-check with no rule, a connect is enough */
-+      if (LIST_ISEMPTY(head)) {
-+              set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
-               goto out_end_tcpcheck;
--
--      /* head is be the first element of the double chained list */
--      head = &s->proxy->tcpcheck_rules;
-+      }
-       /* no step means first step
-        * initialisation */
-@@ -1891,9 +1904,6 @@ static void tcpcheck_main(struct connection *conn)
-               cur = check->current_step;
-       }
--      if (conn->flags & CO_FL_HANDSHAKE)
--              return;
--
-       /* It's only the rules which will enable send/recv */
-       __conn_data_stop_both(conn);
--- 
-2.0.4
-
diff --git a/net/haproxy/patches/0019-BUG-MINOR-tcp-check-report-the-correct-failed-step-i.patch b/net/haproxy/patches/0019-BUG-MINOR-tcp-check-report-the-correct-failed-step-i.patch
deleted file mode 100644 (file)
index b232671..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-From 90055f28a7a0c86cfb37ccb23a548a1da7229551 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Thu, 2 Oct 2014 14:51:02 +0200
-Subject: [PATCH 19/20] BUG/MINOR: tcp-check: report the correct failed step in
- the status
-
-The step number was reported by checking only last_started_step, which
-was not set in case of error during the initial connection phase, and
-caused "step 1" to be returned with an invalid check type (typically
-SEND). So now we first verify that a test was started before returning
-this.
-
-In addition to this, the indication of the test type was taken from
-current_step instead of last_started_step, so the error description
-was matching the next action instead of the one reported in the step
-ID. Thus we could get the confusing "step 1 (send)" report below :
-
-      tcp-check connect
-      tcp-check send foo
-
-In order to ease debugging, when the port number is known for a connect,
-it is indicated in the error report.
-
-Note that this only affects asynchronous error messages, synchronous ones
-are correct.
-
-This fix must be backported to 1.5.
-(cherry picked from commit 213c6785614d0228d7e96e982e5189e1d0777059)
----
- src/checks.c | 43 ++++++++++++++++++++++++++++---------------
- 1 file changed, 28 insertions(+), 15 deletions(-)
-
-diff --git a/src/checks.c b/src/checks.c
-index 9c1a866..5318f35 100644
---- a/src/checks.c
-+++ b/src/checks.c
-@@ -580,6 +580,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
-       struct check *check = conn->owner;
-       const char *err_msg;
-       struct chunk *chk;
-+      int step;
-       if (check->result != CHK_RES_UNKNOWN)
-               return;
-@@ -599,19 +600,27 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
-       chk = get_trash_chunk();
-       if (check->type == PR_O2_TCPCHK_CHK) {
--              chunk_printf(chk, " at step %d of tcp-check", tcpcheck_get_step_id(check->server));
--              /* we were looking for a string */
--              if (check->current_step && check->current_step->action == TCPCHK_ACT_CONNECT) {
--                      chunk_appendf(chk, " (connect)");
--              }
--              else if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT) {
--                      if (check->current_step->string)
--                              chunk_appendf(chk, " (string '%s')", check->current_step->string);
--                      else if (check->current_step->expect_regex)
--                              chunk_appendf(chk, " (expect regex)");
--              }
--              else if (check->current_step && check->current_step->action == TCPCHK_ACT_SEND) {
--                      chunk_appendf(chk, " (send)");
-+              step = tcpcheck_get_step_id(check->server);
-+              if (!step)
-+                      chunk_printf(chk, " at initial connection step of tcp-check");
-+              else {
-+                      chunk_printf(chk, " at step %d of tcp-check", step);
-+                      /* we were looking for a string */
-+                      if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_CONNECT) {
-+                              if (check->last_started_step->port)
-+                                      chunk_appendf(chk, " (connect port %d)" ,check->last_started_step->port);
-+                              else
-+                                      chunk_appendf(chk, " (connect)");
-+                      }
-+                      else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) {
-+                              if (check->last_started_step->string)
-+                                      chunk_appendf(chk, " (string '%s')", check->last_started_step->string);
-+                              else if (check->last_started_step->expect_regex)
-+                                      chunk_appendf(chk, " (expect regex)");
-+                      }
-+                      else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_SEND) {
-+                              chunk_appendf(chk, " (send)");
-+                      }
-               }
-       }
-@@ -1818,6 +1827,10 @@ static int tcpcheck_get_step_id(struct server *s)
-       struct tcpcheck_rule *cur = NULL, *next = NULL;
-       int i = 0;
-+      /* not even started anything yet => step 0 = initial connect */
-+      if (!s->check.current_step)
-+              return 0;
-+
-       cur = s->check.last_started_step;
-       /* no step => first step */
-@@ -1887,9 +1900,9 @@ static void tcpcheck_main(struct connection *conn)
-               goto out_end_tcpcheck;
-       }
--      /* no step means first step
--       * initialisation */
-+      /* no step means first step initialisation */
-       if (check->current_step == NULL) {
-+              check->last_started_step = NULL;
-               check->bo->p = check->bo->data;
-               check->bo->o = 0;
-               check->bi->p = check->bi->data;
--- 
-2.0.4
-
diff --git a/net/haproxy/patches/0020-BUG-MINOR-config-don-t-propagate-process-binding-for.patch b/net/haproxy/patches/0020-BUG-MINOR-config-don-t-propagate-process-binding-for.patch
deleted file mode 100644 (file)
index fab81d9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From c8d57dec6173430bd5602bb76efff302c51e7803 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
-Date: Thu, 2 Oct 2014 19:56:25 +0200
-Subject: [PATCH 20/20] BUG/MINOR: config: don't propagate process binding for
- dynamic use_backend
-
-A segfault was reported with the introduction of the propagate_processes()
-function. It was caused when a use_backend rule was declared with a dynamic
-name, using a log-format string. The backend is not resolved during the
-configuration, which lead to the segfault.
-
-The patch prevents the process binding propagation for such dynamic rules, it
-should also be backported to 1.5.
-(cherry picked from commit 51639696e0a112ea3612e905a5722ad912b3869f)
----
- src/cfgparse.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/src/cfgparse.c b/src/cfgparse.c
-index 6e962c8..ec6d923 100644
---- a/src/cfgparse.c
-+++ b/src/cfgparse.c
-@@ -6015,6 +6015,8 @@ void propagate_processes(struct proxy *from, struct proxy *to)
-       /* use_backend */
-       list_for_each_entry(rule, &from->switching_rules, list) {
-+              if (rule->dynamic)
-+                      continue;
-               to = rule->be.backend;
-               propagate_processes(from, to);
-       }
--- 
-2.0.4
-
index 29e279a2d05ca0a86a922bdb1384c70dfb063d69..607e2705ec23d75c7f267af3be8113f9e02964b7 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_VERSION:=version-$(PKG_VERSION)
 
 PKG_MAINTAINER:=Bruno Randolf <br1@einfach.org>
 PKG_LICENSE:=GPL-2.0+
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 
 PKG_BUILD_PARALLEL:=1
 
index f7dd3a804636a8800ff9eeb6b126f5d9acfc3af9..5a1f58f961f70d1c6302a8488be186b6cc3530fc 100644 (file)
@@ -8,17 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ibrdtn-tools
-PKG_VERSION:=0.12.1
+PKG_VERSION:=1.0.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
-PKG_MD5SUM:=0ce0c6e754263919ad48661967c2f6fd
-PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_MD5SUM:=ec522079278bcdf4181e6a1d86f8d72f
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
 PKG_LICENSE:=Apache-2.0
 
 PKG_INSTALL:=1
-PKG_FIXUP:=autoreconf
 
 include $(INCLUDE_DIR)/package.mk
 
diff --git a/net/ibrdtn-tools/patches/100-add_configure_options.patch b/net/ibrdtn-tools/patches/100-add_configure_options.patch
deleted file mode 100644 (file)
index b918f3d..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -67,34 +67,57 @@ AC_TYPE_UINT8_T
- AC_FUNC_MALLOC
- AC_CHECK_FUNCS([memset])
--PKG_CHECK_MODULES(DAEMON, libdaemon >= 0.12, [
--      AC_SUBST(DAEMON_CFLAGS)
--      AC_SUBST(DAEMON_LIBS)
--      AC_DEFINE(HAVE_LIBDAEMON, [1], ["daemon library is available"])
--      AC_CHECK_LIB(daemon, daemon_reset_sigs, [
--              AC_DEFINE(HAVE_DAEMON_RESET_SIGS, [1], ["daemon library has daemon_reset_sigs() and daemon_unblock_sigs() functions"])
--      ])
--], [
--      AC_MSG_WARN([daemon library not found, daemonize features disabled])
--])
-+AC_ARG_WITH([libdaemon],
-+      AS_HELP_STRING([--without-libdaemon], [Build without daemonize support]),
-+      [
-+              AC_MSG_NOTICE([daemonize support disabled])
-+      ], [
-+              PKG_CHECK_MODULES(DAEMON, libdaemon >= 0.12, [
-+                      AC_SUBST(DAEMON_CFLAGS)
-+                      AC_SUBST(DAEMON_LIBS)
-+                      AC_DEFINE(HAVE_LIBDAEMON, [1], ["daemon library is available"])
-+                      AC_CHECK_LIB(daemon, daemon_reset_sigs, [
-+                              AC_DEFINE(HAVE_DAEMON_RESET_SIGS, [1], ["daemon library has daemon_reset_sigs() and daemon_unblock_sigs() functions"])
-+                      ])
-+              ], [
-+                      AC_MSG_WARN([daemon library not found, daemonize features disabled])
-+              ])
-+      ]
-+)
--PKG_CHECK_MODULES(ARCHIVE, libarchive >= 3.0, [
--      AC_SUBST(ARCHIVE_CFLAGS)
--      AC_SUBST(ARCHIVE_LIBS)
--      AC_DEFINE(HAVE_LIBARCHIVE, [1], ["libarchive is available"])
--              has_libarchive="yes"
--], [
--      AC_MSG_WARN([libarchive not found, dtninbox and dtnoutbox will not be compiled])
--])
-+AC_ARG_WITH([libarchive],
-+      AS_HELP_STRING([--without-libarchive], [Build without archive support]),
-+      [
-+              has_libarchive="no"
-+              AC_MSG_NOTICE([archive support disabled, dtninbox and dtnoutbox will not be compiled])
-+      ], [
-+              PKG_CHECK_MODULES(ARCHIVE, libarchive >= 3.0, [
-+                      AC_SUBST(ARCHIVE_CFLAGS)
-+                      AC_SUBST(ARCHIVE_LIBS)
-+                      AC_DEFINE(HAVE_LIBARCHIVE, [1], ["libarchive is available"])
-+                              has_libarchive="yes"
-+              ], [
-+                      AC_MSG_WARN([libarchive not found, dtninbox and dtnoutbox will not be compiled])
-+              ])
-+      ]
-+)
--PKG_CHECK_MODULES(OPENSSL, openssl, [
--      AC_SUBST(OPENSSL_CFLAGS)
--      AC_SUBST(OPENSSL_LIBS)
--      AC_DEFINE(HAVE_OPENSSL, [1], ["openssl available"])
--              has_openssl="yes"
--], [
--      AC_MSG_WARN([openssl not found, dtninbox and dtnoutbox will not be compiled])
--])
-+AC_ARG_WITH([openssl],
-+      AS_HELP_STRING([--without-openssl], [Build without openssl support]),
-+      [
-+              has_openssl="no"
-+              AC_MSG_NOTICE([openssl support disabled, dtninbox and dtnoutbox will not be compiled])
-+      ], [
-+              PKG_CHECK_MODULES(OPENSSL, openssl, [
-+                      AC_SUBST(OPENSSL_CFLAGS)
-+                      AC_SUBST(OPENSSL_LIBS)
-+                      AC_DEFINE(HAVE_OPENSSL, [1], ["openssl available"])
-+                              has_openssl="yes"
-+              ], [
-+                      AC_MSG_WARN([openssl not found, dtninbox and dtnoutbox will not be compiled])
-+              ])
-+      ]
-+)
- AC_ARG_WITH([tffs],
- AS_HELP_STRING([--with-tffs=PATH], [set the tffs path for fat-image support in dtnoutbox]), [
--- 
-1.9.1
-
index c6281a7b6661313c0414bfca72eb3c6602022145..7b72ac98177e722959f735ec073522a92d0384cf 100644 (file)
@@ -8,17 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ibrdtnd
-PKG_VERSION:=0.12.1
+PKG_VERSION:=1.0.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
-PKG_MD5SUM:=8dad5ebbcfaa4c16ba151c9c289066c3
-PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_MD5SUM:=7fd48b2eec5058fa15f6977afd4e8dab
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
 PKG_LICENSE:=Apache-2.0
 
 PKG_INSTALL:=1
-PKG_FIXUP:=autoreconf
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -26,7 +25,7 @@ define Package/ibrdtnd
   SECTION:=net
   CATEGORY:=Network
   DEPENDS:=+dtndht +ibrdtn +libsqlite3
-  TITLE:=DTN Deamon
+  TITLE:=DTN Daemon
 endef
 
 define Package/ibrdtnd/conffiles
@@ -40,6 +39,7 @@ endef
 CONFIGURE_ARGS += \
        --with-tls \
        --with-sqlite \
+       --with-dht \
        --without-wifip2p \
        --without-vmime \
        --disable-libdaemon
index 82f161cc509d7539b12a68528e47b5b022ff914e..c9a6128cd1eba50ecbc041cacb44a3702e102797 100644 (file)
@@ -116,6 +116,7 @@ add_param $CONFFILE "ibrdtn.dht.allow_neighbour_announcement" "dht_allow_neighbo
 # iterate through all network interfaces
 iter=0
 netinterfaces=
+netinternet=
 while [ 1 == 1 ]; do
        $UCI -q get "ibrdtn.@network[$iter]" > /dev/null
        if [ $? == 0 ]; then
@@ -123,6 +124,9 @@ while [ 1 == 1 ]; do
                add_param $CONFFILE "ibrdtn.@network[$iter].type" "net_lan${iter}_type"
                add_param $CONFFILE "ibrdtn.@network[$iter].interface" "net_lan${iter}_interface"
                add_param $CONFFILE "ibrdtn.@network[$iter].port" "net_lan${iter}_port"
+               if [ "$(uci -q get ibrdtn.@network[$iter].global)" == "yes" ]; then
+                       netinternet="${netinternet} $(uci -q get ibrdtn.@network[$iter].interface)"
+               fi
        else
                break
        fi
@@ -132,6 +136,7 @@ done
 
 # write list of network interfaces
 echo "net_interfaces =$netinterfaces" >> $CONFFILE
+echo "net_internet =${netinternet}" >> $CONFFILE
 
 # iterate through all static routes
 iter=0
index ab4504487c7256536981165ef02a94c07f065712..e0256818031d3ff5d86b852f13dd7ba98df6069c 100644 (file)
@@ -109,6 +109,7 @@ config 'network'
        option type                     tcp
        option interface        eth0
        option port                     4556
+       option global           yes
        
 #config 'network'
 #      option type                     tcp
diff --git a/net/ibrdtnd/patches/100-add_configure_options.patch b/net/ibrdtnd/patches/100-add_configure_options.patch
deleted file mode 100644 (file)
index 360bd69..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -333,30 +333,46 @@ AS_IF([test "x$enable_android" = "xyes"], [
-       dnl optional parameter: Wifi-P2P support
-       dnl -----------------------------------------------
--      PKG_CHECK_MODULES([WIFIP2P], wifip2p >= 0.1 , [
--                              with_wifi_p2p="yes"
--                              AC_SUBST(WIFIP2P_CFLAGS)
--                              AC_SUBST(WIFIP2P_LIBS)
--                              AC_DEFINE(WITH_WIFIP2P, [1], ["wifi-p2p support enabled"])
--                      ], [
--                              with_wifi_p2p="no"
--                              AC_MSG_WARN([wifi-p2p library not found. wifi-p2p support is disabled.])
--                      ])
-+      AC_ARG_WITH([wifip2p],
-+              AS_HELP_STRING([--without-wifip2p], [Build without wifip2p support]),
-+              [
-+                      with_wifi_p2p="no"
-+                      AC_MSG_NOTICE([WIFIP2P support disabled])
-+              ], [
-+                      PKG_CHECK_MODULES([WIFIP2P], wifip2p >= 0.1 , [
-+                                              with_wifi_p2p="yes"
-+                                              AC_SUBST(WIFIP2P_CFLAGS)
-+                                              AC_SUBST(WIFIP2P_LIBS)
-+                                              AC_DEFINE(WITH_WIFIP2P, [1], ["wifi-p2p support enabled"])
-+                                      ], [
-+                                              with_wifi_p2p="no"
-+                                              AC_MSG_WARN([wifi-p2p library not found. wifi-p2p support is disabled.])
-+                                      ])
-+              ]
-+      )
--    dnl -----------------------------------------------
--    dnl optional parameter: VMime support
--    dnl -----------------------------------------------
--
--    PKG_CHECK_MODULES([VMIME], vmime >= 0.9.1 , [
--                with_vmime="yes"
--                AC_SUBST(VMIME_CFLAGS)
--                AC_SUBST(VMIME_LIBS)
--                AC_DEFINE(HAVE_VMIME, [1], ["Email Convergence Layer is available"])
--                AC_CHECK_HEADERS([vmime/utility/smartPtrInt.hpp])
--            ], [
--                with_vmime="no"
--                AC_MSG_WARN([VMime library not found. Email Convergence Layer is disabled.])
--            ])
-+      dnl -----------------------------------------------
-+      dnl optional parameter: VMime support
-+      dnl -----------------------------------------------
-+
-+      AC_ARG_WITH([vmime],
-+              AS_HELP_STRING([--without-vmime], [Build without vmime support]),
-+              [
-+                      with_vmime="no"
-+                      AC_MSG_NOTICE([VMIME support disabled])
-+              ], [
-+                      PKG_CHECK_MODULES([VMIME], vmime >= 0.9.1 , [
-+                                              with_vmime="yes"
-+                                              AC_SUBST(VMIME_CFLAGS)
-+                                              AC_SUBST(VMIME_LIBS)
-+                                              AC_DEFINE(HAVE_VMIME, [1], ["Email Convergence Layer is available"])
-+                                              AC_CHECK_HEADERS([vmime/utility/smartPtrInt.hpp])
-+                                      ], [
-+                                              with_vmime="no"
-+                                              AC_MSG_WARN([VMime library not found. Email Convergence Layer is disabled.])
-+                                      ])
-+              ]
-+      )
-       dnl -----------------------------------------------
-       dnl check for regex capabilities
--- 
-1.9.1
-
diff --git a/net/ibrdtnd/patches/110-add_configure_options_docs.patch b/net/ibrdtnd/patches/110-add_configure_options_docs.patch
deleted file mode 100644 (file)
index 4efdbe2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -138,11 +138,17 @@ AS_IF([test "x$enable_android" = "xyes"], [
-       # Checks for library functions.
-       AC_CHECK_FUNCS([gethostname socket])
--      # Check for presence of pdfLaTeX
--      AC_CHECK_PROG(PDFLATEX, pdflatex, pdflatex)
--      if test -z "$PDFLATEX"; then
--      AC_MSG_WARN([Unable to create PDF version of the documentation.])
--      fi
-+      AC_ARG_ENABLE([docs],
-+              AS_HELP_STRING([--enable-docs], [Build documentation using PDFLaTeX]),
-+      [
-+              # Check for presence of pdfLaTeX
-+              AC_CHECK_PROG(PDFLATEX, pdflatex, pdflatex)
-+              if test -z "$PDFLATEX"; then
-+                      AC_MSG_WARN([Unable to create PDF version of the documentation.])
-+              fi
-+      ], [
-+              PDFLATEX="no"
-+      ])
-       AC_ARG_ENABLE([libdaemon],
-               AS_HELP_STRING([--disable-libdaemon], [Build without libdaemon support]),
--- 
index a1ba11761539602eff834f2732f77d1facdf1a85..ae9c83c00d75abea47ef2e1995e0df9aa3c2e663 100644 (file)
@@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=ipsec-tools
 PKG_VERSION:=0.8.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_MAINTAINER := "Noah Meyerhans <frodo@morgul.net>"
 PKG_LICENSE := BSD-3-Clause
 
@@ -77,8 +77,7 @@ endef
 
 define Package/ipsec-tools/install
        $(INSTALL_DIR) $(1)/etc
-       $(INSTALL_CONF) $(PKG_BUILD_DIR)/src/racoon/samples/racoon.conf $(1)/etc/
-       $(SED) 's|@sysconfdir_x@|/etc|g' $(1)/etc/racoon.conf
+       $(INSTALL_CONF) ./files/racoon.conf $(1)/etc/racoon.conf
        $(INSTALL_DIR) $(1)/etc/racoon
        $(INSTALL_CONF) $(PKG_BUILD_DIR)/src/racoon/samples/psk.txt $(1)/etc/racoon/
        $(INSTALL_DIR) $(1)/etc/init.d
diff --git a/net/ipsec-tools/files/racoon.conf b/net/ipsec-tools/files/racoon.conf
new file mode 100644 (file)
index 0000000..5c05bcd
--- /dev/null
@@ -0,0 +1,36 @@
+# Simple racoon.conf
+# 
+# Refer to http://wiki.openwrt.org/doc/howto/vpn.ipsec.basics.racoon for
+# details about configuring racoon in OpenWRT.
+#
+# Also read the Linux IPSEC Howto up at 
+# http://www.ipsec-howto.org/t1.html 
+#
+# Manual pages for ipsec-tools are not included with OpenWRT. Refer to
+# the following locations to view them online:
+# http://linux.die.net/man/8/racoon
+# http://linux.die.net/man/5/racoon.conf
+# http://linux.die.net/man/8/setkey
+#
+
+log notify;
+path pre_shared_key "/etc/racoon/psk.txt";
+path certificate "/etc/racoon/certs";
+
+#remote 172.31.1.1 {
+#        exchange_mode main,aggressive;
+#        proposal {
+#                encryption_algorithm 3des;
+#                hash_algorithm sha1;
+#                authentication_method pre_shared_key;
+#                dh_group modp1024;
+#        }
+#        generate_policy off;
+#}
+# 
+#sainfo address 192.168.203.10[any] any address 192.168.22.0/24[any] any {
+#        pfs_group modp768;
+#        encryption_algorithm 3des;
+#        authentication_algorithm hmac_md5;
+#        compression_algorithm deflate;
+#}
index d539b363ffce66cb818418cdb0c5a9fd9bdd6e2a..68053c91ee39187533a2806b26d09ebcf37bb2c2 100644 (file)
@@ -1,17 +1,17 @@
 #!/bin/sh /etc/rc.common
 # Copyright (C) 2009-2011 OpenWrt.org
 # Copyright (C) 2011 Artem Makhutov
+# Copyright (C) 2014 Noah Meyerhans <frodo@morgul.net>
 
-START=49
-
-SERVICE_USE_PID=1
+USE_PROCD=1
 
-start() {
-       mkdir -m 0700 -p /var/racoon
-       [ -f /etc/ipsec.conf ] && /usr/sbin/setkey -f /etc/ipsec.conf
-       service_start /usr/sbin/racoon -f /etc/racoon.conf
-}
+START=49
 
-stop() {
-       service_stop /usr/sbin/racoon
+start_service() {
+    mkdir -m 0700 -p /var/racoon
+    [ -f /etc/ipsec.conf ] && /usr/sbin/setkey -f /etc/ipsec.conf
+    procd_open_instance
+    procd_set_param command /usr/sbin/racoon -F -f /etc/racoon.conf
+    procd_set_param respawn
+    procd_close_instance
 }
index 2f920498da119f9efdc04cb8b71fd87db47d0ed6..3fbfef115f3d55089394ec0c80ec41755b0dae6e 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=irssi
-PKG_VERSION:=0.8.16
+PKG_VERSION:=0.8.17
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://irssi.org/files/
-PKG_MD5SUM:=4346119c4c000d0198cda17666ff1f06
+PKG_MD5SUM:=ecf64be47978d89a742b435a81cb47db
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/net/kismet/Makefile b/net/kismet/Makefile
new file mode 100644 (file)
index 0000000..de60949
--- /dev/null
@@ -0,0 +1,142 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=kismet
+PKG_VERSION:=2013-03-R1b
+PKG_RELEASE:=1
+
+PKG_LICENSE:=LGPLv2.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.kismetwireless.net/code
+PKG_MD5SUM:=6cdcd78baf2e15edbe8a9de3c5493f02
+
+PKG_BUILD_DEPENDS:=libpcap libncurses libpcre
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/kismet/Default
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Kismet
+  MAINTAINER:=Sebastian Wendel <packages@sourceindex.de>
+  DEPENDS:= $(CXX_DEPENDS) +libnl
+  URL:=http://www.kismetwireless.net/
+  SUBMENU:=wireless
+endef
+
+define Package/kismet/Default/description
+ An 802.11 layer2 wireless network detector, sniffer, and intrusion
+ detection system.
+endef
+
+define Package/kismet-client/conffiles
+/etc/kismet/kismet.conf
+endef
+
+define Package/kismet-drone/conffiles
+/etc/kismet/kismet_drone.conf
+endef
+
+define Package/kismet-server/conffiles
+/etc/kismet/kismet.conf
+endef
+
+define Package/kismet-client
+$(call Package/kismet/Default)
+  TITLE+= client
+  DEPENDS+= +libncurses
+endef
+
+define Package/kismet-client/description
+$(call Package/kismet/Default/description)
+ This package contains the kismet text interface client.
+endef
+
+define Package/kismet-drone
+$(call Package/kismet/Default)
+  DEPENDS+= +libpcap +libpcre +libcap +wireless-tools 
+  TITLE+= drone
+endef
+
+define Package/kismet-drone/description
+$(call Package/kismet/Default/description)
+ This package contains the kismet remote sniffing.and monitoring drone.
+endef
+
+define Package/kismet-server
+$(call Package/kismet/Default)
+  DEPENDS+= +libpcap +libpcre +libcap +wireless-tools
+  TITLE+= server
+endef
+
+define Package/kismet-server/description
+$(call Package/kismet/Default/description)
+ This package contains the kismet server.
+endef
+
+CONFIGURE_ARGS += \
+       --sysconfdir=/etc/kismet \
+
+CONFIGURE_VARS += \
+       CXXFLAGS="$$$$CXXFLAGS -fno-rtti"  \
+       LIBS="-lm" \
+       CLIENTCLIBS="-lm"
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               LD="$(TARGET_CXX)" \
+               all
+endef
+
+define Package/kismet/install
+       $(INSTALL_DIR) $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/kismet $(1)/usr/bin/kismet
+endef
+
+define Package/kismet-client/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_client $(1)/usr/bin/
+
+       $(INSTALL_DIR) $(1)/etc/kismet/
+       $(INSTALL_CONF) ./files/kismet.conf $(1)/etc/kismet/
+endef
+
+define Package/kismet-drone/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_drone $(1)/usr/bin/
+
+       $(INSTALL_DIR) $(1)/etc/kismet/
+       $(INSTALL_CONF) ./files/kismet_drone.conf $(1)/etc/kismet/
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/kismet_drone.config $(1)/etc/config/kismet_drone
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/kismet_drone.init $(1)/etc/init.d/kismet_drone
+endef
+
+define Package/kismet-server/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_server $(1)/usr/bin/
+
+       $(INSTALL_DIR) $(1)/etc/kismet/
+       $(INSTALL_CONF) ./files/kismet.conf $(1)/etc/kismet/
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/kismet_server.config $(1)/etc/config/kismet_server
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/kismet_server.init $(1)/etc/init.d/kismet_server
+endef
+
+$(eval $(call BuildPackage,kismet-client))
+$(eval $(call BuildPackage,kismet-drone))
+$(eval $(call BuildPackage,kismet-server))
diff --git a/net/kismet/files/kismet.conf b/net/kismet/files/kismet.conf
new file mode 100644 (file)
index 0000000..971f2e2
--- /dev/null
@@ -0,0 +1,304 @@
+# Kismet config file
+# Most of the "static" configs have been moved to here -- the command line
+# config was getting way too crowded and cryptic.  We want functionality,
+# not continually reading --help!
+
+# Version of Kismet config
+version=2009-newcore
+
+# Name of server (Purely for organizational purposes)
+# If commented out, defaults to host name of system
+# servername=Kismet Server
+
+# Prefix of where we log (as used in the logtemplate later)
+logprefix=/tmp
+
+# Do we process the contents of data frames?  If this is enabled, data
+# frames will be truncated to the headers only immediately after frame type
+# detection.  This will disable IP detection, etc, however it is likely
+# safer (and definitely more polite) if monitoring networks you do not own.
+# hidedata=true
+
+# Do we allow plugins to be used?  This will load plugins from the system
+# and user plugin directiories when set to true (See the README for the default
+# plugin locations).
+allowplugins=false
+
+# See the README for full information on the new source format
+# ncsource=interface:options
+# for example:
+# ncsource=wifi0:type=madwifi
+# ncsource=wlan0:name=intel,hop=false,channel=11
+ncsource=wlan0
+
+# Comma-separated list of sources to enable.  This is only needed if you defined
+# multiple sources and only want to enable some of them.  By default, all defined
+# sources are enabled.
+# For example, if sources with name=prismsource and name=ciscosource are defined,
+# and you only want to enable those two:
+# enablesources=prismsource,ciscosource
+
+# Control which channels we like to spend more time on.  By default, the list
+# of channels is pulled from the driver automatically.  By setting preferred channels,
+# if they are present in the channel list, they'll be set with a timing delay so that
+# more time is spent on them.  Since 1, 6, 11 are the common default channels, it makes
+# sense to spend more time monitoring them.
+# For finer control, see further down in the config for the channellist= directives.
+preferredchannels=1,6,11
+
+# How many channels per second do we hop?  (1-10)
+channelvelocity=3
+
+# By setting the dwell time for channel hopping we override the channelvelocity
+# setting above and dwell on each channel for the given number of seconds.
+#channeldwell=10
+
+# Channels are defined as:
+# channellist=name:ch1,ch2,ch3
+# or
+# channellist=name:range-start-end-width-offset,ch,range,ch,...
+#
+# Channels may be a numeric channel or a frequency
+#
+# Channels may specify an additional wait period.  For common default channels,
+# an additional wait period can be useful.  Wait periods delay for that number 
+# of times per second - so a configuration hopping 10 times per second with a
+# channel of 6:3 would delay 3/10ths of a second on channel 6.
+#
+# Channel lists may have up to 256 channels and ranges (combined).  For power 
+# users scanning more than 256 channels with a single card, ranges must be used.
+#
+# Ranges are meant for "power users" who wish to define a very large number of
+# channels.  A range may specify channels or frequencies, and will automatically
+# sort themselves to cover channels in a non-overlapping fashion.  An example
+# range for the normal 802.11b/g spectrum would be:
+#
+# range-1-11-3-1
+#
+# which indicates starting at 1, ending at 11, a channel width of 3 channels,
+# incrementing by one.  A frequency based definition would be:
+#
+# range-2412-2462-22-5
+#
+# since 11g channels are 22 mhz wide and 5 mhz apart.
+#
+# Ranges have the flaw that they cannot be shared between sources in a non-overlapping
+# way, so multiple sources using the same range may hop in lockstep with each other
+# and duplicate the coverage.
+#
+# channellist=demo:1:3,6:3,11:3,range-5000-6000-20-10
+
+# Default channel lists
+# These channel lists MUST BE PRESENT for Kismet to work properly.  While it is
+# possible to change these, it is not recommended.  These are used when the supported
+# channel list can not be found for the source; to force using these instead of
+# the detected supported channels, override with channellist= in the source defintion
+#
+# IN GENERAL, if you think you want to modify these, what you REALLY want to do is
+# copy them and use channellist= in the packet source.
+channellist=IEEE80211b:1:3,6:3,11:3,2,7,3,8,4,9,5,10
+channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165
+channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165
+
+# Client/server listen config
+listen=tcp://127.0.0.1:2501
+#listen=tcp://0.0.0.0:2501
+
+# People allowed to connect, comma seperated IP addresses or network/mask
+# blocks.  Netmasks can be expressed as dotted quad (/255.255.255.0) or as
+# numbers (/24)
+allowedhosts=127.0.0.1
+# Maximum number of concurrent GUI's
+maxclients=5
+# Maximum backlog before we start throwing out or killing clients.  The
+# bigger this number, the more memory and the more power it will use.
+maxbacklog=5000
+
+# Server + Drone config options.  To have a Kismet server export live packets
+# as if it were a drone, uncomment these.
+# dronelisten=tcp://127.0.0.1:3501
+# droneallowedhosts=127.0.0.1
+# dronemaxclients=5
+# droneringlen=65535
+
+# OUI file, expected format 00:11:22<tab>manufname
+# IEEE OUI file used to look up manufacturer info.  We default to the
+# wireshark one since most people have that.
+#ouifile=/usr/share/manuf
+
+# Do we have a GPS?
+gps=false
+# Do we use a locally serial attached GPS, or use a gpsd server, or
+# use a fixed virtual gps?
+# (Pick only one)
+gpstype=gpsd
+# Host:port that GPSD is running on.  This can be localhost OR remote!
+gpshost=localhost:2947
+
+
+# gpstype=serial
+# What serial device do we look for the GPS on?
+# gpsdevice=/dev/rfcomm0
+
+# gpstype=virtual
+# gpsposition=100,-50
+# gpsaltitude=1234
+
+# Do we lock the mode?  This overrides coordinates of lock "0", which will
+# generate some bad information until you get a GPS lock, but it will 
+# fix problems with GPS units with broken NMEA that report lock 0
+gpsmodelock=false
+# Do we try to reconnect if we lose our link to the GPS, or do we just
+# let it die and be disabled?
+gpsreconnect=true
+
+# Do we export packets over tun/tap virtual interfaces?
+tuntap_export=false
+# What virtual interface do we use
+tuntap_device=kistap0
+
+# Packet filtering options:
+# filter_tracker - Packets filtered from the tracker are not processed or
+#                  recorded in any way.
+# filter_export  - Controls what packets influence the exported CSV, network,
+#                  xml, gps, etc files.
+# All filtering options take arguments containing the type of address and
+# addresses to be filtered.  Valid address types are 'ANY', 'BSSID',
+# 'SOURCE', and 'DEST'.  Filtering can be inverted by the use of '!' before
+# the address.  For example,
+# filter_tracker=ANY(!"00:00:DE:AD:BE:EF")
+# has the same effect as the previous mac_filter config file option.
+# filter_tracker=...
+# filter_dump=...
+# filter_export=...
+# filter_netclient=...
+
+# Alerts to be reported and the throttling rates.
+# alert=name,throttle/unit,burst
+# The throttle/unit describes the number of alerts of this type that are
+# sent per time unit.  Valid time units are second, minute, hour, and day.
+# Burst describes the number of alerts sent before throttling takes place.
+# For example:
+# alert=FOO,10/min,5
+# Would allow 5 alerts through before throttling is enabled, and will then
+# limit the number of alerts to 10 per minute.
+# A throttle rate of 0 disables throttling of the alert.
+# See the README for a list of alert types.
+alert=ADHOCCONFLICT,5/min,1/sec
+alert=AIRJACKSSID,5/min,1/sec
+alert=APSPOOF,10/min,1/sec
+alert=BCASTDISCON,5/min,2/sec
+alert=BSSTIMESTAMP,5/min,1/sec
+alert=CHANCHANGE,5/min,1/sec
+alert=CRYPTODROP,5/min,1/sec
+alert=DISASSOCTRAFFIC,10/min,1/sec
+alert=DEAUTHFLOOD,5/min,2/sec
+alert=DEAUTHCODEINVALID,5/min,1/sec
+alert=DISCONCODEINVALID,5/min,1/sec
+alert=DHCPNAMECHANGE,5/min,1/sec
+alert=DHCPOSCHANGE,5/min,1/sec
+alert=DHCPCLIENTID,5/min,1/sec
+alert=DHCPCONFLICT,10/min,1/sec
+alert=NETSTUMBLER,5/min,1/sec
+alert=LUCENTTEST,5/min,1/sec
+alert=LONGSSID,5/min,1/sec
+alert=MSFBCOMSSID,5/min,1/sec
+alert=MSFDLINKRATE,5/min,1/sec
+alert=MSFNETGEARBEACON,5/min,1/sec
+alert=NULLPROBERESP,5/min,1/sec
+alert=PROBENOJOIN,5/min,1/sec
+
+# Controls behavior of the APSPOOF alert.  SSID may be a literal match (ssid=) or
+# a regex (ssidregex=) if PCRE was available when kismet was built.  The allowed 
+# MAC list must be comma-separated and enclosed in quotes if there are multiple 
+# MAC addresses allowed.  MAC address masks are allowed.
+#apspoof=Foo1:ssidregex="(?i:foobar)",validmacs=00:11:22:33:44:55
+#apspoof=Foo2:ssid="Foobar",validmacs="00:11:22:33:44:55,aa:bb:cc:dd:ee:ff"
+
+# Known WEP keys to decrypt, bssid,hexkey.  This is only for networks where
+# the keys are already known, and it may impact throughput on slower hardware.
+# Multiple wepkey lines may be used for multiple BSSIDs.
+# wepkey=00:DE:AD:C0:DE:00,FEEDFACEDEADBEEF01020304050607080900
+
+# Is transmission of the keys to the client allowed?  This may be a security
+# risk for some.  If you disable this, you will not be able to query keys from
+# a client.
+allowkeytransmit=true
+
+# How often (in seconds) do we write all our data files (0 to disable)
+writeinterval=10
+
+# Do we use sound?
+# Not to be confused with GUI sound parameter, this controls wether or not the
+# server itself will play sound.  Primarily for headless or automated systems.
+enablesound=false
+# Path to sound player
+soundbin=play
+
+sound=newnet,true
+sound=newcryptnet,true
+sound=packet,true
+sound=gpslock,true
+sound=gpslost,true
+sound=alert,true
+
+# Does the server have speech? (Again, not to be confused with the GUI's speech)
+enablespeech=false
+# Binary used for speech (if not in path, full path must be specified)
+speechbin=flite
+# Specify raw or festival; Flite (and anything else that doesn't need formatting
+# around the string to speak) is 'raw', festival requires the string be wrapped in
+# SayText("...")
+speechtype=raw
+
+# How do we speak?  Valid options:
+# speech    Normal speech
+# nato      NATO spellings (alpha, bravo, charlie)
+# spell     Spell the letters out (aye, bee, sea)
+speechencoding=nato
+
+speech=new,"New network detected s.s.i.d. %1 channel %2"
+speech=alert,"Alert %1"
+speech=gpslost,"G.P.S. signal lost"
+speech=gpslock,"G.P.S. signal O.K."
+
+# How many alerts do we backlog for new clients?  Only change this if you have
+# a -very- low memory system and need those extra bytes, or if you have a high
+# memory system and a huge number of alert conditions.
+alertbacklog=50
+
+# File types to log, comma seperated.  Built-in log file types:
+# alert                                Text file of alerts
+# gpsxml                       XML per-packet GPS log
+# nettxt                       Networks in text format
+# netxml                       Networks in XML format
+# pcapdump                     tcpdump/wireshark compatible pcap log file
+# string                       All strings seen (increases CPU load)
+logtypes=pcapdump,gpsxml,netxml,alert
+
+# Format of the pcap dump (PPI or 80211)
+pcapdumpformat=ppi
+# pcapdumpformat=80211
+
+# Default log title
+logdefault=Kismet
+
+# logtemplate - Filename logging template.
+# This is, at first glance, really nasty and ugly, but you'll hardly ever
+# have to touch it so don't complain too much.
+#
+# %p is replaced by the logging prefix + '/'
+# %n is replaced by the logging instance name
+# %d is replaced by the starting date as Mon-DD-YYYY
+# %D is replaced by the current date as YYYYMMDD
+# %t is replaced by the starting time as HH-MM-SS
+# %i is replaced by the increment log in the case of multiple logs
+# %l is replaced by the log type (pcapdump, strings, etc)
+# %h is replaced by the home directory
+
+logtemplate=%p%n-%D-%t-%i.%l
+
+# Where state info, etc, is stored.  You shouldnt ever need to change this.
+# This is a directory.
+configdir=%h/.kismet/
+
diff --git a/net/kismet/files/kismet_drone.conf b/net/kismet/files/kismet_drone.conf
new file mode 100644 (file)
index 0000000..bd16540
--- /dev/null
@@ -0,0 +1,69 @@
+# Kismet drone config file
+
+version=newcore.1
+
+# Name of drone server (informational)
+servername=Kismet-Drone
+
+# Drone configuration
+# Protocol, interface, and port to listen on
+dronelisten=tcp://127.0.0.1:2502
+# Hosts allowed to connect, comma separated.  May include netmasks.
+# allowedhosts=127.0.0.1,10.10.10.0/255.255.255.0
+droneallowedhosts=127.0.0.1
+# Maximum number of drone clients
+dronemaxclients=10
+droneringlen=65535
+
+# Do we have a GPS?
+gps=true
+# Do we use a locally serial attached GPS, or use a gpsd server?
+# (Pick only one)
+gpstype=gpsd
+# gpstype=serial
+# What serial device do we look for the GPS on?
+gpsdevice=/dev/rfcomm0
+# Host:port that GPSD is running on.  This can be localhost OR remote!
+gpshost=localhost:2947
+# Do we lock the mode?  This overrides coordinates of lock "0", which will
+# generate some bad information until you get a GPS lock, but it will 
+# fix problems with GPS units with broken NMEA that report lock 0
+gpsmodelock=false
+# Do we try to reconnect if we lose our link to the GPS, or do we just
+# let it die and be disabled?
+gpsreconnect=true
+
+# See the README for full information on the new source format
+# ncsource=interface:options
+ncsource=null
+# for example:
+# ncsource=wlan0
+# ncsource=wifi0:type=madwifi
+# ncsource=wlan0:name=intel,hop=false,channel=11
+
+# Special per-source options
+# sourceopts=[sourcename|*]:opt1,opt2
+# sourceopts=*:fuzzycrypt,weakvalidate
+
+# Comma-separated list of sources to enable, if you don't want to enable all
+# the sources you defined.
+# enablesource=source1,source2
+
+# How many channels per second do we hop?  (1-10)
+channelvelocity=5
+
+# By setting the dwell time for channel hopping we override the channelvelocity
+# setting above and dwell on each channel for the given number of seconds.
+#channeldwell=10
+
+# Users outside the US might want to use this list:
+# channellist=IEEE80211b:1,7,13,2,8,3,14,9,4,10,5,11,6,12
+channellist=IEEE80211b:1:3,6:3,11:3,2,7,3,8,4,9,5,10
+
+# US IEEE 80211a
+channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165
+
+# Combo
+channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165
+
+
diff --git a/net/kismet/files/kismet_drone.config b/net/kismet/files/kismet_drone.config
new file mode 100644 (file)
index 0000000..749505d
--- /dev/null
@@ -0,0 +1,2 @@
+config kismet_drone
+    option enabled 0
diff --git a/net/kismet/files/kismet_drone.init b/net/kismet/files/kismet_drone.init
new file mode 100755 (executable)
index 0000000..2cbbe7e
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013-2014 OpenWrt.org
+
+START=99
+STOP=99
+
+USE_PROCD=1
+PROG=/usr/bin/kismet_drone
+NAME=kismet_drone
+
+kismet_drone_instance() {
+        procd_open_instance
+        procd_set_param command "${PROG}"
+        procd_append_param command -f /etc/kismet/kismet_drone.conf -s
+        procd_set_param respawn
+        procd_close_instance
+}
+
+start_service() {
+        config_load "${NAME}"
+        config_foreach kismet_drone_instance
+}
+
+stop_service() {
+        service_stop "${PROG}"
+}
diff --git a/net/kismet/files/kismet_server.config b/net/kismet/files/kismet_server.config
new file mode 100644 (file)
index 0000000..ad39f3e
--- /dev/null
@@ -0,0 +1,2 @@
+config kismet_server
+    option enabled 0
diff --git a/net/kismet/files/kismet_server.init b/net/kismet/files/kismet_server.init
new file mode 100755 (executable)
index 0000000..7d731e7
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013-2014 OpenWrt.org
+
+START=99
+STOP=99
+
+USE_PROCD=1
+PROG=/usr/bin/kismet_server
+NAME=kismet_server
+
+kismet_server_instance() {
+        procd_open_instance
+        procd_set_param command "${PROG}"
+        procd_append_param command -f /etc/kismet/kismet.conf -s
+        procd_set_param respawn
+        procd_close_instance
+}
+
+start_service() {
+        config_load "${NAME}"
+        config_foreach kismet_server_instance
+}
+
+stop_service() {
+        service_stop "${PROG}"
+}
diff --git a/net/kismet/patches/010-dont-add-host-include-paths.patch b/net/kismet/patches/010-dont-add-host-include-paths.patch
new file mode 100644 (file)
index 0000000..23a87bd
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/configure b/configure
+index 6936a47..9a85269 100755
+--- a/configure
++++ b/configure
+@@ -6980,9 +6980,6 @@ else
+ fi
+-# Add additional cflags since some distros bury panel.h
+-CPPFLAGS="$CPPFLAGS -I/usr/include/ncurses"
+-
+ termcontrol="none";
+ if test "$wantclient" = "yes"; then
index 23740b229fc4615e51c8f37bf8d625f27d6efe8c..5abe85050d365b85beae2e137b287fccb0912a44 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+# Copyright (C) 2014-2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=knot
-PKG_VERSION:=1.5.3
+PKG_VERSION:=1.6.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE_URL:=https://secure.nic.cz/files/knot-dns/
-PKG_MD5SUM:=bab73ec83ad7f1d64bb765bf0c72caae
+PKG_MD5SUM:=acea8f90079c4f90ee841d1cfa3ccd30
 
 PKG_MAINTAINER:=Daniel Salzman <daniel.salzman@nic.cz>
 PKG_LICENSE:=GPL-2.0+
@@ -46,9 +46,27 @@ define Package/knot
        DEPENDS+=+knot-libknot
 endef
 
-define Package/knot-utils
+define Package/knot-dig
        $(call Package/knot/Default)
-       TITLE+= (utils)
+       TITLE+= lookup utility
+       DEPENDS+=+knot-libknot
+endef
+
+define Package/knot-host
+       $(call Package/knot/Default)
+       TITLE+= simple DNS lookup utility
+       DEPENDS+=+knot-libknot
+endef
+
+define Package/knot-nsec3hash
+       $(call Package/knot/Default)
+       TITLE+= simple NSEC3 hash utility
+       DEPENDS+=+knot-libknot
+endef
+
+define Package/knot-nsupdate
+       $(call Package/knot/Default)
+       TITLE+= dynamic DNS update utility
        DEPENDS+=+knot-libknot
 endef
 
@@ -66,8 +84,20 @@ define Package/knot/description
        High-performance authoritative-only DNS server.
 endef
 
-define Package/knot-utils/description
-       DNS utilities: kdig, khost, knsupdate and knsec3hash.
+define Package/knot-dig/description
+       Knot DNS lookup utility.
+endef
+
+define Package/knot-host/description
+       Knot DNS simple DNS lookup utility.
+endef
+
+define Package/knot-nsec3hash/description
+       Knot DNS simple utility to compute NSEC3 hash.
+endef
+
+define Package/knot-nsupdate/description
+       Knot DNS dynamic DNS update utility.
 endef
 
 define Package/knot-tests/description
@@ -114,14 +144,26 @@ define Package/knot/install
        $(INSTALL_BIN) ./files/knotd.init       $(1)/etc/init.d/knotd
 endef
 
-define Package/knot-utils/install
+define Package/knot-dig/install
        $(INSTALL_DIR)                                          $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/kdig          $(1)/usr/bin/
+endef
+
+define Package/knot-host/install
+       $(INSTALL_DIR)                                          $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/khost         $(1)/usr/bin/
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/knsupdate     $(1)/usr/bin/
+endef
+
+define Package/knot-nsec3hash/install
+       $(INSTALL_DIR)                                          $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/knsec3hash    $(1)/usr/bin/
 endef
 
+define Package/knot-nsupdate/install
+       $(INSTALL_DIR)                                          $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/knsupdate     $(1)/usr/bin/
+endef
+
 define Package/knot-tests/install
        $(INSTALL_DIR)                                          $(1)/usr/share/knot
        $(INSTALL_BIN) ./files/runtests.sh                      $(1)/usr/share/knot/
@@ -146,5 +188,8 @@ endef
 
 $(eval $(call BuildPackage,knot-libknot))
 $(eval $(call BuildPackage,knot))
-$(eval $(call BuildPackage,knot-utils))
+$(eval $(call BuildPackage,knot-dig))
+$(eval $(call BuildPackage,knot-host))
+$(eval $(call BuildPackage,knot-nsec3hash))
+$(eval $(call BuildPackage,knot-nsupdate))
 $(eval $(call BuildPackage,knot-tests))
diff --git a/net/knxd/Makefile b/net/knxd/Makefile
new file mode 100644 (file)
index 0000000..9030b98
--- /dev/null
@@ -0,0 +1,154 @@
+#
+# Copyright (C) 2008-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+### Remarks
+### 'python pascal ruby lua' need to be deleted in src/clients/Makefile.am
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=knxd
+PKG_REV:=c97a543043297e38bbe04e1030916e8a4737373c
+PKG_VERSION:=2015-01-14
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=LICENSE
+
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/Makki1/knxd.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_CAT:=zcat
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+PKG_BUILD_DEPENDS:=pthsem argp-standalone
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/knxd
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Eib KNX deamon
+  URL:=https://github.com/Makki1/knxd
+  DEPENDS:=pthsem libusb-1.0
+endef
+
+define Package/knxd/description
+EIB KNX Daemon
+endef
+
+define Package/knxd/conffiles
+/etc/config/knxd
+endef
+
+define Package/knxd-tools
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Eib KNX Utils
+  URL:=https://github.com/Makki1/knxd
+  DEPENDS:=pthsem libusb-1.0
+endef
+
+define Package/knxd-tools/description
+EIB KNX Tools
+endef
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default,\
+               --disable-ft12 \
+               --enable-eibnetip \
+               --enable-eibnetiptunnel \
+               --enable-eibnetipserver \
+               --enable-usb \
+               --enable-tpuart \
+               --enable-tpuarts \
+               --disable-pei16 \
+               --disable-pei16s \
+               --enable-groupcache \
+               --without-pth-test \
+               --without-libstdc )
+endef
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               CC=$(TARGET_CC) \
+               LIBS="-L$(STAGING_DIR)/lib -L$(STAGING_DIR)/usr/lib -fno-builtin -nodefaultlibs -lc -lm -lgcc -largp -lpthsem" \
+               CPPFLAGS="-I$(STAGING_DIR)/include -I$(STAGING_DIR)/usr/include"
+endef
+
+define Package/knxd/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/server/knxd $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/tools/bcu/bcuaddrtab $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/tools/bcu/bcuread $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/tools/eibnet/eibnetsearch $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/tools/eibnet/eibnetdescribe $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/usb/findknxusb $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/knxd.init $(1)/etc/init.d/knxd
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/knxd.config $(1)/etc/config/knxd
+endef
+
+define Package/knxd-tools/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/src/client/c/.libs/libeibclient.so.0.0.0 $(1)/usr/lib/
+       ln -s libeibclient.so.0.0.0 $(1)/usr/lib/libeibclient.so
+       ln -s libeibclient.so.0.0.0 $(1)/usr/lib/libeibclient.so.0
+       $(INSTALL_DIR) $(1)/usr/bin
+       -rm -f $(1)/usr/bin/knxread
+       -rm -f $(1)/usr/bin/knxreadtemp
+       -rm -f $(1)/usr/bin/knxwrite
+       -rm -f $(1)/usr/bin/knxlog
+       -rm -f $(1)/usr/bin/knxon
+       -rm -f $(1)/usr/bin/knxoff
+       -rm -f $(1)/usr/bin/knxif
+       -rm -f $(1)/usr/bin/knxswrite
+       -rm -f $(1)/usr/bin/knxbool
+       -rm -f $(1)/usr/bin/knxdimup
+       ln -s knxtool $(1)/usr/bin/knxread
+       ln -s knxtool $(1)/usr/bin/knxreadtemp
+       ln -s knxtool $(1)/usr/bin/knxwrite
+       ln -s knxtool $(1)/usr/bin/knxlog
+       ln -s knxtool $(1)/usr/bin/knxon
+       ln -s knxtool $(1)/usr/bin/knxoff
+       ln -s knxtool $(1)/usr/bin/knxif
+       ln -s knxtool $(1)/usr/bin/knxswrite
+       ln -s knxtool $(1)/usr/bin/knxbool
+       ln -s knxtool $(1)/usr/bin/knxdimup
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/knxtool $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/busmonitor1 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/busmonitor2 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/busmonitor3 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/eibread-cgi $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/eibwrite-cgi $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/vbusmonitor1 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/vbusmonitor2 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/vbusmonitor3 $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupwrite $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupswrite $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/grouplisten $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupread $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupresponse $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupreadresponse $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupsocketlisten $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupsocketread $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupsocketwrite $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/examples/.libs/groupsocketswrite $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,knxd))
+$(eval $(call BuildPackage,knxd-tools))
diff --git a/net/knxd/files/knxd.config b/net/knxd/files/knxd.config
new file mode 100644 (file)
index 0000000..cd86a62
--- /dev/null
@@ -0,0 +1,12 @@
+config daemon args
+        # daemon is started as 'knxd $options $url'
+        # use 'knxd --help' to get all possible options'
+        #
+        # typical example for options for tunnel mode
+        option options '-D -T -S -d/tmp/knxd.log -i -p/var/run/knxd.pid'
+        # add '-t1023' or '--trace=1023' for full log trace
+
+        # example with tpuarts interface
+        # option url 'tpuarts:/dev/ttyAMA0'
+        # example with IP interface in tunnel mode
+        option url 'ipt:192.168.1.20'
diff --git a/net/knxd/files/knxd.init b/net/knxd/files/knxd.init
new file mode 100644 (file)
index 0000000..df4dc80
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=90
+STOP=20
+NAME=knxd
+PROG=/usr/bin/$NAME
+
+. /lib/functions.sh
+
+start() {
+        local options url
+        config_load "$NAME"
+        config_get options args options ''
+        config_get url args url
+        service_start $PROG $options $url
+}
+
+stop() {
+        service_stop $PROG
+}
+
diff --git a/net/knxd/patches/0099-openwrt.patch b/net/knxd/patches/0099-openwrt.patch
new file mode 100644 (file)
index 0000000..fd73c05
--- /dev/null
@@ -0,0 +1,8 @@
+--- knxd/src/client/Makefile.am.orig    2014-12-21 20:17:14.000000000 +0100
++++ knxd/src/client/Makefile.am 2014-12-21 20:18:50.639995000 +0100
+@@ -4,5 +4,5 @@
+ BUILDJAVA =
+ endif
+
+-SUBDIRS=def c $(BUILDJAVA) php perl cs python pascal ruby lua .
++SUBDIRS=def c $(BUILDJAVA) php perl cs .
index adaac8ac1c638ccf5d7e9a24a78ac6ca815e087b..6eb2e6be6d2a4fa18549026ff3ebae326660674f 100644 (file)
@@ -12,6 +12,7 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 
 PKG_BUILD_PARALLEL:=1
 PKG_INSTALL:=1
+PKG_CHECK_FORMAT_SECURITY:=0
 
 include $(INCLUDE_DIR)/package.mk
 
index e2aa28cd0bd4c8f09dddb6c71b0db1b16282bc0b..8a4819cc0291dce80313db46ee0ccc3e448e1c01 100644 (file)
@@ -8,11 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=lftp
-PKG_VERSION:=4.5.5
+PKG_VERSION:=4.6.0
 PKG_RELEASE:=1
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://lftp.yar.ru/ftp \ http://lftp.cybermirror.org \ http://lftp.cybermirror.org/old
-PKG_MD5SUM:=e58fc886e3d7c6d994de5ce51de46087
+PKG_MD5SUM:=fc5f4e3b45c9011a193eb8c0c12eb2eb
+
+PKG_LICENSE:=GPL-3.0+
+PKG_LICENSE_FILES:=COPYING
 
 include $(INCLUDE_DIR)/uclibc++.mk
 include $(INCLUDE_DIR)/package.mk
@@ -50,6 +53,7 @@ CONFIGURE_ARGS += \
        --without-libiconv-prefix \
        --without-libintl-prefix \
        --without-gnutls \
+       --without-libidn \
        --without-libresolv \
        --with-openssl="$(STAGING_DIR)/usr" \
        --disable-static
diff --git a/net/lftp/patches/010-main_code_fix.patch b/net/lftp/patches/010-main_code_fix.patch
deleted file mode 100644 (file)
index 280c96b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/src/ftpclass.cc
-+++ b/src/ftpclass.cc
-@@ -1071,7 +1071,9 @@ Ftp::Connection::~Connection()
-    control_send=0;
-    control_recv=0;
-+#if USE_SSL
-    control_ssl=0; // ssl should be freed after send/recv
-+#endif
-    if(control_sock!=-1)
-    {
index 6bf91441c412c28da973f2f7acbc21234c9797a1..932fc2a7358246e9203d8687f256521d8eb9b1c6 100644 (file)
@@ -9,14 +9,14 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=lighttpd
 PKG_VERSION:=1.4.35
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://download.lighttpd.net/lighttpd/releases-1.4.x
 PKG_MD5SUM:=c7ae774eab4cb7ac85e41b712f4ee9ba
 
 PKG_LICENSE:=BSD-3c
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
@@ -149,33 +149,39 @@ define BuildPlugin
 endef
 
 $(eval $(call BuildPackage,lighttpd))
-$(eval $(call BuildPlugin,access,Access restrictions,,10))
-$(eval $(call BuildPlugin,accesslog,Access logging,,10))
-$(eval $(call BuildPlugin,alias,Directory alias,,10))
-$(eval $(call BuildPlugin,auth,Authentication,,05))
-$(eval $(call BuildPlugin,cgi,CGI,,10))
-$(eval $(call BuildPlugin,cml,Cache Meta Language,,10))
-$(eval $(call BuildPlugin,compress,Compress output,+PACKAGE_lighttpd-mod-compress:zlib,10))
-$(eval $(call BuildPlugin,evasive,Evasive,,10))
-$(eval $(call BuildPlugin,evhost,Exnhanced Virtual-Hosting,,10))
-$(eval $(call BuildPlugin,expire,Expire,,10))
-$(eval $(call BuildPlugin,extforward,Extract client,,10))
-$(eval $(call BuildPlugin,fastcgi,FastCGI,,10))
-$(eval $(call BuildPlugin,flv_streaming,FLV streaming,,10))
-$(eval $(call BuildPlugin,magnet,Magnet,,10))
-$(eval $(call BuildPlugin,mysql_vhost,Mysql virtual hosting,+PACKAGE_lighttpd-mod-mysql_vhost:libmysqlclient,10))
-$(eval $(call BuildPlugin,proxy,Proxy,,10))
+
+# First, permit redirect from HTTP to HTTPS.
 $(eval $(call BuildPlugin,redirect,URL redirection,+PACKAGE_lighttpd-mod-redirect:libpcre,10))
-$(eval $(call BuildPlugin,rewrite,URL rewriting,+PACKAGE_lighttpd-mod-rewrite:libpcre,10))
-$(eval $(call BuildPlugin,rrdtool,RRDtool,,10))
-$(eval $(call BuildPlugin,scgi,SCGI,,10))
-$(eval $(call BuildPlugin,secdownload,Secure and fast download,,10))
-$(eval $(call BuildPlugin,setenv,Environment variable setting,,10))
-$(eval $(call BuildPlugin,simple_vhost,Simple virtual hosting,,10))
-$(eval $(call BuildPlugin,ssi,SSI,+libpcre,10))
-$(eval $(call BuildPlugin,status,Server status display,,10))
-$(eval $(call BuildPlugin,trigger_b4_dl,Trigger before download,+PACKAGE_lighttpd-mod-trigger_b4_dl:libpcre,10))
-$(eval $(call BuildPlugin,userdir,User directory,,10))
-$(eval $(call BuildPlugin,usertrack,User tracking,,10))
-$(eval $(call BuildPlugin,webdav,WebDAV,+PACKAGE_lighttpd-mod-webdav:libsqlite3 +PACKAGE_lighttpd-mod-webdav:libuuid +PACKAGE_lighttpd-mod-webdav:libxml2,10))
+
+# Next, permit authentication.
+$(eval $(call BuildPlugin,auth,Authentication,,20))
+
+# Finally, everything else.
+$(eval $(call BuildPlugin,access,Access restrictions,,30))
+$(eval $(call BuildPlugin,accesslog,Access logging,,30))
+$(eval $(call BuildPlugin,alias,Directory alias,,30))
+$(eval $(call BuildPlugin,cgi,CGI,,30))
+$(eval $(call BuildPlugin,cml,Cache Meta Language,,30))
+$(eval $(call BuildPlugin,compress,Compress output,+PACKAGE_lighttpd-mod-compress:zlib,30))
+$(eval $(call BuildPlugin,evasive,Evasive,,30))
+$(eval $(call BuildPlugin,evhost,Exnhanced Virtual-Hosting,,30))
+$(eval $(call BuildPlugin,expire,Expire,,30))
+$(eval $(call BuildPlugin,extforward,Extract client,,30))
+$(eval $(call BuildPlugin,fastcgi,FastCGI,,30))
+$(eval $(call BuildPlugin,flv_streaming,FLV streaming,,30))
+$(eval $(call BuildPlugin,magnet,Magnet,,30))
+$(eval $(call BuildPlugin,mysql_vhost,Mysql virtual hosting,+PACKAGE_lighttpd-mod-mysql_vhost:libmysqlclient,30))
+$(eval $(call BuildPlugin,proxy,Proxy,,30))
+$(eval $(call BuildPlugin,rewrite,URL rewriting,+PACKAGE_lighttpd-mod-rewrite:libpcre,30))
+$(eval $(call BuildPlugin,rrdtool,RRDtool,,30))
+$(eval $(call BuildPlugin,scgi,SCGI,,30))
+$(eval $(call BuildPlugin,secdownload,Secure and fast download,,30))
+$(eval $(call BuildPlugin,setenv,Environment variable setting,,30))
+$(eval $(call BuildPlugin,simple_vhost,Simple virtual hosting,,30))
+$(eval $(call BuildPlugin,ssi,SSI,+libpcre,30))
+$(eval $(call BuildPlugin,status,Server status display,,30))
+$(eval $(call BuildPlugin,trigger_b4_dl,Trigger before download,+PACKAGE_lighttpd-mod-trigger_b4_dl:libpcre,30))
+$(eval $(call BuildPlugin,userdir,User directory,,30))
+$(eval $(call BuildPlugin,usertrack,User tracking,,30))
+$(eval $(call BuildPlugin,webdav,WebDAV,+PACKAGE_lighttpd-mod-webdav:libsqlite3 +PACKAGE_lighttpd-mod-webdav:libuuid +PACKAGE_lighttpd-mod-webdav:libxml2,30))
 
diff --git a/net/linknx/Makefile b/net/linknx/Makefile
new file mode 100644 (file)
index 0000000..bfe7683
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2008-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=linknx
+PKG_VERSION:=0.0.1.32
+PKG_RELEASE:=4
+PKG_MD5SUM:=7ecc1208f59bceb05068c752b2250b63
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_SOURCE_URL:=@SF/linknx
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_CAT:=zcat
+PKG_BUILD_DEPENDS:=pthsem curl libesmtp
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+include $(INCLUDE_DIR)/package.mk
+
+define Package/linknx
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=KNX home automation platform
+  URL:=http://sourceforge.net/projects/linknx/
+  DEPENDS:=pthsem +lua +luac +libstdcpp +libcurl +libesmtp
+endef
+
+define Build/Configure
+       (cd $(PKG_BUILD_DIR); touch aclocal.m4 Makefile.in config.h.in configure; \
+       $(SED) 's,\"2.0.4\",\"2.0.4\"\n_pth_version=\"2.0.8\",g' $(PKG_BUILD_DIR)/configure )
+       $(call Build/Configure/Default,--verbose --without-pth-test --with-pth=$(STAGING_DIR) --without-log4cpp --with-lua --with-libcurl --without-mysql, \
+       CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin -lcrypt" \
+       )
+endef
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR)/ \
+               LIBDIR="$(TARGET_LDFLAGS)" \
+               CC="$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) " \
+               LD="$(TARGET_CROSS)ld -shared" \
+               LUA="$(STAGING_DIR_HOST)/bin/lua" \
+               LUAC="$(STAGING_DIR_HOST)/bin/luac" \
+               CFLAGS="$(TARGET_CFLAGS) -nodefaultlibs" all
+endef
+
+define Package/linknx/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/linknx $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/linknx.init $(1)/etc/init.d/linknx
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/linknx.config $(1)/etc/config/linknx
+       $(INSTALL_DATA) ./files/linknx.xml.dist $(1)/etc/linknx.xml.dist
+       $(INSTALL_DIR) $(1)/tmp/linknx/persist
+endef
+
+define Package/linknx/conffiles
+/etc/config/linknx
+/etc/linknx.xml.dist
+endef
+
+$(eval $(call BuildPackage,linknx))
diff --git a/net/linknx/files/linknx.config b/net/linknx/files/linknx.config
new file mode 100644 (file)
index 0000000..d2f0562
--- /dev/null
@@ -0,0 +1,8 @@
+config daemon args
+        # daemon is started as 'linknx --config=$conf $options'
+        # use 'linknx --help' to get all possible options'
+        #
+        # typical example
+        option conf '/etc/linknx.xml'
+        option options '-w --daemon=/tmp/linknx/linknx.log --pid-file=/var/run/linknx.pid'
+
diff --git a/net/linknx/files/linknx.init b/net/linknx/files/linknx.init
new file mode 100644 (file)
index 0000000..d38f194
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=98
+STOP=10
+NAME=linknx
+PROG=/usr/bin/$NAME
+
+. /lib/functions.sh
+
+start() {
+        local conf options
+        config_load "$NAME"
+        config_get conf args conf '/etc/linknx.xml'
+        config_get options args options ''
+        test -f $conf || cp -p /etc/linknx.xml.dist $conf
+        mkdir -p /tmp/$NAME/persist
+        service_start $PROG --config=$conf $options
+}
+
+stop() {
+        service_stop $PROG
+}
diff --git a/net/linknx/files/linknx.xml.dist b/net/linknx/files/linknx.xml.dist
new file mode 100644 (file)
index 0000000..55eb41d
--- /dev/null
@@ -0,0 +1,16 @@
+<config>
+  <objects>
+  </objects>
+
+  <rules>
+  </rules>
+
+  <services>
+    <xmlserver type="inet" port="1028"/>
+    <knxconnection url="ip:localhost"/>
+    <persistence type="file" path="/tmp/linknx/persist"/>
+    <emailserver type="smtp" host="localhost:25" from="linknx@local.local" />
+  </services>
+  <logging format="basic" level="INFO" />
+
+</config>
diff --git a/net/luci-app-bcp38/Makefile b/net/luci-app-bcp38/Makefile
new file mode 100644 (file)
index 0000000..d42916c
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=luci-app-bcp38
+PKG_VERSION:=2
+PKG_RELEASE:=1
+PKG_LICENSE:=Apache-2.0
+LUCI_DIR:=/usr/lib/lua/luci
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/luci-app-bcp38
+  SECTION:=luci
+  CATEGORY:=LuCI
+  TITLE:=BCP38 LuCI interface
+  MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
+  PKGARCH:=all
+  DEPENDS:= lua luci-base +bcp38
+  SUBMENU:=3. Applications
+endef
+
+define Package/luci-app-bcp38/description
+       Control BCP38 subnet blocking
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/luci-app-bcp38/install
+       $(INSTALL_DIR) $(1)$(LUCI_DIR)/controller $(1)$(LUCI_DIR)/model/cbi
+       $(INSTALL_DATA) ./files/bcp38-controller.lua $(1)$(LUCI_DIR)/controller/bcp38.lua
+       $(INSTALL_DATA) ./files/bcp38-cbi.lua $(1)$(LUCI_DIR)/model/cbi/bcp38.lua
+       $(INSTALL_DIR) $(1)/etc/uci-defaults
+       $(INSTALL_BIN) ./files/uci-defaults-bcp38 $(1)/etc/uci-defaults/luci-bcp38
+endef
+
+define Package/luci-app-bcp38/postinst
+#!/bin/sh
+[ -x /etc/uci-defaults/luci-bcp38 ] && /etc/uci-defaults/luci-bcp38 || exit 0
+endef
+
+define Package/luci-app-bcp38/postrm
+#!/bin/sh
+uci delete ucitrack.@bcp38[0]
+uci commit
+endef
+
+$(eval $(call BuildPackage,luci-app-bcp38))
diff --git a/net/luci-app-bcp38/files/bcp38-cbi.lua b/net/luci-app-bcp38/files/bcp38-cbi.lua
new file mode 100644 (file)
index 0000000..b0b8f38
--- /dev/null
@@ -0,0 +1,58 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2014 Toke Høiland-Jørgensen <toke@toke.dk>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+]]--
+
+local wa = require "luci.tools.webadmin"
+local net = require "luci.model.network".init()
+local ifaces = net:get_interfaces()
+
+m = Map("bcp38", translate("BCP38"),
+       translate("This function blocks packets with private address destinations " ..
+               "from going out onto the internet as per " ..
+               "<a href=\"http://tools.ietf.org/html/bcp38\">BCP 38</a>."))
+
+s = m:section(TypedSection, "bcp38", translate("BCP38 config"))
+s.anonymous = true
+-- BASIC
+e = s:option(Flag, "enabled", translate("Enable"))
+e.rmempty = false
+
+a = s:option(Flag, "detect_upstream", translate("Auto-detect upstream IP"),
+                               translate("Attempt to automatically detect if the upstream IP " ..
+                                       "will be blocked by the configuration, and add an exception if it will. " ..
+                                       "If this does not work correctly, you can add exceptions manually below."))
+a.rmempty = false
+
+n = s:option(ListValue, "interface", translate("Interface name"), translate("Interface to apply the blocking to " ..
+                                                       "(should be the upstream WAN interface)."))
+for _, iface in ipairs(ifaces) do
+     if iface:is_up() then
+       n:value(iface:name())
+     end
+end
+n.rmempty = false
+
+ma = s:option(DynamicList, "match",
+       translate("Blocked IP ranges"))
+
+ma.datatype = "ip4addr"
+
+nm = s:option(DynamicList, "nomatch",
+       translate("Allowed IP ranges"), translate("Takes precedence over blocked ranges. "..
+                                                 "Use to whitelist your upstream network if you're behind a double NAT " ..
+                                                 "and the auto-detection doesn't work."))
+
+nm.datatype = "ip4addr"
+
+
+return m
diff --git a/net/luci-app-bcp38/files/bcp38-controller.lua b/net/luci-app-bcp38/files/bcp38-controller.lua
new file mode 100644 (file)
index 0000000..7ea2283
--- /dev/null
@@ -0,0 +1,7 @@
+module("luci.controller.bcp38", package.seeall)
+
+function index()
+       entry({"admin", "network", "firewall", "bcp38"},
+               cbi("bcp38"),
+               _("BCP38"), 50).dependent = false
+end
diff --git a/net/luci-app-bcp38/files/uci-defaults-bcp38 b/net/luci-app-bcp38/files/uci-defaults-bcp38
new file mode 100755 (executable)
index 0000000..c204236
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+       delete ucitrack.@bcp38[-1]
+       add ucitrack bcp38
+        add_list ucitrack.@bcp38[0].affects=firewall
+       commit ucitrack
+EOF
+
+rm -f /tmp/luci-indexcache
+exit 0
diff --git a/net/luci-app-ocserv/Makefile b/net/luci-app-ocserv/Makefile
deleted file mode 100644 (file)
index 18ff019..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#    Copyright (C) 2014 Nikos Mavrogiannopoulos
-#
-#    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.
-#
-#    The full GNU General Public License is included in this distribution in
-#    the file called "COPYING".
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=luci-app-ocserv
-PKG_RELEASE:=1
-
-PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/luci-app-ocserv
-  SECTION:=luci
-  CATEGORY:=LuCI
-  SUBMENU:=3. Applications
-  TITLE:= OpenConnect VPN server configuration and status module
-  DEPENDS:=+luci-lib-json +luci-lib-nixio +luci-mod-admin-full +ocserv
-  MAINTAINER:= Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-endef
-
-define Package/luci-app-ocserv/description
-       ocserv web module for LuCi web interface
-endef
-
-define Build/Prepare
-endef
-
-define Build/Configure
-endef
-
-define Build/Compile
-endef
-
-# Fixme: How can we add <%+ocserv_status%> in view/admin_status/index.htm?
-define Package/luci-app-ocserv/install
-       $(CP) ./files/* $(1)/
-endef
-
-$(eval $(call BuildPackage,luci-app-ocserv))
-
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/controller/ocserv.lua b/net/luci-app-ocserv/files/usr/lib/lua/luci/controller/ocserv.lua
deleted file mode 100644 (file)
index 5cb0fb9..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2014 Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-$Id$
-]]--
-
-module("luci.controller.ocserv", package.seeall)
-
-function index()
-       if not nixio.fs.access("/etc/config/ocserv") then
-               return
-       end
-
-       local page
-
-       page = entry({"admin", "services", "ocserv"}, alias("admin", "services", "ocserv", "main"),
-               _("OpenConnect VPN"))
-       page.dependent = true
-       
-       page = entry({"admin", "services", "ocserv", "main"},
-               cbi("ocserv/main"),
-               _("Server Settings"), 200)
-       page.dependent = true
-
-       page = entry({"admin", "services", "ocserv", "users"},
-               cbi("ocserv/users"),
-               _("User Settings"), 300)
-       page.dependent = true
-
-       entry({"admin", "services", "ocserv", "status"},
-               call("ocserv_status")).leaf = true
-
-       entry({"admin", "services", "ocserv", "disconnect"},
-               call("ocserv_disconnect")).leaf = true
-
-end
-
-function ocserv_status()
-       local ipt = io.popen("/usr/bin/occtl show users");
-
-       if ipt then
-
-               local fwd = { }
-               while true do
-
-                       local ln = ipt:read("*l")
-                       if not ln then break end
-               
-                       local id, user, group, vpn_ip, ip, device, time, cipher, status = 
-                               ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+).*")
-                       if id then
-                               fwd[#fwd+1] = {
-                                       id = id,
-                                       user = user,
-                                       group = group,
-                                       vpn_ip = vpn_ip,
-                                       ip = ip,
-                                       device = device,
-                                       time = time,
-                                       cipher = cipher,
-                                       status = status
-                               }
-                       end
-               end
-               ipt:close()
-               luci.http.prepare_content("application/json")
-               luci.http.write_json(fwd)
-       end
-end
-
-function ocserv_disconnect(num)
-       local idx = tonumber(num)
-       local uci = luci.model.uci.cursor()
-
-       if idx and idx > 0 then
-               luci.sys.call("/usr/bin/occtl disconnect id %d" % idx)
-               luci.http.status(200, "OK")
-
-               return
-       end
-       luci.http.status(400, "Bad request")
-end
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/main.lua b/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/main.lua
deleted file mode 100644 (file)
index 65f8878..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2014 Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-$Id$
-local niulib = require "luci.niulib"
-]]--
-
-local fs = require "nixio.fs"
-local has_ipv6 = fs.access("/proc/net/ipv6_route")
-
-m = Map("ocserv", translate("OpenConnect VPN"))
-
-s = m:section(TypedSection, "ocserv", "OpenConnect")
-s.anonymous = true
-
-s:tab("general",  translate("General Settings"))
-s:tab("ca", translate("CA certificate"))
-s:tab("template", translate("Edit Template"))
-
-local e = s:taboption("general", Flag, "enable", translate("Enable server"))
-e.rmempty = false
-e.default = "1"
-
-function m.on_commit(map)
-       luci.sys.call("/usr/bin/occtl reload  >/dev/null 2>&1")
-end
-
-function e.write(self, section, value)
-       if value == "0" then
-               luci.sys.call("/etc/init.d/ocserv stop >/dev/null 2>&1")
-               luci.sys.call("/etc/init.d/ocserv disable  >/dev/null 2>&1")
-       else
-               luci.sys.call("/etc/init.d/ocserv enable  >/dev/null 2>&1")
-               luci.sys.call("/etc/init.d/ocserv restart  >/dev/null 2>&1")
-       end
-       Flag.write(self, section, value)
-end
-
-local o
-
-o = s:taboption("general", ListValue, "auth", translate("User Authentication"),
-       translate("The authentication method for the users. The simplest is plain with a single username-password pair. Use PAM modules to authenticate using another server (e.g., LDAP, Radius)."))
-o.rmempty = false
-o.default = "plain"
-o:value("plain")
-o:value("PAM")
-
-o = s:taboption("general", Value, "zone", translate("Firewall Zone"),
-       translate("The firewall zone that the VPN clients will be set to"))
-o.nocreate = true
-o.default = "lan"
-o.template = "cbi/firewall_zonelist"
-
-s:taboption("general", Value, "port", translate("Port"),
-       translate("The same UDP and TCP ports will be used"))
-s:taboption("general", Value, "max_clients", translate("Max clients"))
-s:taboption("general", Value, "max_same", translate("Max same clients"))
-s:taboption("general", Value, "dpd", translate("Dead peer detection time (secs)"))
-
-local pip = s:taboption("general", Flag, "predictable_ips", translate("Predictable IPs"),
-       translate("The assigned IPs will be selected deterministically"))
-pip.default = "1"
-
-local udp = s:taboption("general", Flag, "udp", translate("Enable UDP"),
-       translate("Enable UDP channel support; this must be enabled unless you know what you are doing"))
-udp.default = "1"
-
-local cisco = s:taboption("general", Flag, "cisco_compat", translate("AnyConnect client compatibility"),
-       translate("Enable support for CISCO AnyConnect clients"))
-cisco.default = "1"
-
-ipaddr = s:taboption("general", Value, "ipaddr", translate("VPN <abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Network-Address"))
-ipaddr.default = "192.168.100.1"
-
-nm = s:taboption("general", Value, "netmask", translate("VPN <abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
-nm.default = "255.255.255.0"
-nm:value("255.255.255.0")
-nm:value("255.255.0.0")
-nm:value("255.0.0.0")
-
-if has_ipv6 then
-       ip6addr = s:taboption("general", Value, "ip6addr", translate("VPN <abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Network-Address"), translate("<abbr title=\"Classless Inter-Domain Routing\">CIDR</abbr>-Notation: address/prefix"))
-end
-
-
-tmpl = s:taboption("template", Value, "_tmpl",
-       translate("Edit the template that is used for generating the ocserv configuration."))
-
-tmpl.template = "cbi/tvalue"
-tmpl.rows = 20
-
-function tmpl.cfgvalue(self, section)
-       return nixio.fs.readfile("/etc/ocserv/ocserv.conf.template")
-end
-
-function tmpl.write(self, section, value)
-       value = value:gsub("\r\n?", "\n")
-       nixio.fs.writefile("/etc/ocserv/ocserv.conf.template", value)
-end
-
-ca = s:taboption("ca", Value, "_ca",
-       translate("View the CA certificate used by this server. You will need to save it as 'ca.pem' and import it into the clients."))
-
-ca.template = "cbi/tvalue"
-ca.rows = 20
-
-function ca.cfgvalue(self, section)
-       return nixio.fs.readfile("/etc/ocserv/ca.pem")
-end
-
---[[DNS]]--
-
-s = m:section(TypedSection, "dns", translate("DNS servers"),
-       translate("The DNS servers to be provided to clients; can be either IPv6 or IPv4"))
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-
-s:option(Value, "ip", translate("IP Address")).rmempty = true
-
---[[Routes]]--
-
-s = m:section(TypedSection, "routes", translate("Routing table"),
-       translate("The routing table to be provided to clients; you can mix IPv4 and IPv6 routes, the server will send only the appropriate. Leave empty to set a default route"))
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-
-s:option(Value, "ip", translate("IP Address")).rmempty = true
-
-o = s:option(Value, "netmask", translate("Netmask (or IPv6-prefix)"))
-o.default = "255.255.255.0"
-o:value("255.255.255.0")
-o:value("255.255.0.0")
-o:value("255.0.0.0")
-
-
-return m
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/user-config.lua b/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/user-config.lua
deleted file mode 100644 (file)
index 65f8878..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2014 Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-$Id$
-local niulib = require "luci.niulib"
-]]--
-
-local fs = require "nixio.fs"
-local has_ipv6 = fs.access("/proc/net/ipv6_route")
-
-m = Map("ocserv", translate("OpenConnect VPN"))
-
-s = m:section(TypedSection, "ocserv", "OpenConnect")
-s.anonymous = true
-
-s:tab("general",  translate("General Settings"))
-s:tab("ca", translate("CA certificate"))
-s:tab("template", translate("Edit Template"))
-
-local e = s:taboption("general", Flag, "enable", translate("Enable server"))
-e.rmempty = false
-e.default = "1"
-
-function m.on_commit(map)
-       luci.sys.call("/usr/bin/occtl reload  >/dev/null 2>&1")
-end
-
-function e.write(self, section, value)
-       if value == "0" then
-               luci.sys.call("/etc/init.d/ocserv stop >/dev/null 2>&1")
-               luci.sys.call("/etc/init.d/ocserv disable  >/dev/null 2>&1")
-       else
-               luci.sys.call("/etc/init.d/ocserv enable  >/dev/null 2>&1")
-               luci.sys.call("/etc/init.d/ocserv restart  >/dev/null 2>&1")
-       end
-       Flag.write(self, section, value)
-end
-
-local o
-
-o = s:taboption("general", ListValue, "auth", translate("User Authentication"),
-       translate("The authentication method for the users. The simplest is plain with a single username-password pair. Use PAM modules to authenticate using another server (e.g., LDAP, Radius)."))
-o.rmempty = false
-o.default = "plain"
-o:value("plain")
-o:value("PAM")
-
-o = s:taboption("general", Value, "zone", translate("Firewall Zone"),
-       translate("The firewall zone that the VPN clients will be set to"))
-o.nocreate = true
-o.default = "lan"
-o.template = "cbi/firewall_zonelist"
-
-s:taboption("general", Value, "port", translate("Port"),
-       translate("The same UDP and TCP ports will be used"))
-s:taboption("general", Value, "max_clients", translate("Max clients"))
-s:taboption("general", Value, "max_same", translate("Max same clients"))
-s:taboption("general", Value, "dpd", translate("Dead peer detection time (secs)"))
-
-local pip = s:taboption("general", Flag, "predictable_ips", translate("Predictable IPs"),
-       translate("The assigned IPs will be selected deterministically"))
-pip.default = "1"
-
-local udp = s:taboption("general", Flag, "udp", translate("Enable UDP"),
-       translate("Enable UDP channel support; this must be enabled unless you know what you are doing"))
-udp.default = "1"
-
-local cisco = s:taboption("general", Flag, "cisco_compat", translate("AnyConnect client compatibility"),
-       translate("Enable support for CISCO AnyConnect clients"))
-cisco.default = "1"
-
-ipaddr = s:taboption("general", Value, "ipaddr", translate("VPN <abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Network-Address"))
-ipaddr.default = "192.168.100.1"
-
-nm = s:taboption("general", Value, "netmask", translate("VPN <abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
-nm.default = "255.255.255.0"
-nm:value("255.255.255.0")
-nm:value("255.255.0.0")
-nm:value("255.0.0.0")
-
-if has_ipv6 then
-       ip6addr = s:taboption("general", Value, "ip6addr", translate("VPN <abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Network-Address"), translate("<abbr title=\"Classless Inter-Domain Routing\">CIDR</abbr>-Notation: address/prefix"))
-end
-
-
-tmpl = s:taboption("template", Value, "_tmpl",
-       translate("Edit the template that is used for generating the ocserv configuration."))
-
-tmpl.template = "cbi/tvalue"
-tmpl.rows = 20
-
-function tmpl.cfgvalue(self, section)
-       return nixio.fs.readfile("/etc/ocserv/ocserv.conf.template")
-end
-
-function tmpl.write(self, section, value)
-       value = value:gsub("\r\n?", "\n")
-       nixio.fs.writefile("/etc/ocserv/ocserv.conf.template", value)
-end
-
-ca = s:taboption("ca", Value, "_ca",
-       translate("View the CA certificate used by this server. You will need to save it as 'ca.pem' and import it into the clients."))
-
-ca.template = "cbi/tvalue"
-ca.rows = 20
-
-function ca.cfgvalue(self, section)
-       return nixio.fs.readfile("/etc/ocserv/ca.pem")
-end
-
---[[DNS]]--
-
-s = m:section(TypedSection, "dns", translate("DNS servers"),
-       translate("The DNS servers to be provided to clients; can be either IPv6 or IPv4"))
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-
-s:option(Value, "ip", translate("IP Address")).rmempty = true
-
---[[Routes]]--
-
-s = m:section(TypedSection, "routes", translate("Routing table"),
-       translate("The routing table to be provided to clients; you can mix IPv4 and IPv6 routes, the server will send only the appropriate. Leave empty to set a default route"))
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-
-s:option(Value, "ip", translate("IP Address")).rmempty = true
-
-o = s:option(Value, "netmask", translate("Netmask (or IPv6-prefix)"))
-o.default = "255.255.255.0"
-o:value("255.255.255.0")
-o:value("255.255.0.0")
-o:value("255.0.0.0")
-
-
-return m
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/users.lua b/net/luci-app-ocserv/files/usr/lib/lua/luci/model/cbi/ocserv/users.lua
deleted file mode 100644 (file)
index 35c20fc..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2014 Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-$Id$
-]]--
-
-local dsp = require "luci.dispatcher"
-local nixio  = require "nixio"
-
-m = Map("ocserv", translate("OpenConnect VPN"))
-
-if m.uci:get("ocserv", "config", "auth") == "plain" then
-
---[[Users]]--
-
-function m.on_commit(map)
-       luci.sys.call("/etc/init.d/ocserv restart >/dev/null 2>&1")
-end
-
-s = m:section(TypedSection, "ocservusers", translate("Available users"))
-s.anonymous = true
-s.addremove = true
-s.template = "cbi/tblsection"
-
-s:option(Value, "name", translate("Name")).rmempty = true
-s:option(DummyValue, "group", translate("Group")).rmempty = true
-pwd = s:option(Value, "password", translate("Password"))
-pwd.password = false
-
-function pwd.write(self, section, value)
-       local pass
-       if string.match(value, "^\$%d\$.*") then
-               pass = value
-       else
-               local t = tonumber(nixio.getpid()*os.time())
-               local salt = "$5$" .. t .. "$"
-               pass = nixio.crypt(value, salt)
-       end
-       Value.write(self, section, pass)
-end    
-
---[[if plain]]--
-end
-
-local lusers = { }
-local fd = io.popen("/usr/bin/occtl show users", "r")
-if fd then local ln
-       repeat
-               ln = fd:read("*l")
-               if not ln then break end
-
-               local id, user, group, vpn_ip, ip, device, time, cipher, status = 
-                       ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+).*")
-               if id then
-                       table.insert(lusers, {id, user, group, vpn_ip, ip, device, time, cipher, status})
-               end
-       until not ln
-       fd:close()
-end
-
-
---[[Active Users]]--
-
-local s = m:section(Table, lusers, translate("Active users"))
-s.anonymous = true
-s.rmempty = true
-s.template = "cbi/tblsection"
-
-s:option(DummyValue, 1, translate("ID"))
-s:option(DummyValue, 2, translate("Username"))
-s:option(DummyValue, 3, translate("Group"))
-s:option(DummyValue, 4, translate("IP"))
-s:option(DummyValue, 5, translate("VPN IP"))
-s:option(DummyValue, 6, translate("Device"))
-s:option(DummyValue, 7, translate("Time"))
-s:option(DummyValue, 8, translate("Cipher"))
-s:option(DummyValue, 9, translate("Status"))
-
-return m
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/view/admin_status/index/ocserv.htm b/net/luci-app-ocserv/files/usr/lib/lua/luci/view/admin_status/index/ocserv.htm
deleted file mode 100644 (file)
index 4575806..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<%+ocserv_status%>
diff --git a/net/luci-app-ocserv/files/usr/lib/lua/luci/view/ocserv_status.htm b/net/luci-app-ocserv/files/usr/lib/lua/luci/view/ocserv_status.htm
deleted file mode 100644 (file)
index fabc1bc..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<script type="text/javascript">//<![CDATA[
-
-       function ocserv_disconnect(idx) {
-               XHR.get('<%=luci.dispatcher.build_url("admin", "services", "ocserv", "disconnect")%>/' + idx, null,
-                       function(x)
-                       {
-                               var tb = document.getElementById('ocserv_status_table');
-                               if (tb && (idx < tb.rows.length))
-                                       tb.rows[0].parentNode.removeChild(tb.rows[idx]);
-                       }
-               );
-       }
-
-       XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "ocserv", "status")%>', null,
-               function(x, st)
-               {
-                       var tb = document.getElementById('ocserv_status_table');
-                       if (st && tb)
-                       {
-                               /* clear all rows */
-                               while( tb.rows.length > 1 )
-                                       tb.deleteRow(1);
-
-                               for( var i = 0; i < st.length; i++ )
-                               {
-                                       var tr = tb.insertRow(-1);
-                                               tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
-
-                                       tr.insertCell(-1).innerHTML = st[i].user;
-                                       tr.insertCell(-1).innerHTML = st[i].group;
-                                       tr.insertCell(-1).innerHTML = st[i].vpn_ip;
-                                       tr.insertCell(-1).innerHTML = st[i].ip;
-                                       tr.insertCell(-1).innerHTML = st[i].device;
-                                       tr.insertCell(-1).innerHTML = st[i].time;
-                                       tr.insertCell(-1).innerHTML = st[i].cipher;
-                                       tr.insertCell(-1).innerHTML = st[i].status;
-
-                                       tr.insertCell(-1).innerHTML = String.format(
-                                               '<input class="cbi-button cbi-input-remove" type="button" value="<%:Disconnect%>" onclick="ocserv_disconnect(%d)" />',
-                                                       st[i].id
-                                       );
-                               }
-
-                               if( tb.rows.length == 1 )
-                               {
-                                       var tr = tb.insertRow(-1);
-                                               tr.className = 'cbi-section-table-row';
-
-                                       var td = tr.insertCell(-1);
-                                               td.colSpan = 5;
-                                               td.innerHTML = '<em><br /><%:There are no active users.%></em>';
-                               }
-                       }
-               }
-       );
-//]]></script>
-
-<fieldset class="cbi-section">
-       <legend><%:Active OpenConnect Users%></legend>
-       <table class="cbi-section-table" id="ocserv_status_table">
-               <tr class="cbi-section-table-titles">
-                       <th class="cbi-section-table-cell"><%:User%></th>
-                       <th class="cbi-section-table-cell"><%:Group%></th>
-                       <th class="cbi-section-table-cell"><%:IP Address%></th>
-                       <th class="cbi-section-table-cell"><%:VPN IP Address%></th>
-                       <th class="cbi-section-table-cell"><%:Device%></th>
-                       <th class="cbi-section-table-cell"><%:Time%></th>
-                       <th class="cbi-section-table-cell"><%:Cipher%></th>
-                       <th class="cbi-section-table-cell"><%:Status%></th>
-                       <th class="cbi-section-table-cell">&#160;</th>
-               </tr>
-               <tr class="cbi-section-table-row">
-                       <td colspan="5"><em><br /><%:Collecting data...%></em></td>
-               </tr>
-       </table>
-</fieldset>
diff --git a/net/luci-app-sqm/Makefile b/net/luci-app-sqm/Makefile
new file mode 100644 (file)
index 0000000..f0bb2a0
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=luci-app-sqm
+PKG_VERSION:=3
+PKG_RELEASE:=1
+PKG_LICENSE:=GPLv2
+LUCI_DIR:=/usr/lib/lua/luci
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/luci-app-sqm
+  SECTION:=luci
+  CATEGORY:=LuCI
+  TITLE:=SQM Scripts - LuCI interface
+  MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
+  PKGARCH:=all
+  DEPENDS:= lua luci-base +sqm-scripts
+  SUBMENU:=3. Applications
+endef
+
+define Package/luci-app-sqm/description
+       Control the simple_qos SQM script
+endef
+
+define Build/Compile
+endef
+
+define Build/Configure
+endef
+
+define Package/luci-app-sqm/install
+       $(INSTALL_DIR) $(1)$(LUCI_DIR)/controller $(1)$(LUCI_DIR)/model/cbi
+       $(INSTALL_DATA) ./files/sqm-controller.lua $(1)$(LUCI_DIR)/controller/sqm.lua
+       $(INSTALL_DATA) ./files/sqm-cbi.lua $(1)$(LUCI_DIR)/model/cbi/sqm.lua
+       $(INSTALL_DIR) $(1)/etc/uci-defaults
+       $(INSTALL_BIN) ./files/uci-defaults-sqm $(1)/etc/uci-defaults/luci-sqm
+endef
+
+define Package/luci-app-sqm/postinst
+#!/bin/sh
+which uci > /dev/null || exit 0
+uci -q get ucitrack.@sqm[0] > /dev/null || {
+  uci add ucitrack sqm > /dev/null
+  uci set ucitrack.@sqm[0].init=sqm
+  uci add_list ucitrack.@firewall[0].affects=sqm
+  uci commit
+}
+endef
+
+define Package/luci-app-sqm/postrm
+#!/bin/sh
+which uci > /dev/null || exit 0
+uci -q get ucitrack.@sqm[0] > /dev/null && {
+  uci delete ucitrack.@sqm[0]
+  uci del_list ucitrack.@firewall[0].affects=sqm
+  uci commit
+}
+endef
+
+$(eval $(call BuildPackage,luci-app-sqm))
diff --git a/net/luci-app-sqm/files/sqm-cbi.lua b/net/luci-app-sqm/files/sqm-cbi.lua
new file mode 100644 (file)
index 0000000..e7d79df
--- /dev/null
@@ -0,0 +1,217 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2014 Steven Barth <steven@midlink.org>
+Copyright 2014 Dave Taht <dave.taht@bufferbloat.net>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+]]--
+
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
+local net = require "luci.model.network".init()
+local sys = require "luci.sys"
+--local ifaces = net:get_interfaces()
+local ifaces = sys.net:devices()
+local path = "/usr/lib/sqm"
+
+m = Map("sqm", translate("Smart Queue Management"),
+       translate("With <abbr title=\"Smart Queue Management\">SQM</abbr> you " ..
+               "can enable traffic shaping, better mixing (Fair Queueing)," ..
+               " active queue length management (AQM) " ..
+               " and prioritisation on one " ..
+               "network interface."))
+
+s = m:section(TypedSection, "queue", translate("Queues"))
+s:tab("tab_basic", translate("Basic Settings"))
+s:tab("tab_qdisc", translate("Queue Discipline"))
+s:tab("tab_linklayer", translate("Link Layer Adaptation"))
+s.addremove = true -- set to true to allow adding SQM instances in the GUI
+s.anonymous = true
+
+-- BASIC
+e = s:taboption("tab_basic", Flag, "enabled", translate("Enable"))
+e.rmempty = false
+
+n = s:taboption("tab_basic", ListValue, "interface", translate("Interface name"))
+-- sm lifted from luci-app-wol, the original implementation failed to show pppoe-ge00 type interface names
+for _, iface in ipairs(ifaces) do
+--     if iface:is_up() then
+--     n:value(iface:name())
+--     end
+       if iface ~= "lo" then 
+               n:value(iface) 
+       end
+end
+n.rmempty = false
+
+
+dl = s:taboption("tab_basic", Value, "download", translate("Download speed (kbit/s) (ingress):"))
+dl.datatype = "and(uinteger,min(0))"
+dl.rmempty = false
+
+ul = s:taboption("tab_basic", Value, "upload", translate("Upload speed (kbit/s) (egress):"))
+ul.datatype = "and(uinteger,min(0))"
+ul.rmempty = false
+
+-- QDISC
+
+c = s:taboption("tab_qdisc", ListValue, "qdisc", translate("Queueing discipline"))
+c:value("fq_codel", "fq_codel ("..translate("default")..")")
+c:value("efq_codel")
+c:value("nfq_codel")
+c:value("sfq")
+c:value("codel")
+c:value("ns2_codel")
+c:value("pie")
+c:value("sfq")
+c.default = "fq_codel"
+c.rmempty = false
+
+local qos_desc = ""
+sc = s:taboption("tab_qdisc", ListValue, "script", translate("Queue setup script"))
+for file in fs.dir(path) do
+  if string.find(file, ".qos$") then
+    sc:value(file)
+  end
+  if string.find(file, ".qos.help$") then
+    fh = io.open(path .. "/" .. file, "r")
+    qos_desc = qos_desc .. "<p><b>" .. file:gsub(".help$", "") .. ":</b><br />" .. fh:read("*a") .. "</p>"
+  end
+end
+sc.default = "simple.qos"
+sc.rmempty = false
+sc.description = qos_desc
+
+ad = s:taboption("tab_qdisc", Flag, "qdisc_advanced", translate("Show Advanced Configuration"))
+ad.default = false
+ad.rmempty = true
+
+squash_dscp  = s:taboption("tab_qdisc", ListValue, "squash_dscp", translate("Squash DSCP on inbound packets (ingress):"))
+squash_dscp:value("1", "SQUASH")
+squash_dscp:value("0", "DO NOT SQUASH")
+squash_dscp.default = "1"
+squash_dscp.rmempty = true
+squash_dscp:depends("qdisc_advanced", "1")
+
+squash_ingress = s:taboption("tab_qdisc", ListValue, "squash_ingress", translate("Ignore DSCP on ingress:"))
+squash_ingress:value("1", "Ignore")
+squash_ingress:value("0", "Allow")
+squash_ingress.default = "1"
+squash_ingress.rmempty = true
+squash_ingress:depends("qdisc_advanced", "1")
+
+iecn = s:taboption("tab_qdisc", ListValue, "ingress_ecn", translate("Explicit congestion notification (ECN) status on inbound packets (ingress):"))
+iecn:value("ECN", "ECN ("..translate("default")..")")
+iecn:value("NOECN")
+iecn.default = "ECN"
+iecn.rmempty = true
+iecn:depends("qdisc_advanced", "1")
+
+eecn = s:taboption("tab_qdisc", ListValue, "egress_ecn", translate("Explicit congestion notification (ECN) status on outbound packets (egress)."))
+eecn:value("NOECN", "NOECN ("..translate("default")..")")
+eecn:value("ECN")
+eecn.default = "NOECN"
+eecn.rmempty = true
+eecn:depends("qdisc_advanced", "1")
+
+ad2 = s:taboption("tab_qdisc", Flag, "qdisc_really_really_advanced", translate("Show Dangerous Configuration"))
+ad2.default = false
+ad2.rmempty = true
+ad2:depends("qdisc_advanced", "1")
+
+ilim = s:taboption("tab_qdisc", Value, "ilimit", translate("Hard limit on ingress queues; leave empty for default."))
+-- ilim.default = 1000
+ilim.isnumber = true
+ilim.datatype = "and(uinteger,min(0))"
+ilim.rmempty = true
+ilim:depends("qdisc_really_really_advanced", "1")
+
+elim = s:taboption("tab_qdisc", Value, "elimit", translate("Hard limit on egress queues; leave empty for default."))
+-- elim.default = 1000
+elim.datatype = "and(uinteger,min(0))"
+elim.rmempty = true
+elim:depends("qdisc_really_really_advanced", "1")
+
+
+itarg = s:taboption("tab_qdisc", Value, "itarget", translate("Latency target for ingress, e.g 5ms [units: s, ms, or  us]; leave empty for default, or auto for automatic selection."))
+itarg.datatype = "string"
+itarg.rmempty = true
+itarg:depends("qdisc_really_really_advanced", "1")
+
+etarg = s:taboption("tab_qdisc", Value, "etarget", translate("Latency target for egress, e.g. 5ms [units: s, ms, or  us]; leave empty for default, or auto for automatic selection."))
+etarg.datatype = "string"
+etarg.rmempty = true
+etarg:depends("qdisc_really_really_advanced", "1")
+
+
+
+iqdisc_opts = s:taboption("tab_qdisc", Value, "iqdisc_opts", translate("Advanced option string to pass to the ingress queueing disciplines; no error checking, use very carefully."))
+iqdisc_opts.rmempty = true
+iqdisc_opts:depends("qdisc_really_really_advanced", "1")
+
+eqdisc_opts = s:taboption("tab_qdisc", Value, "eqdisc_opts", translate("Advanced option string to pass to the egress queueing disciplines; no error checking, use very carefully."))
+eqdisc_opts.rmempty = true
+eqdisc_opts:depends("qdisc_really_really_advanced", "1")
+
+-- LINKLAYER
+ll = s:taboption("tab_linklayer", ListValue, "linklayer", translate("Which link layer to account for:"))
+ll:value("none", "none ("..translate("default")..")")
+ll:value("ethernet", "Ethernet with overhead: select for e.g. VDSL2.")
+ll:value("atm", "ATM: select for e.g. ADSL1, ADSL2, ADSL2+.")
+-- ll:value("adsl")    -- reduce the options
+ll.default = "none"
+
+po = s:taboption("tab_linklayer", Value, "overhead", translate("Per Packet Overhead (byte):"))
+po.datatype = "and(integer,min(-1500))"
+po.default = 0
+po.isnumber = true
+po.rmempty = true
+po:depends("linklayer", "ethernet")
+-- po:depends("linklayer", "adsl")
+po:depends("linklayer", "atm")
+
+
+adll = s:taboption("tab_linklayer", Flag, "linklayer_advanced", translate("Show Advanced Linklayer Options, (only needed if MTU > 1500)"))
+adll.rmempty = true
+adll:depends("linklayer", "ethernet")
+-- adll:depends("linklayer", "adsl")
+adll:depends("linklayer", "atm")
+
+smtu = s:taboption("tab_linklayer", Value, "tcMTU", translate("Maximal Size for size and rate calculations, tcMTU (byte); needs to be >= interface MTU + overhead:"))
+smtu.datatype = "and(uinteger,min(0))"
+smtu.default = 2047
+smtu.isnumber = true
+smtu.rmempty = true
+smtu:depends("linklayer_advanced", "1")
+
+stsize = s:taboption("tab_linklayer", Value, "tcTSIZE", translate("Number of entries in size/rate tables, TSIZE; for ATM choose TSIZE = (tcMTU + 1) / 16:"))
+stsize.datatype = "and(uinteger,min(0))"
+stsize.default = 128
+stsize.isnumber = true
+stsize.rmempty = true
+stsize:depends("linklayer_advanced", "1")
+
+smpu = s:taboption("tab_linklayer", Value, "tcMPU", translate("Minimal packet size, MPU (byte); needs to be > 0 for ethernet size tables:"))
+smpu.datatype = "and(uinteger,min(0))"
+smpu.default = 0
+smpu.isnumber = true
+smpu.rmempty = true
+smpu:depends("linklayer_advanced", "1")
+
+lla = s:taboption("tab_linklayer", ListValue, "linklayer_adaptation_mechanism", translate("Which linklayer adaptation mechanism to use; for testing only"))
+lla:value("htb_private")
+lla:value("tc_stab", "tc_stab ("..translate("default")..")")
+lla.default = "tc_stab"
+lla.rmempty = true
+lla:depends("linklayer_advanced", "1")
+
+-- PRORITIES?
+
+return m
diff --git a/net/luci-app-sqm/files/sqm-controller.lua b/net/luci-app-sqm/files/sqm-controller.lua
new file mode 100644 (file)
index 0000000..d36f5fd
--- /dev/null
@@ -0,0 +1,26 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2008 Steven Barth <steven@midlink.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+]]--
+
+module("luci.controller.sqm", package.seeall)
+
+function index()
+       if not nixio.fs.access("/etc/config/sqm") then
+               return
+       end
+       
+       local page
+
+       page = entry({"admin", "network", "sqm"}, cbi("sqm"), _("SQM QoS"))
+       page.dependent = true
+end
diff --git a/net/luci-app-sqm/files/uci-defaults-sqm b/net/luci-app-sqm/files/uci-defaults-sqm
new file mode 100644 (file)
index 0000000..cd9e7b2
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+       delete ucitrack.@sqm[-1]
+       add ucitrack sqm
+       set ucitrack.@sqm[-1].init=sqm
+        add_list ucitrack.@firewall[0].affects=sqm
+       commit ucitrack
+EOF
+
+rm -f /tmp/luci-indexcache
+exit 0
diff --git a/net/luci-proto-openconnect/Makefile b/net/luci-proto-openconnect/Makefile
deleted file mode 100644 (file)
index a7b0d35..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#    Copyright (C) 2014 Nikos Mavrogiannopoulos
-#
-#    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.
-#
-#    The full GNU General Public License is included in this distribution in
-#    the file called "COPYING".
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=luci-proto-openconnect
-PKG_RELEASE:=1
-
-PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/luci-proto-openconnect
-  SECTION:=luci
-  CATEGORY:=LuCI
-  SUBMENU:=6. Protocols
-  TITLE:= OpenConnect VPN protocol configuration
-  DEPENDS:=+luci-mod-admin-full +luci-lib-nixio +openconnect
-  MAINTAINER:= Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-endef
-
-define Package/luci-proto-openconnect/description
-       openconnect web module for LuCi web interface
-endef
-
-define Build/Prepare
-endef
-
-define Build/Configure
-endef
-
-define Build/Compile
-endef
-
-# Fixme: How can we add <%+openconnect_status%> in view/admin_status/index.htm?
-define Package/luci-proto-openconnect/install
-       $(CP) ./files/* $(1)/
-endef
-
-$(eval $(call BuildPackage,luci-proto-openconnect))
-
diff --git a/net/luci-proto-openconnect/files/usr/lib/lua/luci/model/cbi/admin_network/proto_openconnect.lua b/net/luci-proto-openconnect/files/usr/lib/lua/luci/model/cbi/admin_network/proto_openconnect.lua
deleted file mode 100644 (file)
index 2e2eace..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-
-Copyright 2014 Nikos Mavrogiannopoulos <nmav@gnutls.org>
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-]]--
-
-local map, section, net = ...
-
-local server, username, password, cert, ca
-local oc_cert_file, oc_key_file, oc_ca_file
-
-local ifc = net:get_interface():name()
-
-oc_cert_file = "/etc/openconnect/user-cert-" .. ifc .. ".pem"
-oc_key_file = "/etc/openconnect/user-key-" .. ifc .. ".pem"
-oc_ca_file = "/etc/openconnect/ca-" .. ifc .. ".pem"
-
-server = section:taboption("general", Value, "server", translate("VPN Server"))
-server.datatype = "host"
-
-port = section:taboption("general", Value, "port", translate("VPN Server port"))
-port.placeholder = "443"
-port.datatype    = "port"
-
-section:taboption("general", Value, "serverhash", translate("VPN Server's certificate SHA1 hash"))
-
-section:taboption("general", Value, "authgroup", translate("AuthGroup"))
-
-username = section:taboption("general", Value, "username", translate("Username"))
-password = section:taboption("general", Value, "password", translate("Password"))
-password.password = true
-
-
-cert = section:taboption("advanced", Value, "usercert", translate("User certificate (PEM encoded)"))
-cert.template = "cbi/tvalue"
-cert.rows = 10
-
-function cert.cfgvalue(self, section)
-       return nixio.fs.readfile(oc_cert_file)
-end
-
-function cert.write(self, section, value)
-       value = value:gsub("\r\n?", "\n")
-       nixio.fs.writefile(oc_cert_file, value)
-end
-
-cert = section:taboption("advanced", Value, "userkey", translate("User key (PEM encoded)"))
-cert.template = "cbi/tvalue"
-cert.rows = 10
-
-function cert.cfgvalue(self, section)
-       return nixio.fs.readfile(oc_key_file)
-end
-
-function cert.write(self, section, value)
-       value = value:gsub("\r\n?", "\n")
-       nixio.fs.writefile(oc_key_file, value)
-end
-
-
-ca = section:taboption("advanced", Value, "ca", translate("CA certificate; if empty it will be saved after the first connection."))
-ca.template = "cbi/tvalue"
-ca.rows = 10
-
-function ca.cfgvalue(self, section)
-       return nixio.fs.readfile(oc_ca_file)
-end
-
-function ca.write(self, section, value)
-       value = value:gsub("\r\n?", "\n")
-       nixio.fs.writefile(oc_ca_file, value)
-end
diff --git a/net/luci-proto-openconnect/files/usr/lib/lua/luci/model/network/proto_openconnect.lua b/net/luci-proto-openconnect/files/usr/lib/lua/luci/model/network/proto_openconnect.lua
deleted file mode 100644 (file)
index f5c16c7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
---[[
-LuCI - Network model - dhcpv6 protocol extension
-
-Copyright 2012 David Woodhouse
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-]]--
-
-local netmod = luci.model.network
-local interface = luci.model.network.interface
-local proto = netmod:register_protocol("openconnect")
-
-function proto.get_i18n(self)
-       return luci.i18n.translate("OpenConnect (CISCO AnyConnect)")
-end
-
-function proto.ifname(self)
-       return "vpn-" .. self.sid
-end
-
-function proto.get_interface(self)
-       return interface(self:ifname(), self)
-end
-
-function proto.opkg_package(self)
-       return "openconnect"
-end
-
-function proto.is_installed(self)
-       return nixio.fs.access("/lib/netifd/proto/openconnect.sh")
-end
-
-function proto.is_floating(self)
-       return true
-end
-
-function proto.is_virtual(self)
-       return true
-end
-
-function proto.get_interfaces(self)
-       return nil
-end
-
-function proto.contains_interface(self, ifc)
-        return (netmod:ifnameof(ifc) == self:ifname())
-
-end
-
-netmod:register_pattern_virtual("^vpn-%w")
index 7e36ceb5e3a7cfda0d64b687ee4013d9bff00a26..91e7e982717794de5b17ece9e2f0aedf440f6392 100644 (file)
@@ -8,13 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mDNSResponder
-PKG_VERSION:=544
-PKG_RELEASE:=4
+PKG_VERSION:=561.1.1
+PKG_RELEASE:=1
 
 PKG_SOURCE:=mDNSResponder-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://opensource.apple.com/tarballs/mDNSResponder/
-PKG_MD5SUM:=39142ab70bd82a096801ce346f86cbab
+PKG_MD5SUM:=d4b56e22798d6f45e29b42cd6720ab6e
 PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
+PKG_LICENSE:=Apache-2.0
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/mDNSResponder-$(PKG_VERSION)
 
@@ -124,10 +125,6 @@ define Build/InstallDev
        $(CP) $(PKG_BUILD_DIR)/mDNSPosix/build/prod/*.so* $(1)/usr/lib/
 endef
 
-define Package/mdns-utils/conffile
-  /etc/init.d/mDNSResponder
-endef
-
 define Package/mdns-utils/install
        $(INSTALL_DIR) $(1)/usr/bin/
        $(CP) $(PKG_INSTALL_DIR)/usr/bin/dns-sd $(1)/usr/bin/
index f824d5e26b0df6498f13831e5f72fd741d141e8d..ad4eaee445b0656fc32b9cfffc4185fade3b8fce 100644 (file)
@@ -56,7 +56,7 @@
  LINKOPTS = -lsocket -lnsl -lresolv
  JAVACFLAGS_OS += -I$(JDK)/include/solaris
  ifneq ($(DEBUG),1)
-@@ -147,7 +148,8 @@ CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp 
+@@ -147,7 +148,8 @@ CFLAGS_OS = -DHAVE_IPV6 -no-cpp-precomp
        -D__MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 \
        -D__APPLE_USE_RFC_2292 #-Wunreachable-code
  CC = gcc
index 851dd31dfede2ca6e245ba3b97dbb4abb7e242bc..ea598a75d6a2e6014e1eed99548613497a2eb740 100644 (file)
@@ -1,6 +1,3 @@
-diff --git a/.gitignore b/.gitignore
-new file mode 100644
-index 0000000..920cdfc
 --- /dev/null
 +++ b/.gitignore
 @@ -0,0 +1,4 @@
@@ -8,8 +5,6 @@ index 0000000..920cdfc
 +mDNSPosix/build
 +mDNSPosix/objects
 +
-diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c
-index 88b3292..e86a6c7 100644
 --- a/mDNSPosix/PosixDaemon.c
 +++ b/mDNSPosix/PosixDaemon.c
 @@ -37,6 +37,11 @@
@@ -75,11 +70,9 @@ index 88b3292..e86a6c7 100644
      if (mStatus_NoError == err)
          err = MainLoop(&mDNSStorage);
  
-diff --git a/mDNSPosix/Responder.c b/mDNSPosix/Responder.c
-index 3996b7b..e58d8eb 100755
 --- a/mDNSPosix/Responder.c
 +++ b/mDNSPosix/Responder.c
-@@ -603,7 +603,8 @@ static mStatus RegisterServicesInFile(const char *filePath)
+@@ -603,7 +603,8 @@ static mStatus RegisterServicesInFile(co
          status = mStatus_UnknownErr;
      }
  
@@ -89,11 +82,9 @@ index 3996b7b..e58d8eb 100755
  
      return status;
  }
-diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
-index 953bf64..4e481ea 100755
 --- a/mDNSPosix/mDNSPosix.c
 +++ b/mDNSPosix/mDNSPosix.c
-@@ -136,7 +136,7 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA
+@@ -136,7 +136,7 @@ mDNSlocal void SockAddrTomDNSAddr(const
  
  // mDNS core calls this routine when it needs to send a packet.
  mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
@@ -102,7 +93,7 @@ index 953bf64..4e481ea 100755
                                         mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass)
  {
      int err = 0;
-@@ -574,9 +574,17 @@ mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
+@@ -574,9 +574,17 @@ mDNSlocal void FreePosixNetworkInterface
  {
      assert(intf != NULL);
      if (intf->intfName != NULL) free((void *)intf->intfName);
@@ -122,7 +113,7 @@ index 953bf64..4e481ea 100755
  #endif
      free(intf);
  }
-@@ -703,6 +711,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
+@@ -703,6 +711,29 @@ mDNSlocal int SetupSocket(struct sockadd
              if (err < 0) { err = errno; perror("setsockopt - IP_MULTICAST_TTL"); }
          }
  
@@ -152,7 +143,7 @@ index 953bf64..4e481ea 100755
          // And start listening for packets
          if (err == 0)
          {
-@@ -784,6 +815,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
+@@ -784,6 +815,29 @@ mDNSlocal int SetupSocket(struct sockadd
              if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_HOPS"); }
          }
  
@@ -182,7 +173,7 @@ index 953bf64..4e481ea 100755
          // And start listening for packets
          if (err == 0)
          {
-@@ -815,7 +869,12 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
+@@ -815,7 +869,12 @@ mDNSlocal int SetupSocket(struct sockadd
      }
  
      // Clean up
@@ -196,7 +187,7 @@ index 953bf64..4e481ea 100755
      assert((err == 0) == (*sktPtr != -1));
      return err;
  }
-@@ -994,7 +1053,7 @@ mDNSlocal mStatus OpenIfNotifySocket(int *pFD)
+@@ -994,7 +1053,7 @@ mDNSlocal mStatus OpenIfNotifySocket(int
      /* Subscribe the socket to Link & IP addr notifications. */
      mDNSPlatformMemZero(&snl, sizeof snl);
      snl.nl_family = AF_NETLINK;
@@ -205,7 +196,7 @@ index 953bf64..4e481ea 100755
      ret = bind(sock, (struct sockaddr *) &snl, sizeof snl);
      if (0 == ret)
          *pFD = sock;
-@@ -1072,11 +1131,18 @@ mDNSlocal mDNSu32       ProcessRoutingNotification(int sd)
+@@ -1072,11 +1131,18 @@ mDNSlocal mDNSu32       ProcessRoutingNo
          PrintNetLinkMsg(pNLMsg);
  #endif
  
@@ -226,7 +217,7 @@ index 953bf64..4e481ea 100755
  
          // Advance pNLMsg to the next message in the buffer
          if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE)
-@@ -1247,8 +1313,12 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
+@@ -1247,8 +1313,12 @@ mDNSexport mStatus mDNSPlatformInit(mDNS
      if (err == mStatus_NoError) err = SetupSocket(&sa, zeroIPPort, 0, &m->p->unicastSocket6);
  #endif
  
@@ -239,7 +230,7 @@ index 953bf64..4e481ea 100755
  
      // Tell mDNS core about DNS Servers
      mDNS_Lock(m);
-@@ -1281,9 +1351,17 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
+@@ -1281,9 +1351,17 @@ mDNSexport void mDNSPlatformClose(mDNS *
  {
      assert(m != NULL);
      ClearInterfaceList(m);
@@ -259,7 +250,7 @@ index 953bf64..4e481ea 100755
  #endif
  }
  
-@@ -1533,14 +1611,14 @@ mDNSexport mStatus    mDNSPlatformClearSPSMACAddr(void)
+@@ -1533,14 +1611,14 @@ mDNSexport mStatus    mDNSPlatformClearS
  mDNSexport mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock)
  {
      (void) sock; // unused
@@ -276,8 +267,6 @@ index 953bf64..4e481ea 100755
      return mDNSfalse;
  }
  
-diff --git a/mDNSPosix/mDNSUNP.c b/mDNSPosix/mDNSUNP.c
-index b392fc7..9f85e0e 100755
 --- a/mDNSPosix/mDNSUNP.c
 +++ b/mDNSPosix/mDNSUNP.c
 @@ -61,154 +61,86 @@
@@ -286,7 +275,9 @@ index b392fc7..9f85e0e 100755
  #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
 -#include <netdb.h>
 -#include <arpa/inet.h>
--
++#include <sys/types.h>
++#include <ifaddrs.h>
 -/* Converts a prefix length to IPv6 network mask */
 -void plen_to_mask(int plen, char *addr) {
 -    int i;
@@ -301,9 +292,6 @@ index b392fc7..9f85e0e 100755
 -        plen -= ones_in_block;
 -    }
 -}
-+#include <sys/types.h>
-+#include <ifaddrs.h>
-+
  
 -/* Gets IPv6 interface information from the /proc filesystem in linux*/
 -struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
@@ -330,45 +318,12 @@ index b392fc7..9f85e0e 100755
 -    ifihead = NULL;
 -    ifipnext = &ifihead;
 -    lastname[0] = 0;
-+  struct ifaddrs *ifap, *ifa;
-+  struct ifi_info *ifi = NULL, *head = NULL;
+-
 -    if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
 -        sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
 -        if (sockfd < 0) {
 -            goto gotError;
-+  /* doaliases seems always true in the calls in current code */
-+  assert(doaliases);
-+
-+  if (getifaddrs(&ifap) < 0)
-+    {
-+      return NULL;
-+    }
-+  for (ifa = ifap ; ifa ; ifa = ifa->ifa_next)
-+    {
-+      /* Care only about IPv6 addresses on non-point-to-point links. */
-+      if (!ifa->ifa_addr
-+          || ifa->ifa_addr->sa_family != AF_INET6)
-+        continue;
-+      ifi = calloc(1, sizeof(*ifi));
-+      if (!ifi)
-+        break;
-+      strncpy(ifi->ifi_name, ifa->ifa_name, IFI_NAME);
-+      /* We ignore ifi_{haddr,hlen}, everyone else does too */
-+      ifi->ifi_flags = ifa->ifa_flags;
-+      /* We ignore ifi_myflags; IFI_ALIAS isn't used anywhere */
-+      ifi->ifi_index = if_nametoindex(ifa->ifa_name);
-+      if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6))))
-+        break;
-+      memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
-+
-+      if (ifa->ifa_netmask)
-+        {
-+          if (!(ifi->ifi_netmask = malloc(sizeof(struct sockaddr_in6))))
-+            break;
-+          memcpy(ifi->ifi_netmask, ifa->ifa_netmask,
-+                 sizeof(struct sockaddr_in6));
-         }
+-        }
 -        while (fscanf(fp,
 -                      "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
 -                      addr[0],addr[1],addr[2],addr[3],
@@ -386,7 +341,7 @@ index b392fc7..9f85e0e 100755
 -            if (ifi == NULL) {
 -                goto gotError;
 -            }
+-
 -            ifipold   = *ifipnext;       /* need this later */
 -            ifiptr    = ifipnext;
 -            *ifipnext = ifi;            /* prev points to this new one */
@@ -409,10 +364,7 @@ index b392fc7..9f85e0e 100755
 -                goto gotError;
 -            }
 -            memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
-+      if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6))))
-+        break;
-+      memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
+-
 -            /* Add netmask of the interface */
 -            char ipv6addr[INET6_ADDRSTRLEN];
 -            plen_to_mask(plen, ipv6addr);
@@ -460,6 +412,8 @@ index b392fc7..9f85e0e 100755
 -        }
 -    }
 -    goto done;
++  struct ifaddrs *ifap, *ifa;
++  struct ifi_info *ifi = NULL, *head = NULL;
  
 -gotError:
 -    if (ifihead != NULL) {
@@ -469,10 +423,47 @@ index b392fc7..9f85e0e 100755
 -    if (res0 != NULL) {
 -        freeaddrinfo(res0);
 -        res0=NULL;
--    }
++  /* doaliases seems always true in the calls in current code */
++  assert(doaliases);
++
++  if (getifaddrs(&ifap) < 0)
++    {
++      return NULL;
+     }
 -done:
 -    if (sockfd != -1) {
 -        assert(close(sockfd) == 0);
++  for (ifa = ifap ; ifa ; ifa = ifa->ifa_next)
++    {
++      /* Care only about IPv6 addresses on non-point-to-point links. */
++      if (!ifa->ifa_addr
++          || ifa->ifa_addr->sa_family != AF_INET6)
++        continue;
++      ifi = calloc(1, sizeof(*ifi));
++      if (!ifi)
++        break;
++      strncpy(ifi->ifi_name, ifa->ifa_name, IFI_NAME);
++      /* We ignore ifi_{haddr,hlen}, everyone else does too */
++      ifi->ifi_flags = ifa->ifa_flags;
++      /* We ignore ifi_myflags; IFI_ALIAS isn't used anywhere */
++      ifi->ifi_index = if_nametoindex(ifa->ifa_name);
++      if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6))))
++        break;
++      memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
++
++      if (ifa->ifa_netmask)
++        {
++          if (!(ifi->ifi_netmask = malloc(sizeof(struct sockaddr_in6))))
++            break;
++          memcpy(ifi->ifi_netmask, ifa->ifa_netmask,
++                 sizeof(struct sockaddr_in6));
++        }
++
++      if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6))))
++        break;
++      memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
++
++
 +      if (ifa->ifa_flags & IFF_POINTOPOINT && ifa->ifa_dstaddr)
 +        {
 +          if (!(ifi->ifi_dstaddr = malloc(sizeof(struct sockaddr_in6))))
@@ -506,7 +497,7 @@ index b392fc7..9f85e0e 100755
  #endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
  
  struct ifi_info *get_ifi_info(int family, int doaliases)
-@@ -229,7 +161,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
+@@ -229,7 +161,7 @@ struct ifi_info *get_ifi_info(int family
  #endif
  
  #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
@@ -515,8 +506,6 @@ index b392fc7..9f85e0e 100755
  #endif
  
      sockfd = -1;
-diff --git a/mDNSPosix/mDNSUNP.h b/mDNSPosix/mDNSUNP.h
-index cc81b7d..e710087 100755
 --- a/mDNSPosix/mDNSUNP.h
 +++ b/mDNSPosix/mDNSUNP.h
 @@ -97,8 +97,7 @@ struct ifi_info {
@@ -529,8 +518,6 @@ index cc81b7d..e710087 100755
  #endif
  
  #if defined(AF_INET6) && HAVE_IPV6
-diff --git a/mDNSShared/dnsextd_parser.y b/mDNSShared/dnsextd_parser.y
-index 18c5990..d4b63ce 100644
 --- a/mDNSShared/dnsextd_parser.y
 +++ b/mDNSShared/dnsextd_parser.y
 @@ -15,6 +15,8 @@
index ce81c6eddb37257f912ed815bd5b4abe6008e9ce..91ae4da644ab1c859718e6fcd7dc2b59d32c1327 100644 (file)
@@ -9,12 +9,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=memcached
-PKG_VERSION:=1.4.20
+PKG_VERSION:=1.4.22
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://memcached.org/files
-PKG_MD5SUM:=92f702bcb28d7bec8fdf9418360fc062
+PKG_MD5SUM:=2b7eefa17c811998f4cd55bfabc12b8e
 PKG_INSTALL:=1
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
 PKG_LICENSE:=permissive free software license
index 586d315346f9553c5f930bd11e310cf50bdb31df..a8e92f204df1913e41ca5f5937face353653109a 100644 (file)
@@ -9,14 +9,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mosquitto
-PKG_VERSION:=1.3.4
+PKG_VERSION:=1.3.5
 PKG_RELEASE:=1
 PKG_LICENSE:=BSD-3-Clause
-PKG_LICENSE_FILE:=LICENSE.txt
+PKG_LICENSE_FILES:=LICENSE.txt
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://mosquitto.org/files/source/
-PKG_MD5SUM:=9d729849efd74c6e3eee17a4a002e1e9
+PKG_MD5SUM:=55094ad4dc7c7985377f43d4fc3d09da
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 
 include $(INCLUDE_DIR)/package.mk
@@ -30,6 +30,7 @@ define Package/$(PKG_NAME)/default
   URL:=http://www.mosquitto.org/
   MAINTAINER:=Karl Palsson <karlp@remake.is>
   DEPENDS:= +librt
+  USERID:=mosquitto=200:mosquitto=200
 endef
 
 define Package/$(PKG_NAME)
index aafa105acb9e1cce74c9475b799021d53415fc26..2b3a93a7f0261c9025943b01677ab97ad01227cc 100755 (executable)
@@ -14,7 +14,6 @@ SERVICE_DAEMONIZE=1
 SERVICE_WRITE_PID=1
 
 start() {
-        user_exists mosquitto 200 || user_add mosquitto 200
         if [ "$USE_UCI_CONFIG" -eq 1 ]; then
             CONF=/tmp/mosquitto.converted.$$.conf
             mosquitto.uci.convert -f $CONF
index 0d421d0c4a332593c50ecda731106516d73b7dd1..7214991be5cb4729808915b96f7a5a4b6d4ce2b9 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mtr
-PKG_VERSION:=0.85
+PKG_VERSION:=0.86
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=ftp://ftp.bitwizard.nl/mtr
-PKG_MD5SUM:=5e665c617e5659b6ec3e201ee7488eb1
+PKG_MD5SUM:=8d63592c9d4579ef20cf491b41843eb2
 PKG_LICENSE:=GPL-2.0+
 PKG_LICENSE_FILES:=COPYING
 
index 50c7230461b44b2a3dbf60a4cfb2b153078bd775..e50b7fbff5022ba8de0f278e1e2b34cda8f6f247 100644 (file)
@@ -1,6 +1,6 @@
 --- a/dns.c
 +++ b/dns.c
-@@ -918,6 +918,507 @@ void restell(char *s)
+@@ -921,6 +921,507 @@ void restell(char *s)
    fputs("\r",stderr);
  }
  
index aeec4edcce44803ab5487ce1fb38935a6e813591..2d9883b4afb16729b530edbb94702913659b4412 100644 (file)
@@ -1,6 +1,6 @@
 --- a/dns.c
 +++ b/dns.c
-@@ -1305,28 +1305,6 @@ res_nmkquery(res_state statp,
+@@ -1308,28 +1308,6 @@ res_nmkquery(res_state statp,
                  return (-1);
          memset(buf, 0, HFIXEDSZ);
          hp = (HEADER *) buf;
diff --git a/net/mtr/patches/521-glib-dependency-fixes.patch b/net/mtr/patches/521-glib-dependency-fixes.patch
deleted file mode 100644 (file)
index 93c9804..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-From 25a2456845b341066adb5f9fcc553dec12a751b7 Mon Sep 17 00:00:00 2001
-From: Roger Wolff <R.E.Wolff@BitWizard.nl>
-Date: Fri, 5 Jul 2013 11:40:02 +0200
-Subject: [PATCH] glib dependency fixes.
-
----
- configure.ac | 32 ++++++++++++++------------------
- mtr.c        |  5 +++++
- report.c     |  2 ++
- 3 files changed, 21 insertions(+), 18 deletions(-)
-
---- a/configure.ac
-+++ b/configure.ac
-@@ -42,25 +42,22 @@ AC_ARG_WITH(gtk,
- [  --without-gtk           Do not try to use GTK+ at all],
- WANTS_GTK=$withval, WANTS_GTK=yes)
--AC_ARG_WITH(glib,
--[  --without-glib          Do not try to use glib at all],
--WANTS_GLIB=$withval, WANTS_GLIB=yes)
--
- AC_ARG_WITH([ipinfo],
- [  --without-ipinfo        Do not try to use ipinfo lookup at all],
--[case "${withval}" in
--  yes) ipinfo=true ;;
--  no)  ipinfo=false ;;
--  *) AC_MSG_ERROR([bad value ${withval} for --with-ipinfo]) ;;
--esac],[ipinfo=true])
--AM_CONDITIONAL([IPINFO], [test x$ipinfo = xtrue])
--if test "x$ipinfo" = "xfalse"; then
--      AC_DEFINE([NO_IPINFO], [1], [Define to disable ipinfo lookup])
--fi
-+[ipinfo="${withval}"], [ipinfo=yes])
-+AM_CONDITIONAL([IPINFO], [test x$ipinfo = xyes])
- AC_ARG_ENABLE(ipv6,
- [  --disable-ipv6          Do not enable IPv6],
- WANTS_IPV6=$enableval, WANTS_IPV6=yes)
-+
-+m4_ifndef([AM_PATH_GTK_2_0], [m4_defun([AM_PATH_GTK_2_0], [AC_MSG_ERROR([
-+  Could not locate the gtk2 automake macros, these are usually located in
-+    .../share/aclocal/gtk-2.0.m4
-+  Before running bootstrap try setting the environment variable
-+    ACLOCAL_PATH="/own/dir"
-+  or configure --without-gtk.
-+])])])
-    
- if test "x$WANTS_GTK" = "xyes"; then
-         AM_PATH_GTK_2_0(2.6.0, CFLAGS="$CFLAGS $GTK_CFLAGS"
-@@ -71,11 +68,10 @@ if test "x$WANTS_GTK" = "xyes"; then
- else
-       AC_DEFINE(NO_GTK)
-       GTK_OBJ=""
--      if test "x$WANTS_GLIB" = "xyes"; then
--              PKG_CHECK_MODULES([GLIB], [glib-2.0])
--      else
--              AC_DEFINE(NO_GLIB, 1, [Define if you don't have the glib libraries available.])
--      fi
-+fi
-+
-+if test "x$ipinfo" = "xno"; then
-+      AC_DEFINE([NO_IPINFO], [1], [Define to disable ipinfo lookup])
- fi
- AC_CHECK_FUNC(socket, , 
---- a/mtr.c
-+++ b/mtr.c
-@@ -464,6 +464,11 @@ void parse_arg (int argc, char **argv)
-     case 'z':
-       ipinfo_no = 0;
-       break;
-+#else
-+    case 'y':
-+    case 'z':
-+      fprintf( stderr, "IPINFO not enabled.\n" );
-+      break;
- #endif
-     }
-   }
---- a/report.c
-+++ b/report.c
-@@ -340,6 +340,7 @@ void csv_close(time_t now)
-     snprint_addr(name, sizeof(name), addr);
-     int last = net_last(at);
-+#ifndef NO_IPINFO
-     if(!ipinfo_no) {
-       char* fmtinfo = fmt_ipinfo(addr);
-       if (fmtinfo != NULL) fmtinfo = trim(fmtinfo);
-@@ -349,6 +350,7 @@ void csv_close(time_t now)
-       printf("MTR.%s;%lu;%s;%s;%d;%s;%d", MTR_VERSION, now, "OK", Hostname,
-              at+1, name, last);
-     }
-+#endif
-     for( i=0; i<MAXFLD; i++ ) {
-       j = fld_index[fld_active[j]];
index 7839ce207220d92c30fdc2de5c0217bdc89fc4cf..c0f720bae5f3978e5ab3ca7db18562b69847bf46 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mwan3
 PKG_VERSION:=1.5
-PKG_RELEASE:=8
+PKG_RELEASE:=10
 PKG_MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
 PKG_LICENSE:=GPLv2
 
@@ -32,14 +32,14 @@ interfaces, connection tracking and an easy to manage traffic ruleset.
 endef
 
 define Package/mwan3/conffiles
-   /etc/config/mwan3
+/etc/config/mwan3
 endef
 
 define Build/Compile
 endef
 
 define Package/mwan3/install
-   $(CP) ./files/* $(1)
+$(CP) ./files/* $(1)
 endef
 
 $(eval $(call BuildPackage,mwan3))
index ea00bd05fac11520e59c1fd3489a376d5af937a1..25044c4d396d96bd38eb90f700126dfc75492e73 100644 (file)
@@ -71,6 +71,10 @@ mwan3_set_connected_iptables()
                        $IPT -A mwan3_connected -d $connected_networks -j MARK --set-xmark 0xff00/0xff00
                done
 
+               for connected_networks in $($IP route list table 0 | awk '{print $2}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do
+                       $IPT -A mwan3_connected -d $connected_networks -j MARK --set-xmark 0xff00/0xff00
+               done
+
                $IPT -I mwan3_connected -d 224.0.0.0/3 -j MARK --set-xmark 0xff00/0xff00
                $IPT -I mwan3_connected -d 127.0.0.0/8 -j MARK --set-xmark 0xff00/0xff00
        fi
@@ -310,7 +314,7 @@ mwan3_ifupdown()
                done
 
                route_args=$($IP route list dev $DEVICE default | head -1 | sed '/.*via \([^ ]*\) .*$/!d;s//via \1/;q' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}')
-               route_args="nexthop $route_args dev $DEVICE"
+               route_args="$route_args dev $DEVICE"
        fi
 
        while [ "$(pgrep -f -o hotplug-call)" -ne $$ -a "$counter" -lt 60 ]; do
index 5d9f719f10619b4f651967bc58ff06b181dc7177..286603a85a51c12fdaa02d0e1ac4bef6eee33799 100755 (executable)
@@ -74,6 +74,7 @@ interfaces()
        
        check_iface_status()
        {
+               let iface_id++
                device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
 
                if [ -z "$device" ]; then
@@ -82,7 +83,6 @@ interfaces()
                fi
 
                config_get enabled "$1" enabled 0
-               let iface_id++
 
                if [ -n "$(ps -w | grep mwan3track | grep -v grep | sed '/.*\/usr\/sbin\/mwan3track \([^ ]*\) .*$/!d;s//\1/' | awk '$1 == "'$1'"')" ]; then
                        tracking="active"
index a89d0826b7ec1a997e86ca1562a7cb6e1b403a5d..2668b7b3e5dd457b7e3527e7347adbf3b4f53d68 100644 (file)
@@ -119,6 +119,16 @@ snmpd_exec_add() {
        config_get miboid "$cfg" miboid
        echo "exec $miboid $name $prog $args" >> $RUN_C
 }
+snmpd_disk_add() {
+        local cfg="$1"
+        local disk='disk'
+
+        config_get partition "$cfg" partition
+        [ -n "$partition" ] || return 0
+        config_get size "$cfg" size
+        [ -n "$size" ] || return 0
+        echo "$disk $partition $size" >> $RUN_C
+}
 start() {
        [ -d $LIB_D ] || mkdir -p $LIB_D
        [ -d $LOG_D ] || mkdir -p $LOG_D
@@ -136,7 +146,8 @@ start() {
        config_foreach snmpd_access_add access
        config_foreach snmpd_pass_add pass
        config_foreach snmpd_exec_add exec
-
+       config_foreach snmpd_disk_add disk
+       
        [ -f $DEFAULT ] && . $DEFAULT
        $DEBUG /usr/sbin/snmpd $OPTIONS
 }
diff --git a/net/netcat/Makefile b/net/netcat/Makefile
new file mode 100644 (file)
index 0000000..0248f0d
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=netcat
+PKG_VERSION:=0.7.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=0a29eff1736ddb5effd0b1ec1f6fe0ef
+PKG_MAINTAINER:=Adam Gensler <openwrt@a.gnslr.us>
+PKG_LICENSE:=GPL-2.0
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/netcat
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=A feature-rich network debugging and exploration tool.
+  URL:=http://netcat.sourceforge.net/
+endef
+
+define Package/netcat/description
+               Netcat is a featured networking utility which reads and writes data across network connections, using the TCP/IP protocol.
+       It is designed to be a reliable "back-end" tool that can be used directly or easily driven by other programs and scripts. At the same time, it is a feature-rich network debugging and exploration tool, since it can create almost any kind of connection you would need and has several interesting built-in capabilities.
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default, \
+               --disable-rpath \
+               --with-included-getopt \
+       )
+endef
+
+define Package/netcat/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/netcat \
+               $(1)/usr/bin
+endef
+
+define Package/netcat/postinst
+#!/bin/sh
+if [ -e $${IPKG_INSTROOT}/usr/bin/nc ]; then
+  rm -rf $${IPKG_INSTROOT}/usr/bin/nc;
+fi
+ln -s ./netcat $${IPKG_INSTROOT}/usr/bin/nc
+endef
+
+define Package/netcat/postrm
+#!/bin/sh
+rm $${IPKG_INSTROOT}/usr/bin/nc
+ln -s ../../bin/busybox $${IPKG_INSTROOT}/usr/bin/nc
+$${IPKG_INSTROOT}/usr/bin/nc 2>&1 | grep 'applet not found' > /dev/null 2>&1 && rm $${IPKG_INSTROOT}/usr/bin/nc
+exit 0
+endef
+
+
+$(eval $(call BuildPackage,netcat))
diff --git a/net/netcat/patches/001-netcat_flag_count.patch b/net/netcat/patches/001-netcat_flag_count.patch
new file mode 100644 (file)
index 0000000..44ee9e1
--- /dev/null
@@ -0,0 +1,22 @@
+Index: netcat-0.7.1/src/flagset.c
+===================================================================
+--- netcat-0.7.1.orig/src/flagset.c    2009-02-06 19:56:01.000000000 +0100
++++ netcat-0.7.1/src/flagset.c 2009-02-06 19:56:13.000000000 +0100
+@@ -134,7 +134,7 @@
+ int netcat_flag_count(void)
+ {
+-  register char c;
++  register unsigned char c;
+   register int i;
+   int ret = 0;
+@@ -154,7 +154,7 @@
+       Assumed that the bit number 1 is the sign, and that we will shift the
+       bit 1 (or the bit that takes its place later) until the the most right,
+       WHY it has to keep the wrong sign? */
+-      ret -= (c >> 7);
++      ret += (c >> 7);
+       c <<= 1;
+     }
+   }
index b5cfcd757b226a2fac98030cb9404a223343e9ad..60212f8bc1a986732517314a28657d4e10199890 100644 (file)
@@ -7,9 +7,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=nfs-kernel-server
-PKG_VERSION:=1.3.0
+PKG_VERSION:=1.3.2
 PKG_RELEASE:=1
-PKG_MD5SUM:=3ac3726eda563946d1f44ac3e5b61d56
+PKG_MD5SUM:=1e2f3c1ed468dee02d00c534c002ea10
 
 PKG_SOURCE_URL:=@SF/nfs
 PKG_SOURCE:=nfs-utils-$(PKG_VERSION).tar.bz2
@@ -77,6 +77,7 @@ CONFIGURE_ARGS += \
        --disable-gss \
        --disable-nfsv4 \
        --disable-nfsv41 \
+       --disable-ipv6 \
        --enable-static \
        --enable-shared \
        --disable-caps \
diff --git a/net/nfs-kernel-server/patches/100-nfs_utils_uclibc.patch b/net/nfs-kernel-server/patches/100-nfs_utils_uclibc.patch
deleted file mode 100644 (file)
index 5e4877e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
---- a/support/nfs/svc_socket.c
-+++ b/support/nfs/svc_socket.c
-@@ -40,10 +40,13 @@ int getservport(u_long number, const cha
-       char rpcdata[1024], servdata[1024];
-       struct rpcent rpcbuf, *rpcp;
-       struct servent servbuf, *servp = NULL;
--      int ret;
--
-+      int ret=0;
-+#ifndef __UCLIBC__
-       ret = getrpcbynumber_r(number, &rpcbuf, rpcdata, sizeof rpcdata,
-                               &rpcp);
-+#else
-+      rpcp = getrpcbynumber (number);
-+#endif
-       if (ret == 0 && rpcp != NULL) {
-               /* First try name.  */
-               ret = getservbyname_r(rpcp->r_name, proto, &servbuf, servdata,
---- a/utils/mountd/cache.c
-+++ b/utils/mountd/cache.c
-@@ -166,6 +166,7 @@ static void auth_unix_gid(FILE *f)
-       pw = getpwuid(uid);
-       if (!pw)
-               rv = -1;
-+#ifndef __UCLIBC__
-       else {
-               rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
-               if (rv == -1 && ngroups >= groups_len) {
-@@ -180,6 +181,7 @@ static void auth_unix_gid(FILE *f)
-                       }
-               }
-       }
-+#endif
-       qword_printuint(f, uid);
-       qword_printtimefrom(f, DEFAULT_TTL);
-       if (rv >= 0) {
diff --git a/net/nfs-kernel-server/patches/100-no_malloc_h.patch b/net/nfs-kernel-server/patches/100-no_malloc_h.patch
new file mode 100644 (file)
index 0000000..afe4c98
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/tools/rpcgen/rpc_cout.c
++++ b/tools/rpcgen/rpc_cout.c
+@@ -36,7 +36,6 @@ static char sccsid[] = "@(#)rpc_cout.c 1
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+-#include <malloc.h>
+ #include <ctype.h>
+ #include "rpc_parse.h"
+ #include "rpc_util.h"
diff --git a/net/nfs-kernel-server/patches/101-no_malloc_h.patch b/net/nfs-kernel-server/patches/101-no_malloc_h.patch
deleted file mode 100644 (file)
index afe4c98..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/tools/rpcgen/rpc_cout.c
-+++ b/tools/rpcgen/rpc_cout.c
-@@ -36,7 +36,6 @@ static char sccsid[] = "@(#)rpc_cout.c 1
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
--#include <malloc.h>
- #include <ctype.h>
- #include "rpc_parse.h"
- #include "rpc_util.h"
index e84b3cc355da24b895e669a94ab484809507950d..251b91e2dbe512b13127ae25a259f0fd749da4f1 100644 (file)
@@ -14,14 +14,14 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=nmap
 PKG_VERSION:=6.47
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_MAINTAINER=Nuno Goncalves <nunojpg@gmail.com>
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://nmap.org/dist/
 PKG_MD5SUM:=edfe81f6763223c0a29bfa15a8526e2a
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 
@@ -87,7 +87,8 @@ CONFIGURE_ARGS += \
        --with-libdnet=included \
        --with-libpcre=included \
        --with-libpcap="$(STAGING_DIR)/usr" \
-       --without-liblua
+       --without-liblua \
+       --without-zenmap
 
 CONFIGURE_VARS += CXXFLAGS="$$$$CXXFLAGS -fno-builtin"
 
index 2b6496431aef66eaf9296efd873416f2cf64cc49..2c8dcece05ff349bada7733ce3861d2e3ad9914d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,14 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ntp
-PKG_VERSION:=4.2.6p5
+PKG_VERSION:=4.2.8
 PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/
-PKG_MD5SUM:=00df80a84ec9528fcfb09498075525bc
+PKG_MD5SUM:=6972a626be6150db8cfbd0b63d8719e7
 
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_LICENSE:=Unique
+PKG_LICENSE_FILES:=COPYRIGHT html/copyright.html
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 
 PKG_FIXUP:=autoreconf
 PKG_LIBTOOL_PATHS:=. sntp
@@ -30,19 +33,20 @@ define Package/ntpd/Default
   TITLE:=ISC ntp
   MAINTAINER:=Peter Wagner <tripolar@gmx.at>
   URL:=http://www.ntp.org/
-  DEPENDS:=+libcap
+  DEPENDS:=+libopenssl +libpthread
 endef
 
 define Package/ntpd/Default/description
  The ISC ntp suite is a collection of tools used to synchronize the
- system clock with remote NTP time servers and run/montior local NTP
+ system clock with remote NTP time servers and run/monitor local NTP
  servers.
 endef
 
 define Package/ntpd
 $(call Package/ntpd/Default)
   TITLE+= server
-  VARIANT:=nossl
+  DEPENDS+= +libcap
+  USERID:=ntp=123:ntp=123
 endef
 
 define Package/ntpd/description
@@ -51,23 +55,9 @@ $(call Package/ntpd/Default/description)
  This package contains the ntpd server.
 endef
 
-define Package/ntpd-ssl
-$(call Package/ntpd/Default)
-  TITLE+= server (with OpenSSL support)
-  VARIANT:=ssl
-  DEPENDS+= +libopenssl
-endef
-
-define Package/ntpd-ssl/description
-$(call Package/ntpd/Default/description)
- .
- This package contains the ntpd server with OpenSSL support.
-endef
-
 define Package/ntpdate
 $(call Package/ntpd/Default)
   TITLE+=date
-  VARIANT:=nossl
 endef
 
 define Package/ntpdate/description
@@ -79,7 +69,6 @@ endef
 define Package/ntp-utils
 $(call Package/ntpd/Default)
   TITLE+= utilities
-  VARIANT:=nossl
 endef
 
 define Package/ntp-utils/description
@@ -91,7 +80,6 @@ endef
 define Package/ntp-keygen
 $(call Package/ntpd/Default)
   TITLE+=keygen
-  VARIANT:=nossl
 endef
 
 define Package/ntp-keygen/description
@@ -100,19 +88,6 @@ $(call Package/ntpd/Default/description)
  This package contains the ntp-keygen.
 endef
 
-define Package/ntp-keygen-ssl
-$(call Package/ntpd/Default)
-  TITLE+=keygen (with OpenSSL support)
-  VARIANT:=ssl
-  DEPENDS+= +libopenssl
-endef
-
-define Package/ntp-keygen-ssl/description
-$(call Package/ntpd/Default/description)
- .
- This package contains the ntp-keygen with OpenSSL support.
-endef
-
 define Package/ntpd/conffiles
 /etc/ntp.conf
 endef
@@ -130,14 +105,11 @@ CONFIGURE_ARGS += \
        --enable-NMEA \
        --enable-LOCAL-CLOCK \
        --enable-SHM \
-       --enable-linuxcaps
-
-ifeq ($(BUILD_VARIANT),ssl)
-  CONFIGURE_ARGS += \
+       --enable-linuxcaps \
+       --with-yielding-select=yes \
        --with-crypto \
        --with-openssl-incdir="$(STAGING_DIR)/usr/include" \
        --with-openssl-libdir="$(STAGING_DIR)/usr/lib"
-endif
 
 define Package/ntpd/install
        $(INSTALL_DIR) $(1)/sbin
@@ -162,9 +134,6 @@ define Package/ntpd/postrm
 exit 0
 endef
 
-Package/ntpd-ssl/conffiles = $(Package/ntpd/conffiles)
-Package/ntpd-ssl/install = $(Package/ntpd/install)
-
 define Package/ntpdate/install
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/ntpdate/ntpdate $(1)/usr/sbin/
@@ -184,11 +153,7 @@ define Package/ntp-keygen/install
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/util/ntp-keygen $(1)/usr/sbin/
 endef
 
-Package/ntp-keygen-ssl/install = $(Package/ntp-keygen/install)
-
 $(eval $(call BuildPackage,ntpd))
-$(eval $(call BuildPackage,ntpd-ssl))
 $(eval $(call BuildPackage,ntpdate))
 $(eval $(call BuildPackage,ntp-utils))
 $(eval $(call BuildPackage,ntp-keygen))
-$(eval $(call BuildPackage,ntp-keygen-ssl))
index 05c317e9577e35d6ee8e9d95ae1ee92e5ad22b9d..e626e248ff2099fd6fec27cd1567fca80d688a04 100644 (file)
@@ -9,8 +9,6 @@ USE_PROCD=1
 start_service() {
 #      ln -sf /dev/ttyS0 /dev/gps0
 #      /usr/sbin/setgarmin -d /dev/gps -c /etc/setgarmin.conf
-       user_exists ntp 123 || user_add ntp 123 123 ntp /var/lib/ntp
-       group_exists ntp 123 || group_add ntp 123
        mkdir -p /var/lib/ntp
        chown -R ntp:ntp /var/lib/ntp
 
diff --git a/net/nut/Config.in b/net/nut/Config.in
new file mode 100644 (file)
index 0000000..b37dbca
--- /dev/null
@@ -0,0 +1,107 @@
+       config NUT_SERVER
+               depends on PACKAGE_nut
+               bool "Include server components (upsd)"
+               help
+                       upsd is responsible for serving the data from the drivers to the
+                       clients. It connects to each driver and maintains a local cache of the
+                       current state. Queries from the clients are served from this cache, so
+                       delays are minimal. This program is essential, and must be running at
+                       all times to actually make any use out of the drivers and clients.
+               default y
+               
+       config NUT_CLIENTS_UPSC
+               depends on PACKAGE_nut
+               bool "Include command line client (upsc)"
+               help
+                       upsc is provided as a quick way to poll the status of a UPS server. It
+                       can be used inside shell scripts and other programs that need UPS data
+                       but don't want to include the full interface.
+               default y
+               
+       config NUT_CLIENTS_UPSLOG
+               depends on PACKAGE_nut
+               bool "Include logging client (upslog)"
+               help
+                       upslog is a daemon that will poll a UPS at periodic intervals, fetch the
+                       variables that interest you, format them, and write them to a file.
+               default n
+               
+       config NUT_CLIENTS_UPSCMD
+               depends on PACKAGE_nut
+               bool "Include UPS controller (upscmd)"
+               help
+                       upscmd allows you to invoke "instant commands" in your UPS hardware. Not
+                       all hardware supports this, so check the list with -l to see if anything
+                       will work on your equipment. On hardware that supports it, you can use
+                       this program to start and stop battery tests, invoke a front panel test
+                       (beep!), turn the load on or off, and more.
+               default n
+               
+       config NUT_CLIENTS_UPSRW
+               depends on PACKAGE_nut
+               bool "Include UPS variable editor (upsrw)"
+               help
+                       upsrw allows you to view and change the read/write variables inside your
+                       UPS. It sends commands via the upsd to your driver, which configures the
+                       hardware for you. The list of variables that allow you to change their
+                       values is based on the capabilities of your UPS equipment. Not all
+                       models support this feature. Typically, cheaper hardware does not
+                       support any of them.
+               default n
+               
+       config NUT_CLIENTS_UPSMON
+               depends on PACKAGE_nut
+               bool "Include monitor and shutdown controller (upsmon)"
+               help
+                       upsmon is the client process that is responsible for the most important
+                       part of UPS monitoring--shutting down the system when the power goes
+                       out. It can call out to other helper programs for notification purposes
+                       during power events. upsmon can monitor multiple systems using a single
+                       process. Every UPS that is defined in the upsmon.conf configuration file
+                       is assigned a power value and a type (slave or master).
+               default y
+               
+       config NUT_CLIENTS_UPSSCHED
+               depends on NUT_CLIENTS_UPSMON
+               bool "Include helper for triggering events from upsmon (upssched)"
+               help
+                       upssched was created to allow users to execute programs at times relative
+                       to events being monitored by upsmon. The original purpose was to allow
+                       for a shutdown to occur after some fixed period on battery, but there are
+                       other uses that are possible.
+                       You can alternatively write your own script and save some space.
+               default n
+       
+       config NUT_SSL
+               depends on PACKAGE_nut
+               bool "Build with support for OpenSSL"
+               help
+                       SSL allows sessions between upsd and clients to be encrypted and can
+                       also be used to authenticate servers. This means that stealing port
+                       3493 from upsd will no longer net you interesting passwords. SSL is
+                       available via OpenSSL on OpenWRT (NSS doesn't seem to work). If you
+                       are happy with using passwords to authenticate clients, you can save
+                       some space and build NUT without SSL support.
+               default n
+       
+       config NUT_DRIVER_SERIAL
+               depends on PACKAGE_nut
+               bool "Build with support for serial drivers"
+               help
+                       If you have a UPS connected via serial, select this.
+               default n
+       
+       config NUT_DRIVER_USB
+               depends on PACKAGE_nut
+               bool "Build with support for USB drivers"
+               help
+                       If you have a UPS connected via USB, select this.
+               default y
+       
+       config NUT_DRIVER_SNMP
+               depends on PACKAGE_nut
+               bool "Build with support for SNMP drivers"
+               help
+                       If you have a UPS you can connect to via SNMP, select this.
+               default n
+               
diff --git a/net/nut/Makefile b/net/nut/Makefile
new file mode 100644 (file)
index 0000000..d23b7cb
--- /dev/null
@@ -0,0 +1,292 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nut
+PKG_VERSION:=2.7.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.networkupstools.org/source/2.7/
+PKG_MD5SUM:=c3568b42e058cfc385b46d25140dced4
+PKG_MAINTAINER:=Martin Rowe <martin.p.rowe@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE-GPL2
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/nut-$(PKG_VERSION)
+PKG_INSTALL:=1
+
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_NUT_CLIENTS_UPSC \
+       CONFIG_NUT_CLIENTS_UPSCMD \
+       CONFIG_NUT_CLIENTS_UPSLOG \
+       CONFIG_NUT_CLIENTS_UPSMON \
+       CONFIG_NUT_CLIENTS_UPSRW \
+       CONFIG_NUT_CLIENTS_UPSSCHED \
+       CONFIG_NUT_DRIVER_SERIAL \
+       CONFIG_NUT_DRIVER_SNMP \
+       CONFIG_NUT_DRIVER_USB \
+       CONFIG_NUT_SERVER \
+       CONFIG_NUT_SSL \
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/nut/Default
+       SECTION:=net
+       CATEGORY:=Network
+       URL:=http://www.networkupstools.org/
+       DEPENDS:=nut
+endef
+
+define Package/nut/description
+Network UPS Tools (NUT) is a client/server monitoring system that
+allows computers to share uninterruptible power supply (UPS) and
+power distribution unit (PDU) hardware. Clients access the hardware
+through the server, and are notified whenever the power status
+changes.
+endef
+
+define Package/nut
+       $(call Package/nut/Default)
+       TITLE:=Network UPS Tools
+       DEPENDS:= \
+               +NUT_DRIVER_SNMP:libnetsnmp \
+               +NUT_DRIVER_USB:libusb-compat \
+               +NUT_SSL:libopenssl
+       MENU:=1
+endef
+
+define Package/nut/config
+       source "$(SOURCE)/Config.in"
+endef
+
+define Package/nut/conffiles
+       /etc/nut/nut.conf
+       $(if $(CONFIG_NUT_CLIENTS_UPSMON),/etc/nut/upsmon.conf)
+       $(if $(CONFIG_NUT_CLIENTS_UPSSCHED),/etc/nut/upssched.conf)
+       $(if $(CONFIG_NUT_SERVER),/etc/nut/ups.conf)
+       $(if $(CONFIG_NUT_SERVER),/etc/nut/upsd.conf)
+       $(if $(CONFIG_NUT_SERVER),/etc/nut/upsd.users)
+endef
+
+define Package/nut/install
+       $(INSTALL_DIR) $(1)/etc/nut
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/nut.conf.sample $(1)/etc/nut/nut.conf
+       $(if $(or $(CONFIG_NUT_CLIENTS_UPSC),\
+               $(CONFIG_NUT_CLIENTS_UPSCMD),\
+               $(CONFIG_NUT_CLIENTS_LOG),\
+               $(CONFIG_NUT_CLIENTS_UPSRW),\
+               $(CONFIG_NUT_CLIENTS_UPSMON),\
+               $(CONFIG_NUT_CLIENTS_UPSSCHED)),$(CP) $(PKG_INSTALL_DIR)/usr/lib/libupsclient.so* $(1)/usr/lib/)
+       $(if $(or $(CONFIG_NUT_SERVER),\
+               $(CONFIG_NUT_CLIENTS_UPSMON)),$(INSTALL_DIR) $(1)/etc/init.d)
+       $(if $(CONFIG_NUT_SERVER),$(INSTALL_DIR) $(1)/lib/nut)
+       $(if $(CONFIG_NUT_SERVER),$(INSTALL_DIR) $(1)/usr/share/nut)
+       $(if $(CONFIG_NUT_SERVER),$(CP) ./files/nut-server.init $(1)/etc/init.d/)
+       $(if $(CONFIG_NUT_SERVER),$(CP) $(PKG_INSTALL_DIR)/usr/sbin/upsd $(1)/usr/sbin)
+       $(if $(CONFIG_NUT_SERVER),$(CP) $(PKG_INSTALL_DIR)/usr/sbin/upsdrvctl $(1)/usr/sbin)
+       $(if $(CONFIG_NUT_SERVER),$(CP) $(PKG_INSTALL_DIR)/usr/share/nut/cmdvartab $(1)/usr/share/nut/)
+       $(if $(CONFIG_NUT_SERVER),$(CP) $(PKG_INSTALL_DIR)/usr/share/nut/driver.list $(1)/usr/share/nut/)
+       $(if $(CONFIG_NUT_SERVER),$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/ups.conf.sample $(1)/etc/nut/ups.conf)
+       $(if $(CONFIG_NUT_SERVER),$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsd.conf.sample $(1)/etc/nut/upsd.conf)
+       $(if $(CONFIG_NUT_SERVER),$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsd.users.sample $(1)/etc/nut/upsd.users)
+       $(if $(CONFIG_NUT_CLIENTS_UPSC),$(CP) $(PKG_INSTALL_DIR)/usr/bin/upsc $(1)/usr/bin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSCMD),$(CP) $(PKG_INSTALL_DIR)/usr/bin/upscmd $(1)/usr/bin/)
+       $(if $(CONFIG_NUT_CLIENTS_LOG),$(CP) $(PKG_INSTALL_DIR)/usr/bin/upslog $(1)/usr/bin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSRW),$(CP) $(PKG_INSTALL_DIR)/usr/bin/upsrw $(1)/usr/bin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSMON),$(CP) ./files/nut-monitor.init $(1)/etc/init.d/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSMON),$(CP) $(PKG_INSTALL_DIR)/usr/sbin/upsmon $(1)/usr/sbin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSMON),$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upsmon.conf.sample $(1)/etc/nut/upsmon.conf)
+       $(if $(CONFIG_NUT_CLIENTS_UPSSCHED),$(CP) $(PKG_INSTALL_DIR)/usr/bin/upssched-cmd $(1)/usr/bin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSSCHED),$(CP) $(PKG_INSTALL_DIR)/usr/sbin/upssched $(1)/usr/sbin/)
+       $(if $(CONFIG_NUT_CLIENTS_UPSSCHED),$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/nut/upssched.conf.sample $(1)/etc/nut/upssched.conf)
+endef
+
+# Dealing with all of the drivers is very repetitive, but the previous
+# maintainer had a neat solution which just needed some tweaking.
+define DriverPackage
+        define Package/nut-driver-$(2)
+               $(call Package/nut/Default)
+               TITLE:=$(2) (NUT $(1) driver)
+               $(if $(filter $(1),serial),DEPENDS+= @NUT_DRIVER_SERIAL)
+               $(if $(filter $(1),snmp),DEPENDS+= @NUT_DRIVER_SNMP)
+               $(if $(filter $(1),usb),DEPENDS+= @NUT_DRIVER_USB)
+        endef
+       # Deliberately empty description in order to trigger a build failure.
+       # It should be overridden by the list below, and when updating to a
+       # new version of nut we will need to provide descriptions for any new
+       # drivers.
+        define Package/nut-driver-$(2)/description
+               
+        endef
+        define Package/nut-driver-$(2)/install
+               $(INSTALL_DIR) $$(1)/lib/nut
+               $(CP) $$(PKG_INSTALL_DIR)/lib/nut/$(2) $$(1)/lib/nut/
+               $(if $(filter $(2),clone),$(CP) $$(PKG_INSTALL_DIR)/lib/nut/$(2)-outlet $$(1)/lib/nut/)
+        endef
+endef
+define DriverDescription
+        define Package/nut-driver-$(2)/description
+               $(3)
+        endef
+endef
+# These lists are lifted *directly* from drivers/Makefile.am in the nut
+# source tree. This it to make it simpler to keep in sync when updating
+# to a newer version of nut. Do not edit this manually.
+#
+# DO NOT EDIT (except to update with a fresh cut/paste)!
+SERIAL_DRIVERLIST = al175 bcmxcp belkin belkinunv bestfcom     \
+ bestfortress bestuferrups bestups dummy-ups etapro everups     \
+ gamatronic genericups isbmex liebert liebert-esp2 masterguard metasys \
+ oldmge-shut mge-utalk microdowell mge-shut oneac optiups powercom rhino        \
+ safenet skel solis tripplite tripplitesu upscode2 victronups powerpanel \
+ blazer_ser clone clone-outlet ivtscd apcsmart apcsmart-old apcupsd-ups riello_ser     \
+ nutdrv_qx
+SNMP_DRIVERLIST = snmp-ups
+USB_LIBUSB_DRIVERLIST = usbhid-ups bcmxcp_usb tripplite_usb \
+ blazer_usb richcomm_usb riello_usb \
+ nutdrv_atcl_usb \
+ nutdrv_qx
+# END: DO NOT EDIT!
+SERIAL_DRIVERLIST_IGNORE:=skel clone-outlet nutdrv_qx
+# nutdrv_qx can be either USB or serial. Given most routers have USB
+# instead of serial ports, and not wanting two identical packages with
+# different names that conflict with each other, only the option for the
+# driver with USB bindings is provided. If you really want to save that
+# tiny bit of space and build it without USB support, remove nutdrv_qx
+# from the previous line.
+
+$(foreach d,$(filter-out $(SERIAL_DRIVERLIST_IGNORE),$(SERIAL_DRIVERLIST)),$(eval $(call DriverPackage,serial,$(d))))
+$(foreach d,$(SNMP_DRIVERLIST),$(eval $(call DriverPackage,snmp,$(d))))
+$(foreach d,$(USB_LIBUSB_DRIVERLIST),$(eval $(call DriverPackage,usb,$(d))))
+
+$(eval $(call DriverDescription,serial,al175,\
+       Driver for Eltek UPS models with AL175 alarm module))
+$(eval $(call DriverDescription,serial,bcmxcp,\
+       Driver for UPSes supporting the serial BCM/XCP protocol))
+$(eval $(call DriverDescription,serial,belkin,\
+       Driver for Belkin serial UPS equipment))
+$(eval $(call DriverDescription,serial,belkinunv,\
+       Driver for Belkin "Universal UPS" and compatible))
+$(eval $(call DriverDescription,serial,bestfcom,\
+       Driver for Best Power Fortress/Ferrups))
+$(eval $(call DriverDescription,serial,bestfortress,\
+       Driver for old Best Fortress UPS equipment))
+$(eval $(call DriverDescription,serial,bestuferrups,\
+       Driver for Best Power Micro-Ferrups))
+$(eval $(call DriverDescription,serial,bestups,\
+       Driver for Best Power / SOLA (Phoenixtec protocol) UPS equipment))
+$(eval $(call DriverDescription,serial,dummy-ups,\
+       Driver for multi-purpose UPS emulation))
+$(eval $(call DriverDescription,serial,etapro,\
+       Driver for ETA UPS equipment))
+$(eval $(call DriverDescription,serial,everups,\
+       Driver for Ever UPS models))
+$(eval $(call DriverDescription,serial,gamatronic,\
+       Driver for Gamatronic UPS equipment))
+$(eval $(call DriverDescription,serial,genericups,\
+       Driver for contact-closure UPS equipment))
+$(eval $(call DriverDescription,serial,isbmex,\
+       Driver for ISBMEX UPS equipment))
+$(eval $(call DriverDescription,serial,liebert,\
+       Driver for Liebert contact-closure UPS equipment))
+$(eval $(call DriverDescription,serial,liebert-esp2,\
+       Driver for Liebert UPS, using the ESP-II serial protocol))
+$(eval $(call DriverDescription,serial,masterguard,\
+       Driver for Masterguard UPS equipment))
+$(eval $(call DriverDescription,serial,metasys,\
+       Driver for Meta System UPS equipment))
+$(eval $(call DriverDescription,serial,oldmge-shut,\
+       Driver for SHUT Protocol UPS equipment, deprecated, use mge-shut))
+$(eval $(call DriverDescription,serial,mge-utalk,\
+       Driver for MGE UPS SYSTEMS UTalk protocol equipment))
+$(eval $(call DriverDescription,serial,microdowell,\
+       Driver for Microdowell Enterprise UPS series))
+$(eval $(call DriverDescription,serial,mge-shut,\
+       Driver for SHUT Protocol UPS equipment))
+$(eval $(call DriverDescription,serial,oneac,\
+       Driver for Oneac UPS equipment))
+$(eval $(call DriverDescription,serial,optiups,\
+       Driver for Opti-UPS (Viewsonic) UPS and Zinto D (ONLINE-USV) equipment))
+$(eval $(call DriverDescription,serial,powercom,\
+       Driver for serial Powercom/Trust/Advice UPS equipment))
+$(eval $(call DriverDescription,serial,rhino,\
+       Driver for Brazilian Microsol RHINO UPS equipment))
+$(eval $(call DriverDescription,serial,safenet,\
+       Driver for SafeNet compatible UPS equipment))
+$(eval $(call DriverDescription,serial,solis,\
+       Driver for Brazilian Microsol SOLIS UPS equipment))
+$(eval $(call DriverDescription,serial,tripplite,\
+       Driver for Tripp-Lite SmartPro UPS equipment))
+$(eval $(call DriverDescription,serial,tripplitesu,\
+       Driver for Tripp-Lite SmartOnline (SU) UPS equipment))
+$(eval $(call DriverDescription,serial,upscode2,\
+       Driver for UPScode II compatible UPS equipment))
+$(eval $(call DriverDescription,serial,victronups,\
+       Driver for IMV/Victron UPS unit Match, Match Lite, NetUps))
+$(eval $(call DriverDescription,serial,powerpanel,\
+       Driver for PowerPanel Plus compatible UPS equipment))
+$(eval $(call DriverDescription,serial,blazer_ser,\
+       Driver for Megatec/Q1 protocol serial based UPS equipment))
+$(eval $(call DriverDescription,serial,clone,\
+       UPS driver clone))
+$(eval $(call DriverDescription,serial,ivtscd,\
+       Driver for the IVT Solar Controller Device))
+$(eval $(call DriverDescription,serial,apcsmart,\
+       Driver for American Power Conversion Smart Protocol UPS equipment))
+$(eval $(call DriverDescription,serial,apcsmart-old,\
+       Driver for American Power Conversion Smart Protocol UPS equipment))
+$(eval $(call DriverDescription,serial,apcupsd-ups,\
+       Driver for apcupsd client access))
+$(eval $(call DriverDescription,serial,riello_ser,\
+       Driver for Riello UPS Protocol UPS equipment))
+$(eval $(call DriverDescription,snmp,snmp-ups,\
+       Multi-MIB Driver for SNMP UPS equipment))
+$(eval $(call DriverDescription,usb,usbhid-ups,\
+       Driver for USB/HID UPS equipment))
+$(eval $(call DriverDescription,usb,bcmxcp_usb,\
+       Experimental driver for UPSes supporting the BCM/XCP protocol over USB))
+$(eval $(call DriverDescription,usb,tripplite_usb,\
+       Driver for older Tripp Lite USB UPSes (not PDC HID)))
+$(eval $(call DriverDescription,usb,blazer_usb,\
+       Driver for Megatec/Q1 protocol USB based UPS equipment))
+$(eval $(call DriverDescription,usb,richcomm_usb,\
+       Driver for UPS equipment using Richcomm dry-contact to USB solution))
+$(eval $(call DriverDescription,usb,riello_usb,\
+       Driver for Riello UPS Protocol UPS equipment via USB))
+$(eval $(call DriverDescription,usb,nutdrv_atcl_usb,\
+       Driver for ATCL FOR UPS equipment))
+$(eval $(call DriverDescription,usb,nutdrv_qx,\
+       Driver for Q* protocol serial and USB based UPS equipment))
+
+CONFIGURE_ARGS += \
+       --$(if $(CONFIG_NUT_DRIVER_SERIAL),with,without)-serial \
+       --$(if $(CONFIG_NUT_DRIVER_USB),with,without)-usb \
+       --$(if $(CONFIG_NUT_DRIVER_SNMP),with,without)-snmp \
+       --without-neon \
+       --without-powerman \
+       --without-ipmi \
+       --without-freeipmi \
+       --$(if $(CONFIG_NUT_SSL),with,without)-ssl $(if $(CONFIG_NUT_SSL),--with-openssl) \
+       --without-avahi \
+       --without-libltdl \
+       --with-user=root \
+       --with-group=root \
+       --sysconfdir=/etc/nut \
+       --with-drvpath=/lib/nut \
+       --with-statepath=/var/run \
+       --datadir=/usr/share/nut
+
+$(eval $(call BuildPackage,nut))
+$(foreach d,$(filter-out $(SERIAL_DRIVERLIST_IGNORE),$(SERIAL_DRIVERLIST)),$(eval $(call BuildPackage,nut-driver-$(d))))
+$(foreach d,$(SNMP_DRIVERLIST),$(eval $(call BuildPackage,nut-driver-$(d))))
+$(foreach d,$(USB_LIBUSB_DRIVERLIST),$(eval $(call BuildPackage,nut-driver-$(d))))
diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init
new file mode 100755 (executable)
index 0000000..e9fdb33
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh /etc/rc.common
+
+START=60
+USE_PROCD=1
+
+restart() {
+       stop_service
+       start_service
+}
+
+start_service() {
+       upsmon -p
+}
+
+stop_service() {
+       upsmon -c stop
+}
+
+reload_service() {
+       upsmon -c reload
+}
diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init
new file mode 100755 (executable)
index 0000000..f9971be
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+USE_PROCD=1
+
+restart() {
+       stop_service
+       start_service
+}
+
+start_service() {
+       upsdrvctl start
+       upsd
+}
+
+stop_service() {
+       upsd -c stop
+       upsdrvctl stop
+}
+
+reload_service() {
+       upsd -c reload
+}
diff --git a/net/nut/patches/001-fix-missing-libmath-flags.patch b/net/nut/patches/001-fix-missing-libmath-flags.patch
new file mode 100644 (file)
index 0000000..88996be
--- /dev/null
@@ -0,0 +1,22 @@
+--- a/drivers/Makefile.am
++++ b/drivers/Makefile.am
+@@ -171,7 +171,7 @@ tripplite_usb_SOURCES = tripplite_usb.c
+ tripplite_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+ bcmxcp_usb_SOURCES = bcmxcp_usb.c bcmxcp.c usb-common.c
+-bcmxcp_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS)
++bcmxcp_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+ blazer_usb_SOURCES = blazer.c blazer_usb.c libusb.c usb-common.c
+ blazer_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+--- a/drivers/Makefile.in
++++ b/drivers/Makefile.in
+@@ -785,7 +785,7 @@ usbhid_ups_LDADD = $(LDADD_DRIVERS) $(LI
+ tripplite_usb_SOURCES = tripplite_usb.c libusb.c usb-common.c
+ tripplite_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+ bcmxcp_usb_SOURCES = bcmxcp_usb.c bcmxcp.c usb-common.c
+-bcmxcp_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS)
++bcmxcp_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+ blazer_usb_SOURCES = blazer.c blazer_usb.c libusb.c usb-common.c
+ blazer_usb_LDADD = $(LDADD_DRIVERS) $(LIBUSB_LIBS) -lm
+ nutdrv_atcl_usb_SOURCES = nutdrv_atcl_usb.c usb-common.c
diff --git a/net/nut/patches/010-ignore_automake_k_bug.patch b/net/nut/patches/010-ignore_automake_k_bug.patch
new file mode 100644 (file)
index 0000000..8d3645d
--- /dev/null
@@ -0,0 +1,28 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -431,12 +431,6 @@ distclean-libtool:
+ # (2) otherwise, pass the desired values on the `make' command line.
+ $(RECURSIVE_TARGETS):
+       @fail= failcom='exit 1'; \
+-      for f in x $$MAKEFLAGS; do \
+-        case $$f in \
+-          *=* | --[!k]*);; \
+-          *k*) failcom='fail=yes';; \
+-        esac; \
+-      done; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+@@ -456,12 +450,6 @@ $(RECURSIVE_TARGETS):
+ $(RECURSIVE_CLEAN_TARGETS):
+       @fail= failcom='exit 1'; \
+-      for f in x $$MAKEFLAGS; do \
+-        case $$f in \
+-          *=* | --[!k]*);; \
+-          *k*) failcom='fail=yes';; \
+-        esac; \
+-      done; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
index beace7bb26e184aec19b109f69f72e0a822bbe33..81075fd81329d489f9838b5a379b26ed5b0af1f5 100644 (file)
@@ -11,4 +11,8 @@ config OCSERV_PROTOBUF
        bool "use external libprotobuf"
        default y
 
+config OCSERV_HTTP_PARSER
+       bool "use external libhttp-parser"
+       default y
+
 endmenu
index 42d9584ca584d5877104cb2940abda86c30f015d..3ddc5be7dce18aff9ecf5de90bdfd94009188754 100644 (file)
@@ -8,18 +8,22 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ocserv
-PKG_VERSION:=0.8.6
-PKG_RELEASE:=1
+PKG_VERSION:=0.9.0
+PKG_RELEASE:=3
 
 PKG_BUILD_DIR :=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL :=ftp://ftp.infradead.org/pub/ocserv/
-PKG_MD5SUM:=78301874643ae658d43a8c7f4aaabadb
+PKG_MD5SUM:=50994bf7e40fd6bedda33bb2f99b1f11
 
 PKG_LICENSE:=GPLv2
 PKG_LICENSE_FILES:=COPYING
 PKG_FIXUP:=autoreconf
 
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_OCSERV_PAM \
+       CONFIG_OCSERV_PROTOBUF \
+
 include $(INCLUDE_DIR)/package.mk
 
 define Package/ocserv/config
@@ -33,7 +37,8 @@ define Package/ocserv
   TITLE:=OpenConnect VPN server
   URL:=http://www.infradead.org/ocserv/
   MAINTAINER:=Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
-  DEPENDS:= +libgnutls +certtool +libncurses +libreadline +OCSERV_PAM:libpam +OCSERV_PROTOBUF:libprotobuf-c
+  DEPENDS:= +OCSERV_HTTP_PARSER:libhttp-parser +libgnutls +certtool +libncurses +libreadline +OCSERV_PAM:libpam +OCSERV_PROTOBUF:libprotobuf-c +kmod-tun
+  USERID:=ocserv=72:ocserv=72
 endef
 
 define Package/ocserv/description
@@ -61,6 +66,10 @@ ifneq ($(CONFIG_OCSERV_PROTOBUF),y)
 CONFIGURE_ARGS += --without-protobuf
 endif
 
+ifneq ($(CONFIG_OCSERV_HTTP_PARSER),y)
+CONFIGURE_ARGS += --without-http-parser
+endif
+
 define Package/ocserv/conffiles
 /etc/config/ocserv
 endef
@@ -78,6 +87,8 @@ define Package/ocserv/install
        $(INSTALL_CONF) ./files/ocserv.conf.template $(1)/etc/ocserv/ocserv.conf.template
        $(INSTALL_DIR) $(1)/etc/config
        $(INSTALL_CONF) ./files/config $(1)/etc/config/ocserv
+       $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
+       $(INSTALL_DATA) ./files/ocserv.upgrade $(1)/lib/upgrade/keep.d/ocserv
 endef
 
 $(eval $(call BuildPackage,ocserv))
index 96055d51d88162c48cad8c36a7fcba34b55b48ea..961f33e4efb272698d4079bb95e91ecd51884ba0 100644 (file)
@@ -4,7 +4,7 @@ To setup a server the provides access to LAN with network address
 10.100.2.0/255.255.255.0 using the VPN address range
 10.100.3.0/255.255.255.0 add the following to /etc/config/ocserv:
 
------------------------------------------------------------------
+----/etc/config/ocserv-------------------------------------------
 config ocserv 'config'
        option port '4443'
        option dpd '120'
@@ -13,8 +13,9 @@ config ocserv 'config'
        option netmask '255.255.255.0'
        option ipaddr '10.100.3.0'
        option auth 'plain'
-       option zone 'lan'
-       option fwport '4443'
+       option zone 'vpn'
+       option default_domain 'lan'
+       option compression '1'
        option enable '1'
 
 config dns
@@ -38,6 +39,34 @@ The server can be enabled and started using:
 # /etc/init.d/ocserv start
 
 
+To simplify firewall configuration, you should setup an unmanaged interface
+(e.g., called vpn), and will have assigned the 'vpns+' interfaces. Then a zone
+called vpn should be setup to handle interactions with lan. An example
+follows:
+----/etc/config/network------------------------------------------
+config interface 'vpn'
+        option proto 'none'
+        option ifname 'vpns+'
+-----------------------------------------------------------------
+
+----/etc/config/firewall-----------------------------------------
+config zone
+        option input 'ACCEPT'
+        option forward 'REJECT'
+        option output 'ACCEPT'
+        option name 'vpn'
+        option device 'vpns+'
+        option network 'vpn'
+
+config forwarding
+        option dest 'lan'
+        option src 'vpn'
+
+config forwarding
+        option dest 'vpn'
+        option src 'lan'
+-----------------------------------------------------------------
+
 
 There is a luci plugin to allow configuring the server from
 the web environment; see the package luci-app-ocserv.
index c26774f7a296cc811248412545b216f2c8a8aae2..8307bf6507540c35ef40c18ba926ae7cc24b1edb 100644 (file)
@@ -18,6 +18,11 @@ auth = "|AUTH|"
 # A banner to be displayed on clients
 banner = "Welcome to OpenWRT"
 
+# When the server has a dynamic DNS address (that may change),
+# should set that to true to ask the client to resolve again on
+# reconnects.
+listen-host-is-dyndns = |DYNDNS|
+
 # Use listen-host to limit to specific IPs or to the IPs of a provided 
 # hostname.
 #listen-host = [IP|HOSTNAME]
@@ -38,6 +43,12 @@ max-same-clients = |MAX_SAME|
 tcp-port = |PORT|
 |UDP|udp-port = |PORT|
 
+# Stats report time. The number of seconds after which each
+# worker process will report its usage statistics (number of
+# bytes transferred etc). This is useful when accounting like
+# radius is in use.
+#stats-report-time = 360
+
 # Keepalive in seconds
 keepalive = 32400
 
@@ -104,11 +115,14 @@ server-key = /etc/ocserv/server-key.pem
 # The revocation list of the certificates issued by the 'ca-cert' above.
 #crl = /etc/ocserv/crl.pem
 
+# Uncomment this to enable compression negotiation (LZS, LZ4).
+|COMPRESSION|compression = true
+
 # GnuTLS priority string
-tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT"
+tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0"
 
 # To enforce perfect forward secrecy (PFS) on the main channel.
-#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA"
+#tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-RSA"
 
 # The time (in seconds) that a client is allowed to stay connected prior
 # to authentication
@@ -124,7 +138,7 @@ auth-timeout = 40
 
 # The time (in seconds) that a client is not allowed to reconnect after 
 # a failed authentication attempt.
-#min-reauth-time = 2
+min-reauth-time = 360
 
 # Cookie timeout (in seconds)
 # which he can reconnect. That cookie will be invalided if not
@@ -159,8 +173,11 @@ rekey-method = ssl
 # DEVICE, IP_REAL (the real IP of the client), IP_LOCAL (the local IP
 # in the P-t-P connection), IP_REMOTE (the VPN IP of the client),
 # ID (a unique numeric ID); REASON may be "connect" or "disconnect".
-connect-script = /usr/bin/ocserv-script
-disconnect-script = /usr/bin/ocserv-script
+
+# These scripts are not needed if you have setup an interface for all vpns+
+# devices.
+#connect-script = /usr/bin/ocserv-script
+#disconnect-script = /usr/bin/ocserv-script
 
 # UTMP
 use-utmp = false
@@ -212,7 +229,7 @@ device = vpns
 predictable-ips = |PREDICTABLE_IPS|
 
 # The default domain to be advertised
-#default-domain = example.com
+|ENABLE_DEFAULT_DOMAIN|default-domain = |DEFAULT_DOMAIN|
 
 # The pool of addresses that leases will be given from.
 ipv4-network = |IPV4ADDR|
@@ -272,8 +289,8 @@ ping-leases = false
 # based on a user or group. The syntax depends on the input accepted
 # by the commands route-add-cmd and route-del-cmd (see below).
 
-#config-per-user = /etc/ocserv/config-per-user/
-#config-per-group = /etc/ocserv/config-per-group/
+config-per-user = /etc/ocserv/config-per-user/
+config-per-group = /etc/ocserv/config-per-group/
 
 # When config-per-xxx is specified and there is no group or user that
 # matches, then utilize the following configuration.
@@ -304,8 +321,8 @@ ping-leases = false
 # The following example is from linux systems. %{R} should be something
 # like 192.168.2.0/24
 
-#route-add-cmd = "ip route add %{R} dev %{D}"
-#route-del-cmd = "ip route delete %{R} dev %{D}"
+route-add-cmd = "/sbin/route add -net %{R} dev %{D}"
+route-del-cmd = "/sbin/route del -net %{R} dev %{D}"
 
 # This option allows to forward a proxy. The special strings '%{U}'
 # and '%{G}', if present will be replaced by the username and group name.
index 612262087a862c2a24d478b66e27a3a4be972b4f..aee342d685fd39d22f3df84d459e97c8b3667634 100644 (file)
@@ -10,19 +10,25 @@ setup_config() {
        config_get max_same     $1 max_same "2"
        config_get dpd          $1 dpd "120"
        config_get predictable_ips  $1 predictable_ips "1"
+       config_get compression  $1 compression "0"
        config_get udp          $1 udp "1"
        config_get auth         $1 auth "plain"
        config_get cisco_compat $1 cisco_compat "1"
        config_get ipaddr       $1 ipaddr "192.168.100.0"
        config_get netmask      $1 netmask "255.255.255.0"
        config_get ip6addr      $1 ip6addr ""
+       config_get default_domain  $1 default_domain ""
 
+       enable_default_domain="#"
+       enable_udp="#"
+       enable_compression="#"
        test $predictable_ips = "0" && predictable_ips="false"
        test $predictable_ips = "1" && predictable_ips="true"
        test $cisco_compat = "0" && cisco_compat="false"
        test $cisco_compat = "1" && cisco_compat="true"
-       test $udp = "0" && udp="#"
-       test $udp = "1" && udp=""
+       test $udp = "1" && enable_udp=""
+       test $compression = "1" && enable_compression=""
+       test -z $default_domain && enable_default_domain=""
        test -z $ip6addr && enable_ipv6="#"
 
        ipv6_addr=`echo $ip6addr|cut -d '/' -f 1`
@@ -30,15 +36,23 @@ setup_config() {
 
        test $auth = "plain" && authsuffix="\[/var/etc/ocpasswd\]"
 
+       dyndns="false"
+       hostname=`uci show ddns|grep domain|head -1|cut -d '=' -f 2 2>/dev/null`
+       [ -n "$hostname" ] && dyndns="true"
+
        mkdir -p /var/etc
        sed -e "s/|PORT|/$port/g" \
            -e "s/|MAX_CLIENTS|/$max_clients/g" \
            -e "s/|MAX_SAME|/$max_same/g" \
            -e "s/|DPD|/$dpd/g" \
            -e "s#|AUTH|#$auth$authsuffix#g" \
+           -e "s#|DYNDNS|#$dyndns#g" \
            -e "s/|PREDICTABLE_IPS|/$predictable_ips/g" \
+           -e "s/|DEFAULT_DOMAIN|/$default_domain/g" \
+           -e "s/|ENABLE_DEFAULT_DOMAIN|/$enable_default_domain/g" \
            -e "s/|CISCO_COMPAT|/$cisco_compat/g" \
-           -e "s/|UDP|/$udp/g" \
+           -e "s/|UDP|/$enable_udp/g" \
+           -e "s/|COMPRESSION|/$enable_compression/g" \
            -e "s/|IPV4ADDR|/$ipaddr/g" \
            -e "s/|NETMASK|/$netmask/g" \
            -e "s/|IPV6ADDR|/$ipv6_addr/g" \
@@ -86,11 +100,14 @@ setup_dns() {
 start() {
        local hostname iface
 
-       user_exists ocserv 72 || user_add ocserv 72 72 /var/lib/ocserv
-       group_exists ocserv 72 || group_add ocserv 72
+       hostname=`uci show ddns|grep domain|head -1|cut -d '=' -f 2 2>/dev/null`
+       [ -z "$hostname" ] && hostname=`uci get system.@system[0].hostname 2>/dev/null`
 
-       hostname=`uci get ddns.myddns.domain`
-       [ -z "$hostname" ] && hostname=`uci get system.@system[0].hostname`
+       [ -f /etc/config/ocserv-dir/ca-key.pem ] && mv /etc/config/ocserv-dir/ca-key.pem /etc/ocserv/ca-key.pem
+       [ -f /etc/config/ocserv-dir/ca.pem ] && mv /etc/config/ocserv-dir/ca.pem /etc/ocserv/ca.pem
+       [ -f /etc/config/ocserv-dir/server-key.pem ] && mv /etc/config/ocserv-dir/server-key.pem /etc/ocserv/server-key.pem
+       [ -f /etc/config/ocserv-dir/server-cert.pem ] && mv /etc/config/ocserv-dir/server-cert.pem /etc/ocserv/server-cert.pem 
+       [ -d /etc/config/ocserv-dir ] && rmdir /etc/config/ocserv-dir
 
        [ ! -f /etc/ocserv/ca-key.pem ] && [ -x /usr/bin/certtool ] && {
                logger -t ocserv "Generating CA certificate..."
diff --git a/net/ocserv/files/ocserv.upgrade b/net/ocserv/files/ocserv.upgrade
new file mode 100644 (file)
index 0000000..4c6c350
--- /dev/null
@@ -0,0 +1,7 @@
+/etc/ocserv/ca-key.pem
+/etc/ocserv/ca.pem
+/etc/ocserv/server-key.pem
+/etc/ocserv/server-cert.pem
+/etc/ocserv/config-per-user/*
+/etc/ocserv/config-per-group/*
+/etc/ocserv/crl.pem
diff --git a/net/ocserv/patches/001-add-http-heads.h b/net/ocserv/patches/001-add-http-heads.h
new file mode 100644 (file)
index 0000000..0bacb6a
--- /dev/null
@@ -0,0 +1,166 @@
+diff --git a/src/http-heads.h b/src/http-heads.h
+new file mode 100644
+index 0000000..9f0927b
+--- /dev/null
++++ b/src/http-heads.h
+@@ -0,0 +1,160 @@
++/* ANSI-C code produced by gperf version 3.0.4 */
++/* Command-line: gperf --global-table -t http-heads.gperf  */
++/* Computed positions: -k'3,8' */
++
++#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
++      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
++      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
++      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
++      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
++      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
++      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
++      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
++      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
++      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
++      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
++      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
++      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
++      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
++      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
++      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
++      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
++      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
++      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
++      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
++      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
++      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
++      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
++/* The character set is not based on ISO-646.  */
++#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
++#endif
++
++#line 1 "http-heads.gperf"
++
++#include "vpn.h"
++#line 6 "http-heads.gperf"
++struct http_headers_st { const char *name; unsigned id; };
++
++#define TOTAL_KEYWORDS 12
++#define MIN_WORD_LENGTH 6
++#define MAX_WORD_LENGTH 34
++#define MIN_HASH_VALUE 6
++#define MAX_HASH_VALUE 35
++/* maximum key range = 30, duplicates = 0 */
++
++#ifdef __GNUC__
++__inline
++#else
++#ifdef __cplusplus
++inline
++#endif
++#endif
++static unsigned int
++hash (register const char *str, register unsigned int len)
++{
++  static const unsigned char asso_values[] =
++    {
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36,  0, 15,  5,  0, 36,
++       0, 36, 10, 36, 36, 36, 36,  5, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36,  5, 36, 36, 36,  0, 36, 36, 36, 36,
++       0,  0, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
++      36, 36, 36, 36, 36, 36
++    };
++  register int hval = len;
++
++  switch (hval)
++    {
++      default:
++        hval += asso_values[(unsigned char)str[7]];
++      /*FALLTHROUGH*/
++      case 7:
++      case 6:
++      case 5:
++      case 4:
++      case 3:
++        hval += asso_values[(unsigned char)str[2]];
++        break;
++    }
++  return hval;
++}
++
++static const struct http_headers_st wordlist[] =
++  {
++    {""}, {""}, {""}, {""}, {""}, {""},
++#line 8 "http-heads.gperf"
++    {"Cookie", HEADER_COOKIE},
++    {""}, {""}, {""},
++#line 12 "http-heads.gperf"
++    {"Connection", HEADER_CONNECTION},
++    {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
++#line 9 "http-heads.gperf"
++    {"User-Agent", HEADER_USER_AGENT},
++    {""},
++#line 11 "http-heads.gperf"
++    {"X-DTLS-Accept-Encoding", HEADER_DTLS_ENCODING},
++#line 14 "http-heads.gperf"
++    {"X-DTLS-CipherSuite", HEADER_DTLS_CIPHERSUITE},
++#line 16 "http-heads.gperf"
++    {"X-CSTP-Address-Type", HEADER_CSTP_ATYPE},
++#line 13 "http-heads.gperf"
++    {"X-DTLS-Master-Secret", HEADER_MASTER_SECRET},
++    {""},
++#line 10 "http-heads.gperf"
++    {"X-CSTP-Accept-Encoding", HEADER_CSTP_ENCODING},
++    {""}, {""},
++#line 17 "http-heads.gperf"
++    {"X-CSTP-Hostname", HEADER_HOSTNAME},
++    {""},
++#line 18 "http-heads.gperf"
++    {"X-CSTP-Full-IPv6-Capability", HEADER_FULL_IPV6},
++    {""},
++#line 19 "http-heads.gperf"
++    {"X-AnyConnect-Identifier-DeviceType", HEADER_DEVICE_TYPE},
++#line 15 "http-heads.gperf"
++    {"X-CSTP-Base-MTU", HEADER_CSTP_BASE_MTU}
++  };
++
++#ifdef __GNUC__
++__inline
++#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
++__attribute__ ((__gnu_inline__))
++#endif
++#endif
++const struct http_headers_st *
++in_word_set (register const char *str, register unsigned int len)
++{
++  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
++    {
++      register int key = hash (str, len);
++
++      if (key <= MAX_HASH_VALUE && key >= 0)
++        {
++          register const char *s = wordlist[key].name;
++
++          if (*str == *s && !strcmp (str + 1, s + 1))
++            return &wordlist[key];
++        }
++    }
++  return 0;
++}
diff --git a/net/ola/Makefile b/net/ola/Makefile
new file mode 100644 (file)
index 0000000..0af8176
--- /dev/null
@@ -0,0 +1,128 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2015 Christian Beier <dontmind@freeshell.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ola
+PKG_VERSION:=0.9.3
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/OpenLightingProject/ola.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=d949ab88ab2c12d4d94b50a0a0df633d634f08fd
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_LICENSE:=LGPL-2.1+
+
+PKG_FIXUP:=libtool
+PKG_INSTALL:=1
+
+PKG_BUILD_PARALLEL:=1
+PKG_USE_MIPS16:=0
+
+PKG_BUILD_DEPENDS:=protobuf/host ola/host
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/ola
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Open Lighting Architecture Daemon
+  URL:=https://www.openlighting.org/
+  MAINTAINER:=Christian Beier <dontmind@freeshell.org>
+  DEPENDS:=+protobuf +libusb-1.0 +libuuid +libstdcpp +libpthread +librt +zlib +libncurses +sudo @BROKEN
+endef
+
+define Package/ola/description
+  OLA (Open Lighting Architecture) is a framework that allows applications to 
+  send and receive DMX512, using various hardware devices and 'DMX over IP'
+  protocols. It enables software controllers talk to DMX hardware.
+endef
+
+
+include $(INCLUDE_DIR)/host-build.mk
+
+# When building the host part, disable as much as possible to speed up
+# the configure step and avoid missing host dependencies.
+# Stolen from http://git.buildroot.net/buildroot/commit/?id=66056a5179ef49f2ec10ba5d7fbd1a58863d1350
+define Host/Configure
+   $(call Host/Configure/Default,\
+       --disable-all-plugins \
+       --disable-slp \
+       --disable-osc \
+       --disable-uart \
+       --disable-libusb \
+       --disable-libftdi \
+       --disable-http  \
+       --disable-examples \
+       --disable-unittests \
+       --disable-doxygen-html \
+       --disable-doxygen-doc)
+endef
+
+# only build the ola_protoc thingy
+define Host/Compile
+       cd $(HOST_BUILD_DIR); \
+           $(MAKE) protoc/ola_protoc
+endef
+
+# only need ola_protoc
+define Host/Install
+       $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+       $(CP) $(HOST_BUILD_DIR)/protoc/ola_protoc $(STAGING_DIR_HOST)/bin/
+endef
+
+$(eval $(call HostBuild))
+
+
+
+define Build/Configure
+  $(call Build/Configure/Default,\
+       --disable-dependency-tracking \
+       --disable-static \
+       --disable-fatal-warnings \
+       --disable-unittests \
+       --disable-http  \
+       --with-ola-protoc=$(STAGING_DIR_HOST)/bin/ola_protoc)
+endef
+
+
+define Build/InstallDev
+       mkdir -p $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/ola $(1)/usr/include/
+       mkdir -p $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/olad $(1)/usr/include/
+       mkdir -p $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define Package/ola/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/olad.init $(1)/etc/init.d/olad
+       $(INSTALL_DIR) $(1)/usr/share/ola/pids
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/ola/pids/* $(1)/usr/share/ola/pids
+endef
+
+define Package/ola/postinst
+#!/bin/sh
+
+# make sure the conf dir exists and is writeable by the group olad uses
+mkdir -p /etc/ola
+chgrp nogroup /etc/ola
+chmod 775 $(1)/etc/ola
+
+exit 0
+endef
+
+
+$(eval $(call BuildPackage,ola))
diff --git a/net/ola/files/olad.init b/net/ola/files/olad.init
new file mode 100644 (file)
index 0000000..9a0e113
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2009-2011 OpenWrt.org
+# Copyright (C) 2015 Christian Beier <dontmind@freeshell.org>
+
+USE_PROCD=1
+
+START=90
+
+start_service() {
+    procd_open_instance
+    procd_set_param command sudo -u nobody /usr/bin/olad --syslog --log-level 3 --config-dir /etc/ola
+    procd_set_param respawn
+    procd_close_instance
+}
+
index 1daaeaa6a09724cf9cce2e113b43df5bd37e297b..d73bd3a88d08dec7084487a63da4f8445e5c4cf9 100644 (file)
@@ -15,4 +15,7 @@ config OPENCONNECT_OPENSSL
 
 endchoice
 
+config OPENCONNECT_STOKEN
+       bool "stoken support"
+
 endmenu
index 00fbf8b6127f9443a659c77bf8e1ae45f072f6e6..46234cbf66208259ef37fd3a0f5192e87a06c6f0 100644 (file)
@@ -8,12 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=openconnect
-PKG_VERSION:=6.00
-PKG_RELEASE:=3
+PKG_VERSION:=7.04
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/openconnect/
-PKG_MD5SUM:=7e28e23c6e281be31446e6c365f5d273
+PKG_MD5SUM:=828fe81388b7ea1155419b8be64a350f
+
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_OPENCONNECT_GNUTLS \
+       CONFIG_OPENCONNECT_OPENSSL \
+
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -24,7 +29,7 @@ endef
 define Package/openconnect
   SECTION:=net
   CATEGORY:=Network
-  DEPENDS:=+libxml2 +kmod-tun +resolveip +OPENCONNECT_OPENSSL:libopenssl +OPENCONNECT_GNUTLS:libgnutls
+  DEPENDS:=+libxml2 +kmod-tun +resolveip +OPENCONNECT_OPENSSL:libopenssl +OPENCONNECT_GNUTLS:libgnutls +OPENCONNECT_STOKEN:libstoken
   TITLE:=OpenConnect VPN client (Cisco AnyConnect compatible)
   MAINTAINER:=Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
   URL:=http://www.infradead.org/openconnect/
@@ -42,13 +47,20 @@ endef
 
 CONFIGURE_ARGS += \
        --disable-shared \
-       --with-vpnc-script=/lib/netifd/vpnc-script
+       --with-vpnc-script=/lib/netifd/vpnc-script \
+       --without-libpcsclite \
+       --without-stoken
 
 ifeq ($(CONFIG_OPENCONNECT_OPENSSL),y)
 CONFIGURE_ARGS += \
        --without-gnutls
 endif
 
+ifeq ($(CONFIG_OPENCONNECT_STOKEN),y)
+CONFIGURE_ARGS += \
+       --with-stoken
+endif
+
 define Package/openconnect/install
        $(INSTALL_DIR) $(1)/etc/openconnect/
        $(INSTALL_DIR) $(1)/lib/netifd/proto
@@ -57,6 +69,8 @@ define Package/openconnect/install
        $(INSTALL_DIR) $(1)/usr/sbin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/openconnect $(1)/usr/sbin/
        $(INSTALL_BIN) ./files/openconnect-wrapper $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
+       $(INSTALL_DATA) ./files/openconnect.upgrade $(1)/lib/upgrade/keep.d/openconnect
 endef
 
 $(eval $(call BuildPackage,openconnect))
index fd2a1f936f4b7f254a7a786f348cec163648ae5c..3cd562194adcf4e9478f2c7005e72521f113ef69 100644 (file)
@@ -3,19 +3,20 @@ The openconnect client expects to be configured using the uci interface.
 To setup a VPN connection, add the following to /etc/config/network:
 
 config interface 'MYVPN'
-        option _orig_ifname 'vpnc'
-        option _orig_bridge 'false'
         option proto 'openconnect'
         option server 'vpn.example.com'
         option port '4443'
         option username 'test'
         option password 'secret'
         option serverhash 'AE7FF6A0426F0A0CD0A02EB9EC3C5066FAEB0B25'
+        option token_mode 'rsa' # when built with stoken support
+        option token_secret 'secret' # when built with stoken support
+        option authgroup 'DEFAULT'
 
 The additional files are also used:
 /etc/openconnect/user-cert-vpn-MYVPN.pem: The user certificate
 /etc/openconnect/user-key-vpn-MYVPN.pem: The user private key
-/etc/openconnect/ca-cert-vpn-MYVPN.pem: The CA certificate (instead of serverhash)
+/etc/openconnect/ca-vpn-MYVPN.pem: The CA certificate (instead of serverhash)
 
 After these are setup you can initiate the VPN using "ifup MYVPN", and
 deinitialize it using ifdown. You may also use the luci web interface
@@ -26,4 +27,4 @@ the MYVPN interface and lan.
 
 
 There is a luci plugin to allow configuring an openconnect interface from
-the web environment; see the luci-protocol-openconnect package.
+the web environment; see the luci-proto-openconnect package.
index 744e5a5cd00ee22a24ea10623a07757abbd15f86..082dfba73ae551ca9fdf36b9ebe2fc06f10de2d7 100755 (executable)
@@ -22,7 +22,17 @@ cleanup()
        exit 0
 }
 
-trap cleanup 1 2 3 6 15
+cleanup2()
+{
+       if ! test -z "$pid";then
+               kill -2 $pid
+               wait $pid
+       fi
+       exit 0
+}
+
+trap cleanup2 2
+trap cleanup 1 3 6 15
 
 rm -f "$pidfile"
 /usr/sbin/openconnect $* <$pwfile &
index ad708073a39048fa5734d942d90ea66713e9c184..cd97c2cb254de690facc0c0346be43c95b55f572 100755 (executable)
@@ -17,7 +17,7 @@ proto_openconnect_init_config() {
 proto_openconnect_setup() {
        local config="$1"
 
-       json_get_vars server port username serverhash authgroup password vgroup
+       json_get_vars server port username serverhash authgroup password vgroup token_mode token_secret
 
        grep -q tun /proc/modules || insmod tun
 
@@ -38,10 +38,21 @@ proto_openconnect_setup() {
 
        cmdline="$server$port -i vpn-$config --non-inter --syslog --script /lib/netifd/vpnc-script"
 
-       [ -f /etc/openconnect/ca-vpn-$config.pem ] && append cmdline "--cafile /etc/openconnect/ca-vpn-$config.pem"
+       # migrate to standard config files
+       [ -f "/etc/config/openconnect-user-cert-vpn-$config.pem" ] && mv "/etc/config/openconnect-user-cert-vpn-$config.pem" "/etc/openconnect/user-cert-vpn-$config.pem"
+       [ -f "/etc/config/openconnect-user-key-vpn-$config.pem" ] && mv "/etc/config/openconnect-user-key-vpn-$config.pem" "/etc/openconnect/user-key-vpn-$config.pem"
+       [ -f "/etc/config/openconnect-ca-vpn-$config.pem" ] && mv "/etc/config/openconnect-ca-vpn-$config.pem" "/etc/openconnect/ca-vpn-$config.pem"
+
        [ -f /etc/openconnect/user-cert-vpn-$config.pem ] && append cmdline "-c /etc/openconnect/user-cert-vpn-$config.pem"
        [ -f /etc/openconnect/user-key-vpn-$config.pem ] && append cmdline "--sslkey /etc/openconnect/user-key-vpn-$config.pem"
-       [ -n "$serverhash" ] && append cmdline "--servercert=$serverhash"
+       [ -f /etc/openconnect/ca-vpn-$config.pem ] && {
+               append cmdline "--cafile /etc/openconnect/ca-vpn-$config.pem"
+               append cmdline "--no-system-trust"
+       }
+       [ -n "$serverhash" ] && {
+               append cmdline " --servercert=$serverhash"
+               append cmdline "--no-system-trust"
+       }
        [ -n "$authgroup" ] && append cmdline "--authgroup $authgroup"
        [ -n "$username" ] && append cmdline "-u $username"
        [ -n "$password" ] && {
@@ -51,10 +62,13 @@ proto_openconnect_setup() {
                append cmdline "--passwd-on-stdin"
        }
 
+       [ -n "$token_mode" ] && append cmdline "--token-mode=$token_mode"
+       [ -n "$token_secret" ] && append cmdline "--token-secret=$token_secret"
+
        proto_export INTERFACE="$config"
        logger -t openconnect "executing 'openconnect $cmdline'"
 
-       if [ -f "$pwfile" ];then
+       if [ -f "$pwfile" ]; then
                proto_run_command "$config" /usr/sbin/openconnect-wrapper $pwfile $cmdline
        else
                proto_run_command "$config" /usr/sbin/openconnect $cmdline
@@ -68,7 +82,7 @@ proto_openconnect_teardown() {
 
        rm -f $pwfile
        logger -t openconnect "bringing down openconnect"
-       proto_kill_command "$config"
+       proto_kill_command "$config" 2
 }
 
 add_protocol openconnect
diff --git a/net/openconnect/files/openconnect.upgrade b/net/openconnect/files/openconnect.upgrade
new file mode 100644 (file)
index 0000000..0e9192d
--- /dev/null
@@ -0,0 +1,3 @@
+/etc/openconnect/user-cert-vpn-*.pem
+/etc/openconnect/user-key-vpn-*.pem
+/etc/openconnect/ca-vpn-*.pem
index c8151471b947d09708d5cd729689bdef25e21006..c6007ab8562427645b24d4fe868f7883ffbab13c 100755 (executable)
@@ -26,6 +26,8 @@
 #* CISCO_IPV6_SPLIT_INC_%d_ADDR -- IPv6 network address
 #* CISCO_IPV6_SPLIT_INC_$%d_MASKLEN -- IPv6 subnet masklen
 
+HOOKS_DIR=/etc/openconnect
+
 # FIXMEs:
 
 # Section A: route handling
 
 # Section B: Split DNS handling
 
-# 1) Maybe dnsmasq can do something like that
-# 2) Parse dns packets going out via tunnel and redirect them to original dns-server
+# 1) We parse CISCO_SPLIT_DNS and use dnsmasq to set it
 
 do_connect() {
        if [ -n "$CISCO_BANNER" ]; then
                logger -t openconnect "Connect Banner:"
-               logger -t openconnect "$CISCO_BANNER" | while read LINE ; do logger -t openconnect "|" "$LINE" ; done
+               echo "$CISCO_BANNER" | while read LINE ; do logger -t openconnect "|" "$LINE" ; done
        fi
 
        proto_init_update "$TUNDEV" 1
@@ -80,8 +81,24 @@ do_connect() {
                [[ "$addr" != "$mask" ]] && proto_add_ipv6_address "$addr" "$mask"
        fi
 
-       [ -n "$INTERNAL_IP4_DNS" ] && proto_add_dns_server "$INTERNAL_IP4_DNS"
-       [ -n "$CISCO_DEF_DOMAIN" ] && proto_add_dns_search "$CISCO_DEF_DOMAIN"
+       if [ -n "$CISCO_SPLIT_DNS" ] && [ -d "/tmp/dnsmasq.d/" ];then
+               SDNS=`echo $CISCO_SPLIT_DNS|sed 's/,/\n/g'`
+               DNSMASQ_FILE="/tmp/dnsmasq.d/openconnect.$TUNDEV"
+               rm -f $DNSMASQ_FILE
+               echo "$SDNS" | while read i; do
+                       if [ -n "$INTERNAL_IP4_DNS" ];then
+                               echo "server=/$i/$INTERNAL_IP4_DNS" >> $DNSMASQ_FILE
+                       fi
+                       if [ -n "$INTERNAL_IP6_DNS" ];then
+                               echo "server=/$i/$INTERNAL_IP6_DNS" >> $DNSMASQ_FILE
+                       fi
+                       echo "rebind-domain-ok=$i" >> $DNSMASQ_FILE
+               done
+               /etc/init.d/dnsmasq restart
+       else
+               [ -n "$INTERNAL_IP4_DNS" ] && proto_add_dns_server "$INTERNAL_IP4_DNS"
+               [ -n "$CISCO_DEF_DOMAIN" ] && proto_add_dns_search "$CISCO_DEF_DOMAIN"
+       fi
 
        if [ -n "$CISCO_SPLIT_INC" ]; then
                i=0
@@ -118,10 +135,22 @@ do_connect() {
 }
 
 do_disconnect() {
+       rm -f "/tmp/dnsmasq.d/openconnect.$TUNDEV"
        proto_init_update "$TUNDEV" 0
        proto_send_update "$INTERFACE"
 }
 
+#### Hooks
+run_hooks() {
+       HOOK="$1"
+
+       if [ -d ${HOOKS_DIR}/${HOOK}.d ]; then
+               for script in ${HOOKS_DIR}/${HOOK}.d/* ; do
+                       [ -f $script ] && . $script
+               done
+       fi
+}
+
 #### Main
 
 if [ -z "$reason" ]; then
@@ -137,14 +166,20 @@ fi
 
 case "$reason" in
        pre-init)
+               run_hooks pre-init
                ;;
        connect)
+               run_hooks connect
                do_connect
+               run_hooks post-connect
                ;;
        disconnect)
+               run_hooks disconnect
                do_disconnect
+               run_hooks post-disconnect
                ;;
        reconnect)
+               run_hooks reconnect
                ;;
        *)
                logger -t openconnect "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
diff --git a/net/openconnect/patches/001-Added-a-default-timeout-value-in-CSTP-handshake-usin.patch b/net/openconnect/patches/001-Added-a-default-timeout-value-in-CSTP-handshake-usin.patch
deleted file mode 100644 (file)
index 8981805..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 826ad45a86f1556910c2f00dfa6477879deb978f Mon Sep 17 00:00:00 2001
-From: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-Date: Thu, 24 Jul 2014 21:59:01 +0200
-Subject: [PATCH] Added a default timeout value in CSTP handshake using gnutls
-
-[dwmw2: move it to openconnect_open_https() so it's done only once]
-
-Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
----
- gnutls.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/gnutls.c b/gnutls.c
-index 3e3204a..2ef836c 100644
---- a/gnutls.c
-+++ b/gnutls.c
-@@ -2017,6 +2017,10 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
-       vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
-                    vpninfo->hostname);
-+#ifdef GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT
-+      gnutls_handshake_set_timeout(vpninfo->https_sess,
-+                                   GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
-+#endif
-       err = cstp_handshake(vpninfo, 1);
-       if (err)
--- 
-2.0.0
-
index a635e07fe159749d0013499e13e556ec98a46aa5..055b0030e01b33161d384f3394fb421989a611ef 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2006-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=openssh
-PKG_VERSION:=6.6p1
-PKG_RELEASE:=1
+PKG_VERSION:=6.7p1
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/ \
                http://ftp.belnet.be/pub/OpenBSD/OpenSSH/portable/
-PKG_MD5SUM:=3e9800e6bca1fbac0eea4d41baa7f239
+PKG_MD5SUM:=3246aa79317b1d23cae783a3bf8275d6
 
 PKG_LICENSE:=BSD ISC
-PKG_LICENSE_FILE:=LICENCE
+PKG_LICENSE_FILES:=LICENCE
 
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
@@ -83,6 +83,7 @@ define Package/openssh-server
        $(call Package/openssh/Default)
        DEPENDS+= +openssh-keygen
        TITLE+= server
+       USERID:=sshd=22:sshd=22
 endef
 
 define Package/openssh-server/description
@@ -98,6 +99,7 @@ define Package/openssh-server-pam
        DEPENDS+= +libpthread +openssh-keygen +libpam
        TITLE+= server (with PAM support)
        VARIANT:=with-pam
+       USERID:=sshd=22:sshd=22
 endef
 
 define Package/openssh-server-pam/description
@@ -129,6 +131,21 @@ define Package/openssh-sftp-server/description
 OpenSSH SFTP server.
 endef
 
+define Package/openssh-sftp-avahi-service
+       $(call Package/openssh/Default)
+       TITLE+= (SFTP Avahi service)
+       DEPENDS:=+openssh-sftp-server +avahi-daemon
+endef
+
+define Package/openssh-sftp-avahi-service/description
+ This package contains the service definition for announcing
+ SFTP support via mDNS/DNS-SD.
+endef
+
+define Package/openssh-sftp-avahi-service/conffiles
+/etc/avahi/services/sftp-ssh.service
+endef
+
 CONFIGURE_ARGS+= \
        $(DISABLE_NLS) \
        --sysconfdir=/etc/ssh \
@@ -257,6 +274,11 @@ define Package/openssh-sftp-server/install
        ln -sf ../lib/sftp-server $(1)/usr/libexec/sftp-server
 endef
 
+define Package/openssh-sftp-avahi-service/install
+       $(INSTALL_DIR) $(1)/etc/avahi/services
+       $(INSTALL_DATA) ./files/sftp-ssh.service $(1)/etc/avahi/services/
+endef
+
 $(eval $(call BuildPackage,openssh-client))
 $(eval $(call BuildPackage,openssh-moduli))
 $(eval $(call BuildPackage,openssh-client-utils))
@@ -265,3 +287,4 @@ $(eval $(call BuildPackage,openssh-server))
 $(eval $(call BuildPackage,openssh-server-pam))
 $(eval $(call BuildPackage,openssh-sftp-client))
 $(eval $(call BuildPackage,openssh-sftp-server))
+$(eval $(call BuildPackage,openssh-sftp-avahi-service))
diff --git a/net/openssh/files/sftp-ssh.service b/net/openssh/files/sftp-ssh.service
new file mode 100644 (file)
index 0000000..17e0927
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+ <name replace-wildcards="yes">%h</name>
+  <service>
+   <type>_sftp-ssh._tcp</type>
+   <port>22</port>
+  </service>
+</service-group>
index 879df12cdb9e44357d3770e1533879e5cee5b8d5..c5a54e0079a6926056d29575ac917af2fbe631a1 100644 (file)
@@ -18,8 +18,6 @@ start_service() {
                        }
                }
        }; done
-       user_exists sshd 22 || user_add sshd 22 22 sshd /var/empty
-       group_exists sshd 22 || group_add sshd 22 
        mkdir -m 0700 -p /var/empty
 
        procd_open_instance
index 751e5896fe48d7047591b6b44717228ee007fafb..5a4ecb1223e62b83d838df15d18575912bf196ef 100644 (file)
@@ -1,6 +1,6 @@
 --- a/cipher.c
 +++ b/cipher.c
-@@ -80,8 +80,10 @@ static const struct Cipher ciphers[] = {
+@@ -88,8 +88,10 @@ static const struct sshcipher ciphers[]
        { "3des-cbc",   SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
        { "blowfish-cbc",
                        SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
index bfcf65cba88c04a77784eda840646e1b3d70d984..9fafaf2e384fb72d97175827fbad304d5098c1e3 100644 (file)
@@ -8,9 +8,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=opentracker
-PKG_VERSION:=20130804
+PKG_VERSION:=20141007
 PKG_RELEASE:=1
-PKG_REV:=954f5029dfa17734dc408336ef710c192268e8a4
+PKG_REV:=6c60309745ced3c121a2c5c7d80ed85a573b848e
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=Beerware
 
index f3f9038028cebcc509c471a4e1522186a8bdfb46..bbaf8d99e60451ef4631cc89e2dae7630c6aea2f 100644 (file)
@@ -1,7 +1,5 @@
-Index: opentracker-20130804/Makefile
-===================================================================
---- opentracker-20130804.orig/Makefile
-+++ opentracker-20130804/Makefile
+--- a/Makefile
++++ b/Makefile
 @@ -9,13 +9,13 @@ CC?=gcc
  
  # BSD flavour
index 710e89845a573599604fd852063f9784240cd704..7f3737cfba0488a4ff5e95bb651dd408e60a6b48 100644 (file)
@@ -11,21 +11,22 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=openvswitch
 
-PKG_RELEASE:=1
-PKG_VERSION:=2.3.0
+PKG_RELEASE:=2
+PKG_VERSION:=2.3.1
 PKG_RELEASE=$(PKG_SOURCE_VERSION)
 PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_USE_MIPS16:=0
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/openvswitch/ovs
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=2b70c4b929d18d1f36dcdeb71ea5c383cbb662e9
+PKG_SOURCE_VERSION:=0dfed4ba9c8a16a1f316d709b7831a4e139472d4
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/kernel.mk
+$(call include_mk, python-package.mk)
 
 PKG_FIXUP=libtool
 
@@ -56,6 +57,27 @@ define Package/openvswitch/description
   Provides the main userspace components required for Open vSwitch to function.
 endef
 
+define Package/openvswitch-python
+  $(call Package/openvswitch/Default)
+  TITLE:=Open vSwitch Python Support
+  DEPENDS:=@PACKAGE_openvswitch +PACKAGE_openvswitch:openvswitch +python
+endef
+
+define Package/openvswitch-python/description
+  Provides bindings and libraries for using Python to manipulate/work with Open vSwitch.
+endef
+
+define Package/openvswitch-ipsec
+  $(call Package/openvswitch/Default)
+  TITLE:=Open vSwitch Userspace Package
+  DEPENDS:=@PACKAGE_openvswitch +PACKAGE_openvswitch:openvswitch-python
+endef
+
+define Package/openvswitch-ipsec/description
+  The ovs-monitor-ipsec script provides support for encrypting GRE tunnels with 
+  IPsec.
+endef
+
 define Package/openvswitch-benchmark
   $(call Package/openvswitch/Default)
   TITLE:=Open vSwitch Userspace Package
@@ -72,7 +94,7 @@ define KernelPackage/openvswitch
   SUBMENU:=Network Support
   TITLE:=Open vSwitch Kernel Package
   KCONFIG:=CONFIG_BRIDGE
-  DEPENDS:=+kmod-stp +kmod-ipv6 +kmod-gre +kmod-lib-crc32c
+  DEPENDS:=+kmod-stp +kmod-ipv6 +kmod-gre +kmod-lib-crc32c +kmod-vxlan
   FILES:= \
        $(PKG_BUILD_DIR)/datapath/linux/openvswitch.$(LINUX_KMOD_SUFFIX)
   AUTOLOAD:=$(call AutoLoad,21,openvswitch)
@@ -97,6 +119,11 @@ define Build/Configure
        $(call Build/Configure/Default,$(CONFIGURE_ARGS))
 endef
 
+KCFLAGS=
+ifeq ($(CONFIG_GCC_VERSION_4_9),y)
+KCFLAGS:=-Wno-error=date-time
+endif
+
 define Build/Compile
        $(MAKE) -C $(PKG_BUILD_DIR) \
                $(TARGET_CONFIGURE_OPTS) \
@@ -109,6 +136,7 @@ define Build/Compile
                ARCH="$(LINUX_KARCH)" \
                SUBDIRS="$(PKG_BUILD_DIR)/datapath/linux" \
                PATH="$(TARGET_PATH)" \
+               EXTRA_CFLAGS="$(KCFLAGS)" \
                KCC="$(KERNEL_CC)"
 endef
 
@@ -141,6 +169,16 @@ define Package/openvswitch/install
        $(INSTALL_CONF) $(PKG_BUILD_DIR)/vswitchd/vswitch.ovsschema $(1)/usr/share/openvswitch/
 endef
 
+define Package/openvswitch-python/install
+       $(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON_VERSION)/
+       $(CP) $(PKG_BUILD_DIR)/python/ovs/ $(1)/usr/lib/python$(PYTHON_VERSION)/
+endef
+
+define Package/openvswitch-ipsec/install
+       $(INSTALL_DIR) $(1)/usr/sbin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/debian/ovs-monitor-ipsec $(1)/usr/sbin/
+endef
+
 define Package/openvswitch-benchmark/install
        $(INSTALL_DIR) $(1)/usr/bin/
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/.libs/ovs-benchmark $(1)/usr/bin/
@@ -152,6 +190,8 @@ define Package/openvswitch/postinst
 endef
 
 $(eval $(call BuildPackage,openvswitch))
+$(eval $(call BuildPackage,openvswitch-python))
+$(eval $(call BuildPackage,openvswitch-ipsec))
 $(eval $(call BuildPackage,openvswitch-benchmark))
 $(eval $(call KernelPackage,openvswitch))
 
diff --git a/net/openvswitch/patches/0004-datapath-Use-ccflags-y-instead-of-deprecated-EXTRA_C.patch b/net/openvswitch/patches/0004-datapath-Use-ccflags-y-instead-of-deprecated-EXTRA_C.patch
new file mode 100644 (file)
index 0000000..95891a1
--- /dev/null
@@ -0,0 +1,41 @@
+From 36fd4f214f9ba74aaf0e5fb3e4ba271b946a1550 Mon Sep 17 00:00:00 2001
+From: Thomas Graf <tgraf@noironetworks.com>
+Date: Wed, 26 Nov 2014 15:52:31 +0100
+Subject: [PATCH] datapath: Use ccflags-y instead of deprecated EXTRA_CFLAGS
+
+This allows users to pass in additional compiler flags through the
+environment variable EXTRA_CFLAGS, e.g.
+
+   make EXTRA_CFLAGS=-Wno-error=foo V=1
+
+Reported-by: Alexandru Ardelean <ardeleanalex@gmail.com>
+Signed-off-by: Thomas Graf <tgraf@noironetworks.com>
+Acked-by: Pravin B Shelar <pshelar@nicira.com>
+---
+ datapath/linux/Kbuild.in | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/datapath/linux/Kbuild.in b/datapath/linux/Kbuild.in
+index 6f6f65f..cb98c11 100644
+--- a/datapath/linux/Kbuild.in
++++ b/datapath/linux/Kbuild.in
+@@ -7,11 +7,11 @@ export VERSION = @VERSION@
+ include $(srcdir)/../Modules.mk
+ include $(srcdir)/Modules.mk
+-EXTRA_CFLAGS := -DVERSION=\"$(VERSION)\"
+-EXTRA_CFLAGS += -I$(srcdir)/..
+-EXTRA_CFLAGS += -I$(builddir)/..
+-EXTRA_CFLAGS += -g
+-EXTRA_CFLAGS += -include $(builddir)/kcompat.h
++ccflags-y := -DVERSION=\"$(VERSION)\"
++ccflags-y += -I$(srcdir)/..
++ccflags-y += -I$(builddir)/..
++ccflags-y += -g
++ccflags-y += -include $(builddir)/kcompat.h
+ # These include directories have to go before -I$(KSRC)/include.
+ # NOSTDINC_FLAGS just happens to be a variable that goes in the
+-- 
+2.1.2
+
diff --git a/net/pen/Makefile b/net/pen/Makefile
new file mode 100644 (file)
index 0000000..52357f7
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=pen
+PKG_VERSION:=0.25.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://siag.nu/pub/pen/
+PKG_MD5SUM:=13e517350ec3fbfa06a512a36067ae2b
+
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/pen
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+libopenssl
+  TITLE:=Simple TCP load balancer
+  URL:=http://morestuff.siag.nu/category/pen/
+endef
+
+define Package/pen/description
+       This is pen, a load balancer for "simple" TCP based protocols
+       such as HTTP or SMTP. It allows several servers to appear as
+       one to the outside and automatically detects servers that are
+       down and distributes clients among the available servers.
+       This gives high availability and scalable performance.
+endef
+
+CONFIGURE_ARGS += \
+               --with-poll \
+               --with-ssl="$(STAGING_DIR)/usr" \
+               --without-geoip \
+
+define Package/pen/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/mergelogs $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/pen $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/penctl $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/penlog $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/penlogd $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/penctl.cgi $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/penstats $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,pen))
index 1f1858c8501b4078995cd73d6ad56cea22023cd6..03969f79d6a1ec4eb8224462131a82151068eaa6 100644 (file)
@@ -29,6 +29,7 @@ define Package/portmap
   TITLE:=The RPC Portmapper
   URL:=http://neil.brown.name/portmap/
   MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+  USERID:=rpc=65533:rpc=65533
 endef
 
 define Package/portmap/description
index e3e27b7ede35b69379360cce84def09551519865..621c313a07fa08eb0cadc31c0bfd66138d3d6ff2 100644 (file)
@@ -7,9 +7,6 @@ STOP=19
 USE_PROCD=1
 
 start_service() {
-       user_exists rpc 65533 || user_add rpc 65533 65533 rpc /var/empty
-       group_exists rpc 65533 || group_add rpc 65533
-       
        procd_open_instance
        procd_set_param command /usr/sbin/portmap -f
        procd_close_instance
diff --git a/net/privoxy/Makefile b/net/privoxy/Makefile
new file mode 100644 (file)
index 0000000..4209cae
--- /dev/null
@@ -0,0 +1,166 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=privoxy
+PKG_VERSION:=3.0.22
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-stable-src.tar.gz
+PKG_SOURCE_URL:=@SF/ijbswa
+PKG_MD5SUM:=aa121751d332a51d37d3c6e4b7594daa
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-stable
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=christian.schoenebeck@gmail.com
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/privoxy
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Web Servers/Proxies
+  DEPENDS:=+libpcre +libpthread +zlib
+  TITLE:=web proxy with advanced filtering capabilities
+  URL:=http://www.privoxy.org/
+  USERID:=privoxy=8118:privoxy=8118
+endef
+
+define Package/privoxy/description
+Privoxy is a web proxy with advanced filtering capabilities for
+ protecting privacy, modifying web page content, managing cookies,
+ controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. Privoxy has a very flexible configuration
+ and can be customized to suit individual needs and tastes. Privoxy
+ has application for both stand-alone systems and multi-user networks.
+Version: $(PKG_VERSION)-$(PKG_RELEASE)
+endef
+
+CONFIGURE_ARGS += \
+       --sysconfdir=/etc/privoxy
+
+# needed otherwise errors during compile
+MAKE_FLAGS:=
+
+define Build/Install
+       $(call Build/Install/Default,)
+       # rename original sample config from pkg_source to save existing one during install
+       mv $(PKG_INSTALL_DIR)/etc/privoxy/config $(PKG_INSTALL_DIR)/etc/privoxy/config.privoxy
+endef
+
+define Package/privoxy/conffiles
+/etc/config/privoxy
+/etc/privoxy/config    # temporary needed if updating from old version
+endef
+
+define Package/privoxy/preinst
+       #!/bin/sh
+       # if run within buildroot exit
+       [ -n "$${IPKG_INSTROOT}" ] && exit 0
+       # stop service if PKG_UPGRADE
+       [ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/privoxy stop >/dev/null 2>&1
+       exit 0  # supress errors from stop command
+endef
+
+define Package/privoxy/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(CP) $(PKG_INSTALL_DIR)/usr/sbin/privoxy $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/privoxy.init $(1)/etc/init.d/privoxy
+       $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+       $(INSTALL_BIN) ./files/privoxy.hotplug $(1)/etc/hotplug.d/iface/80-privoxy
+
+       $(INSTALL_DIR) $(1)/etc/privoxy
+       $(CP) $(PKG_INSTALL_DIR)/etc/privoxy/* $(1)/etc/privoxy/
+       # temporary needed if updating from old version
+       # otherwise old config file will be delete by opkg
+       $(INSTALL_CONF) ./files/privoxy.oldconfig $(1)/etc/privoxy/config
+       # create .old file to be removed with next pacakge builds during update
+       $(INSTALL_CONF) ./files/privoxy.oldconfig $(1)/etc/privoxy/config.old
+       # copy NEW config
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/privoxy.config $(1)/etc/config/privoxy
+endef
+
+define Package/privoxy/postinst
+       #!/bin/sh
+
+       # if fresh install we don't need old config file in privoxy directory
+       [ "$${PKG_UPGRADE}" = "0" ] && rm -f /etc/privoxy/config
+
+       # if run within buildroot exit here
+       [ -n "$${IPKG_INSTROOT}" ] && exit 0
+
+       # if PKG_UPGRADE then build uci configuration
+       # from existing(?) old /etc/privoxy/config file
+       if [ "$${PKG_UPGRADE}" = "1" -a -f /etc/privoxy/config ]; then
+
+               echo "converting OLD config to NEW uci configuration"
+
+               SECTION="privoxy.privoxy"
+               CFGFILE=/etc/privoxy/config
+
+               echo -n > /etc/config/privoxy           # clear/create uci configuration file
+               cp -f $${CFGFILE} $${CFGFILE}.old       # save old configuration
+
+               # cleanup
+               sed -i 's/^[ \t]*//;s/[ \t]*$$//' $${CFGFILE}   # remove invisible chars at beginning and end of lines
+               sed -i '/^#/d' $${CFGFILE}                      # remove lines with "#"
+               sed -i '/^$$/d' $${CFGFILE}                     # remove empty lines
+
+               uci -q set $${SECTION}="privoxy"                # create section
+
+               cat $${CFGFILE} | while read LINE; do
+                       # option is first parameter; uci did not like "-" in option names
+                       OPT=$$(echo $${LINE} | awk '{print $$1}' | sed 's/-/_/g')
+                       VAL=$$(echo $${LINE} | awk '{print $$2}')
+                       case $${OPT} in
+                               # debug 1024 => debug_1024 '1'
+                               debug)
+                                       uci -q set $${SECTION}.debug_$${VAL}="1"
+                                       ;;
+                               # handle list values; splitted case for better reading
+                               actionsfile|filterfile|listen_address)
+                                       uci -q add_list $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                               permit_access|deny_access)
+                                       uci -q add_list $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                               trust_info_url|forward)
+                                       uci -q add_list $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                               forward_socks4|forward_socks4a)
+                                       uci -q add_list $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                               forward_socks5|forward_socks5t)
+                                       uci -q add_list $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                               # all others are normal options
+                               *)
+                                       uci -q set $${SECTION}.$${OPT}="$${VAL}"
+                                       ;;
+                       esac
+               done
+               uci -q commit privoxy   # commit changes
+               rm -f $${CFGFILE}       # remove old configuration file
+       fi
+
+       # set permissions to privoxy group
+       echo "setting permissions"
+       chgrp -R privoxy /etc/privoxy/*
+       chmod 664 /etc/privoxy/*
+       chmod 755 /etc/privoxy/templates
+       chmod 644 /etc/privoxy/templates/*
+endef
+
+$(eval $(call BuildPackage,privoxy))
diff --git a/net/privoxy/files/privoxy.config b/net/privoxy/files/privoxy.config
new file mode 100644 (file)
index 0000000..50e401f
--- /dev/null
@@ -0,0 +1,43 @@
+# this file support all available configuration options of
+# Privoxy web-proxy
+# the scripts move all options to the final privoxy readable configuration file
+#
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !!! privoxy uses "-" in option names but uci only support "_"         !!!
+# !!! privoxy "listen-address" must be uci "listen_address"             !!!
+# !!!                                                                   !!!
+# !!! if you add entries please use                                      !!!
+# !!! option for options with one parameter (option confdir)             !!!
+# !!! list   for options with multiple parameters (list listen_address) !!!
+# !!!                                                                   !!!
+# !!! special handling for debug option                                 !!!
+# !!! privoxy option "debug 1024" must be uci option debug_1024 '1'     !!!
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#
+config privoxy 'privoxy'
+       option  confdir         '/etc/privoxy'
+       option  logdir          '/var/log'
+       option  logfile         'privoxy.log'
+       list    filterfile      'default.filter'
+       list    actionsfile     'match-all.action'
+       list    actionsfile     'default.action'
+#      list    actionsfile     'user.action'
+       list    listen_address  '127.0.0.1:8118'
+       list    listen_address  '192.168.1.1:8118'
+       option  toggle          '1'
+       option  enable_remote_toggle    '1'
+       option  enable_remote_http_toggle       '0'
+       option  enable_edit_actions     '1'
+       option  enforce_blocks          '0'
+       option  buffer_limit            '4096'
+       option  forwarded_connect_retries       '0'
+       option  accept_intercepted_requests     '0'
+       option  allow_cgi_request_crunching     '0'
+       option  split_large_forms       '0'
+       option  keep_alive_timeout      '300'
+       option  socket_timeout          '300'
+       list    permit_access           '192.168.1.0/24'
+       option  debug_1         '0'
+       option  debug_1024      '0'
+       option  debug_4096      '1'
+       option  debug_8192      '1'
diff --git a/net/privoxy/files/privoxy.hotplug b/net/privoxy/files/privoxy.hotplug
new file mode 100644 (file)
index 0000000..bd66801
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# only (re-)start on ifup
+[ "$ACTION" = "ifup" ] || exit 0
+
+PIDFILE=/var/run/privoxy.pid
+
+_PID=$(cat $PIDFILE 2>/dev/null)
+kill -1 $_PID 2>/dev/null
+if [ $? -eq 0 ]; then
+       # only restart if already running
+       logger -p daemon.info -t "privoxy[$_PID]" \
+               "Restart request due to '$ACTION' of interface '$INTERFACE'"
+       /etc/init.d/privoxy restart
+else
+       # only start if enabled
+       /etc/init.d/privoxy enabled && /etc/init.d/privoxy start
+fi
diff --git a/net/privoxy/files/privoxy.init b/net/privoxy/files/privoxy.init
new file mode 100644 (file)
index 0000000..8ffc6f2
--- /dev/null
@@ -0,0 +1,119 @@
+#!/bin/sh /etc/rc.common
+
+START=80
+STOP=20
+
+PIDFILE=/var/run/privoxy.pid
+CFGFILE=/var/etc/privoxy.conf
+CFGTEMP=/var/etc/privoxy.conf.tmp
+
+_uci2conf() {
+       local _LOGDIR="/var/log"        # set default
+       local _LOGFILE="privoxy.log"    # set default
+
+       # redefined callback for options when calling config_load
+       option_cb()
+       {
+               # $1    name of variable
+               # $2    value
+               local __OPT="$1"
+               local __VAL="$2"
+               case $__OPT in
+                       logdir)         # logdir handled later
+                               _LOGDIR="$__VAL"  ;;
+                       logfile)        # logfile handled later
+                               _LOGFILE="$__VAL" ;;
+                       *)
+                               # detect list options (LENGTH) and ignore
+                               echo $__OPT | grep -i "_LENGTH" >/dev/null 2>&1 && return
+                               # detect list options (ITEM) and ignore
+                               echo $__OPT | grep -i "_ITEM" >/dev/null 2>&1 && __OPT=$(echo $__OPT | sed -e "s#_ITEM.##g")
+                               # filter debug_*
+                               echo $__OPT | grep -i "debug_" >/dev/null 2>&1 && {
+                                       [ $__VAL -eq 0 ] && return      # not set ignore
+                                       __VAL=$(echo $__OPT | sed -e "s#debug_##g")
+                                       __OPT="debug"
+                               }
+                               # uci only accept "_" but we need "-"
+                               local __OPT=$(echo $__OPT | sed -e "s#_#-#g")
+                               # write to config
+                               echo -e "$__OPT\t$__VAL" >> $CFGTEMP
+                               ;;
+               esac
+       }
+
+       mkdir -m0755 -p /var/etc
+       echo "" > $CFGTEMP      # create tmp config file
+       chmod 644 $CFGTEMP      # garantee that privoxy can read
+       chgrp privoxy $CFGTEMP
+
+       echo '### AUTO-GENERATED CONFIGURATION'    >> $CFGTEMP
+       echo '### USED BY PRIVOXY'                 >> $CFGTEMP
+       echo '### DO NOT EDIT'                     >> $CFGTEMP
+       echo '### SEE /etc/config/privoxy INSTEAD' >> $CFGTEMP
+       echo ''                                    >> $CFGTEMP
+
+       config_load privoxy     # calling above option_cb()
+
+       # write logdir/logfile to config
+       echo -e "logdir\t$_LOGDIR" >> $CFGTEMP
+       echo -e "logfile\t$_LOGFILE" >> $CFGTEMP
+
+       # create logfile and set permissions
+       touch $_LOGDIR/$_LOGFILE
+       chmod 664 $_LOGDIR/$_LOGFILE
+       chown privoxy:privoxy $_LOGDIR/$_LOGFILE
+
+       # move temp to final privoxy readable configuration
+       mv -f $CFGTEMP $CFGFILE
+}
+
+boot() {
+       return 0        # will be started by "iface" hotplug events
+}
+
+start() {
+       # if already running do nothing
+       local _PID=$(cat $PIDFILE 2>/dev/null)
+       kill -1 $_PID 2>/dev/null && return 0
+
+       _uci2conf
+       /usr/sbin/privoxy --pidfile $PIDFILE --user privoxy.privoxy $CFGFILE
+
+       # verify startup
+       _PID=$(cat $PIDFILE 2>/dev/null)
+       kill -1 $_PID 2>/dev/null
+       local _ERR=$?
+       [ $_ERR -eq 0 ] \
+               && logger -p daemon.notice -t "privoxy[$_PID]" "Started successfully"\
+               || logger -p daemon.warn -t "privoxy[-----]" "Failed to start"
+       return $_ERR
+}
+
+reload() {
+       # reload is also used by luci-app-privoxy
+       local _PID=$(cat $PIDFILE 2>/dev/null)
+       kill -1 $_PID 2>/dev/null
+       if [ $? -eq 0 ]; then
+               # only restart if already running
+               restart
+       else
+               # only start if enabled
+               enabled && start
+       fi
+       return 0
+}
+
+stop() {
+       local _PID=$(cat $PIDFILE 2>/dev/null)
+       kill -15 $_PID 2>/dev/null
+       sleep 1                 # give time to shutdown
+       local _tmp=$(pgrep privoxy)
+       if [ -z "$_tmp" ]; then
+               logger -p daemon.notice -t "privoxy[$_PID]" "Shutdown successfully"
+       else
+               killall -9 privoxy
+               logger -p daemon.warn -t "privoxy[-----]" "Shutdown forced by KILL"
+       fi
+       return 0
+}
diff --git a/net/privoxy/files/privoxy.oldconfig b/net/privoxy/files/privoxy.oldconfig
new file mode 100644 (file)
index 0000000..9496356
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# original configuration file used by privoxy
+# this is no longer supported by this package
+# it's converted and moved to uci configuration
+# please look at /etc/config/privoxy
+#
+confdir /etc/privoxy
+logdir /var/log
+logfile privoxy.log
+filterfile default.filter
+actionsfile match-all.action # Actions that are applied to all sites and maybe overruled later on.
+actionsfile default.action   # Main actions file
+#actionsfile user.action      # User customizations
+listen-address  127.0.0.1:8118
+toggle  1
+enable-remote-toggle  1
+enable-remote-http-toggle  0
+enable-edit-actions 1
+enforce-blocks 0
+buffer-limit 4096
+forwarded-connect-retries  0
+accept-intercepted-requests 0
+allow-cgi-request-crunching 0
+split-large-forms 0
+keep-alive-timeout 300
+socket-timeout 300
+permit-access  192.168.1.0/24
+debug   1    # show each GET/POST/CONNECT request
+debug   4096 # Startup banner and warnings
+debug   8192 # Errors - *we highly recommended enabling this*
+#admin-address privoxy-admin@example.com
+#proxy-info-url http://www.example.com/proxy-service.html
+
index 4ba1d6fecd1406e1667a959b29802ed8b4c5e38d..a829ce8c20a4b2a2977e5dc24a792867c94dc225 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=prosody
-PKG_VERSION:=0.9.4
+PKG_VERSION:=0.9.7
 PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://prosody.im/downloads/source
-PKG_MD5SUM:=94f9a613c834c276352ac5b142fb72e0
+PKG_MD5SUM:=47de7f593279e327792df78cfa93e8a7
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
 PKG_LICENSE:=MIT/X11
 
@@ -28,6 +28,7 @@ define Package/prosody
   DEPENDS:=+luafilesystem +libidn +luaexpat +luasec +libopenssl +libidn +liblua 
   TITLE:=XMPP server
   URL:=http://prosody.im/
+  USERID:=prosody=54:prosody=54
 endef
 
 define Package/prosody/description
index 9dd74f594233fdaf48db8c2ece92e6564bb12eca..bab0ae7d5919c5952f3f2ba3c920614bb3fffbdc 100644 (file)
@@ -14,8 +14,6 @@ RUN_USER=prosody
 RUN_GROUP=prosody
 
 start() {
-       user_exists prosody 54 || user_add prosody 54
-       group_exists prosody 54 || group_add prosody 54
        [ -d /var/run/prosody ] || {
                mkdir -m 0755 -p /var/run/prosody
                chown prosody:prosody /var/run/prosody
diff --git a/net/prosody/patches/010-fix-randomseed.patch b/net/prosody/patches/010-fix-randomseed.patch
new file mode 100644 (file)
index 0000000..05bdffa
--- /dev/null
@@ -0,0 +1,12 @@
+diff -u --recursive prosody-0.9.7-vanilla/net/dns.lua prosody-0.9.7/net/dns.lua
+--- prosody-0.9.7-vanilla/net/dns.lua  2015-01-02 00:26:19.981433830 -0500
++++ prosody-0.9.7/net/dns.lua  2015-01-02 00:33:10.467077715 -0500
+@@ -225,7 +225,7 @@
+ function dns.random(...)    -- - - - - - - - - - - - - - - - - - -  dns.random
+-      math.randomseed(math.floor(10000*socket.gettime()) % 0x100000000);
++      math.randomseed(math.floor(10000*socket.gettime()) % 0x80000000);
+       dns.random = math.random;
+       return dns.random(...);
+ end
index b36503aa1c9d3390e1e9960532cab965eab7ee51..f155532c04c96db28de234ae366ae5a2928d4d9f 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=radsecproxy
-PKG_VERSION:=1.6.5
+PKG_VERSION:=1.6.6
 PKG_RELEASE:=1
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://software.uninett.no/radsecproxy/
-PKG_MD5SUM:=f74f82a7ae2cdf2b1d9d271a5c360617
+PKG_MD5SUM:=8270b2a9d7cb1dcf30ddd677f3e7ac5f
 
 PKG_INSTALL:=1
 
index dd0dfb2cc5915105744766052669fbc11fa32faf..284e922cb8c23b892a0faa6e84ee88a8e93ead75 100644 (file)
@@ -14,10 +14,9 @@ PKG_RELEASE:=1
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://rsync.samba.org/ftp/rsync/src
 PKG_MD5SUM:=43bd6676f0b404326eee2d63be3cdcfe
-PKG_LICENSE:=GPL-3.0
-PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
index 482d612674944b52e1c39d08415d99ffc1be69dc..077dcf18ddf77e2d425d2ad7e32e34392f70689c 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=rtorrent
-PKG_VERSION:=0.9.4-git
-PKG_RELEASE:=2
+PKG_VERSION:=0.9.4-git-0
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/rakshasa/rtorrent.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=6a3234eaa79f15857260df31f98711ef24266191
+PKG_SOURCE_VERSION:=7343e33a6a0d279179b304a380bf011f1c8be64a
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_BUILD_PARALLEL:=1
index 203544ec3c779cc7ca3b29c5d185fea34e80986d..a4213514534022afaaed6b3e53d54dbb87ec98c0 100644 (file)
@@ -10,7 +10,7 @@
  AC_PROG_LIBTOOL
 --- a/scripts/common.m4
 +++ b/scripts/common.m4
-@@ -223,7 +223,7 @@ dnl   Need to fix this so that it uses t
+@@ -153,7 +153,7 @@ dnl   Need to fix this so that it uses t
  AC_DEFUN([TORRENT_CHECK_EXECINFO], [
    AC_MSG_CHECKING(for execinfo.h)
  
@@ -19,7 +19,7 @@
        #include <execinfo.h>
        int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
        ])],
-@@ -238,7 +238,7 @@ AC_DEFUN([TORRENT_CHECK_EXECINFO], [
+@@ -168,7 +168,7 @@ AC_DEFUN([TORRENT_CHECK_EXECINFO], [
  AC_DEFUN([TORRENT_CHECK_ALIGNED], [
    AC_MSG_CHECKING(the byte alignment)
  
diff --git a/net/seafile-ccnet/Makefile b/net/seafile-ccnet/Makefile
new file mode 100644 (file)
index 0000000..3fd7e1c
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=seafile-ccnet
+PKG_VERSION:=3.1.7
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_LICENSE:=GPL-3.0
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/haiwen/ccnet.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=ddf42784fab3b5924f65e648facd21c3bffa2c72
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/seafile-ccnet
+    SECTION:=net
+    CATEGORY:=Network
+    TITLE:=Seafile server - ccnet component
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=http://seafile.com/
+    DEPENDS:=+libsearpc +libevent2 +libopenssl \
+               +glib2 +python +libzdb +libuuid \
+               +libpthread +libsqlite3 +jansson $(ICONV_DEPENDS)
+endef
+
+define Package/seafile-ccnet/description
+   Ccnet is a framework for writing networked applications in C.
+endef
+
+CONFIGURE_ARGS += --disable-client \
+                   --enable-server \
+                   --disable-ldap \
+                   --disable-cluster \
+                   --enable-python \
+                   --disable-server-pkg \
+                   --disable-static-build \
+                   --disable-compile-demo \
+                   --disable-console
+
+PKG_BUILD_DEPENDS:=vala/host \
+                  libsearpc/host
+
+TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib -liconv \
+                   -L$(STAGING_DIR)/usr/lib/mysql -lmysqlclient -lz
+
+define Package/seafile-ccnet/install
+       $(INSTALL_DIR) $(1)/usr/{bin,lib}
+       $(INSTALL_DIR) $(1)/usr/lib/python2.7/site-packages
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/ccnet* $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/ccnet $(1)/usr/lib/python2.7/site-packages/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libccnet.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/ccnet* $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libccnet.pc $(1)/usr/lib/pkgconfig/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libccnet.a $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libccnet.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,seafile-ccnet))
diff --git a/net/seafile-seahub/Makefile b/net/seafile-seahub/Makefile
new file mode 100644 (file)
index 0000000..be4aa5c
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=seafile-seahub
+PKG_VERSION:=3.1.7
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_LICENSE:=Apache-2.0
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/haiwen/seahub.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=a984c86442e7fc10c3bcf6d92b4843f7263547eb
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+include $(INCLUDE_DIR)/package.mk
+$(call include_mk, python-package.mk)
+
+define Package/seafile-seahub
+    SECTION:=net
+    CATEGORY:=Network
+    TITLE:=Seafile server - seahub component
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=http://seafile.com/
+    DEPENDS:=+python +simplejson +python-imglib +python-setuptools
+endef
+
+define Package/seafile-seahub/description
+   The web end of seafile server.
+
+   NOTE: in order to have better performance, language support is turned off by default.
+   Please set 'USE_I18N = True' in seahub_settings.py to support multiple languages.
+endef
+
+PKG_BUILD_DEPENDS:=python-setuptools
+PYTHONPATH:=$(PYTHONPATH):$(PKG_BUILD_DIR)/thirdpart
+
+define Build/Configure
+endef
+
+define Build/Compile
+       # Install python dependencies
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://www.djangoproject.com/m/releases/1.5/Django-1.5.8.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://github.com/djblets/djblets/archive/release-0.6.14.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/g/gunicorn/gunicorn-0.16.1.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/s/six/six-1.4.1.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/c/chardet/chardet-2.1.1.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/2.6/f/flup/flup-1.0.2-py2.6.egg)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/l/lockfile/lockfile-0.9.1.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/p/python-daemon/python-daemon-1.5.5.tar.gz)
+       $(call HostPython,, \
+               $(STAGING_DIR_ROOT)/usr/bin/easy_install -d $(PKG_BUILD_DIR)/thirdpart -Z -N \
+               https://pypi.python.org/packages/source/p/python-dateutil/python-dateutil-1.5.tar.gz)
+endef
+
+define Package/seafile-seahub/install
+       $(INSTALL_DIR) $(1)/usr/share/seafile/seafile-server/seahub
+       $(CP) $(PKG_BUILD_DIR)/{locale,media,seahub,sql,subdomain,tests,thirdpart,tools} $(1)/usr/share/seafile/seafile-server/seahub/
+       $(CP) $(PKG_BUILD_DIR)/*.{sh,template,py,txt} $(1)/usr/share/seafile/seafile-server/seahub/
+       $(CP) $(PKG_BUILD_DIR)/{CONTRIBUTORS,HACKING,README.markdown} $(1)/usr/share/seafile/seafile-server/seahub/
+       $(CP) $(PKG_BUILD_DIR)/pylintrc* $(1)/usr/share/seafile/seafile-server/seahub/
+       # fix python exec path in scripts
+       sed -i 's/#!.*/#!\/usr\/bin\/python/g' $(1)/usr/share/seafile/seafile-server/seahub/thirdpart/chardetect.py
+       sed -i 's/#!.*/#!\/usr\/bin\/python/g' $(1)/usr/share/seafile/seafile-server/seahub/thirdpart/django-admin.py
+       sed -i 's/#!.*/#!\/usr\/bin\/python/g' $(1)/usr/share/seafile/seafile-server/seahub/thirdpart/gunicorn
+       sed -i 's/#!.*/#!\/usr\/bin\/python/g' $(1)/usr/share/seafile/seafile-server/seahub/thirdpart/gunicorn_django
+       sed -i 's/#!.*/#!\/usr\/bin\/python/g' $(1)/usr/share/seafile/seafile-server/seahub/thirdpart/gunicorn_paster
+       find $(1) -name "*\.pyc" -o -name "*\.pyo" | xargs rm -f
+       sed -i "s/\(SEAFILE_VERSION\s*=\s*\)'\([0-9]\.[0-9]\.[0-9]\)'/\1'$(PKG_VERSION)'/g" $(1)/usr/share/seafile/seafile-server/seahub/seahub/settings.py
+endef
+
+$(eval $(call BuildPackage,seafile-seahub))
diff --git a/net/seafile-seahub/patches/010-default-config.patch b/net/seafile-seahub/patches/010-default-config.patch
new file mode 100644 (file)
index 0000000..4168dc1
--- /dev/null
@@ -0,0 +1,30 @@
+diff -rupN seahub-3.1.7-server.orig/seahub/settings.py seahub-3.1.7-server/seahub/settings.py
+--- seahub-3.1.7-server.orig/seahub/settings.py        2014-10-20 09:32:35.000000000 +0200
++++ seahub-3.1.7-server/seahub/settings.py     2014-12-10 15:47:21.625104606 +0100
+@@ -46,7 +46,7 @@ SITE_ID = 1
+ # If you set this to False, Django will make some optimizations so as not
+ # to load the internationalization machinery.
+-USE_I18N = True
++USE_I18N = False
+ # If you set this to False, Django will not format dates, numbers and
+ # calendars according to the current locale.
+@@ -209,7 +209,7 @@ SHOW_REPO_DOWNLOAD_BUTTON = False
+ REPO_PASSWORD_MIN_LENGTH = 8
+ # mininum length for user's password
+-USER_PASSWORD_MIN_LENGTH = 6
++USER_PASSWORD_MIN_LENGTH = 8
+ # LEVEL based on four types of input:
+ # num, upper letter, lower letter, other symbols
+@@ -218,7 +218,7 @@ USER_PASSWORD_STRENGTH_LEVEL = 3
+ # default False, only check USER_PASSWORD_MIN_LENGTH
+ # when True, check password strength level, STRONG(or above) is allowed
+-USER_STRONG_PASSWORD_REQUIRED = False
++USER_STRONG_PASSWORD_REQUIRED = True
+ # Using server side crypto by default, otherwise, let user choose crypto method.
+ FORCE_SERVER_CRYPTO = True
diff --git a/net/seafile-server/Makefile b/net/seafile-server/Makefile
new file mode 100644 (file)
index 0000000..3b977bd
--- /dev/null
@@ -0,0 +1,116 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=seafile-server
+PKG_VERSION:=3.1.7
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_LICENSE:=GPL-3.0
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/haiwen/seafile.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=69658fca88f258276be92447b1b4462b64a1c6b9
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/seafile-server
+    SECTION:=net
+    CATEGORY:=Network
+    TITLE:=Seafile server
+    MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+    URL:=http://seafile.com/
+    DEPENDS:=+shadow-useradd +libarchive +libopenssl +glib2 +seafile-ccnet +libsearpc +sqlite3-cli +python-mysql \
+               +jansson +libevent2 +libevent2-openssl +zlib +libzdb +libsqlite3 +libmysqlclient +libevhtp \
+               +libpthread +libuuid +seafile-seahub +bash +sudo +procps +procps-pkill $(ICONV_DEPENDS)
+endef
+
+define Package/seafile-server/description
+   Open source cloud storage with advanced features on privacy protection and teamwork.
+endef
+
+CONFIGURE_ARGS += --disable-riak \
+                   --disable-client \
+                   --disable-fuse \
+                   --enable-server \
+                   --enable-python \
+                   --disable-static-build \
+                   --disable-server-pkg \
+                   --disable-console
+
+PKG_BUILD_DEPENDS:=vala/host \
+                   libsearpc/host
+
+TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib -liconv \
+                   -L$(STAGING_DIR)/usr/lib/mysql -lmysqlclient -lz
+
+define Package/seafile-server/install
+       $(INSTALL_DIR) $(1)/usr/{bin,lib}
+       $(INSTALL_DIR) $(1)/usr/lib/python2.7/site-packages
+       $(INSTALL_DIR) $(1)/usr/share/seafile/seafile-server/runtime
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/seafile/ $(1)/usr/lib/python2.7/site-packages/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/seaserv/ $(1)/usr/lib/python2.7/site-packages/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libseafile.so* $(1)/usr/lib/
+       $(CP) $(PKG_BUILD_DIR)/scripts/seaf-gc.sh $(1)/usr/share/seafile/seafile-server/
+       $(CP) $(PKG_BUILD_DIR)/scripts/setup-seafile-mysql.py $(1)/usr/share/seafile/seafile-server/
+       $(CP) $(PKG_BUILD_DIR)/scripts/setup-seafile-mysql.sh $(1)/usr/share/seafile/seafile-server/
+       $(CP) $(PKG_BUILD_DIR)/scripts/sqlite2mysql.py $(1)/usr/share/seafile/seafile-server/
+       $(CP) $(PKG_BUILD_DIR)/scripts/sqlite2mysql.sh $(1)/usr/share/seafile/seafile-server/
+       $(CP) $(PKG_BUILD_DIR)/scripts/upgrade/ $(1)/usr/share/seafile/seafile-server/
+       $(INSTALL_BIN) ./files/seafile.init $(1)/etc/init.d/seafile
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/seafile/ $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libseafile.pc $(1)/usr/lib/pkgconfig/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libseafile.so* $(1)/usr/lib/
+endef
+
+define Package/seafile-server/postinst
+#!/bin/sh
+
+if ! id -u seafile >/dev/null 2>&1; then
+    useradd seafile -d "/usr/share/seafile" -s /bin/sh; fi
+
+chown -R seafile:seafile /usr/share/seafile/
+chmod -R o-rwx /usr/share/seafile/
+
+if [ ! -d "/usr/share/seafile/seafile-data" ]
+then
+   echo "*** Installation completed, running configuration script..."
+   /etc/init.d/seafile setup
+
+   if [ $$? -ne 0 ]
+   then
+      echo
+      echo "*** ERROR: Configuration failed. Please fix the issues if any and re-run the script using the command below:"
+      echo "*** \"/etc/init.d/seafile setup\""
+   fi
+echo
+echo "*** NOTE: you need to create an admin account before using Seafile."
+echo "*** Please run \"/etc/init.d/seafile create_admin\" to do so."
+fi
+
+/etc/init.d/seafile enable
+/etc/init.d/seafile restart
+endef
+
+define Package/seafile-server/prerm
+#!/bin/sh
+/etc/init.d/seafile stop
+endef
+
+$(eval $(call BuildPackage,seafile-server))
diff --git a/net/seafile-server/files/seafile.init b/net/seafile-server/files/seafile.init
new file mode 100755 (executable)
index 0000000..eed4f79
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+APP=seafile
+EXTRA_HELP="   setup   Runs the setup script
+       create_admin    Creates the administrative login
+       reset_admin     Alias to create_admin"
+EXTRA_COMMANDS="setup create_admin reset_admin"
+
+export PATH="/usr/share/seafile/seafile-server/seahub/thirdpart:$PATH"
+export PYTHONPATH="/usr/share/seafile/seafile-server/seahub/thirdpart:$PYTHONPATH"
+
+start() {
+       if [ ! -d /var/run/seafile ]
+       then
+           mkdir /var/run/seafile
+           chown seafile:seafile /var/run/seafile
+           chmod o-rwx /var/run/seafile
+       fi
+
+       cd "/usr/share/seafile" && \
+           sudo PYTHONPATH="$PYTHONPATH" -u seafile -E \
+           "/usr/bin/seafile-admin" start
+}
+
+stop() {
+       cd "/usr/share/seafile" && \
+           sudo PYTHONPATH="$PYTHONPATH" -u seafile -E \
+           "/usr/bin/seafile-admin" stop
+}
+
+setup() {
+       cd "/usr/share/seafile" && \
+           sudo PYTHONPATH="$PYTHONPATH" -u seafile -E \
+           "/usr/bin/seafile-admin" setup
+}
+
+create_admin() {
+       cd "/usr/share/seafile" && \
+           sudo PYTHONPATH="$PYTHONPATH" -u seafile -E \
+           "/usr/bin/seafile-admin" create-admin
+}
+
+reset_admin() {
+       create_admin
+}
diff --git a/net/seafile-server/patches/010-makefile-fix.patch b/net/seafile-server/patches/010-makefile-fix.patch
new file mode 100644 (file)
index 0000000..1ae971e
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rupN seafile-3.1.7-server.orig/fileserver/Makefile.am seafile-3.1.7-server/fileserver/Makefile.am
+--- seafile-3.1.7-server.orig/fileserver/Makefile.am   2014-10-16 05:30:04.000000000 +0200
++++ seafile-3.1.7-server/fileserver/Makefile.am        2014-12-08 00:16:44.289364980 +0100
+@@ -6,7 +6,7 @@ AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)
+       -I$(top_srcdir)/lib \
+       -I$(top_builddir)/lib \
+       -I$(top_srcdir)/common \
+-      -I$(includedir) \
++      -I$(STAGING_DIR)$(includedir) \
+       @CCNET_CFLAGS@ \
+       @SEARPC_CFLAGS@ \
+       @GLIB2_CFLAGS@ \
diff --git a/net/seafile-server/patches/020-script-patches.patch b/net/seafile-server/patches/020-script-patches.patch
new file mode 100644 (file)
index 0000000..8bb7ae7
--- /dev/null
@@ -0,0 +1,40 @@
+diff -rupN seafile-3.1.7-server.orig/scripts/seaf-gc.sh seafile-3.1.7-server/scripts/seaf-gc.sh
+--- seafile-3.1.7-server.orig/scripts/seaf-gc.sh       2014-10-16 05:30:04.000000000 +0200
++++ seafile-3.1.7-server/scripts/seaf-gc.sh    2014-12-13 00:51:12.919136978 +0100
+@@ -6,11 +6,10 @@ SCRIPT=$(readlink -f "$0")
+ INSTALLPATH=$(dirname "${SCRIPT}")
+ TOPDIR=$(dirname "${INSTALLPATH}")
+ default_ccnet_conf_dir=${TOPDIR}/ccnet
+-seaf_gc=${INSTALLPATH}/seafile/bin/seafserv-gc
++seaf_gc=/usr/bin/seafserv-gc
+ seaf_gc_opts=""
+-export PATH=${INSTALLPATH}/seafile/bin:$PATH
+-export SEAFILE_LD_LIBRARY_PATH=${INSTALLPATH}/seafile/lib/:${INSTALLPATH}/seafile/lib64:${LD_LIBRARY_PATH}
++export PYTHONPATH="/usr/share/seafile/seafile-server/seahub/thirdpart:$PYTHONPATH"
+ script_name=$0
+ function usage () {
+@@ -78,9 +77,7 @@ function run_seaf_gc () {
+     echo "Starting seafserv-gc, please wait ..."
+-    LD_LIBRARY_PATH=$SEAFILE_LD_LIBRARY_PATH ${seaf_gc} \
+-        -c "${default_ccnet_conf_dir}" -d "${seafile_data_dir}" \
+-        ${seaf_gc_opts}
++    ${seaf_gc} -c "${default_ccnet_conf_dir}" -d "${seafile_data_dir}" ${seaf_gc_opts}
+     echo "seafserv-gc run done"
+     echo
+diff -rupN seafile-3.1.7-server.orig/scripts/setup-seafile-mysql.sh seafile-3.1.7-server/scripts/setup-seafile-mysql.sh
+--- seafile-3.1.7-server.orig/scripts/setup-seafile-mysql.sh   2014-10-16 05:30:04.000000000 +0200
++++ seafile-3.1.7-server/scripts/setup-seafile-mysql.sh        2014-12-13 00:51:49.242172631 +0100
+@@ -9,6 +9,8 @@ set -e
+ SCRIPT=$(readlink -f "$0")
+ INSTALLPATH=$(dirname "${SCRIPT}")
++export PYTHONPATH="/usr/share/seafile/seafile-server/seahub/thirdpart:$PYTHONPATH"
++
+ cd "$INSTALLPATH"
+ python_script=setup-seafile-mysql.py
diff --git a/net/seafile-server/patches/030-pidfiles-in-same-directory.patch b/net/seafile-server/patches/030-pidfiles-in-same-directory.patch
new file mode 100644 (file)
index 0000000..4338f17
--- /dev/null
@@ -0,0 +1,24 @@
+diff -rupN seafile-3.1.7-server.orig/controller/seafile-controller.c seafile-3.1.7-server/controller/seafile-controller.c
+--- seafile-3.1.7-server.orig/controller/seafile-controller.c  2014-10-16 05:30:04.000000000 +0200
++++ seafile-3.1.7-server/controller/seafile-controller.c       2014-11-28 16:50:24.053674057 +0100
+@@ -21,7 +21,7 @@
+ SeafileController *ctl;
+-static char *controller_pidfile = NULL;
++static char *controller_pidfile = "/var/run/seafile/seafile-controller.pid";
+ char *bin_dir = NULL;
+ char *installpath = NULL;
+@@ -614,9 +614,9 @@ stop_ccnet_server ()
+ static void
+ init_pidfile_path (SeafileController *ctl)
+ {
+-    char *pid_dir = g_build_filename (topdir, "pids", NULL);
++    char *pid_dir = g_path_get_dirname (controller_pidfile);
+     if (!g_file_test(pid_dir, G_FILE_TEST_EXISTS)) {
+-        if (g_mkdir(pid_dir, 0777) < 0) {
++        if (g_mkdir(pid_dir, 0755) < 0) {
+             seaf_warning("failed to create pid dir %s: %s", pid_dir, strerror(errno));
+             controller_exit(1);
+         }
diff --git a/net/seafile-server/patches/040-seafile-admin.patch b/net/seafile-server/patches/040-seafile-admin.patch
new file mode 100644 (file)
index 0000000..1948c73
--- /dev/null
@@ -0,0 +1,68 @@
+diff -rupN seafile-3.1.7-server.orig/tools/seafile-admin seafile-3.1.7-server/tools/seafile-admin
+--- seafile-3.1.7-server.orig/tools/seafile-admin      2014-10-16 05:30:04.000000000 +0200
++++ seafile-3.1.7-server/tools/seafile-admin   2014-12-22 21:52:25.929781054 +0100
+@@ -416,13 +416,13 @@ def create_gunicorn_conf():
+     content = '''\
+ import os
+ daemon = True
+-workers = 3
++workers = 1
++threads = 3
+ # Logging
+ runtime_dir = os.path.dirname(__file__)
+-pidfile = os.path.join(runtime_dir, 'seahub.pid')
++pidfile = '/var/run/seafile/seahub.pid'
+ errorlog = os.path.join(runtime_dir, 'error.log')
+-accesslog = os.path.join(runtime_dir, 'access.log')
+ '''
+     try:
+         with open(confpath, 'w') as fp:
+@@ -607,6 +607,7 @@ def start_seahub_gunicorn():
+         'gunicorn_django',
+         '-c', conf[CONF_SEAHUB_CONF],
+         '-b', '0.0.0.0:%s' % conf[CONF_SEAHUB_PORT],
++        '-t', '120',
+     ]
+     info('Starting seahub...')
+@@ -625,6 +626,7 @@ def start_seahub_fastcgi():
+         'pidfile=%(pidfile)s',
+         'outlog=%(outlog)s',
+         'errlog=%(errlog)s',
++        'method=threaded',
+     ]
+     cmdline = ' '.join(argv) % \
+@@ -693,7 +695,7 @@ def check_layout(args):
+     conf[CONF_SEAFILE_DIR]      = seafile_data_dir
+     conf[CONF_SEAHUB_DIR]       = seahub_dir
+     conf[CONF_SEAHUB_CONF]      = seahub_conf
+-    conf[CONF_SEAHUB_PIDFILE]   = os.path.join(runtime_dir, 'seahub.pid')
++    conf[CONF_SEAHUB_PIDFILE]   = '/var/run/seafile/seahub.pid'
+     conf[CONF_SEAHUB_OUTLOG]    = os.path.join(runtime_dir, 'access.log')
+     conf[CONF_SEAHUB_ERRLOG]    = os.path.join(runtime_dir, 'error.log')
+@@ -738,10 +740,9 @@ def setup_seafile(args):
+     print '-----------------------------------------------------------------'
+     print '-----------------------------------------------------------------'
+     print
+-    print 'To start/stop seafile server:'
++    print 'To start, stop or restart seafile server, please run as root:'
+     print
+-    print highlight('         $ cd %s' % cwd)
+-    print highlight('         $ %s { start | stop }' % SCRIPT_NAME)
++    print highlight('         # /etc/init.d/seafile { start | stop | restart }')
+     print
+     print 'If you have any problem, refer to\n'
+     print
+@@ -802,8 +803,7 @@ def start_seafile(args):
+ def stop_seafile(dummy):
+     info('Stopping seafile server')
+     pkill('seafile-controller')
+-    runtime_dir = os.path.join(cwd, 'seafile-server', 'runtime')
+-    pidfile = os.path.join(runtime_dir, 'seahub.pid')
++    pidfile = '/var/run/seafile/seahub.pid'
+     try:
+         with open(pidfile, 'r') as fp:
+             pid = fp.read().strip('\n ')
diff --git a/net/ser2net/Makefile b/net/ser2net/Makefile
new file mode 100644 (file)
index 0000000..ec0b573
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ser2net
+PKG_VERSION:=2.10.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/ser2net
+PKG_MD5SUM:=cd937041144de83d41d811521e72158c
+
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ser2net
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Serial to Network Proxy
+  URL:=http://sourceforge.net/projects/ser2net/
+endef
+
+define Package/ser2net/description
+  This project provides a proxy that allows telnet/tcp connections to be made to
+  serial ports on a machine.
+endef
+
+define Package/ser2net/conffiles
+/etc/ser2net.conf
+endef
+
+define Package/ser2net/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(CP) $(PKG_INSTALL_DIR)/usr/sbin/ser2net $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/ser2net.conf $(1)/etc/
+endef
+
+$(eval $(call BuildPackage,ser2net))
diff --git a/net/ser2net/patches/001-fix_TIOCSRS485_undeclared_error.patch b/net/ser2net/patches/001-fix_TIOCSRS485_undeclared_error.patch
new file mode 100644 (file)
index 0000000..370d0b9
--- /dev/null
@@ -0,0 +1,59 @@
+ser2net: Fix compilation failures due to missing TIOCSRS485 macro
+
+Patch sent upstream:
+       https://sourceforge.net/p/ser2net/mailman/message/32905302/
+
+Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
+
+From: Yegor Yefremov <yegorslists@googlemail.com>
+
+include <asm-generic/ioctls.h> fixes compilations for systems,
+where <asm-generic/ioctls.h> won't be included automatically.
+
+Move special Linux includes to dataxfer.h.
+
+Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
+---
+ dataxfer.h | 5 +++--
+ devcfg.c   | 2 --
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+--- a/dataxfer.h
++++ b/dataxfer.h
+@@ -20,8 +20,6 @@
+ #ifndef DATAXFER
+ #define DATAXFER
+-#include <linux/serial.h>
+-
+ #include "controller.h"
+ #ifdef USE_UUCP_LOCKING
+@@ -30,6 +28,9 @@ extern int uucp_locking_enabled;
+ #ifdef linux
++#include <linux/serial.h>
++#include <asm-generic/ioctls.h>
++
+ #define USE_RS485_FEATURE
+ /* Check, if the toolchain provides serial_rs485 structure and macros */
+--- a/devcfg.c
++++ b/devcfg.c
+@@ -18,7 +18,6 @@
+  */
+ /* This code handles generating the configuration for the serial port. */
+-
+ #include <unistd.h>
+ #include <termios.h>
+ #include <sys/ioctl.h>
+@@ -31,7 +30,6 @@
+ #include <signal.h>
+ #include <errno.h>
+ #include <syslog.h>
+-#include <linux/serial.h>
+ #include "ser2net.h"
+ #include "selector.h"
diff --git a/net/snort/Makefile b/net/snort/Makefile
new file mode 100644 (file)
index 0000000..2c94866
--- /dev/null
@@ -0,0 +1,202 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=snort
+PKG_VERSION:=2.9.7.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.snort.org/downloads/snort/
+PKG_MD5SUM:=c2a45bc56441ee9456478f219dd8d1e2
+
+PKG_BUILD_DEPENDS:=librpc
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/snort/Default
+  SUBMENU:=Firewall
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+libdaq +libdnet +libopenssl +libpcap +libpcre +libpthread +libuuid +zlib
+  TITLE:=Lightweight Network Intrusion Detection System
+  URL:=http://www.snort.org/
+endef
+
+define Package/snort/Default/description
+  Snort is an open source network intrusion detection and prevention system.
+  It is capable of performing real-time traffic analysis, alerting, blocking
+  and packet logging on IP networks.  It utilizes a combination of protocol
+  analysis and pattern matching in order to detect anomalies, misuse and
+  attacks.
+endef
+
+define Package/snort
+  $(call Package/snort/Default)
+  VARIANT:=basic
+endef
+
+define Package/snort/description
+  $(call Package/snort/Default/description)
+endef
+
+define Package/snort-mysql
+  $(call Package/snort/Default)
+  DEPENDS+= +libmysqlclient
+  TITLE+= (MySQL)
+  VARIANT:=mysql
+endef
+
+define Package/snort-mysql/description
+  $(call Package/snort/Default/description)
+  This package contains snort with support for logging to a MySQL database.
+endef
+
+define Package/snort-pgsql
+  $(call Package/snort/Default)
+  DEPENDS+= +libpq +libuuid
+  TITLE+= (PostgreSQL)
+  VARIANT:=pgsql
+endef
+
+define Package/snort-pgsql/description
+  $(call Package/snort/Default/description)
+  This package contains snort with support for logging to a PostgreSQL database.
+endef
+
+CONFIGURE_ARGS += \
+       --prefix="/usr" \
+       --enable-flexresp \
+       --with-dnet-includes="$(STAGING_DIR)/usr/include" \
+       --with-dnet-libraries="$(STAGING_DIR)/usr/lib" \
+       --with-libpcap-includes="$(STAGING_DIR)/usr/include" \
+       --with-libpcap-libraries="$(STAGING_DIR)/usr/lib" \
+       --with-libpcre-includes="$(STAGING_DIR)/usr/include" \
+       --with-libpcre-libraries="$(STAGING_DIR)/usr/lib" \
+       --with-daq-includes="$(STAGING_DIR)/usr/include" \
+       --with-daq-libraries="$(STAGING_DIR)/usr/lib" \
+       --disable-static-daq
+
+CONFIGURE_VARS += \
+       CPPFLAGS="$$$$CPPFLAGS -I$(STAGING_DIR)/usr/include/mysql" \
+       LDFLAGS="$$$$LDFLAGS -L$(STAGING_DIR)/usr/lib/mysql" \
+       PATH="$(STAGING_DIR)/usr/lib/libnet-1.0.x/bin:$$$$PATH"
+
+MAKE_FLAGS += \
+       extra_incl=""
+
+ifeq ($(BUILD_VARIANT),basic)
+  CONFIGURE_ARGS += \
+       --without-mysql \
+       --without-postgresql
+endif
+ifeq ($(BUILD_VARIANT),mysql)
+  CONFIGURE_VARS += \
+       mysql_has_reconnect=yes
+  CONFIGURE_ARGS += \
+       --with-mysql="$(STAGING_DIR)/usr" \
+       --without-postgresql
+endif
+ifeq ($(BUILD_VARIANT),pgsql)
+  CONFIGURE_ARGS += \
+       --without-mysql \
+       --with-postgresql="$(STAGING_DIR)/usr"
+endif
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/include/snort/dynamic_preproc
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/include/snort/dynamic_preproc/* \
+               $(STAGING_DIR)/usr/include/snort/dynamic_preproc/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/lib/snort/dynamic_preproc
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/snort/dynamic_preproc/* \
+               $(STAGING_DIR)/usr/lib/snort/dynamic_preproc/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/lib/snort_dynamicengine
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/snort_dynamicengine/* \
+               $(STAGING_DIR)/usr/lib/snort_dynamicengine/
+       $(INSTALL_DIR) $(STAGING_DIR)/usr/lib/snort_dynamicpreprocessor
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/snort_dynamicpreprocessor/* \
+               $(STAGING_DIR)/usr/lib/snort_dynamicpreprocessor/
+endef
+
+define Package/snort/conffiles
+/etc/config/snort
+/etc/snort/snort.conf
+endef
+
+Package/snort-mysql/conffiles = $(Package/snort/conffiles)
+Package/snort-mysql/install = $(Package/snort/install)
+
+Package/snort-pgsql/conffiles = $(Package/snort/conffiles)
+Package/snort-pgsql/install = $(Package/snort/install)
+
+define Package/snort/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/snort  \
+               $(1)/usr/bin/snort
+
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/u2{boat,spewfoo} \
+               $(1)/usr/bin
+
+       $(INSTALL_DIR) $(1)/usr/lib/snort_dynamicengine
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/snort_dynamicengine/libsf_engine.so* \
+               $(1)/usr/lib/snort_dynamicengine/
+
+       $(INSTALL_DIR) $(1)/usr/lib/snort_dynamicpreprocessor
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/snort_dynamicpreprocessor/libsf*.so* \
+               $(1)/usr/lib/snort_dynamicpreprocessor/
+
+       $(INSTALL_DIR) $(1)/etc/snort
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/etc/snort.conf \
+               $(1)/etc/snort/
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/etc/attribute_table.dtd \
+               $(1)/etc/snort/
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/etc/classification.config \
+               $(1)/etc/snort/
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/etc/gen-msg.map \
+               $(1)/etc/snort/
+       $(INSTALL_CONF) \
+                       $(PKG_BUILD_DIR)/etc/reference.config \
+                       $(1)/etc/snort/
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/etc/unicode.map \
+               $(1)/etc/snort/
+
+       $(INSTALL_DIR) $(1)/etc/snort/preproc_rules
+       $(INSTALL_CONF) \
+               $(PKG_BUILD_DIR)/preproc_rules/*.rules \
+               $(1)/etc/snort/preproc_rules/
+
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) \
+               ./files/snort.init \
+               $(1)/etc/init.d/snort
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) \
+               ./files/snort.config \
+               $(1)/etc/config/snort
+endef
+
+$(eval $(call BuildPackage,snort))
+$(eval $(call BuildPackage,snort-mysql))
+$(eval $(call BuildPackage,snort-pgsql))
diff --git a/net/snort/files/snort.config b/net/snort/files/snort.config
new file mode 100644 (file)
index 0000000..cda7441
--- /dev/null
@@ -0,0 +1,3 @@
+config snort 'snort'
+       option config_file '/etc/snort/snort.conf'
+       option interface 'lo'
diff --git a/net/snort/files/snort.init b/net/snort/files/snort.init
new file mode 100644 (file)
index 0000000..fcdb090
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/bin/snort
+
+validate_snort_section() {
+       uci_validate_section snort snort "${1}" \
+               'config_file:string' \
+               'interface:string'
+}
+
+start_service() {
+       local config_file interface
+
+       validate_snort_section snort || {
+               echo "validation failed"
+               return 1
+       }
+
+       procd_open_instance
+       procd_set_param command $PROG "-q" "--daq-dir" "/usr/lib/daq/" "-i" "$interface" "-s" "-N"
+       procd_set_param file $CONFIGFILE
+       procd_set_param respawn
+       procd_close_instance
+}
+
+stop_service()
+{
+       service_stop ${PROG}
+}
+
+service_triggers()
+{
+       procd_add_reload_trigger "snort"
+       procd_add_validation validate_snort_section
+}
diff --git a/net/snort/patches/001-compile.patch b/net/snort/patches/001-compile.patch
new file mode 100644 (file)
index 0000000..06d283a
--- /dev/null
@@ -0,0 +1,105 @@
+--- /dev/null
++++ b/acinclude.m4
+@@ -0,0 +1 @@
++sinclude(m4/libprelude.m4)
+--- a/configure.in
++++ b/configure.in
+@@ -285,21 +285,7 @@ AC_CHECK_TYPES([int8_t,int16_t,int32_t,i
+ AC_CHECK_TYPES([boolean])
+ # In case INADDR_NONE is not defined (like on Solaris)
+-have_inaddr_none="no"
+-AC_MSG_CHECKING([for INADDR_NONE])
+-AC_RUN_IFELSE(
+-[AC_LANG_PROGRAM(
+-[[
+-#include <sys/types.h>
+-#include <netinet/in.h>
+-#include <arpa/inet.h>
+-]],
+-[[
+-      if (inet_addr("10,5,2") == INADDR_NONE);
+-    return 0;
+-]])],
+-[have_inaddr_none="yes"],
+-[have_inaddr_none="no"])
++have_inaddr_none="yes"
+ AC_MSG_RESULT($have_inaddr_none)
+ if test "x$have_inaddr_none" = "xno"; then
+       AC_DEFINE([INADDR_NONE],[-1],[For INADDR_NONE definition])
+@@ -433,16 +419,7 @@ if test "x$LPCAP" = "xno"; then
+ fi
+ AC_MSG_CHECKING([for pcap_lex_destroy])
+-AC_RUN_IFELSE(
+-[AC_LANG_PROGRAM(
+-[[
+-#include <pcap.h>
+-]],
+-[[
+-   pcap_lex_destroy();
+-]])],
+-[have_pcap_lex_destroy="yes"],
+-[have_pcap_lex_destroy="no"])
++have_pcap_lex_destroy="yes"
+ AC_MSG_RESULT($have_pcap_lex_destroy)
+ if test "x$have_pcap_lex_destroy" = "xyes"; then
+     AC_DEFINE([HAVE_PCAP_LEX_DESTROY],[1],[Can cleanup lex buffer stack created by pcap bpf filter])
+@@ -727,54 +704,21 @@ if test "x$ac_cv_func_daq_dp_add_dc" = "
+ fi
+-AC_MSG_CHECKING([for daq address space ID])
+-AC_RUN_IFELSE(
+-[AC_LANG_PROGRAM(
+-[[
+-#include <daq.h>
+-]],
+-[[
+-   DAQ_PktHdr_t hdr;
+-   hdr.address_space_id = 0;
+-]])],
+-[have_daq_address_space_id="yes"],
+-[have_daq_address_space_id="no"])
++have_daq_address_space_id="yes"
+ AC_MSG_RESULT($have_daq_address_space_id)
+ if test "x$have_daq_address_space_id" = "xyes"; then
+     AC_DEFINE([HAVE_DAQ_ADDRESS_SPACE_ID],[1],
+         [DAQ version supports address space ID in header.])
+ fi
+-AC_MSG_CHECKING([for daq flow ID])
+-AC_RUN_IFELSE(
+-[AC_LANG_PROGRAM(
+-[[
+-#include <daq.h>
+-]],
+-[[
+-   DAQ_PktHdr_t hdr;
+-   hdr.flow_id = 0;
+-]])],
+-[have_daq_flow_id="yes"],
+-[have_daq_flow_id="no"])
++have_daq_flow_id="yes"
+ AC_MSG_RESULT($have_daq_flow_id)
+ if test "x$have_daq_flow_id" = "xyes"; then
+     AC_DEFINE([HAVE_DAQ_FLOW_ID],[1],
+         [DAQ version supports flow ID in header.])
+ fi
+-AC_MSG_CHECKING([for DAQ_VERDICT_RETRY])
+-AC_RUN_IFELSE(
+-[AC_LANG_PROGRAM(
+-[[
+-#include <daq.h>
+-]],
+-[[
+-   DAQ_Verdict verdict;
+-   verdict = DAQ_VERDICT_RETRY;
+-]])],
+-[have_daq_verdict_retry="yes"],
+-[have_daq_verdict_retry="no"])
++have_daq_verdict_retry="yes"
+ AC_MSG_RESULT($have_daq_verdict_retry)
+ if test "x$have_daq_verdict_retry" = "xyes"; then
+     AC_DEFINE([HAVE_DAQ_VERDICT_RETRY],[1],
index 91a86a32aabe09af218689c8daa242bd1cf3103d..bb3fc7d64b4e7c983d558ed0d83ba545192cdebf 100644 (file)
@@ -18,7 +18,7 @@ PKG_MD5SUM:=69b8155dd442a6f24e28ef5407d868eb
 PKG_MAINTAINER:= Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0 OpenSSL
-PKG_LICENSE_FILE:=COPYING COPYING.OpenSSL
+PKG_LICENSE_FILES:=COPYING COPYING.OpenSSL
 
 PKG_INSTALL:=1
 
diff --git a/net/sqm-scripts/Makefile b/net/sqm-scripts/Makefile
new file mode 100644 (file)
index 0000000..298220d
--- /dev/null
@@ -0,0 +1,57 @@
+# 
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sqm-scripts
+PKG_VERSION:=7
+PKG_RELEASE:=3
+PKG_LICENSE:=GPLv2
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sqm-scripts
+  SECTION:=net
+  CATEGORY:=Base system
+  DEPENDS:=+tc +kmod-sched +kmod-ifb iptables +ip \
+       +iptables-mod-filter +iptables-mod-ipopt +iptables-mod-conntrack-extra
+  TITLE:=SQM Scripts (QoS)
+  PKGARCH:=all
+  MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
+endef
+
+define Package/sqm-scripts/description
+ A set of scripts that does simple SQM configuration.
+endef
+
+define Package/sqm-scripts/conffiles
+/etc/config/sqm
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/sqm-scripts/install
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/etc/init.d/sqm $(1)/etc/init.d/sqm
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/etc/config/sqm $(1)/etc/config/sqm
+       $(INSTALL_DIR) $(1)/usr/lib/sqm
+       $(INSTALL_BIN) ./files/usr/lib/sqm/*.sh $(1)/usr/lib/sqm/
+       $(INSTALL_BIN) ./files/usr/lib/sqm/*.qos $(1)/usr/lib/sqm/
+       $(INSTALL_DATA) ./files/usr/lib/sqm/*.help $(1)/usr/lib/sqm/
+endef
+
+$(eval $(call BuildPackage,sqm-scripts))
diff --git a/net/sqm-scripts/files/etc/config/sqm b/net/sqm-scripts/files/etc/config/sqm
new file mode 100644 (file)
index 0000000..d039808
--- /dev/null
@@ -0,0 +1,16 @@
+
+config queue 'eth1'
+        option enabled '0'
+        option interface 'eth1'
+        option download '85000'
+        option upload '10000'
+        option qdisc 'fq_codel'
+        option script 'simple.qos'
+        option qdisc_advanced '0'
+        option ingress_ecn 'ECN'
+        option egress_ecn 'NOECN'
+        option qdisc_really_really_advanced '0'
+        option itarget 'auto'
+        option etarget 'auto'
+        option linklayer 'none'
+
diff --git a/net/sqm-scripts/files/etc/init.d/sqm b/net/sqm-scripts/files/etc/init.d/sqm
new file mode 100755 (executable)
index 0000000..70307a6
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+
+reload()
+{
+/usr/lib/sqm/run.sh
+}
+
+restart()
+{
+reload
+}
+
+start()
+{
+reload
+}
+
+stop()
+{
+/usr/lib/sqm/run.sh stop
+}
\ No newline at end of file
diff --git a/net/sqm-scripts/files/usr/lib/sqm/functions.sh b/net/sqm-scripts/files/usr/lib/sqm/functions.sh
new file mode 100644 (file)
index 0000000..3411b8f
--- /dev/null
@@ -0,0 +1,458 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+#improve the logread output
+sqm_logger() {
+    logger -t SQM -s ${1}
+}
+
+insmod() {
+  lsmod | grep -q ^$1 || $INSMOD $1
+}
+
+ipt() {
+  d=`echo $* | sed s/-A/-D/g`
+  [ "$d" != "$*" ] && {
+       iptables $d > /dev/null 2>&1
+       ip6tables $d > /dev/null 2>&1
+  }
+  d=`echo $* | sed s/-I/-D/g`
+  [ "$d" != "$*" ] && {
+       iptables $d > /dev/null 2>&1
+       ip6tables $d > /dev/null 2>&1
+  }
+  iptables $* > /dev/null 2>&1
+  ip6tables $* > /dev/null 2>&1
+}
+
+do_modules() {
+#sm TODO: check first whether the modules exist and only load then
+       insmod act_ipt
+       insmod sch_$QDISC
+       insmod sch_ingress
+       insmod act_mirred
+       insmod cls_fw
+       insmod sch_htb
+}
+
+
+# You need to jiggle these parameters. Note limits are tuned towards a <10Mbit uplink <60Mbup down
+
+[ -z "$UPLINK" ] && UPLINK=2302
+[ -z "$DOWNLINK" ] && DOWNLINK=14698
+[ -z "$IFACE" ] && IFACE=ge00
+[ -z "$QDISC" ] && QDISC=fq_codel
+[ -z "$LLAM" ] && LLAM="tc_stab"
+[ -z "$LINKLAYER" ] && LINKLAYER="none"
+[ -z "$OVERHEAD" ] && OVERHEAD=0
+[ -z "$STAB_MTU" ] && STAB_MTU=2047
+[ -z "$STAB_MPU" ] && STAB_MPU=0
+[ -z "$STAB_TSIZE" ] && STAB_TSIZE=512
+[ -z "$AUTOFLOW" ] && AUTOFLOW=0
+[ -z "$LIMIT" ] && LIMIT=1001  # sane global default for *LIMIT for fq_codel on a small memory device
+[ -z "$ILIMIT" ] && ILIMIT=
+[ -z "$ELIMIT" ] && ELIMIT=
+[ -z "$ITARGET" ] && ITARGET=
+[ -z "$ETARGET" ] && ETARGET=
+[ -z "$IECN" ] && IECN="ECN"
+[ -z "$EECN" ] && EECN="NOECN"
+[ -z "$SQUASH_DSCP" ] && SQUASH_DSCP="1"
+[ -z "$SQUASH_INGRESS" ] && SQUASH_INGRESS="1"
+[ -z "$IQDISC_OPTS" ] && IQDISC_OPTS=""
+[ -z "$EQDISC_OPTS" ] && EQDISC_OPTS=""
+[ -z "$TC" ] && TC=`which tc`
+#[ -z "$TC" ] && TC="sqm_logger tc"# this redirects all tc calls into the log
+[ -z "$IP" ] && IP=$( which ip )
+[ -z "$INSMOD" ] && INSMOD=`which insmod`
+[ -z "$TARGET" ] && TARGET="5ms"
+[ -z "$IPT_MASK" ] && IPT_MASK="0xff"
+[ -z "$IPT_MASK_STRING" ] && IPT_MASK_STRING="/${IPT_MASK}"    # for set-mark
+
+#sqm_logger "${0} IPT_MASK: ${IPT_MASK_STRING}"
+
+
+
+# find the ifb device associated with a specific interface, return nothing of no ifb is associated with IF
+get_ifb_associated_with_if() {
+    CUR_IF=$1
+    # CUR_IFB=$( tc -p filter show parent ffff: dev ${CUR_IF} | grep -o -e ifb'[[:digit:]]\+' )
+    CUR_IFB=$( tc -p filter show parent ffff: dev ${CUR_IF} | grep -o -e ifb'[^)]\+' ) # my editor's syntax coloration is limitied so I need a single quote in this line (between eiditor and s)
+    sqm_logger "ifb associated with interface ${CUR_IF}: ${CUR_IFB}"
+    echo ${CUR_IFB}
+}
+
+# ATTENTION, IFB names can only be 15 chararcters, so we chop of excessive characters at the start of the interface name 
+# if required
+create_new_ifb_for_if() {
+    CUR_IF=$1
+    MAX_IF_NAME_LENGTH=15
+    IFB_PREFIX="ifb4"
+    NEW_IFB="${IFB_PREFIX}${CUR_IF}"
+    IFB_NAME_LENGTH=${#NEW_IFB}
+    if [ ${IFB_NAME_LENGTH} -gt ${MAX_IF_NAME_LENGTH} ]; 
+    then
+       sqm_logger "The requsted IFB name ${NEW_IFB} is longer than the allowed 15 characters, trying to make it shorter"
+       OVERLIMIT=$(( ${#NEW_IFB} - ${MAX_IF_NAME_LENGTH} ))
+       NEW_IFB=${IFB_PREFIX}${CUR_IF:${OVERLIMIT}:$(( ${MAX_IF_NAME_LENGTH} - ${#IFB_PREFIX} ))}
+    fi
+    sqm_logger "trying to create new IFB: ${NEW_IFB}"
+    $IP link add name ${NEW_IFB} type ifb #>/dev/null 2>&1     # better be verbose
+    echo ${NEW_IFB}
+}
+
+# the best match is either the IFB already associated with the current interface or a new named IFB
+get_ifb_for_if() {
+    CUR_IF=$1
+    # if an ifb is already associated return that
+    CUR_IFB=$( get_ifb_associated_with_if ${CUR_IF} )
+    [ -z "$CUR_IFB" ] && CUR_IFB=$( create_new_ifb_for_if ${CUR_IF} )
+    [ -z "$CUR_IFB" ] && sqm_logger "Could not find existing IFB for ${CUR_IF}, nor create a new IFB instead..."
+    echo ${CUR_IFB}
+}
+
+#sm: we need the functions above before trying to set the ingress IFB device
+[ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} )      # automagically get the right IFB device for the IFACE"
+
+
+get_htb_adsll_string() {
+       ADSLL=""
+       if [ "$LLAM" = "htb_private" -a "$LINKLAYER" != "none" ]; 
+       then
+               # HTB defaults to MTU 1600 and an implicit fixed TSIZE of 256, but HTB as of around 3.10.0
+               # does not actually use a table in the kernel
+               ADSLL="mpu ${STAB_MPU} linklayer ${LINKLAYER} overhead ${OVERHEAD} mtu ${STAB_MTU}"
+               sqm_logger "ADSLL: ${ADSLL}"
+       fi
+       echo ${ADSLL}
+}
+
+get_stab_string() {
+       STABSTRING=""
+       if [ "${LLAM}" = "tc_stab" -a "$LINKLAYER" != "none" ]; 
+       then
+               STABSTRING="stab mtu ${STAB_MTU} tsize ${STAB_TSIZE} mpu ${STAB_MPU} overhead ${OVERHEAD} linklayer ${LINKLAYER}"
+               sqm_logger "STAB: ${STABSTRING}"
+       fi
+       echo ${STABSTRING}
+}
+
+sqm_stop() {
+       $TC qdisc del dev $IFACE ingress
+       $TC qdisc del dev $IFACE root
+       $TC qdisc del dev $DEV root
+}
+
+# Note this has side effects on the prio variable
+# and depends on the interface global too
+
+fc() {
+       $TC filter add dev $interface protocol ip parent $1 prio $prio u32 match ip tos $2 0xfc classid $3
+       prio=$(($prio + 1))
+       $TC filter add dev $interface protocol ipv6 parent $1 prio $prio u32 match ip6 priority $2 0xfc classid $3
+       prio=$(($prio + 1))
+}
+
+fc_pppoe() {
+       PPPOE_SESSION_ETHERTYPE="0x8864"
+       PPPOE_DISCOVERY_ETHERTYPE="0x8863"
+       PPP_PROTO_IP4="0x0021"
+       PPP_PROTO_IP6="0x0057"
+       ARP_PROTO_IP4="0x0806"
+       $TC filter add dev $interface protocol ip parent $1 prio $prio u32 match ip tos $2 0xfc classid $3
+       $TC filter add dev $interface parent $1 protocol ${PPPOE_SESSION_ETHERTYPE} prio $(( 400 + ${prio}  )) u32 \
+           match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+           match u8 $2 0xfc at 9 \
+           flowid $3
+
+       prio=$(($prio + 1))
+       $TC filter add dev $interface protocol ipv6 parent $1 prio $prio u32 match ip6 priority $2 0xfc classid $3
+       $TC filter add dev $interface parent $1 protocol ${PPPOE_SESSION_ETHERTYPE} prio $(( 600 + ${prio} )) u32 \
+           match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+           match u16 0x0${2:2:2}0 0x0fc0 at 8 \
+           flowid $3
+       
+
+
+
+       prio=$(($prio + 1))
+
+
+}
+# FIXME: actually you need to get the underlying MTU on PPOE thing
+
+get_mtu() {
+       BW=$2
+       F=`cat /sys/class/net/$1/mtu`
+       if [ -z "$F" ]
+       then
+       F=1500
+       fi
+       if [ $BW -gt 20000 ]
+       then
+               F=$(($F * 2))
+       fi
+       if [ $BW -gt 30000 ]
+       then
+               F=$(($F * 2))
+       fi
+       if [ $BW -gt 40000 ]
+       then
+               F=$(($F * 2))
+       fi
+       if [ $BW -gt 50000 ]
+       then
+               F=$(($F * 2))
+       fi
+       if [ $BW -gt 60000 ]
+       then
+               F=$(($F * 2))
+       fi
+       if [ $BW -gt 80000 ]
+       then
+               F=$(($F * 2))
+       fi
+       echo $F
+}
+
+# FIXME should also calculate the limit
+# Frankly I think Xfq_codel can pretty much always run with high numbers of flows
+# now that it does fate sharing
+# But right now I'm trying to match the ns2 model behavior better
+# So SET the autoflow variable to 1 if you want the cablelabs behavior
+
+get_flows() {
+       if [ "$AUTOFLOW" -eq "1" ] 
+       then
+               FLOWS=8
+               [ $1 -gt 999 ] && FLOWS=16
+               [ $1 -gt 2999 ] && FLOWS=32
+               [ $1 -gt 7999 ] && FLOWS=48
+               [ $1 -gt 9999 ] && FLOWS=64
+               [ $1 -gt 19999 ] && FLOWS=128
+               [ $1 -gt 39999 ] && FLOWS=256
+               [ $1 -gt 69999 ] && FLOWS=512
+               [ $1 -gt 99999 ] && FLOWS=1024
+               case $QDISC in
+                       codel|ns2_codel|pie|*fifo|pfifo_fast) ;;
+                       fq_codel|*fq_codel|sfq) echo flows $FLOWS ;;
+               esac
+       fi
+}      
+
+# set the target parameter, also try to only take well formed inputs
+# Note, the link bandwidth in the current direction (ingress or egress) 
+# is required to adjust the target for slow links
+get_target() {
+       local CUR_TARGET=${1}
+       local CUR_LINK_KBPS=${2}
+       [ ! -z "$CUR_TARGET" ] && sqm_logger "cur_target: ${CUR_TARGET} cur_bandwidth: ${CUR_LINK_KBPS}"
+       CUR_TARGET_STRING=
+       # either e.g. 100ms or auto
+       CUR_TARGET_VALUE=$( echo ${CUR_TARGET} | grep -o -e \^'[[:digit:]]\+' )
+       CUR_TARGET_UNIT=$( echo ${CUR_TARGET} | grep -o -e '[[:alpha:]]\+'\$ )
+#      [ ! -z "$CUR_TARGET" ] && sqm_logger "CUR_TARGET_VALUE: $CUR_TARGET_VALUE"
+#      [ ! -z "$CUR_TARGET" ] && sqm_logger "CUR_TARGET_UNIT: $CUR_TARGET_UNIT"
+       
+       AUTO_TARGET=
+       UNIT_VALID=
+       
+       case $QDISC in
+               *codel|*pie) 
+                       if [ ! -z "${CUR_TARGET_VALUE}" -a ! -z "${CUR_TARGET_UNIT}" ];
+                       then
+                           case ${CUR_TARGET_UNIT} in
+                                   # permissible units taken from: tc_util.c get_time()
+                                   s|sec|secs|ms|msec|msecs|us|usec|usecs) 
+                                       CUR_TARGET_STRING="target ${CUR_TARGET_VALUE}${CUR_TARGET_UNIT}" 
+                                       UNIT_VALID="1"
+                                       ;;
+                           esac
+                       fi
+                       case ${CUR_TARGET_UNIT} in
+                           auto|Auto|AUTO) 
+                               if [ ! -z "${CUR_LINK_KBPS}" ];
+                               then
+                                   TMP_TARGET_US=$( adapt_target_to_slow_link $CUR_LINK_KBPS )
+                                   TMP_INTERVAL_STRING=$( adapt_interval_to_slow_link $TMP_TARGET_US )
+                                   CUR_TARGET_STRING="target ${TMP_TARGET_US}us ${TMP_INTERVAL_STRING}"
+                                   AUTO_TARGET="1"
+                               else
+                                   sqm_logger "required link bandwidth in kbps not passed to get_target()." 
+                               fi
+                           ;;
+                       esac
+                       if [ ! -z "${CUR_TARGET}" ];
+                           then
+                           if [ -z "${CUR_TARGET_VALUE}" -o -z "${UNIT_VALID}" ];
+                           then 
+                               [ -z "$AUTO_TARGET" ] && sqm_logger "${CUR_TARGET} is not a well formed tc target specifier; e.g.: 5ms (or s, us), or the string auto."
+                           fi
+                       fi
+                   ;;
+       esac
+#      sqm_logger "target: ${CUR_TARGET_STRING}"
+       echo $CUR_TARGET_STRING
+}      
+
+# for low bandwidth links fq_codels default target of 5ms does not work too well
+# so increase target for slow links (note below roughly 2500kbps a single packet will \
+# take more than 5 ms to be tansfered over the wire)
+adapt_target_to_slow_link() {
+    CUR_LINK_KBPS=$1
+    CUR_EXTENDED_TARGET_US=
+    MAX_PAKET_DELAY_IN_US_AT_1KBPS=$(( 1000 * 1000 *1540 * 8 / 1000 ))
+    CUR_EXTENDED_TARGET_US=$(( ${MAX_PAKET_DELAY_IN_US_AT_1KBPS} / ${CUR_LINK_KBPS} )) # note this truncates the decimals
+    # do not change anything for fast links
+    [ "$CUR_EXTENDED_TARGET_US" -lt 5000 ] && CUR_EXTENDED_TARGET_US=5000
+    case ${QDISC} in
+        *codel|pie)
+           echo "${CUR_EXTENDED_TARGET_US}"
+           ;;
+    esac
+}
+
+# codel looks at a whole interval to figure out wether observed latency stayed below target
+# if target >= interval that will not work well, so increase interval by the same amonut that target got increased
+adapt_interval_to_slow_link() {
+    CUR_TARGET_US=$1
+    case ${QDISC} in
+        *codel)
+            CUR_EXTENDED_INTERVAL_US=$(( (100 - 5) * 1000 + ${CUR_TARGET_US} ))
+           echo "interval ${CUR_EXTENDED_INTERVAL_US}us"
+           ;;
+       pie)
+           ## not sure if pie needs this, probably not
+           #CUR_EXTENDED_TUPDATE_US=$(( (30 - 20) * 1000 + ${CUR_TARGET_US} ))
+           #echo "tupdate ${CUR_EXTENDED_TUPDATE_US}us"
+           ;;
+    esac
+}
+
+
+# set quantum parameter if available for this qdisc
+get_quantum() {
+    case $QDISC in
+       *fq_codel|fq_pie|drr) echo quantum $1 ;;
+       *) ;;
+    esac
+}
+
+# only show limits to qdiscs that can handle them...
+# Note that $LIMIT contains the default limit
+get_limit() {
+    CURLIMIT=$1
+    case $QDISC in
+    *codel|*pie|pfifo_fast|sfq|pfifo) [ -z ${CURLIMIT} ] && CURLIMIT=${LIMIT}  # use the global default limit
+        ;;
+    bfifo) [ -z "$CURLIMIT" ] && [ ! -z "$LIMIT" ] && CURLIMIT=$(( ${LIMIT} * $( cat /sys/class/net/${IFACE}/mtu ) ))  # bfifo defaults to txquelength * MTU, 
+        ;;
+    *) sqm_logger "${QDISC} does not support a limit"
+        ;;
+    esac
+    sqm_logger "get_limit: $1 CURLIMIT: ${CURLIMIT}"
+    
+    if [ ! -z "$CURLIMIT" ]
+    then
+    echo "limit ${CURLIMIT}"
+    fi
+}
+
+get_ecn() {
+    CURECN=$1
+    #sqm_logger CURECN: $CURECN
+       case ${CURECN} in
+               ECN)
+                       case $QDISC in
+                               *codel|*pie|*red)
+                                   CURECN=ecn 
+                                   ;;
+                               *) 
+                                   CURECN="" 
+                                   ;;
+                       esac
+                       ;;
+               NOECN)
+                       case $QDISC in
+                               *codel|*pie|*red) 
+                                   CURECN=noecn 
+                                   ;;
+                               *) 
+                                   CURECN="" 
+                                   ;;
+                       esac
+                       ;;
+               *)
+                   sqm_logger "ecn value $1 not handled"
+                   ;;
+       esac
+       #sqm_logger "get_ECN: $1 CURECN: ${CURECN} IECN: ${IECN} EECN: ${EECN}"
+       echo ${CURECN}
+
+}
+
+# This could be a complete diffserv implementation
+
+diffserv() {
+
+interface=$1
+prio=1
+
+# Catchall
+
+$TC filter add dev $interface parent 1:0 protocol all prio 999 u32 \
+        match ip protocol 0 0x00 flowid 1:12
+
+# Find the most common matches fast
+#fc_pppoe() instead of fc() with effectice ingress classification for pppoe is very expensive and destroys LUL
+
+fc 1:0 0x00 1:12 # BE
+fc 1:0 0x20 1:13 # CS1
+fc 1:0 0x10 1:11 # IMM
+fc 1:0 0xb8 1:11 # EF
+fc 1:0 0xc0 1:11 # CS3
+fc 1:0 0xe0 1:11 # CS6
+fc 1:0 0x90 1:11 # AF42 (mosh)
+
+# Arp traffic
+$TC filter add dev $interface protocol arp parent 1:0 prio $prio handle 500 fw flowid 1:11
+
+
+prio=$(($prio + 1))
+
+
+}
+
+diffserv_pppoe() {
+
+interface=$1
+prio=1
+
+# Catchall
+
+$TC filter add dev $interface parent 1:0 protocol all prio 999 u32 \
+        match ip protocol 0 0x00 flowid 1:12
+
+# Find the most common matches fast
+#fc_pppoe() instead of fc() with effectice ingress classification for pppoe is very expensive and destroys LUL
+
+fc_pppoe 1:0 0x00 1:12 # BE
+fc_pppoe 1:0 0x20 1:13 # CS1
+fc_pppoe 1:0 0x10 1:11 # IMM
+fc_pppoe 1:0 0xb8 1:11 # EF
+fc_pppoe 1:0 0xc0 1:11 # CS3
+fc_pppoe 1:0 0xe0 1:11 # CS6
+fc_pppoe 1:0 0x90 1:11 # AF42 (mosh)
+
+# Arp traffic
+$TC filter add dev $interface protocol arp parent 1:0 prio $prio handle 500 fw flowid 1:11
+
+
+prio=$(($prio + 1))
+
+
+}
+
+
diff --git a/net/sqm-scripts/files/usr/lib/sqm/run.sh b/net/sqm-scripts/files/usr/lib/sqm/run.sh
new file mode 100755 (executable)
index 0000000..d7b86a2
--- /dev/null
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+
+. /lib/functions.sh
+
+STOP=$1
+ACTIVE_STATE_PREFIX="SQM_active_on_"
+ACTIVE_STATE_FILE_DIR="/var/run/SQM"
+mkdir -p ${ACTIVE_STATE_FILE_DIR}
+
+# the current uci config file does not necessarily contain sections for all interfaces with active
+# SQM instances, so use the ACTIVE_STATE_FILES to detect the interfaces on which to stop SQM.
+# Currently the .qos scripts start with stopping any existing traffic shaping so this should not
+# effectively change anything...
+PROTO_STATE_FILE_LIST=$( ls ${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}* 2> /dev/null )
+for STATE_FILE in ${PROTO_STATE_FILE_LIST} ; do
+    if [ -f ${STATE_FILE} ] ;
+    then
+       STATE_FILE_BASE_NAME=$( basename ${STATE_FILE} )
+       CURRENT_INTERFACE=${STATE_FILE_BASE_NAME:${#ACTIVE_STATE_PREFIX}:$(( ${#STATE_FILE_BASE_NAME} - ${#ACTIVE_STATE_PREFIX} ))}        
+       logger -t SQM -s "${0} Stopping SQM on interface: ${CURRENT_INTERFACE}"
+       /usr/lib/sqm/stop.sh ${CURRENT_INTERFACE}
+       rm ${STATE_FILE}        # well, we stop it so it is not running anymore and hence no active state file needed...
+    fi
+done
+
+config_load sqm
+
+run_simple_qos() {
+       local section="$1"
+       export IFACE=$(config_get "$section" interface)
+       ACTIVE_STATE_FILE_FQN="${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}${IFACE}" # this marks interfaces as active with SQM
+       [ -f "${ACTIVE_STATE_FILE_FQN}" ] && logger -t SQM -s "Uh, oh, ${ACTIVE_STATE_FILE_FQN} should already be stopped."     # Not supposed to happen
+
+       if [ $(config_get "$section" enabled) -ne 1 ];
+       then
+           if [ -f "${ACTIVE_STATE_FILE_FQN}" ];
+           then
+               # this should not be possible, delete after testing
+               local SECTION_STOP="stop"       # it seems the user just de-selected enable, so stop the active SQM
+           else
+               logger -t SQM -s "${0} SQM for interface ${IFACE} is not enabled, skipping over..."
+               return 0        # since SQM is not active on the current interface nothing to do here
+           fi
+       fi
+
+       export UPLINK=$(config_get "$section" upload)
+       export DOWNLINK=$(config_get "$section" download)
+       export LLAM=$(config_get "$section" linklayer_adaptation_mechanism)
+       export LINKLAYER=$(config_get "$section" linklayer)
+       export OVERHEAD=$(config_get "$section" overhead)
+       export STAB_MTU=$(config_get "$section" tcMTU)
+       export STAB_TSIZE=$(config_get "$section" tcTSIZE)
+       export STAB_MPU=$(config_get "$section" tcMPU)
+       export ILIMIT=$(config_get "$section" ilimit)
+       export ELIMIT=$(config_get "$section" elimit)
+       export ITARGET=$(config_get "$section" itarget)
+       export ETARGET=$(config_get "$section" etarget)
+       export IECN=$(config_get "$section" ingress_ecn)
+       export EECN=$(config_get "$section" egress_ecn)
+       export IQDISC_OPTS=$(config_get "$section" iqdisc_opts)
+       export EQDISC_OPTS=$(config_get "$section" eqdisc_opts)
+       export TARGET=$(config_get "$section" target)
+       export SQUASH_DSCP=$(config_get "$section" squash_dscp)
+       export SQUASH_INGRESS=$(config_get "$section" squash_ingress)
+
+       export QDISC=$(config_get "$section" qdisc)
+       export SCRIPT=/usr/lib/sqm/$(config_get "$section" script)
+
+#      # there should be nothing left to stop, so just avoid calling the script
+       if [ "$STOP" == "stop" -o "$SECTION_STOP" == "stop" ];
+       then 
+#           /usr/lib/sqm/stop.sh
+#           [ -f ${ACTIVE_STATE_FILE_FQN} ] && rm ${ACTIVE_STATE_FILE_FQN}     # conditional to avoid errors ACTIVE_STATE_FILE_FQN does not exist anymore
+#           $(config_set "$section" enabled 0) # this does not save to the config file only to the loaded memory representation
+            logger -t SQM -s "${0} SQM qdiscs on ${IFACE} removed"
+            return 0
+       fi
+       logger -t SQM -s "${0} Queue Setup Script: ${SCRIPT}"
+       [ -x "$SCRIPT" ] && { $SCRIPT ; touch ${ACTIVE_STATE_FILE_FQN}; }
+}
+
+config_foreach run_simple_qos
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simple.qos b/net/sqm-scripts/files/usr/lib/sqm/simple.qos
new file mode 100755 (executable)
index 0000000..5df6aa7
--- /dev/null
@@ -0,0 +1,215 @@
+#!/bin/sh
+# Cero3 Shaper
+# A 3 bin tc_codel and ipv6 enabled shaping script for
+# ethernet gateways
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+# Compared to the complexity that debloat had become
+# this cleanly shows a means of going from diffserv marking
+# to prioritization using the current tools (ip(6)tables
+# and tc. I note that the complexity of debloat exists for
+# a reason, and it is expected that script is run first
+# to setup various other parameters such as BQL and ethtool.
+# (And that the debloat script has setup the other interfaces)
+
+# You need to jiggle these parameters. Note limits are tuned towards a <10Mbit uplink <60Mbup down
+
+. /usr/lib/sqm/functions.sh
+
+ipt_setup() {
+
+ipt -t mangle -N QOS_MARK_${IFACE}
+
+ipt -t mangle -A QOS_MARK_${IFACE} -j MARK --set-mark 0x2${IPT_MASK_STRING}
+# You can go further with classification but...
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS1 -j MARK --set-mark 0x3${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS6 -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class EF -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class AF42 -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m tos  --tos Minimize-Delay -j MARK --set-mark 0x1${IPT_MASK_STRING}
+
+# and it might be a good idea to do it for udp tunnels too
+
+# Turn it on. Preserve classification if already performed
+
+if [ "$SQUASH_DSCP" = "1" ]
+then
+sqm_logger "Squashing differentiated services code points (DSCP) from ingress."
+ipt -t mangle -I PREROUTING -i $IFACE -m dscp ! --dscp 0 -j DSCP --set-dscp-class be
+else
+sqm_logger "Keeping differentiated services code points (DSCP) from ingress."
+ipt -t mangle -A PREROUTING -i $IFACE -m mark --mark 0x00${IPT_MASK_STRING} -g QOS_MARK_${IFACE} 
+fi
+
+ipt -t mangle -A POSTROUTING -o $IFACE -m mark --mark 0x00${IPT_MASK_STRING} -g QOS_MARK_${IFACE} 
+
+# The Syn optimization was nice but fq_codel does it for us
+# ipt -t mangle -A PREROUTING -i s+ -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x01
+# Not sure if this will work. Encapsulation is a problem period
+
+ipt -t mangle -I PREROUTING -i vtun+ -p tcp -j MARK --set-mark 0x2${IPT_MASK_STRING} # tcp tunnels need ordering
+
+# Emanating from router, do a little more optimization
+# but don't bother with it too much. 
+
+ipt -t mangle -A OUTPUT -p udp -m multiport --ports 123,53 -j DSCP --set-dscp-class AF42
+
+#Not clear if the second line is needed
+#ipt -t mangle -A OUTPUT -o $IFACE -g QOS_MARK_${IFACE}
+
+}
+
+
+# TC rules
+
+egress() {
+
+CEIL=${UPLINK}
+PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
+BE_RATE=`expr $CEIL / 6`   # Min for best effort
+BK_RATE=`expr $CEIL / 6`   # Min for background
+BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
+
+LQ="quantum `get_mtu $IFACE $CEIL`"
+
+$TC qdisc del dev $IFACE root 2> /dev/null
+$TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 12
+$TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:11 htb $LQ rate 128kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+
+$TC qdisc add dev $IFACE parent 1:11 handle 110: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${PRIO_RATE}` ${EQDISC_OPTS}
+$TC qdisc add dev $IFACE parent 1:12 handle 120: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BE_RATE}` ${EQDISC_OPTS}
+$TC qdisc add dev $IFACE parent 1:13 handle 130: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${EQDISC_OPTS}
+
+
+# Need a catchall rule
+
+$TC filter add dev $IFACE parent 1:0 protocol all prio 999 u32 \
+        match ip protocol 0 0x00 flowid 1:12  
+
+# FIXME should probably change the filter here to do pre-nat
+        
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 3 handle 3 fw classid 1:13
+
+# ipv6 support. Note that the handle indicates the fw mark bucket that is looked for
+
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 4 handle 1 fw classid 1:11
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 5 handle 2 fw classid 1:12
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 6 handle 3 fw classid 1:13
+
+# Arp traffic
+
+$TC filter add dev $IFACE parent 1:0 protocol arp prio 7 handle 1 fw classid 1:11
+
+# ICMP traffic - Don't impress your friends. Deoptimize to manage ping floods
+# better instead
+
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 8 \
+        u32 match ip protocol 1 0xff flowid 1:13
+
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 9 \
+        u32 match ip protocol 1 0xff flowid 1:13
+
+#diffserv $IFACE
+
+}
+
+ingress() {
+
+CEIL=$DOWNLINK
+PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
+BE_RATE=`expr $CEIL / 6`   # Min for best effort
+BK_RATE=`expr $CEIL / 6`   # Min for background
+BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
+
+LQ="quantum `get_mtu $IFACE $CEIL`"
+
+$TC qdisc del dev $IFACE handle ffff: ingress 2> /dev/null
+$TC qdisc add dev $IFACE handle ffff: ingress
+
+$TC qdisc del dev $DEV root  2> /dev/null
+
+if [ "$SQUASH_INGRESS" = "1" ]
+then
+sqm_logger "Do not perform DSCP based filtering on ingress. (1-tier classification)"
+# Revert to no dscp based filtering
+$TC qdisc del dev $DEV root 2>/dev/null
+$TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10
+$TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit prio 0 `get_htb_adsll_string`
+$TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS}
+
+else
+sqm_logger "Perform DSCP based filtering on ingress. (3-tier classification)"
+$TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 12
+$TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:11 htb $LQ rate 32kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+
+# I'd prefer to use a pre-nat filter but that causes permutation...
+
+$TC qdisc add dev $DEV parent 1:11 handle 110: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 500` `get_flows ${PRIO_RATE}` ${IQDISC_OPTS}
+$TC qdisc add dev $DEV parent 1:12 handle 120: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 1500` `get_flows ${BE_RATE}` ${IQDISC_OPTS}
+$TC qdisc add dev $DEV parent 1:13 handle 130: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${IQDISC_OPTS}
+
+diffserv $DEV
+
+fi
+
+ifconfig $DEV up
+
+# redirect all IP packets arriving in $IFACE to ifb0 
+
+$TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \
+  match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV
+
+}
+
+do_modules
+ipt_setup
+
+if [ "$UPLINK" -ne 0 ];
+then
+       egress
+       sqm_logger "egress shaping activated"
+else
+       sqm_logger "egress shaping deactivated"
+       tc qdisc del dev $IFACE root 2> /dev/null
+fi
+if [ "$DOWNLINK" -ne 0 ];
+then
+       ingress
+       sqm_logger "ingress shaping activated"
+else
+       sqm_logger "ingress shaping deactivated"
+       tc qdisc del dev $DEV root 2> /dev/null
+       tc qdisc del dev $IFACE ingress 2> /dev/null
+fi
+
+
+
+# References:
+# This alternate shaper attempts to go for 1/u performance in a clever way
+# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD
+
+# Comments
+# This does the right thing with ipv6 traffic.
+# It also tries to leverage diffserv to some sane extent. In particular,
+# the 'priority' queue is limited to 33% of the total, so EF, and IMM traffic
+# cannot starve other types. The rfc suggested 30%. 30% is probably
+# a lot in today's world.
+
+# Flaws
+# Many!
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simple.qos.help b/net/sqm-scripts/files/usr/lib/sqm/simple.qos.help
new file mode 100644 (file)
index 0000000..b059601
--- /dev/null
@@ -0,0 +1 @@
+BW-limited three-tier prioritisation scheme with fq_codel on each queue. (default)
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos b/net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos
new file mode 100755 (executable)
index 0000000..d40d1bb
--- /dev/null
@@ -0,0 +1,398 @@
+#!/bin/sh
+# Cero3 Shaper
+# A 3 bin tc_codel and ipv6 enabled shaping script for
+# ethernet gateways
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+# Compared to the complexity that debloat had become
+# this cleanly shows a means of going from diffserv marking
+# to prioritization using the current tools (ip(6)tables
+# and tc. I note that the complexity of debloat exists for
+# a reason, and it is expected that script is run first
+# to setup various other parameters such as BQL and ethtool.
+# (And that the debloat script has setup the other interfaces)
+
+# You need to jiggle these parameters. Note limits are tuned towards a <10Mbit uplink <60Mbup down
+
+#sm: Goal to create a set of tc filters that also apply on pppoe encapsulated packets
+#      but having multiple filters run in succession is slow, so look at tc filter hashing 
+#      (this should help cut down the number of OPs per packet considerably)
+
+
+. /usr/lib/sqm/functions.sh
+#sqm_logger IPT_MASK: ${IPT_MASK_STRING}
+ipt_setup() {
+
+ipt -t mangle -N QOS_MARK_${IFACE}
+
+ipt -t mangle -A QOS_MARK_${IFACE} -j MARK --set-mark 0x2${IPT_MASK_STRING}
+# You can go further with classification but...
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS1 -j MARK --set-mark 0x3${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class CS6 -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class EF -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m dscp --dscp-class AF42 -j MARK --set-mark 0x1${IPT_MASK_STRING}
+ipt -t mangle -A QOS_MARK_${IFACE} -m tos  --tos Minimize-Delay -j MARK --set-mark 0x1${IPT_MASK_STRING}
+
+# and it might be a good idea to do it for udp tunnels too
+
+# Turn it on. Preserve classification if already performed
+
+if [ "$SQUASH_DSCP" = "1" ]
+then
+sqm_logger "Squashing differentiated services code points (DSCP) from ingress."
+ipt -t mangle -I PREROUTING -i $IFACE -m dscp ! --dscp 0 -j DSCP --set-dscp-class be
+else
+sqm_logger "Keeping differentiad services code points (DSCP) from ingress."
+ipt -t mangle -A PREROUTING -i $IFACE -m mark --mark 0x00${IPT_MASK_STRING} -g QOS_MARK_${IFACE} 
+fi
+
+ipt -t mangle -A POSTROUTING -o $IFACE -m mark --mark 0x00${IPT_MASK_STRING} -g QOS_MARK_${IFACE} 
+
+# The Syn optimization was nice but fq_codel does it for us
+# ipt -t mangle -A PREROUTING -i s+ -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x01
+# Not sure if this will work. Encapsulation is a problem period
+
+ipt -t mangle -I PREROUTING -i vtun+ -p tcp -j MARK --set-mark 0x2${IPT_MASK_STRING} # tcp tunnels need ordering
+
+# Emanating from router, do a little more optimization
+# but don't bother with it too much. 
+
+ipt -t mangle -A OUTPUT -p udp -m multiport --ports 123,53 -j DSCP --set-dscp-class AF42
+
+#Not clear if the second line is needed
+#ipt -t mangle -A OUTPUT -o $IFACE -g QOS_MARK_${IFACE}
+
+}
+
+
+MYBURST=1600   #sm: make burst and cburst as well as quantum configurable for ingress and egress in the GUI
+# TC rules
+
+egress() {
+
+CEIL=${UPLINK}
+PRIO_RATE=`expr $CEIL / 3` # Ceiling for priority
+BE_RATE=`expr $CEIL / 6`   # Min for best effort
+BK_RATE=`expr $CEIL / 6`   # Min for background
+BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
+
+LQ="quantum `get_mtu $IFACE $CEIL`"
+HTB_BURSTS="burst ${MYBURST} cburst ${MYBURST}"
+
+$TC qdisc del dev $IFACE root 2> /dev/null
+$TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 12
+$TC class add dev $IFACE parent 1: classid 1:1 htb $LQ ${HTB_BURSTS} rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ ${HTB_BURSTS} rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:11 htb $LQ ${HTB_BURSTS} rate 128kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:12 htb $LQ ${HTB_BURSTS} rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:13 htb $LQ ${HTB_BURSTS} rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+
+$TC qdisc add dev $IFACE parent 1:11 handle 110: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${PRIO_RATE}` ${EQDISC_OPTS}
+$TC qdisc add dev $IFACE parent 1:12 handle 120: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BE_RATE}` ${EQDISC_OPTS}
+$TC qdisc add dev $IFACE parent 1:13 handle 130: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${EQDISC_OPTS}
+
+
+#sm: for testing we need a band to collect PPPOEd packets
+$TC class add dev $IFACE parent 1:1 classid 1:14 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
+$TC qdisc add dev $IFACE parent 1:14 handle 140: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${EQDISC_OPTS}
+
+
+# Need a catchall rule (should also match VLANs and PPPoE packets)
+
+$TC filter add dev $IFACE parent 1:0 protocol all prio 999 u32 \
+        match ip protocol 0 0x00 flowid 1:12  
+
+# FIXME should probably change the filter here to do pre-nat
+        
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 3 handle 3 fw classid 1:13
+
+# ipv6 support. Note that the handle indicates the fw mark bucket that is looked for
+
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 4 handle 1 fw classid 1:11
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 5 handle 2 fw classid 1:12
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 6 handle 3 fw classid 1:13
+
+# Arp traffic
+
+$TC filter add dev $IFACE parent 1:0 protocol arp prio 7 handle 1 fw classid 1:11
+
+# ICMP traffic - Don't impress your friends. Deoptimize to manage ping floods
+# better instead
+
+$TC filter add dev $IFACE parent 1:0 protocol ip prio 8 \
+        u32 match ip protocol 1 0xff flowid 1:13
+
+$TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 9 \
+        u32 match ip protocol 1 0xff flowid 1:13
+
+
+
+
+# PPPoE encapsulated packets traversing the router (e.g.: the router does PPPoE termination but we shape 
+# on the underlaying ethernet interface instead of the pppoe device)
+
+PPPOE_SESSION_ETHERTYPE="0x8864"
+PPPOE_DISCOVERY_ETHERTYPE="0x8863"
+PPP_PROTO_IP4="0x0021"
+PPP_PROTO_IP6="0x0057"
+ARP_PROTO_IP4="0x0806"
+
+# NOTE it seems prio can not be reused?
+#$TC filter add dev $IFACE protocol 0x8863 parent 1:0 prio 1 u32 flowid 1:14
+# PPPoE can be selected for by ether_type, the encapsulated IP version from the PPP (0x0021 IPv4, 0x0057 IPv6)
+#U32_PREFIX="$TC filter add dev $IFACE" parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE}"
+
+#BE: 1:12 is the default anyway, but this will catch all non marked packets
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 400 u32 \
+#      match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+#      match u8 0x00 0xfb at 9 \
+#      flowid 1:12
+
+#AF42
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 401 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0x90 0xfc at 9 \
+       flowid 1:11
+#EF
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 402 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0xb8 0xfc at 9 \
+       flowid 1:11
+#CS1
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 403 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0x20 0xf0 at 9 \
+       flowid 1:13
+#IMM
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 404 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0x10 0xf0 at 9 \
+       flowid 1:11
+#CS3
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 405 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0xc0 0xf0 at 9 \
+       flowid 1:11
+#CS6
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 406 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0xe0 0xf0 at 9 \
+       flowid 1:11
+
+
+## Arp traffic
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 409 u32 \
+#      match u16 ${ARP_PROTO_IP4} 0xffff at 6 \
+#      flowid 1:14
+
+# ICMP traffic - Don't impress your friends. Deoptimize to manage ping floods
+# better instead; sm: really only deprio echo requestst and echo replies instead?
+# ECHO request, the rest stays in best effort
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 410 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0x01 0xff at 17 \
+       match u8 0x08 0xff at 28 \
+       flowid 1:13
+# ECHO reply
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 410 u32 \
+       match u16 ${PPP_PROTO_IP4} 0xffff at 6 \
+       match u8 0x01 0xff at 17 \
+       match u8 0x00 0xff at 28 \
+       flowid 1:13
+
+## ICMPv6 133-137 (NDP) is equivalent to IPv4 ARP, so only push echo request and reply into the bulk class
+## 133
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u8 0x85 0xff at 48 \
+#      match u8 0x3a 0xff at 14 \
+#      flowid 1:14
+## 134
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u8 0x86 0xff at 48 \
+#      match u8 0x3a 0xff at 14 \
+#      flowid 1:14
+## 135
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u8 0x87 0xff at 48 \
+#      match u8 0x3a 0xff at 14 \
+#      flowid 1:14
+## 136
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u8 0x88 0xff at 48 \
+#      match u8 0x3a 0xff at 14 \
+#      flowid 1:14
+## 137
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u8 0x89 0xff at 48 \
+#      match u8 0x3a 0xff at 14 \
+#      flowid 1:14
+
+# ICMPv6 echo request
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u8 0x3a 0xff at 14 \
+       match u8 0x80 0xff at 48 \
+       flowid 1:13
+# ICMPv6 echo reply
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 610 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u8 0x3a 0xff at 14 \
+       match u8 0x81 0xff at 48 \
+       flowid 1:13
+
+
+
+
+#IPV6
+#BE: careful, will override ICMP
+#$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 600 u32 \
+#      match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+#      match u16 0x0000 0x0fb0 at 8 \
+#      flowid 1:12
+#AF42
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 601 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0900 0x0fc0 at 8 \
+       flowid 1:11
+#EF
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 602 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0b80 0x0fc0 at 8 \
+       flowid 1:11
+#CS1
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 603 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0200 0x0fc0 at 8 \
+       flowid 1:13
+#IMM
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 604 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0100 0x0fc0 at 8 \
+       flowid 1:11
+#CS3
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 605 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0c00 0x0fc0 at 8 \
+       flowid 1:11
+#CS6
+$TC filter add dev $IFACE parent 1:0 protocol ${PPPOE_SESSION_ETHERTYPE} prio 606 u32 \
+       match u16 ${PPP_PROTO_IP6} 0xffff at 6 \
+       match u16 0x0e00 0x0fc0 at 8 \
+       flowid 1:11
+
+
+
+
+#diffserv $IFACE
+
+}
+
+ingress() {
+
+CEIL=$DOWNLINK
+PRIO_RATE=`expr $CEIL / 3` # Ceiling for prioirty
+BE_RATE=`expr $CEIL / 6`   # Min for best effort
+BK_RATE=`expr $CEIL / 6`   # Min for background
+BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
+
+LQ="quantum `get_mtu $IFACE $CEIL`"
+HTB_BURSTS="burst ${MYBURST} cburst ${MYBURST}"
+
+$TC qdisc del dev $IFACE handle ffff: ingress 2> /dev/null
+$TC qdisc add dev $IFACE handle ffff: ingress
+
+$TC qdisc del dev $DEV root  2> /dev/null
+
+if [ "$SQUASH_INGRESS" = "1" ]
+then
+sqm_logger "Do not perform DSCP based filtering on ingress. (1-tier classification)"
+# Revert to no dscp based filtering
+$TC qdisc del dev $DEV root 2>/dev/null
+$TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10
+$TC class add dev $DEV parent 1: classid 1:1 htb $LQ ${HTB_BURSTS} rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ ${HTB_BURSTS} rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit prio 0 `get_htb_adsll_string`
+$TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS}
+
+else
+sqm_logger "Perform DSCP based filtering on ingress. (3-tier classification)"
+$TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 12
+$TC class add dev $DEV parent 1: classid 1:1 htb $LQ ${HTB_BURSTS} rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ ${HTB_BURSTS} rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:11 htb $LQ ${HTB_BURSTS} rate 32kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:12 htb $LQ ${HTB_BURSTS} rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:13 htb $LQ ${HTB_BURSTS} rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+
+# I'd prefer to use a pre-nat filter but that causes permutation...
+
+$TC qdisc add dev $DEV parent 1:11 handle 110: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 500` `get_flows ${PRIO_RATE}` ${IQDISC_OPTS}
+$TC qdisc add dev $DEV parent 1:12 handle 120: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 1500` `get_flows ${BE_RATE}` ${IQDISC_OPTS}
+$TC qdisc add dev $DEV parent 1:13 handle 130: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${IQDISC_OPTS}
+
+#sm: for PPPoE packet testing
+$TC class add dev $DEV parent 1:1 classid 1:14 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+$TC qdisc add dev $DEV parent 1:14 handle 140: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 300` `get_flows ${BK_RATE}` ${IQDISC_OPTS}
+
+
+
+#diffserv $DEV
+diffserv_pppoe $DEV
+
+fi
+
+ifconfig $DEV up
+
+# redirect all IP packets arriving in $IFACE to ifb0 
+
+$TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \
+  match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV
+
+}
+
+do_modules
+ipt_setup
+
+if [ "$UPLINK" -ne 0 ];
+then
+       egress
+       sqm_logger "egress shaping activated"
+else
+       sqm_logger "egress shaping deactivated"
+       tc qdisc del dev $IFACE root 2> /dev/null
+fi
+if [ "$DOWNLINK" -ne 0 ];
+then
+       ingress
+       sqm_logger "ingress shaping activated"
+else
+       sqm_logger "ingress shaping deactivated"
+       tc qdisc del dev $DEV root 2> /dev/null
+       tc qdisc del dev $IFACE ingress 2> /dev/null
+fi
+
+
+
+# References:
+# This alternate shaper attempts to go for 1/u performance in a clever way
+# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD
+
+# Comments
+# This does the right thing with ipv6 traffic.
+# It also tries to leverage diffserv to some sane extent. In particular,
+# the 'priority' queue is limited to 33% of the total, so EF, and IMM traffic
+# cannot starve other types. The rfc suggested 30%. 30% is probably
+# a lot in today's world.
+
+# Flaws
+# Many!
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos.help b/net/sqm-scripts/files/usr/lib/sqm/simple_pppoe.qos.help
new file mode 100644 (file)
index 0000000..cc9af9d
--- /dev/null
@@ -0,0 +1,2 @@
+BW-limited three-tier prioritisation scheme with fq_codel on each queue. Temporary version to implement shaping
+of pass through PPPOE encapsulated packets.
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simplest.qos b/net/sqm-scripts/files/usr/lib/sqm/simplest.qos
new file mode 100755 (executable)
index 0000000..f06c252
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Cero3 Simple Shaper
+# A 1 bin tc_codel and ipv6 enabled shaping script for
+# ethernet gateways. This is nearly the simplest possible
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+. /usr/lib/sqm/functions.sh
+sqm_logger "Starting simplest.qos"
+
+egress() {
+
+LQ="quantum `get_mtu $IFACE ${UPLINK}`"
+
+$TC qdisc del dev $IFACE root 2>/dev/null
+$TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 10
+$TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit `get_htb_adsll_string`
+$TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit prio 0 `get_htb_adsll_string`
+$TC qdisc add dev $IFACE parent 1:10 handle 110: $QDISC `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_flows ${UPLINK}` ${EQDISC_OPTS}
+
+}
+
+
+ingress() {
+sqm_logger "ingress"
+$TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null
+$TC qdisc add dev $IFACE handle ffff: ingress
+
+LQ="quantum `get_mtu $IFACE ${DOWNLINK}`"
+$TC qdisc del dev $DEV root 2>/dev/null
+$TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10
+$TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit `get_htb_adsll_string`
+$TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit prio 0 `get_htb_adsll_string`
+
+# FIXME: I'd prefer to use a pre-nat filter but we need to detect if nat is on this interface
+# AND we need to permute by a random number which we can't do from userspace filters
+
+# Most high rate flows are REALLY close. This stomps on those harder, but hurts on high rate long distance
+#$TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC limit $LIMIT $ECN interval 20ms target 3ms `get_flows ${DOWNLINK}`
+$TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS}
+
+ifconfig $DEV up
+
+# redirect all IP packets arriving in $IFACE to ifb0 
+
+$TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \
+  match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV
+
+}
+
+do_modules
+
+if [ "$UPLINK" -ne 0 ];
+then
+       egress
+       sqm_logger "egress shaping activated"
+else
+       sqm_logger "egress shaping deactivated"
+       tc qdisc del dev $IFACE root 2> /dev/null
+fi
+if [ "$DOWNLINK" -ne 0 ];
+then
+       ingress
+       sqm_logger "ingress shaping activated"
+else
+       sqm_logger "ingress shaping deactivated"
+       tc qdisc del dev $DEV root 2> /dev/null
+       tc qdisc del dev $IFACE ingress 2> /dev/null
+fi
+
+
+# References:
+# This alternate shaper attempts to go for 1/u performance in a clever way
+# http://git.coverfire.com/?p=linux-qos-scripts.git;a=blob;f=src-3tos.sh;hb=HEAD
+
+# Comments
+# This does the right thing with ipv6 traffic.
+# Flaws
+# Many!
diff --git a/net/sqm-scripts/files/usr/lib/sqm/simplest.qos.help b/net/sqm-scripts/files/usr/lib/sqm/simplest.qos.help
new file mode 100644 (file)
index 0000000..c359256
--- /dev/null
@@ -0,0 +1 @@
+Simplest possible configuration: HTB rate limiter with your qdisc attached.
diff --git a/net/sqm-scripts/files/usr/lib/sqm/stop.sh b/net/sqm-scripts/files/usr/lib/sqm/stop.sh
new file mode 100755 (executable)
index 0000000..29e213b
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+#       Copyright (C) 2012-4 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+
+# allow passing in the IFACE as first command line argument
+[ ! -z ${1} ] && IFACE=${1}
+# now IFACE is defined so we can source functions.sh without creating a spurious ifb4ge00
+. /usr/lib/sqm/functions.sh
+# sqm_logger is defined in functions.sh...
+sqm_logger "${0}: Stopping ${IFACE}"
+
+# make sure to only delete the ifb associated with the current interface
+CUR_IFB=$( get_ifb_associated_with_if ${IFACE} )
+
+sqm_stop() {
+       tc qdisc del dev $IFACE ingress 2> /dev/null
+       tc qdisc del dev $IFACE root 2> /dev/null
+       [ ! -z "$CUR_IFB" ] && tc qdisc del dev $CUR_IFB root 2> /dev/null
+        [ ! -z "$CUR_IFB" ] && sqm_logger "${0}: ${CUR_IFB} shaper deleted"
+}
+
+ipt_stop() {
+       [ ! -z "$CUR_IFB" ] && ipt -t mangle -D POSTROUTING -o $CUR_IFB -m mark --mark 0x00 -g QOS_MARK_${IFACE} 
+       ipt -t mangle -D POSTROUTING -o $IFACE -m mark --mark 0x00 -g QOS_MARK_${IFACE} 
+       ipt -t mangle -D PREROUTING -i vtun+ -p tcp -j MARK --set-mark 0x2
+       ipt -t mangle -D OUTPUT -p udp -m multiport --ports 123,53 -j DSCP --set-dscp-class AF42
+       ipt -t mangle -F QOS_MARK_${IFACE}
+       ipt -t mangle -X QOS_MARK_${IFACE}
+}
+
+
+sqm_stop
+ipt_stop
+[ ! -z "$CUR_IFB" ] && ifconfig ${CUR_IFB} down
+[ ! -z "$CUR_IFB" ] && ip link delete ${CUR_IFB} type ifb
+[ ! -z "$CUR_IFB" ] && sqm_logger "${0}: ${CUR_IFB} interface deleted"
+
+exit 0
\ No newline at end of file
diff --git a/net/squid/Makefile b/net/squid/Makefile
new file mode 100644 (file)
index 0000000..f06df6d
--- /dev/null
@@ -0,0 +1,133 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=squid
+PKG_VERSION:=3.4.11
+PKG_RELEASE:=2
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://www.squid-cache.org/Versions/v3/3.4/
+PKG_MD5SUM:=e79ddb108d24823da8c1dbc0fc4a31fb
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/squid/Default
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Web Servers/Proxies
+  URL:=http://www.squid-cache.org/
+endef
+
+define Package/squid
+  $(call Package/squid/Default)
+  MENU:=1
+  DEPENDS:=+libopenssl +libpthread +librt +libltdl +libstdcpp
+  TITLE:=full-featured Web proxy cache
+endef
+
+define Package/squid/description
+  Squid is a caching proxy for the Web supporting HTTP, HTTPS, FTP, and more.
+  It reduces bandwidth and improves response times by caching and reusing
+  frequently-requested web pages.
+endef
+
+define Package/squid-mod-cachemgr
+  $(call Package/squid/Default)
+  DEPENDS:=squid
+  TITLE:=Web based proxy manager and reporting tool
+endef
+
+CONFIGURE_ARGS += \
+       --config-cache \
+       --datadir=/usr/share/squid \
+       --libexecdir=/usr/lib/squid \
+       --sysconfdir=/etc/squid \
+       --enable-shared \
+       --disable-static \
+       --enable-icmp \
+       --enable-delay-pools \
+       --enable-icap-client \
+       --enable-kill-parent-hack \
+       --disable-snmp \
+       --enable-ssl \
+       --enable-cache-digests \
+       --enable-auth \
+       --enable-auth-basic \
+       --enable-auth-ntlm \
+       --enable-auth-negotiate \
+       --enable-auth-digest \
+       --enable-linux-netfilter \
+       --disable-unlinkd \
+       --enable-x-accelerator-vary \
+       --disable-translation \
+       --disable-auto-locale \
+       --with-dl \
+       --with-pthreads \
+       --without-expat \
+       --without-libxml2 \
+       --without-nettle \
+       --with-openssl=$(STAGING_DIR)/usr \
+       --enable-epoll \
+       --with-maxfd=4096 \
+       --disable-external-acl-helpers \
+       --disable-auth-negotiate \
+       --disable-auth-ntlm \
+       --disable-auth-digest \
+       --disable-auth-basic \
+       --disable-arch-native \
+       --with-krb5-config=no \
+       --without-libcap \
+       --without-netfilter-conntrack \
+
+CONFIGURE_VARS += \
+       ac_cv_header_linux_netfilter_ipv4_h=yes \
+       ac_cv_epoll_works=yes \
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR)/lib \
+               all
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               install
+endef
+
+define Package/squid/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/squid $(1)/usr/sbin/
+
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/squid.config $(1)/etc/config/squid
+
+       $(INSTALL_DIR) $(1)/etc/squid
+       $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/squid/mime.conf $(1)/etc/squid/
+       $(INSTALL_CONF) ./files/squid.conf $(1)/etc/squid/
+
+       $(INSTALL_DIR) $(1)/etc/init.d/
+       $(INSTALL_BIN) ./files/squid.init $(1)/etc/init.d/squid
+
+       $(INSTALL_DIR) $(1)/usr/share/squid/icons/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/squid/icons/* $(1)/usr/share/squid/icons/
+
+       $(INSTALL_DIR) $(1)/usr/share/squid/errors/templates/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/squid/errors/templates/* $(1)/usr/share/squid/errors/templates/
+endef
+
+define Package/squid-mod-cachemgr/install
+       $(INSTALL_DIR) $(1)/www/cgi-bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/squid/cachemgr.cgi $(1)/www/cgi-bin/
+endef
+
+$(eval $(call BuildPackage,squid))
+$(eval $(call BuildPackage,squid-mod-cachemgr))
diff --git a/net/squid/files/squid.conf b/net/squid/files/squid.conf
new file mode 100644 (file)
index 0000000..96333ad
--- /dev/null
@@ -0,0 +1,44 @@
+acl localnet src 10.0.0.0/8
+acl localnet src 172.16.0.0/12
+acl localnet src 192.168.0.0/16
+acl localnet src fc00::/7
+acl localnet src fe80::/10
+
+acl ssl_ports port 443
+
+acl safe_ports port 80
+acl safe_ports port 21
+acl safe_ports port 443
+acl safe_ports port 70
+acl safe_ports port 210
+acl safe_ports port 1025-65535
+acl safe_ports port 280
+acl safe_ports port 488
+acl safe_ports port 591
+acl safe_ports port 777
+acl connect method connect
+
+http_access deny !safe_ports
+http_access deny connect !ssl_ports
+
+http_access allow localhost manager
+http_access deny manager
+
+http_access deny to_localhost
+
+http_access allow localnet
+http_access allow localhost
+
+http_access deny all
+
+refresh_pattern ^ftp: 1440 20% 10080
+refresh_pattern ^gopher: 1440 0% 1440
+refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
+refresh_pattern . 0 20% 4320
+
+access_log none
+cache_log /dev/null
+cache_store_log /dev/null
+logfile_rotate 0
+
+logfile_daemon /dev/null
diff --git a/net/squid/files/squid.config b/net/squid/files/squid.config
new file mode 100644 (file)
index 0000000..4c0daae
--- /dev/null
@@ -0,0 +1,5 @@
+config squid 'squid'
+       option config_file '/etc/squid/squid.conf'
+       option http_port '3128'
+       option coredump_dir '/tmp/squid'
+       option visible_hostname 'OpenWrt'
diff --git a/net/squid/files/squid.init b/net/squid/files/squid.init
new file mode 100644 (file)
index 0000000..8b30948
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/sbin/squid
+CONFIGFILE="/tmp/squid/squid.conf"
+
+validate_squid_section() {
+       uci_validate_section squid squid "${1}" \
+               'config_file:string' \
+               'http_port:port:3128' \
+               'coredump_dir:string' \
+               'visible_hostname:string:OpenWrt' \
+               'pinger_enable:string:off'
+}
+
+start_service() {
+       local config_file http_port coredump_dir visible_hostname pinger_enable
+
+       validate_squid_section squid || {
+               echo "validation failed"
+               return 1
+       }
+
+       mkdir -p $(dirname $CONFIGFILE)
+
+       cat $config_file > $CONFIGFILE
+       echo http_port $http_port >> $CONFIGFILE
+       echo coredump_dir $coredump_dir >> $CONFIGFILE
+       echo visible_hostname $visible_hostname >> $CONFIGFILE
+       echo pinger_enable $pinger_enable >> $CONFIGFILE
+
+       procd_open_instance
+       procd_set_param command $PROG -s -f $CONFIGFILE -N
+       procd_set_param file $CONFIGFILE
+       procd_set_param respawn
+       procd_close_instance
+}
+
+stop_service()
+{
+        ${PROG} -f $CONFIGFILE -N -k shutdown 2>/dev/null
+}
+
+service_triggers()
+{
+       procd_add_reload_trigger "squid"
+       procd_add_validation validate_squid_section
+}
diff --git a/net/squid/patches/001-cross_compile.patch b/net/squid/patches/001-cross_compile.patch
new file mode 100644 (file)
index 0000000..8b1d772
--- /dev/null
@@ -0,0 +1,49 @@
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -7742,7 +7742,7 @@ cache_cf.o: cf_parser.cci
+ # cf_gen builds the configuration files.
+ cf_gen$(EXEEXT): $(cf_gen_SOURCES) $(cf_gen_DEPENDENCIES) cf_gen_defines.cci
+-      $(HOSTCXX) -o $@ $(srcdir)/cf_gen.cc -I$(srcdir) -I$(top_builddir)/include/ -I$(top_builddir)/src
++      g++ -o $@ $(srcdir)/cf_gen.cc -I$(srcdir) -I$(top_builddir)/include/ -I$(top_builddir)/src
+ # squid.conf.default is built by cf_gen when making cf_parser.cci
+ squid.conf.default squid.conf.documented: cf_parser.cci
+--- a/configure
++++ b/configure
+@@ -22226,7 +22226,7 @@ $as_echo_n "checking whether the SSL_get
+   if test "$cross_compiling" = yes; then :
+   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
++_as_fn_error $? "cannot run test program while cross compiling
+ See \`config.log' for more details" "$LINENO" 5; }
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -22274,7 +22274,7 @@ $as_echo_n "checking whether the workaro
+   if test "$cross_compiling" = yes; then :
+   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
++_as_fn_error $? "cannot run test program while cross compiling
+ See \`config.log' for more details" "$LINENO" 5; }
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -24924,7 +24924,7 @@ else
+     if test "$cross_compiling" = yes; then :
+   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
++_as_fn_error $? "cannot run test program while cross compiling
+ See \`config.log' for more details" "$LINENO" 5; }
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -24949,7 +24949,7 @@ else
+     if test "$cross_compiling" = yes; then :
+   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
++_as_fn_error $? "cannot run test program while cross compiling
+ See \`config.log' for more details" "$LINENO" 5; }
+ else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
diff --git a/net/squid/patches/100-mime.patch b/net/squid/patches/100-mime.patch
new file mode 100644 (file)
index 0000000..b5f3aaf
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/src/mime.conf.default
++++ b/src/mime.conf.default
+@@ -1,19 +1,3 @@
+-# This file associates filename extensions (for servers or services
+-# that don't automatically include them - like ftp) with a mime type
+-# and a graphical icon.
+-#
+-#
+-# This file has the format :
+-# regex content-type icon content-encoding transfer-mode
+-#-----------------------------------------------------------------------------------
+-#
+-#
+-# Content-Encodings are taken from section 3.1 of RFC2068 (HTTP/1.1)
+-#
+-#
+-#
+-# regexp      content-type                    icon                            encoding mode   actions
+-#--------------------------------------------------------------------------------------------------------
+ \.gif$                        image/gif               silk/image.png                  -       image   +download
+ \.mime$                       www/mime                silk/page_white_text.png        -       ascii   +download
+ ^internal-dirup$      -                       silk/arrow_up.png               -       -
+@@ -190,6 +174,4 @@ README             text/plain                      silk/information.pn
+ \.xml$                text/xml                        silk/page_world.png             -       ascii   +download
+ \.xsl$                text/xml                        silk/layout.png                 -       ascii   +download
+ \.xyz$                chemical/x-xyz                  silk/chart_line.png             -       image   +download
+-
+-# the default
+ .             text/plain                      silk/bullet_red.png             -       image   +download +view
diff --git a/net/sshfs/Makefile b/net/sshfs/Makefile
new file mode 100644 (file)
index 0000000..d99dd92
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sshfs
+PKG_VERSION:=2.5
+PKG_RELEASE:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
+
+PKG_SOURCE:=$(PKG_NAME)-fuse-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/fuse
+PKG_MD5SUM:=17494910db8383a366b1301e5f5148a9
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-fuse-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/sshfs
+  TITLE:=SSHFS
+  DEPENDS:=+libfuse +fuse-utils +glib2 +libpthread
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Filesystem
+  URL:=http://fuse.sourceforge.net/
+endef
+
+define Package/sshfs/description
+       Mount remote system over sftp.
+endef
+
+CONFIGURE_VARS += \
+       SSHFS_CFLAGS=" \
+               -D_FILE_OFFSET_BITS=64 \
+               -I$(STAGING_DIR)/usr/include/glib-2.0 \
+               -I$(STAGING_DIR)/usr/lib/glib-2.0/include \
+               -I$(STAGING_DIR)/usr/include/fuse" \
+       SSHFS_LIBS=" \
+               -lglib-2.0 -liconv $(if $(INTL_FULL),-lintl) -lfuse -pthread -lgthread-2.0 \
+               -L$(STAGING_DIR)/usr/lib"
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               ARCH="$(LINUX_KARCH)" \
+               CROSS_COMPILE="$(TARGET_CROSS)" \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               all install
+endef
+
+define Package/sshfs/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sshfs $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,sshfs))
diff --git a/net/sstp-client/Makefile b/net/sstp-client/Makefile
new file mode 100644 (file)
index 0000000..185e6c0
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sstp-client
+PKG_VERSION:=1.0.9
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/sstp-client/$(PKG_VERSION)
+PKG_MD5SUM:=40f1d1b1596b4f1817ec903f58b2780c
+PKG_LICENSE=GPLv2
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sstp-client
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS=+libevent2 +libopenssl +ppp
+  TITLE:=SSTP is Microsofts Remote Access Solution for PPP over SSL
+  URL:=http://sstp-client.sourceforge.net/
+  MAINTAINER:=Federico Di Marco <fededim@gmail.com>
+endef
+
+define Package/sstp-client/description
+ It can be used instead of PPTP or L2TP, and is only available with Windows Vista/7 connecting to a Windows 2008 Server. The advantage of SSTP  compared to PPTP and L2TP is that it cannot be easily blocked by firewalls since the traffic is transmitted over HTTPS on port 443.
+ Windows Vista/7 uses SSTP whenever PPTP or L2TP cannot be established. For further information on SSTP check out wikipedia's article on Secure Socket Tunneling Protocol.
+endef
+
+define Package/sstp-client/conffiles
+       /etc/ppp/chap-secrets
+       /etc/ppp/peers/peer-sstp-example-nopty.txt
+       /etc/ppp/peers/peer-sstp-example.txt
+endef
+
+define Package/sstp-client/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/.libs/sstpc $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/src/libsstp-api/.libs/*.so* $(1)/usr/lib/
+       $(CP) $(PKG_BUILD_DIR)/src/pppd-plugin/.libs/*.so* $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/etc/ppp
+       $(INSTALL_DIR) $(1)/etc/peers
+endef
+
+$(eval $(call BuildPackage,sstp-client))
diff --git a/net/sstp-client/files/etc/ppp/chap-secrets b/net/sstp-client/files/etc/ppp/chap-secrets
new file mode 100644 (file)
index 0000000..3b93768
--- /dev/null
@@ -0,0 +1,4 @@
+# Secrets for authentication using CHAP
+# client (domain\\username)    server          secret (password)       acceptable local IP addresses
+# SSTP-TEST\\JonDoe            sstp-test       'testme1234!'           *
+
diff --git a/net/sstp-client/files/etc/ppp/peers/peer-sstp-example-nopty.txt b/net/sstp-client/files/etc/ppp/peers/peer-sstp-example-nopty.txt
new file mode 100644 (file)
index 0000000..0149220
--- /dev/null
@@ -0,0 +1,14 @@
+remotename     sstp-test
+linkname       sstp-test
+ipparam        sstp-test
+name           SSTP-TEST\\jdoe
+plugin      sstp-pppd-plugin.so
+sstp-sock   /tmp/sstp-uds-sock
+usepeerdns
+require-mppe
+noauth
+refuse-eap
+debug
+
+# adopt defaults from the pptp-linux package
+file /etc/ppp/options.pptp
diff --git a/net/sstp-client/files/etc/ppp/peers/peer-sstp-example.txt b/net/sstp-client/files/etc/ppp/peers/peer-sstp-example.txt
new file mode 100644 (file)
index 0000000..e96e188
--- /dev/null
@@ -0,0 +1,15 @@
+remotename     sstp-test
+linkname       sstp-test
+ipparam        sstp-test
+pty            "sstpc --server n3zz-dc1.sstp-test.net --nolaunchpppd "
+name           SSTP-TEST\\jdoe
+plugin         sstp-pppd-plugin.so
+sstp-sock      /tmp/sstpc-uds-sock
+usepeerdns
+require-mppe
+refuse-eap
+noauth
+debug
+
+# adopt defaults from the pptp-linux package
+file /etc/ppp/options.pptp
index 8039951221c3bf04c43cc45fb0b3131d8e55b2f5..85816dd37dbd4a151f5e0360f0c16332f812e531 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 OpenWrt.org
+# Copyright (C) 2012-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=strongswan
-PKG_VERSION:=5.2.0
+PKG_VERSION:=5.2.2
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://download.strongswan.org/ http://download2.strongswan.org/
-PKG_MD5SUM:=5cee4ee1a6ccb74400758b3ace54d46e
+PKG_MD5SUM:=7ee1a33060b2bde35be0f6d78a1d26d0
 PKG_LICENSE:=GPL-2.0+
 PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
 
@@ -298,22 +298,16 @@ define BuildPlugin
     DEPENDS:= +strongswan $(3)
   endef
 
-  strongswan_mod_conf=$(wildcard $(PKG_INSTALL_DIR)/etc/strongswan.d/charon/$(1).conf)
   define Package/strongswan-mod-$(1)/install
        $(INSTALL_DIR) $$(1)/etc/strongswan.d/charon
-       $(if $(call strongswan_mod_conf,$(1)), \
-               $(INSTALL_DATA) \
-                       $(call strongswan_mod_conf,$(1)) \
-                       $$(1)/etc/strongswan.d/charon/ \
-       )
+       if [ -f $(PKG_INSTALL_DIR)/etc/strongswan.d/charon/$(1).conf ]; then \
+               $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/strongswan.d/charon/$(1).conf $$(1)/etc/strongswan.d/charon/; fi
        $(INSTALL_DIR) $$(1)/usr/lib/ipsec/plugins
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/ipsec/plugins/libstrongswan-$(1).so \
                $$(1)/usr/lib/ipsec/plugins/
        $(call Plugin/$(1)/install,$$(1))
   endef
 
-  Package/strongswan-mod-$(1)/conffiles=$(patsubst $(PKG_INSTALL_DIR)%,%,$(call strongswan_mod_conf,$(1)))
-
   $$(eval $$(call BuildPackage,strongswan-mod-$(1)))
 endef
 
index ae0407203bf192a61fde966e09135803c95a4aec..1f120a908fc168f04eae02596d27bad1f7d2ca78 100644 (file)
@@ -21,7 +21,7 @@ PKG_SOURCE_URL:=http://www.spreadspace.org/tcpproxy/releases/
 PKG_MD5SUM:=55126473bcde635f9ee019c6caf19bb7
 PKG_MAINTAINER:=Christian Pointner <equinox@spreadspace.org>
 PKG_LICENSE:=GPL-3.0+
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 include $(INCLUDE_DIR)/package.mk
 
 
index 8efa9e72aa5e4aa6e1ca42ef8a6e54dde8da31db..54f568f883d786f44791e2adbe7005889061f7b0 100644 (file)
@@ -7,9 +7,10 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tgt
-PKG_VERSION:=1.0.48
-PKG_REV:=22d9567f39e5eb8a794ce2cb5a2190abdbecaa1f
+PKG_VERSION:=1.0.53
+PKG_REV:=9764e0afd9a7115e356fc85569a780f9003c4eac
 PKG_RELEASE:=1
+PKG_USE_MIPS16:=0
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/fujita/tgt.git
index 945ca781cdcb74bf114e4ffb03784b79ab042d0d..0656ec983b779c18e2d2167b0bfe41642f7b4fb3 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tinc
-PKG_VERSION:=1.0.24
-PKG_RELEASE:=2
+PKG_VERSION:=1.0.25
+PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.tinc-vpn.org/packages
-PKG_MD5SUM:=14a91eb2e85bdc0451a815612521b708
+PKG_MD5SUM:=0b91b693f7cf76f481b547d0c86f9578
 
 PKG_INSTALL:=1
 
index 36b920692bdc915ea6e30bb0044d65af5e67a82d..6ffcf43bd21fcbf6e172c30b1b59d42a6005f297 100644 (file)
@@ -8,15 +8,15 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tor
-PKG_VERSION:=0.2.4.23
+PKG_VERSION:=0.2.5.10
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.torproject.org/dist \
        https://archive.torproject.org/tor-package-archive
-PKG_MD5SUM:=9e39928e310612c3bffee727f554c63f
+PKG_MD5SUM:=4bde375229a7a7f77c0596ae05556527
 PKG_MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de>
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 
 PKG_BUILD_DEPENDS:=libminiupnpc libnatpmp
 PKG_INSTALL:=1
@@ -27,6 +27,7 @@ define Package/tor/Default
   SECTION:=net
   CATEGORY:=Network
   URL:=https://www.torproject.org/
+  USERID:=tor=52:tor=52
 endef
 
 define Package/tor/Default/description
index 7c548b40b8183dc47487cf1c4e0460a219d030ce..6974057d45d83e6901502fb5ec9e064b96a86501 100644 (file)
@@ -7,8 +7,6 @@ STOP=50
 USE_PROCD=1
 
 start_service() {
-       user_exists tor 52 || user_add tor 52 52 /var/lib/tor
-       group_exists tor 52 || group_add tor 52
        [ -f /var/run/tor.pid ] || {
                touch /var/run/tor.pid
                chown tor:tor /var/run/tor.pid
index 5e98197d14d9d12a83d08ecf7a804019934ee908..5091920e430b8edc6661584c0b6cb53a566fd0b7 100644 (file)
@@ -21,7 +21,7 @@ PKG_MD5SUM:=ce47ad45003ff1d84eaf5276941b9ddf
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_MAINTAINER:=Christian Pointner <equinox@spreadspace.org>
 PKG_LICENSE:=GPL-3.0+
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 include $(INCLUDE_DIR)/package.mk
 
 
index b8df5b817ab07bae4e684c0ddc25fb124e743340..8fc927645c92f999c8d12b6a81f037a375ea9728 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=udpxy
-PKG_VERSION:=2014-08-24
+PKG_VERSION:=2014-10-27
 PKG_RELEASE:=$(PKG_SOURCE_VERSION)
 
 PKG_SOURCE_PROTO:=git
index 8ef2a1e0507b9043435f7b22e360108bd3981652..9117a53e37ff8745138d5e219346de003cbc3010 100644 (file)
@@ -1,4 +1,6 @@
 config udpxy
+       option disabled '1'
+       option respawn '1'
        option verbose '0'
        option status '1'
        # option bind '0.0.0.0'
index a08f4a1348ca06981a3d7d13c7e55b3ac560f617..6f911a6fb713403bcc4cd87b68da0f3a09f33e19 100644 (file)
@@ -4,57 +4,64 @@
 START=50
 USE_PROCD=1
 
-udpxy_parse() {
+append_arg() {
        local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
 
-       local cfg_verbose
-       local cfg_status
-       local cfg_mcsub_renew
-       local cfg_bind
-       local cfg_port
-       local cfg_source
-       local cfg_max_clients
-       local cfg_log_file
-       local cfg_buffer_size
-       local cfg_buffer_messages
-       local cfg_buffer_time
-       local cfg_nice_increment
-       local cfg_mcsub_renew
-
-       config_get_bool cfg_verbose $cfg 'verbose' 0
-       config_get_bool cfg_status $cfg 'status' 1
-       config_get cfg_bind $cfg 'bind'
-       config_get cfg_port $cfg 'port' '4022'
-       config_get cfg_source $cfg 'source'
-       config_get cfg_max_clients $cfg 'max_clients'
-       config_get cfg_log_file $cfg 'log_file'
-       config_get cfg_buffer_size $cfg 'buffer_size'
-       config_get cfg_buffer_messages $cfg 'buffer_messages'
-       config_get cfg_buffer_time $cfg 'buffer_time'
-       config_get cfg_nice_increment $cfg 'nice_increment'
-       config_get cfg_mcsub_renew $cfg 'mcsub_renew'
+       config_get val "$cfg" "$var"
+       [ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}"
+}
+
+append_bool() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get_bool val "$cfg" "$var" "$def"
+       [ "$val" = 1 ] && procd_append_param command "$opt"
+}
+
+start_instance() {
+       local cfg="$1"
+       local aux
+
+       config_get_bool aux "$cfg" 'disabled' '0'
+       [ "$aux" = 1 ] && return 1
 
        procd_open_instance
 
        procd_set_param command /usr/bin/udpxy
-       procd_append_param command -T -p $cfg_port
-       [ "$cfg_verbose" -eq 1 ] && procd_append_param command -v
-       [ "$cfg_status" -eq 1 ] && procd_append_param command -S
-       [ ! -z "$cfg_bind" ] && procd_append_param command -a $cfg_bind
-       [ ! -z "$cfg_source" ] && procd_append_param command -m $cfg_source
-       [ ! -z "$cfg_max_clients" ] && procd_append_param command -c $cfg_max_clients
-       [ ! -z "$cfg_log_file" ] && procd_append_param command -l $cfg_log_file
-       [ ! -z "$cfg_buffer_size" ] && procd_append_param command -B $cfg_buffer_size
-       [ ! -z "$cfg_buffer_messages" ] && procd_append_param command -R $cfg_buffer_messages
-       [ ! -z "$cfg_buffer_time" ] && procd_append_param command -H $cfg_buffer_time
-       [ ! -z "$cfg_nice_increment" ] && procd_append_param command -n $cfg_nice_increment
-       [ ! -z "$cfg_mcsub_renew" ] && procd_append_param command -M $cfg_mcsub_renew
-
-       procd_set_param respawn
+       procd_append_param command "-T"
+
+       append_bool "$cfg" verbose "-V"
+       append_bool "$cfg" status "-S"
+       append_arg "$cfg" bind "-a"
+       append_arg "$cfg" port "-p"
+       append_arg "$cfg" source "-m"
+       append_arg "$cfg" max_clients "-c"
+       append_arg "$cfg" log_file "-l"
+       append_arg "$cfg" buffer_size "-B"
+       append_arg "$cfg" buffer_messages "-R"
+       append_arg "$cfg" buffer_time "-H"
+       append_arg "$cfg" nice_increment "-n"
+       append_arg "$cfg" mcsub_renew "-M"
+
+       config_get_bool aux "$cfg" 'respawn' '0'
+       [ "$aux" = 1 ] && procd_set_param respawn
+
        procd_close_instance
 }
 
+service_triggers() { 
+       procd_add_reload_trigger "udpxy" 
+}
+
 start_service() {
        config_load udpxy
-       config_foreach udpxy_parse udpxy
+       config_foreach start_instance udpxy
 }
index 375712b7ea0bd7cd7749e2a58d5e4a874fe2092d..0cca3e4d9d725e600b6916a05e27ce459cfbe17f 100644 (file)
@@ -19,7 +19,7 @@ PKG_SOURCE_URL:=ftp://ftp.netfilter.org/pub/ulogd/ \
 PKG_MD5SUM:=7c71ec460dfea5287eba27472c521ebc
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_FIXUP:=autoreconf
index 55867ee55a35e7d1811e5a3b4b1596a9bded0529..5567dca6ddaf469fe4dbe58c8a24e4878f84e3f2 100644 (file)
@@ -12,7 +12,7 @@ PKG_VERSION:=1.4.22
 PKG_RELEASE:=1
 
 PKG_LICENSE:=BSD-3-Clause
-PKG_LICENSE_FILE:=LICENSE
+PKG_LICENSE_FILES:=LICENSE
 PKG_MAINTAINER:=Michael Hanselmann <public@hansmi.ch>
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
index c03dffcb36de728ed32b4ba86cba41cbbc5d3fda..a1682b3578b3fd18c4398ce88f7ce10e497f149e 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2011 OpenWrt.org
+# Copyright (C) 2007-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,14 +8,15 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=wget
-PKG_VERSION:=1.15
+PKG_VERSION:=1.16.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_MD5SUM:=7a279d5ac5594919124d5526e7143e28
+PKG_MD5SUM:=78942cc0cce0a23e18114d982789e360
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=GPL-3.0+
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 
@@ -65,7 +66,8 @@ endef
 
 CONFIGURE_ARGS+= \
        --disable-rpath \
-       --disable-iri
+       --disable-iri \
+       --without-libuuid
 
 CONFIGURE_VARS += \
        ac_cv_header_uuid_uuid_h=no
index 1d73922f4ef820435f866db741c8eb7afdfb576b..9681c47333ee7237a270f3ddcd9d3f6104ab5f28 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=znc
 PKG_VERSION:=1.4
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://znc.in/releases \
@@ -33,7 +33,7 @@ endef
 
 define Package/znc
   $(Package/znc/default)
-  DEPENDS:=+libopenssl +libpthread $(CXX_DEPENDS)
+  DEPENDS:=+libopenssl +libpthread +libstdcpp
   MENU:=1
 endef
 
@@ -261,14 +261,13 @@ $(eval $(call webskin,ice))
 
 PKG_CONFIG_DEPENDS := $(patsubst %,CONFIG_PACKAGE_%,$(ZNC_MODULES))
 
-include $(INCLUDE_DIR)/uclibc++.mk
 include $(INCLUDE_DIR)/package.mk
 
 CONFIGURE_VARS += \
-       CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin -fno-rtti -nostdinc++" \
+       CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin -fno-rtti" \
        CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
        LDFLAGS="-nodefaultlibs -lc -L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \
-       LIBS="-luClibc++ -lm -lssl -lcrypto $(LIBGCC_S) -lc"
+       LIBS="-lstdc++ -lm -lssl -lcrypto $(LIBGCC_S) -lc"
 
 CONFIGURE_ARGS += \
        --disable-c-ares \
diff --git a/net/znc/patches/002-Uclibcpp_build_fix.patch b/net/znc/patches/002-Uclibcpp_build_fix.patch
deleted file mode 100644 (file)
index df27c80..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From fa14938321eda39f16bee6068296e6abc9df7b85 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski+openwrt@gmail.com>
-Date: Wed, 6 Apr 2011 04:11:48 +0200
-Subject: [PATCH] Add a uClibc++ build workaround
-
----
- modules/webadmin.cpp |    4 +++-
- 1 files changed, 3 insertions(+), 1 deletions(-)
-
---- a/modules/webadmin.cpp
-+++ b/modules/webadmin.cpp
-@@ -20,6 +20,7 @@
- #include <znc/IRCNetwork.h>
- #include <znc/IRCSock.h>
-+using std::string;
- using std::stringstream;
- using std::make_pair;
- using std::set;
-@@ -75,7 +76,7 @@ class CWebAdminMod : public CModule {
- public:
-       MODCONSTRUCTOR(CWebAdminMod) {
-               VPair vParams;
--              vParams.push_back(make_pair("user", ""));
-+              vParams.push_back(make_pair((string)"user", (string)""));
-               AddSubPage(new CWebSubPage("settings", "Global Settings", CWebSubPage::F_ADMIN));
-               AddSubPage(new CWebSubPage("edituser", "Your Settings", vParams));
-               AddSubPage(new CWebSubPage("traffic", "Traffic Info", CWebSubPage::F_ADMIN));
diff --git a/net/znc/patches/900-remove_cpp11_usage.patch b/net/znc/patches/900-remove_cpp11_usage.patch
deleted file mode 100644 (file)
index e87730b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/modules/certauth.cpp b/modules/certauth.cpp
-index 61e5687..4857d59 100644
---- a/modules/certauth.cpp
-+++ b/modules/certauth.cpp
-@@ -204,7 +204,7 @@ public:
-                       return;
-               }
--              SCString::const_iterator it2 = it->second.begin();
-+              SCString::iterator it2 = it->second.begin();
-               while (id > 1) {
-                       ++it2;
-                       id--;
diff --git a/sound/espeak/Makefile b/sound/espeak/Makefile
new file mode 100644 (file)
index 0000000..fd06c6e
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=espeak
+PKG_VERSION:=1.48.04
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-source.zip
+PKG_SOURCE_URL:=@SF/espeak
+PKG_MD5SUM:=cadd7482eaafe9239546bdc09fa244c3
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=License.txt
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-source
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/espeak
+  SECTION:=sound
+  CATEGORY:=Sound
+  DEPENDS:=+libpthread +libstdcpp +portaudio
+  TITLE:=Speech synthesizer
+  URL:=http://espeak.sourceforge.net/
+endef
+
+define Package/espeak/description
+ eSpeak is a compact open source software speech synthesizer for English and
+ other languages.
+endef
+
+MAKE_FLAGS+= \
+       AUDIO="portaudio" \
+       DATADIR="/usr/share/espeak" \
+       CXXFLAGS="$(TARGET_CFLAGS)" \
+       LDFLAGS="$(TARGET_LDFLAGS)" \
+
+MAKE_PATH:=./src
+
+define Package/espeak/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/espeak $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libespeak.so.* $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/share
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/espeak $(1)/usr/share/
+endef
+
+$(eval $(call BuildPackage,espeak))
diff --git a/sound/espeak/patches/101-portaudio.patch b/sound/espeak/patches/101-portaudio.patch
new file mode 100644 (file)
index 0000000..ff396b3
--- /dev/null
@@ -0,0 +1,2093 @@
+--- a/src/portaudio.h
++++ /dev/null
+@@ -1,466 +0,0 @@
+-// NOTE: Copy this file to  portaudio.h  in order to compile with V18 portaudio
+-
+-
+-#ifndef PORT_AUDIO_H
+-#define PORT_AUDIO_H
+-
+-#ifdef __cplusplus
+-extern "C"
+-{
+-#endif /* __cplusplus */
+-
+-/*
+- * $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $
+- * PortAudio Portable Real-Time Audio Library
+- * PortAudio API Header File
+- * Latest version available at: http://www.audiomulch.com/portaudio/
+- *
+- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+- *
+- * 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.
+- *
+- * Any person wishing to distribute modifications to the Software is
+- * requested to send the modifications to the original developer so that
+- * they can be incorporated into the canonical version.
+- *
+- * 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.
+- *
+- */
+-
+-typedef int PaError;
+-typedef enum {
+-    paNoError = 0,
+-
+-    paHostError = -10000,
+-    paInvalidChannelCount,
+-    paInvalidSampleRate,
+-    paInvalidDeviceId,
+-    paInvalidFlag,
+-    paSampleFormatNotSupported,
+-    paBadIODeviceCombination,
+-    paInsufficientMemory,
+-    paBufferTooBig,
+-    paBufferTooSmall,
+-    paNullCallback,
+-    paBadStreamPtr,
+-    paTimedOut,
+-    paInternalError,
+-    paDeviceUnavailable
+-} PaErrorNum;
+-
+-/*
+- Pa_Initialize() is the library initialisation function - call this before
+- using the library.
+-
+-*/
+-
+-PaError Pa_Initialize( void );
+-
+-/*
+- Pa_Terminate() is the library termination function - call this after
+- using the library.
+-
+-*/
+-
+-PaError Pa_Terminate( void );
+-
+-/*
+- Pa_GetHostError() returns a host specific error code.
+- This can be called after receiving a PortAudio error code of paHostError.
+-
+-*/
+-
+-long Pa_GetHostError( void );
+-
+-/*
+- Pa_GetErrorText() translates the supplied PortAudio error number
+- into a human readable message.
+- 
+-*/
+-
+-const char *Pa_GetErrorText( PaError errnum );
+-
+-/*
+- Sample formats
+- 
+- These are formats used to pass sound data between the callback and the
+- stream. Each device has a "native" format which may be used when optimum
+- efficiency or control over conversion is required.
+- 
+- Formats marked "always available" are supported (emulated) by all 
+- PortAudio implementations.
+- 
+- The floating point representation (paFloat32) uses +1.0 and -1.0 as the 
+- maximum and minimum respectively.
+-
+- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+-
+-*/
+-
+-typedef unsigned long PaSampleFormat;
+-#define paFloat32      ((PaSampleFormat) (1<<0)) /*always available*/
+-#define paInt16        ((PaSampleFormat) (1<<1)) /*always available*/
+-#define paInt32        ((PaSampleFormat) (1<<2)) /*always available*/
+-#define paInt24        ((PaSampleFormat) (1<<3))
+-#define paPackedInt24  ((PaSampleFormat) (1<<4))
+-#define paInt8         ((PaSampleFormat) (1<<5))
+-#define paUInt8        ((PaSampleFormat) (1<<6))
+-#define paCustomFormat ((PaSampleFormat) (1<<16))
+-
+-/*
+- Device enumeration mechanism.
+- 
+- Device ids range from 0 to Pa_CountDevices()-1.
+- 
+- Devices may support input, output or both.
+-
+-*/
+-
+-typedef int PaDeviceID;
+-#define paNoDevice -1
+-
+-int Pa_CountDevices( void );
+-
+-typedef struct
+-{
+-    int structVersion;
+-    const char *name;
+-    int maxInputChannels;
+-    int maxOutputChannels;
+-    /* Number of discrete rates, or -1 if range supported. */
+-    int numSampleRates;
+-    /* Array of supported sample rates, or {min,max} if range supported. */
+-    const double *sampleRates;
+-    PaSampleFormat nativeSampleFormats;
+-}
+-PaDeviceInfo;
+-
+-/*
+- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
+- default device ids for input and output respectively, or paNoDevice if
+- no device is available.
+- The result can be passed to Pa_OpenStream().
+- 
+- On the PC, the user can specify a default device by
+- setting an environment variable. For example, to use device #1.
+- 
+-  set PA_RECOMMENDED_OUTPUT_DEVICE=1
+- 
+- The user should first determine the available device ids by using
+- the supplied application "pa_devs".
+-
+-*/
+-
+-PaDeviceID Pa_GetDefaultInputDeviceID( void );
+-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
+-
+-
+-
+-/*
+- Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
+- for the device specified.
+- If the device parameter is out of range the function returns NULL.
+-
+- PortAudio manages the memory referenced by the returned pointer, the client
+- must not manipulate or free the memory. The pointer is only guaranteed to be
+- valid between calls to Pa_Initialize() and Pa_Terminate().
+-
+-*/
+-
+-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
+-
+-/*
+- PaTimestamp is used to represent a continuous sample clock with arbitrary
+- start time that can be used for syncronization. The type is used for the
+- outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
+-
+-*/
+-
+-typedef double PaTimestamp;
+-
+-/*
+- PortAudioCallback is implemented by PortAudio clients.
+- 
+- inputBuffer and outputBuffer are arrays of interleaved samples,
+- the format, packing and number of channels used by the buffers are
+- determined by parameters to Pa_OpenStream() (see below).
+- 
+- framesPerBuffer is the number of sample frames to be processed by the callback.
+- 
+- outTime is the time in samples when the buffer(s) processed by
+- this callback will begin being played at the audio output.
+- See also Pa_StreamTime()
+- 
+- userData is the value of a user supplied pointer passed to Pa_OpenStream()
+- intended for storing synthesis data etc.
+- 
+- return value:
+- The callback can return a non-zero value to stop the stream. This may be
+- useful in applications such as soundfile players where a specific duration
+- of output is required. However, it is not necessary to utilise this mechanism
+- as StopStream() will also terminate the stream. A callback returning a
+- non-zero value must fill the entire outputBuffer.
+- 
+- NOTE: None of the other stream functions may be called from within the
+- callback function except for Pa_GetCPULoad().
+-
+-*/
+-
+-typedef int (PortAudioCallback)(
+-    void *inputBuffer, void *outputBuffer,
+-    unsigned long framesPerBuffer,
+-    PaTimestamp outTime, void *userData );
+-
+-
+-/*
+- Stream flags
+- 
+- These flags may be supplied (ored together) in the streamFlags argument to
+- the Pa_OpenStream() function.
+-
+-*/
+-
+-#define   paNoFlag      (0)
+-#define   paClipOff     (1<<0)   /* disable default clipping of out of range samples */
+-#define   paDitherOff   (1<<1)   /* disable default dithering */
+-#define   paPlatformSpecificFlags (0x00010000)
+-typedef   unsigned long PaStreamFlags;
+-
+-/*
+- A single PortAudioStream provides multiple channels of real-time
+- input and output audio streaming to a client application.
+- Pointers to PortAudioStream objects are passed between PortAudio functions.
+-*/
+-
+-typedef void PortAudioStream;
+-#define PaStream PortAudioStream
+-
+-/*
+- Pa_OpenStream() opens a stream for either input, output or both.
+- 
+- stream is the address of a PortAudioStream pointer which will receive
+- a pointer to the newly opened stream.
+- 
+- inputDevice is the id of the device used for input (see PaDeviceID above.)
+- inputDevice may be paNoDevice to indicate that an input device is not required.
+- 
+- numInputChannels is the number of channels of sound to be delivered to the
+- callback. It can range from 1 to the value of maxInputChannels in the
+- PaDeviceInfo record for the device specified by the inputDevice parameter.
+- If inputDevice is paNoDevice numInputChannels is ignored.
+- 
+- inputSampleFormat is the sample format of inputBuffer provided to the callback
+- function. inputSampleFormat may be any of the formats described by the
+- PaSampleFormat enumeration (see above). PortAudio guarantees support for
+- the device's native formats (nativeSampleFormats in the device info record)
+- and additionally 16 and 32 bit integer and 32 bit floating point formats.
+- Support for other formats is implementation defined.
+- 
+- inputDriverInfo is a pointer to an optional driver specific data structure
+- containing additional information for device setup or stream processing.
+- inputDriverInfo is never required for correct operation. If not used
+- inputDriverInfo should be NULL.
+- 
+- outputDevice is the id of the device used for output (see PaDeviceID above.)
+- outputDevice may be paNoDevice to indicate that an output device is not required.
+- 
+- numOutputChannels is the number of channels of sound to be supplied by the
+- callback. See the definition of numInputChannels above for more details.
+- 
+- outputSampleFormat is the sample format of the outputBuffer filled by the
+- callback function. See the definition of inputSampleFormat above for more
+- details.
+- 
+- outputDriverInfo is a pointer to an optional driver specific data structure
+- containing additional information for device setup or stream processing.
+- outputDriverInfo is never required for correct operation. If not used
+- outputDriverInfo should be NULL.
+- 
+- sampleRate is the desired sampleRate. For full-duplex streams it is the
+- sample rate for both input and output
+- 
+- framesPerBuffer is the length in sample frames of all internal sample buffers
+- used for communication with platform specific audio routines. Wherever
+- possible this corresponds to the framesPerBuffer parameter passed to the
+- callback function.
+- 
+- numberOfBuffers is the number of buffers used for multibuffered communication
+- with the platform specific audio routines. If you pass zero, then an optimum
+- value will be chosen for you internally. This parameter is provided only
+- as a guide - and does not imply that an implementation must use multibuffered
+- i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
+- on the Macintosh.)
+- 
+- streamFlags may contain a combination of flags ORed together.
+- These flags modify the behaviour of the streaming process. Some flags may only
+- be relevant to certain buffer formats.
+- 
+- callback is a pointer to a client supplied function that is responsible
+- for processing and filling input and output buffers (see above for details.)
+- 
+- userData is a client supplied pointer which is passed to the callback
+- function. It could for example, contain a pointer to instance data necessary
+- for processing the audio buffers.
+- 
+- return value:
+- Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
+- valid PortAudioStream in the stream argument. The stream is inactive (stopped).
+- If a call to Pa_OpenStream() fails a non-zero error code is returned (see
+- PaError above) and the value of stream is invalid.
+- 
+-*/
+-
+-PaError Pa_OpenStream( PortAudioStream** stream,
+-                       PaDeviceID inputDevice,
+-                       int numInputChannels,
+-                       PaSampleFormat inputSampleFormat,
+-                       void *inputDriverInfo,
+-                       PaDeviceID outputDevice,
+-                       int numOutputChannels,
+-                       PaSampleFormat outputSampleFormat,
+-                       void *outputDriverInfo,
+-                       double sampleRate,
+-                       unsigned long framesPerBuffer,
+-                       unsigned long numberOfBuffers,
+-                       PaStreamFlags streamFlags,
+-                       PortAudioCallback *callback,
+-                       void *userData );
+-
+-
+-/*
+- Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens
+- the default input and/or output devices. Most parameters have identical meaning
+- to their Pa_OpenStream() counterparts, with the following exceptions:
+- 
+- If either numInputChannels or numOutputChannels is 0 the respective device
+- is not opened. This has the same effect as passing paNoDevice in the device
+- arguments to Pa_OpenStream().
+- 
+- sampleFormat applies to both the input and output buffers.
+-
+-*/
+-
+-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
+-                              int numInputChannels,
+-                              int numOutputChannels,
+-                              PaSampleFormat sampleFormat,
+-                              double sampleRate,
+-                              unsigned long framesPerBuffer,
+-                              unsigned long numberOfBuffers,
+-                              PortAudioCallback *callback,
+-                              void *userData );
+-
+-/*
+- Pa_CloseStream() closes an audio stream, flushing any pending buffers.
+-
+-*/
+-
+-PaError Pa_CloseStream( PortAudioStream* );
+-
+-/*
+- Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
+- Pa_StopStream() waits until all pending audio buffers have been played.
+- Pa_AbortStream() stops playing immediately without waiting for pending
+- buffers to complete.
+-    
+-*/
+-
+-PaError Pa_StartStream( PortAudioStream *stream );
+-
+-PaError Pa_StopStream( PortAudioStream *stream );
+-
+-PaError Pa_AbortStream( PortAudioStream *stream );
+-
+-/*
+- Pa_StreamActive() returns one (1) when the stream is active (ie playing
+- or recording audio), zero (0) when not playing, or a negative error number
+- if the stream is invalid.
+- The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
+- but may also become inactive if the callback returns a non-zero value.
+- In the latter case, the stream is considered inactive after the last
+- buffer has finished playing.
+- 
+-*/
+-
+-PaError Pa_StreamActive( PortAudioStream *stream );
+-
+-/*
+- Pa_StreamTime() returns the current output time in samples for the stream.
+- This time may be used as a time reference (for example synchronizing audio to
+- MIDI).
+- 
+-*/
+-
+-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
+-
+-/*
+- Pa_GetCPULoad() returns the CPU Load for the stream.
+- The "CPU Load" is a fraction of total CPU time consumed by the stream's
+- audio processing routines including, but not limited to the client supplied
+- callback.
+- A value of 0.5 would imply that PortAudio and the sound generating
+- callback was consuming roughly 50% of the available CPU time.
+- This function may be called from the callback function or the application.
+- 
+-*/
+-
+-double Pa_GetCPULoad( PortAudioStream* stream );
+-
+-/*
+- Pa_GetMinNumBuffers() returns the minimum number of buffers required by
+- the current host based on minimum latency.
+- On the PC, for the DirectSound implementation, latency can be optionally set
+- by user by setting an environment variable.
+- For example, to set latency to 200 msec, put:
+- 
+-    set PA_MIN_LATENCY_MSEC=200
+- 
+- in the AUTOEXEC.BAT file and reboot.
+- If the environment variable is not set, then the latency will be determined
+- based on the OS. Windows NT has higher latency than Win95.
+- 
+-*/
+-
+-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
+-
+-/*
+- Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
+- You may sleep longer than the requested time so don't rely on this for
+- accurate musical timing.
+- 
+- Pa_Sleep() is provided as a convenience for authors of portable code (such as
+- the tests and examples in the PortAudio distribution.)
+- 
+-*/
+-
+-void Pa_Sleep( long msec );
+-
+-/*
+- Pa_GetSampleSize() returns the size in bytes of a single sample in the
+- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
+- no supported.
+-  
+-*/
+-
+-PaError Pa_GetSampleSize( PaSampleFormat format );
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif /* __cplusplus */
+-#endif /* PORT_AUDIO_H */
+--- a/src/portaudio18.h
++++ /dev/null
+@@ -1,466 +0,0 @@
+-// NOTE: Copy this file to  portaudio.h  in order to compile with V18 portaudio
+-
+-
+-#ifndef PORT_AUDIO_H
+-#define PORT_AUDIO_H
+-
+-#ifdef __cplusplus
+-extern "C"
+-{
+-#endif /* __cplusplus */
+-
+-/*
+- * $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $
+- * PortAudio Portable Real-Time Audio Library
+- * PortAudio API Header File
+- * Latest version available at: http://www.audiomulch.com/portaudio/
+- *
+- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+- *
+- * 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.
+- *
+- * Any person wishing to distribute modifications to the Software is
+- * requested to send the modifications to the original developer so that
+- * they can be incorporated into the canonical version.
+- *
+- * 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.
+- *
+- */
+-
+-typedef int PaError;
+-typedef enum {
+-    paNoError = 0,
+-
+-    paHostError = -10000,
+-    paInvalidChannelCount,
+-    paInvalidSampleRate,
+-    paInvalidDeviceId,
+-    paInvalidFlag,
+-    paSampleFormatNotSupported,
+-    paBadIODeviceCombination,
+-    paInsufficientMemory,
+-    paBufferTooBig,
+-    paBufferTooSmall,
+-    paNullCallback,
+-    paBadStreamPtr,
+-    paTimedOut,
+-    paInternalError,
+-    paDeviceUnavailable
+-} PaErrorNum;
+-
+-/*
+- Pa_Initialize() is the library initialisation function - call this before
+- using the library.
+-
+-*/
+-
+-PaError Pa_Initialize( void );
+-
+-/*
+- Pa_Terminate() is the library termination function - call this after
+- using the library.
+-
+-*/
+-
+-PaError Pa_Terminate( void );
+-
+-/*
+- Pa_GetHostError() returns a host specific error code.
+- This can be called after receiving a PortAudio error code of paHostError.
+-
+-*/
+-
+-long Pa_GetHostError( void );
+-
+-/*
+- Pa_GetErrorText() translates the supplied PortAudio error number
+- into a human readable message.
+- 
+-*/
+-
+-const char *Pa_GetErrorText( PaError errnum );
+-
+-/*
+- Sample formats
+- 
+- These are formats used to pass sound data between the callback and the
+- stream. Each device has a "native" format which may be used when optimum
+- efficiency or control over conversion is required.
+- 
+- Formats marked "always available" are supported (emulated) by all 
+- PortAudio implementations.
+- 
+- The floating point representation (paFloat32) uses +1.0 and -1.0 as the 
+- maximum and minimum respectively.
+-
+- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+-
+-*/
+-
+-typedef unsigned long PaSampleFormat;
+-#define paFloat32      ((PaSampleFormat) (1<<0)) /*always available*/
+-#define paInt16        ((PaSampleFormat) (1<<1)) /*always available*/
+-#define paInt32        ((PaSampleFormat) (1<<2)) /*always available*/
+-#define paInt24        ((PaSampleFormat) (1<<3))
+-#define paPackedInt24  ((PaSampleFormat) (1<<4))
+-#define paInt8         ((PaSampleFormat) (1<<5))
+-#define paUInt8        ((PaSampleFormat) (1<<6))
+-#define paCustomFormat ((PaSampleFormat) (1<<16))
+-
+-/*
+- Device enumeration mechanism.
+- 
+- Device ids range from 0 to Pa_CountDevices()-1.
+- 
+- Devices may support input, output or both.
+-
+-*/
+-
+-typedef int PaDeviceID;
+-#define paNoDevice -1
+-
+-int Pa_CountDevices( void );
+-
+-typedef struct
+-{
+-    int structVersion;
+-    const char *name;
+-    int maxInputChannels;
+-    int maxOutputChannels;
+-    /* Number of discrete rates, or -1 if range supported. */
+-    int numSampleRates;
+-    /* Array of supported sample rates, or {min,max} if range supported. */
+-    const double *sampleRates;
+-    PaSampleFormat nativeSampleFormats;
+-}
+-PaDeviceInfo;
+-
+-/*
+- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
+- default device ids for input and output respectively, or paNoDevice if
+- no device is available.
+- The result can be passed to Pa_OpenStream().
+- 
+- On the PC, the user can specify a default device by
+- setting an environment variable. For example, to use device #1.
+- 
+-  set PA_RECOMMENDED_OUTPUT_DEVICE=1
+- 
+- The user should first determine the available device ids by using
+- the supplied application "pa_devs".
+-
+-*/
+-
+-PaDeviceID Pa_GetDefaultInputDeviceID( void );
+-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
+-
+-
+-
+-/*
+- Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
+- for the device specified.
+- If the device parameter is out of range the function returns NULL.
+-
+- PortAudio manages the memory referenced by the returned pointer, the client
+- must not manipulate or free the memory. The pointer is only guaranteed to be
+- valid between calls to Pa_Initialize() and Pa_Terminate().
+-
+-*/
+-
+-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
+-
+-/*
+- PaTimestamp is used to represent a continuous sample clock with arbitrary
+- start time that can be used for syncronization. The type is used for the
+- outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
+-
+-*/
+-
+-typedef double PaTimestamp;
+-
+-/*
+- PortAudioCallback is implemented by PortAudio clients.
+- 
+- inputBuffer and outputBuffer are arrays of interleaved samples,
+- the format, packing and number of channels used by the buffers are
+- determined by parameters to Pa_OpenStream() (see below).
+- 
+- framesPerBuffer is the number of sample frames to be processed by the callback.
+- 
+- outTime is the time in samples when the buffer(s) processed by
+- this callback will begin being played at the audio output.
+- See also Pa_StreamTime()
+- 
+- userData is the value of a user supplied pointer passed to Pa_OpenStream()
+- intended for storing synthesis data etc.
+- 
+- return value:
+- The callback can return a non-zero value to stop the stream. This may be
+- useful in applications such as soundfile players where a specific duration
+- of output is required. However, it is not necessary to utilise this mechanism
+- as StopStream() will also terminate the stream. A callback returning a
+- non-zero value must fill the entire outputBuffer.
+- 
+- NOTE: None of the other stream functions may be called from within the
+- callback function except for Pa_GetCPULoad().
+-
+-*/
+-
+-typedef int (PortAudioCallback)(
+-    void *inputBuffer, void *outputBuffer,
+-    unsigned long framesPerBuffer,
+-    PaTimestamp outTime, void *userData );
+-
+-
+-/*
+- Stream flags
+- 
+- These flags may be supplied (ored together) in the streamFlags argument to
+- the Pa_OpenStream() function.
+-
+-*/
+-
+-#define   paNoFlag      (0)
+-#define   paClipOff     (1<<0)   /* disable default clipping of out of range samples */
+-#define   paDitherOff   (1<<1)   /* disable default dithering */
+-#define   paPlatformSpecificFlags (0x00010000)
+-typedef   unsigned long PaStreamFlags;
+-
+-/*
+- A single PortAudioStream provides multiple channels of real-time
+- input and output audio streaming to a client application.
+- Pointers to PortAudioStream objects are passed between PortAudio functions.
+-*/
+-
+-typedef void PortAudioStream;
+-#define PaStream PortAudioStream
+-
+-/*
+- Pa_OpenStream() opens a stream for either input, output or both.
+- 
+- stream is the address of a PortAudioStream pointer which will receive
+- a pointer to the newly opened stream.
+- 
+- inputDevice is the id of the device used for input (see PaDeviceID above.)
+- inputDevice may be paNoDevice to indicate that an input device is not required.
+- 
+- numInputChannels is the number of channels of sound to be delivered to the
+- callback. It can range from 1 to the value of maxInputChannels in the
+- PaDeviceInfo record for the device specified by the inputDevice parameter.
+- If inputDevice is paNoDevice numInputChannels is ignored.
+- 
+- inputSampleFormat is the sample format of inputBuffer provided to the callback
+- function. inputSampleFormat may be any of the formats described by the
+- PaSampleFormat enumeration (see above). PortAudio guarantees support for
+- the device's native formats (nativeSampleFormats in the device info record)
+- and additionally 16 and 32 bit integer and 32 bit floating point formats.
+- Support for other formats is implementation defined.
+- 
+- inputDriverInfo is a pointer to an optional driver specific data structure
+- containing additional information for device setup or stream processing.
+- inputDriverInfo is never required for correct operation. If not used
+- inputDriverInfo should be NULL.
+- 
+- outputDevice is the id of the device used for output (see PaDeviceID above.)
+- outputDevice may be paNoDevice to indicate that an output device is not required.
+- 
+- numOutputChannels is the number of channels of sound to be supplied by the
+- callback. See the definition of numInputChannels above for more details.
+- 
+- outputSampleFormat is the sample format of the outputBuffer filled by the
+- callback function. See the definition of inputSampleFormat above for more
+- details.
+- 
+- outputDriverInfo is a pointer to an optional driver specific data structure
+- containing additional information for device setup or stream processing.
+- outputDriverInfo is never required for correct operation. If not used
+- outputDriverInfo should be NULL.
+- 
+- sampleRate is the desired sampleRate. For full-duplex streams it is the
+- sample rate for both input and output
+- 
+- framesPerBuffer is the length in sample frames of all internal sample buffers
+- used for communication with platform specific audio routines. Wherever
+- possible this corresponds to the framesPerBuffer parameter passed to the
+- callback function.
+- 
+- numberOfBuffers is the number of buffers used for multibuffered communication
+- with the platform specific audio routines. If you pass zero, then an optimum
+- value will be chosen for you internally. This parameter is provided only
+- as a guide - and does not imply that an implementation must use multibuffered
+- i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
+- on the Macintosh.)
+- 
+- streamFlags may contain a combination of flags ORed together.
+- These flags modify the behaviour of the streaming process. Some flags may only
+- be relevant to certain buffer formats.
+- 
+- callback is a pointer to a client supplied function that is responsible
+- for processing and filling input and output buffers (see above for details.)
+- 
+- userData is a client supplied pointer which is passed to the callback
+- function. It could for example, contain a pointer to instance data necessary
+- for processing the audio buffers.
+- 
+- return value:
+- Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
+- valid PortAudioStream in the stream argument. The stream is inactive (stopped).
+- If a call to Pa_OpenStream() fails a non-zero error code is returned (see
+- PaError above) and the value of stream is invalid.
+- 
+-*/
+-
+-PaError Pa_OpenStream( PortAudioStream** stream,
+-                       PaDeviceID inputDevice,
+-                       int numInputChannels,
+-                       PaSampleFormat inputSampleFormat,
+-                       void *inputDriverInfo,
+-                       PaDeviceID outputDevice,
+-                       int numOutputChannels,
+-                       PaSampleFormat outputSampleFormat,
+-                       void *outputDriverInfo,
+-                       double sampleRate,
+-                       unsigned long framesPerBuffer,
+-                       unsigned long numberOfBuffers,
+-                       PaStreamFlags streamFlags,
+-                       PortAudioCallback *callback,
+-                       void *userData );
+-
+-
+-/*
+- Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens
+- the default input and/or output devices. Most parameters have identical meaning
+- to their Pa_OpenStream() counterparts, with the following exceptions:
+- 
+- If either numInputChannels or numOutputChannels is 0 the respective device
+- is not opened. This has the same effect as passing paNoDevice in the device
+- arguments to Pa_OpenStream().
+- 
+- sampleFormat applies to both the input and output buffers.
+-
+-*/
+-
+-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
+-                              int numInputChannels,
+-                              int numOutputChannels,
+-                              PaSampleFormat sampleFormat,
+-                              double sampleRate,
+-                              unsigned long framesPerBuffer,
+-                              unsigned long numberOfBuffers,
+-                              PortAudioCallback *callback,
+-                              void *userData );
+-
+-/*
+- Pa_CloseStream() closes an audio stream, flushing any pending buffers.
+-
+-*/
+-
+-PaError Pa_CloseStream( PortAudioStream* );
+-
+-/*
+- Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
+- Pa_StopStream() waits until all pending audio buffers have been played.
+- Pa_AbortStream() stops playing immediately without waiting for pending
+- buffers to complete.
+-    
+-*/
+-
+-PaError Pa_StartStream( PortAudioStream *stream );
+-
+-PaError Pa_StopStream( PortAudioStream *stream );
+-
+-PaError Pa_AbortStream( PortAudioStream *stream );
+-
+-/*
+- Pa_StreamActive() returns one (1) when the stream is active (ie playing
+- or recording audio), zero (0) when not playing, or a negative error number
+- if the stream is invalid.
+- The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
+- but may also become inactive if the callback returns a non-zero value.
+- In the latter case, the stream is considered inactive after the last
+- buffer has finished playing.
+- 
+-*/
+-
+-PaError Pa_StreamActive( PortAudioStream *stream );
+-
+-/*
+- Pa_StreamTime() returns the current output time in samples for the stream.
+- This time may be used as a time reference (for example synchronizing audio to
+- MIDI).
+- 
+-*/
+-
+-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
+-
+-/*
+- Pa_GetCPULoad() returns the CPU Load for the stream.
+- The "CPU Load" is a fraction of total CPU time consumed by the stream's
+- audio processing routines including, but not limited to the client supplied
+- callback.
+- A value of 0.5 would imply that PortAudio and the sound generating
+- callback was consuming roughly 50% of the available CPU time.
+- This function may be called from the callback function or the application.
+- 
+-*/
+-
+-double Pa_GetCPULoad( PortAudioStream* stream );
+-
+-/*
+- Pa_GetMinNumBuffers() returns the minimum number of buffers required by
+- the current host based on minimum latency.
+- On the PC, for the DirectSound implementation, latency can be optionally set
+- by user by setting an environment variable.
+- For example, to set latency to 200 msec, put:
+- 
+-    set PA_MIN_LATENCY_MSEC=200
+- 
+- in the AUTOEXEC.BAT file and reboot.
+- If the environment variable is not set, then the latency will be determined
+- based on the OS. Windows NT has higher latency than Win95.
+- 
+-*/
+-
+-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
+-
+-/*
+- Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
+- You may sleep longer than the requested time so don't rely on this for
+- accurate musical timing.
+- 
+- Pa_Sleep() is provided as a convenience for authors of portable code (such as
+- the tests and examples in the PortAudio distribution.)
+- 
+-*/
+-
+-void Pa_Sleep( long msec );
+-
+-/*
+- Pa_GetSampleSize() returns the size in bytes of a single sample in the
+- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
+- no supported.
+-  
+-*/
+-
+-PaError Pa_GetSampleSize( PaSampleFormat format );
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif /* __cplusplus */
+-#endif /* PORT_AUDIO_H */
+--- a/src/portaudio19.h
++++ /dev/null
+@@ -1,1127 +0,0 @@
+-// NOTE: Copy this file to  portaudio.h  in order to compile with V19 portaudio
+-
+-#ifndef PORTAUDIO_H
+-#define PORTAUDIO_H
+-/*
+- * $Id: portaudio.h 1061 2006-06-19 22:46:41Z lschwardt $
+- * PortAudio Portable Real-Time Audio Library
+- * PortAudio API Header File
+- * Latest version available at: http://www.portaudio.com/
+- *
+- * Copyright (c) 1999-2002 Ross Bencina and Phil Burk
+- *
+- * 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.
+- *
+- * Any person wishing to distribute modifications to the Software is
+- * requested to send the modifications to the original developer so that
+- * they can be incorporated into the canonical version.
+- *
+- * 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.
+- */
+-
+-/** @file
+- @brief The PortAudio API.
+-*/
+-
+-
+-#ifdef __cplusplus
+-extern "C"
+-{
+-#endif /* __cplusplus */
+-
+- 
+-/** Retrieve the release number of the currently running PortAudio build,
+- eg 1900.
+-*/
+-int Pa_GetVersion( void );
+-
+-
+-/** Retrieve a textual description of the current PortAudio build,
+- eg "PortAudio V19-devel 13 October 2002".
+-*/
+-const char* Pa_GetVersionText( void );
+-
+-
+-/** Error codes returned by PortAudio functions.
+- Note that with the exception of paNoError, all PaErrorCodes are negative.
+-*/
+-
+-typedef int PaError;
+-typedef enum PaErrorCode
+-{
+-    paNoError = 0,
+-
+-    paNotInitialized = -10000,
+-    paUnanticipatedHostError,
+-    paInvalidChannelCount,
+-    paInvalidSampleRate,
+-    paInvalidDevice,
+-    paInvalidFlag,
+-    paSampleFormatNotSupported,
+-    paBadIODeviceCombination,
+-    paInsufficientMemory,
+-    paBufferTooBig,
+-    paBufferTooSmall,
+-    paNullCallback,
+-    paBadStreamPtr,
+-    paTimedOut,
+-    paInternalError,
+-    paDeviceUnavailable,
+-    paIncompatibleHostApiSpecificStreamInfo,
+-    paStreamIsStopped,
+-    paStreamIsNotStopped,
+-    paInputOverflowed,
+-    paOutputUnderflowed,
+-    paHostApiNotFound,
+-    paInvalidHostApi,
+-    paCanNotReadFromACallbackStream,      /**< @todo review error code name */
+-    paCanNotWriteToACallbackStream,       /**< @todo review error code name */
+-    paCanNotReadFromAnOutputOnlyStream,   /**< @todo review error code name */
+-    paCanNotWriteToAnInputOnlyStream,     /**< @todo review error code name */
+-    paIncompatibleStreamHostApi,
+-    paBadBufferPtr
+-} PaErrorCode;
+-
+-
+-/** Translate the supplied PortAudio error code into a human readable
+- message.
+-*/
+-const char *Pa_GetErrorText( PaError errorCode );
+-
+-
+-/** Library initialization function - call this before using PortAudio.
+- This function initialises internal data structures and prepares underlying
+- host APIs for use. This function MUST be called before using any other
+- PortAudio API functions.
+-
+- If Pa_Initialize() is called multiple times, each successful 
+- call must be matched with a corresponding call to Pa_Terminate(). 
+- Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not 
+- required to be fully nested.
+-
+- Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
+- NOT be called.
+-
+- @return paNoError if successful, otherwise an error code indicating the cause
+- of failure.
+-
+- @see Pa_Terminate
+-*/
+-PaError Pa_Initialize( void );
+-
+-
+-/** Library termination function - call this when finished using PortAudio.
+- This function deallocates all resources allocated by PortAudio since it was
+- initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has
+- been called multiple times, each call must be matched with a corresponding call
+- to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
+- close any PortAudio streams that are still open.
+-
+- Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
+- Failure to do so may result in serious resource leaks, such as audio devices
+- not being available until the next reboot.
+-
+- @return paNoError if successful, otherwise an error code indicating the cause
+- of failure.
+- 
+- @see Pa_Initialize
+-*/
+-PaError Pa_Terminate( void );
+-
+-
+-
+-/** The type used to refer to audio devices. Values of this type usually
+- range from 0 to (Pa_DeviceCount-1), and may also take on the PaNoDevice
+- and paUseHostApiSpecificDeviceSpecification values.
+-
+- @see Pa_DeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification
+-*/
+-typedef int PaDeviceIndex;
+-
+-
+-/** A special PaDeviceIndex value indicating that no device is available,
+- or should be used.
+-
+- @see PaDeviceIndex
+-*/
+-#define paNoDevice ((PaDeviceIndex)-1)
+-
+-
+-/** A special PaDeviceIndex value indicating that the device(s) to be used
+- are specified in the host api specific stream info structure.
+-
+- @see PaDeviceIndex
+-*/
+-#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2)
+-
+-
+-/* Host API enumeration mechanism */
+-
+-/** The type used to enumerate to host APIs at runtime. Values of this type
+- range from 0 to (Pa_GetHostApiCount()-1).
+-
+- @see Pa_GetHostApiCount
+-*/
+-typedef int PaHostApiIndex;
+-
+-
+-/** Retrieve the number of available host APIs. Even if a host API is
+- available it may have no devices available.
+-
+- @return A non-negative value indicating the number of available host APIs
+- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+- or an error is encountered.
+-
+- @see PaHostApiIndex
+-*/
+-PaHostApiIndex Pa_GetHostApiCount( void );
+-
+-
+-/** Retrieve the index of the default host API. The default host API will be
+- the lowest common denominator host API on the current platform and is
+- unlikely to provide the best performance.
+-
+- @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1)
+- indicating the default host API index or, a PaErrorCode (which are always
+- negative) if PortAudio is not initialized or an error is encountered.
+-*/
+-PaHostApiIndex Pa_GetDefaultHostApi( void );
+-
+-
+-/** Unchanging unique identifiers for each supported host API. This type
+- is used in the PaHostApiInfo structure. The values are guaranteed to be
+- unique and to never change, thus allowing code to be written that
+- conditionally uses host API specific extensions.
+-
+- New type ids will be allocated when support for a host API reaches
+- "public alpha" status, prior to that developers should use the
+- paInDevelopment type id.
+-
+- @see PaHostApiInfo
+-*/
+-typedef enum PaHostApiTypeId
+-{
+-    paInDevelopment=0, /* use while developing support for a new host API */
+-    paDirectSound=1,
+-    paMME=2,
+-    paASIO=3,
+-    paSoundManager=4,
+-    paCoreAudio=5,
+-    paOSS=7,
+-    paALSA=8,
+-    paAL=9,
+-    paBeOS=10,
+-    paWDMKS=11,
+-    paJACK=12,
+-    paWASAPI=13,
+-    paAudioScienceHPI=14
+-} PaHostApiTypeId;
+-
+-
+-/** A structure containing information about a particular host API. */
+-
+-typedef struct PaHostApiInfo
+-{
+-    /** this is struct version 1 */
+-    int structVersion;
+-    /** The well known unique identifier of this host API @see PaHostApiTypeId */
+-    PaHostApiTypeId type;
+-    /** A textual description of the host API for display on user interfaces. */
+-    const char *name;
+-
+-    /**  The number of devices belonging to this host API. This field may be
+-     used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate
+-     all devices for this host API.
+-     @see Pa_HostApiDeviceIndexToDeviceIndex
+-    */
+-    int deviceCount;
+-
+-    /** The default input device for this host API. The value will be a
+-     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+-     if no default input device is available.
+-    */
+-    PaDeviceIndex defaultInputDevice;
+-
+-    /** The default output device for this host API. The value will be a
+-     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+-     if no default output device is available.
+-    */
+-    PaDeviceIndex defaultOutputDevice;
+-    
+-} PaHostApiInfo;
+-
+-
+-/** Retrieve a pointer to a structure containing information about a specific
+- host Api.
+-
+- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+-
+- @return A pointer to an immutable PaHostApiInfo structure describing
+- a specific host API. If the hostApi parameter is out of range or an error
+- is encountered, the function returns NULL.
+-
+- The returned structure is owned by the PortAudio implementation and must not
+- be manipulated or freed. The pointer is only guaranteed to be valid between
+- calls to Pa_Initialize() and Pa_Terminate().
+-*/
+-const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
+-
+-
+-/** Convert a static host API unique identifier, into a runtime
+- host API index.
+-
+- @param type A unique host API identifier belonging to the PaHostApiTypeId
+- enumeration.
+-
+- @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
+- a PaErrorCode (which are always negative) if PortAudio is not initialized
+- or an error is encountered.
+- 
+- The paHostApiNotFound error code indicates that the host API specified by the
+- type parameter is not available.
+-
+- @see PaHostApiTypeId
+-*/
+-PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
+-
+-
+-/** Convert a host-API-specific device index to standard PortAudio device index.
+- This function may be used in conjunction with the deviceCount field of
+- PaHostApiInfo to enumerate all devices for the specified host API.
+-
+- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+-
+- @param hostApiDeviceIndex A valid per-host device index in the range
+- 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1)
+-
+- @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1)
+- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+- or an error is encountered.
+-
+- A paInvalidHostApi error code indicates that the host API index specified by
+- the hostApi parameter is out of range.
+-
+- A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
+- is out of range.
+- 
+- @see PaHostApiInfo
+-*/
+-PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
+-        int hostApiDeviceIndex );
+-
+-
+-
+-/** Structure used to return information about a host error condition.
+-*/
+-typedef struct PaHostErrorInfo{
+-    PaHostApiTypeId hostApiType;    /**< the host API which returned the error code */
+-    long errorCode;                 /**< the error code returned */
+-    const char *errorText;          /**< a textual description of the error if available, otherwise a zero-length string */
+-}PaHostErrorInfo;
+-
+-
+-/** Return information about the last host error encountered. The error
+- information returned by Pa_GetLastHostErrorInfo() will never be modified
+- asyncronously by errors occurring in other PortAudio owned threads
+- (such as the thread that manages the stream callback.)
+-
+- This function is provided as a last resort, primarily to enhance debugging
+- by providing clients with access to all available error information.
+-
+- @return A pointer to an immutable structure constaining information about
+- the host error. The values in this structure will only be valid if a
+- PortAudio function has previously returned the paUnanticipatedHostError
+- error code.
+-*/
+-const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void );
+-
+-
+-
+-/* Device enumeration and capabilities */
+-
+-/** Retrieve the number of available devices. The number of available devices
+- may be zero.
+-
+- @return A non-negative value indicating the number of available devices or,
+- a PaErrorCode (which are always negative) if PortAudio is not initialized
+- or an error is encountered.
+-*/
+-PaDeviceIndex Pa_GetDeviceCount( void );
+-
+-
+-/** Retrieve the index of the default input device. The result can be
+- used in the inputDevice parameter to Pa_OpenStream().
+-
+- @return The default input device index for the default host API, or paNoDevice
+- if no default input device is available or an error was encountered.
+-*/
+-PaDeviceIndex Pa_GetDefaultInputDevice( void );
+-
+-
+-/** Retrieve the index of the default output device. The result can be
+- used in the outputDevice parameter to Pa_OpenStream().
+-
+- @return The default output device index for the defualt host API, or paNoDevice
+- if no default output device is available or an error was encountered.
+-
+- @note
+- On the PC, the user can specify a default device by
+- setting an environment variable. For example, to use device #1.
+-<pre>
+- set PA_RECOMMENDED_OUTPUT_DEVICE=1
+-</pre>
+- The user should first determine the available device ids by using
+- the supplied application "pa_devs".
+-*/
+-PaDeviceIndex Pa_GetDefaultOutputDevice( void );
+-
+-
+-/** The type used to represent monotonic time in seconds that can be used
+- for syncronisation. The type is used for the outTime argument to the
+- PaStreamCallback and as the result of Pa_GetStreamTime().
+-     
+- @see PaStreamCallback, Pa_GetStreamTime
+-*/
+-typedef double PaTime;
+-
+-
+-/** A type used to specify one or more sample formats. Each value indicates
+- a possible format for sound data passed to and from the stream callback,
+- Pa_ReadStream and Pa_WriteStream.
+-
+- The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
+- and aUInt8 are usually implemented by all implementations.
+-
+- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
+- maximum and minimum respectively.
+-
+- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+-
+- The paNonInterleaved flag indicates that a multichannel buffer is passed
+- as a set of non-interleaved pointers.
+-
+- @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
+- @see paFloat32, paInt16, paInt32, paInt24, paInt8
+- @see paUInt8, paCustomFormat, paNonInterleaved
+-*/
+-typedef unsigned long PaSampleFormat;
+-
+-
+-#define paFloat32        ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */
+-#define paInt32          ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */
+-#define paInt24          ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */
+-#define paInt16          ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
+-#define paInt8           ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
+-#define paUInt8          ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
+-#define paCustomFormat   ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */
+-
+-#define paNonInterleaved ((PaSampleFormat) 0x80000000)
+-
+-/** A structure providing information and capabilities of PortAudio devices.
+- Devices may support input, output or both input and output.
+-*/
+-typedef struct PaDeviceInfo
+-{
+-    int structVersion;  /* this is struct version 2 */
+-    const char *name;
+-    PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
+-    
+-    int maxInputChannels;
+-    int maxOutputChannels;
+-
+-    /* Default latency values for interactive performance. */
+-    PaTime defaultLowInputLatency;
+-    PaTime defaultLowOutputLatency;
+-    /* Default latency values for robust non-interactive applications (eg. playing sound files). */
+-    PaTime defaultHighInputLatency;
+-    PaTime defaultHighOutputLatency;
+-
+-    double defaultSampleRate;
+-} PaDeviceInfo;
+-
+-
+-/** Retrieve a pointer to a PaDeviceInfo structure containing information
+- about the specified device.
+- @return A pointer to an immutable PaDeviceInfo structure. If the device
+- parameter is out of range the function returns NULL.
+-
+- @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+-
+- @note PortAudio manages the memory referenced by the returned pointer,
+- the client must not manipulate or free the memory. The pointer is only
+- guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
+-
+- @see PaDeviceInfo, PaDeviceIndex
+-*/
+-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device );
+-
+-
+-/** Parameters for one direction (input or output) of a stream.
+-*/
+-typedef struct PaStreamParameters
+-{
+-    /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+-     specifying the device to be used or the special constant
+-     paUseHostApiSpecificDeviceSpecification which indicates that the actual
+-     device(s) to use are specified in hostApiSpecificStreamInfo.
+-     This field must not be set to paNoDevice.
+-    */
+-    PaDeviceIndex device;
+-    
+-    /** The number of channels of sound to be delivered to the
+-     stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
+-     It can range from 1 to the value of maxInputChannels in the
+-     PaDeviceInfo record for the device specified by the device parameter.
+-    */
+-    int channelCount;
+-
+-    /** The sample format of the buffer provided to the stream callback,
+-     a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
+-     by the PaSampleFormat enumeration.
+-    */
+-    PaSampleFormat sampleFormat;
+-
+-    /** The desired latency in seconds. Where practical, implementations should
+-     configure their latency based on these parameters, otherwise they may
+-     choose the closest viable latency instead. Unless the suggested latency
+-     is greater than the absolute upper limit for the device implementations
+-     should round the suggestedLatency up to the next practial value - ie to
+-     provide an equal or higher latency than suggestedLatency wherever possibe.
+-     Actual latency values for an open stream may be retrieved using the
+-     inputLatency and outputLatency fields of the PaStreamInfo structure
+-     returned by Pa_GetStreamInfo().
+-     @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
+-    */
+-    PaTime suggestedLatency;
+-
+-    /** An optional pointer to a host api specific data structure
+-     containing additional information for device setup and/or stream processing.
+-     hostApiSpecificStreamInfo is never required for correct operation,
+-     if not used it should be set to NULL.
+-    */
+-    void *hostApiSpecificStreamInfo;
+-
+-} PaStreamParameters;
+-
+-
+-/** Return code for Pa_IsFormatSupported indicating success. */
+-#define paFormatIsSupported (0)
+-
+-/** Determine whether it would be possible to open a stream with the specified
+- parameters.
+-
+- @param inputParameters A structure that describes the input parameters used to
+- open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+- for a description of these parameters. inputParameters must be NULL for
+- output-only streams.
+-
+- @param outputParameters A structure that describes the output parameters used
+- to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+- for a description of these parameters. outputParameters must be NULL for
+- input-only streams.
+-
+- @param sampleRate The required sampleRate. For full-duplex streams it is the
+- sample rate for both input and output
+-
+- @return Returns 0 if the format is supported, and an error code indicating why
+- the format is not supported otherwise. The constant paFormatIsSupported is
+- provided to compare with the return value for success.
+-
+- @see paFormatIsSupported, PaStreamParameters
+-*/
+-PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
+-                              const PaStreamParameters *outputParameters,
+-                              double sampleRate );
+-
+-
+-
+-/* Streaming types and functions */
+-
+-
+-/**
+- A single PaStream can provide multiple channels of real-time
+- streaming audio input and output to a client application. A stream
+- provides access to audio hardware represented by one or more
+- PaDevices. Depending on the underlying Host API, it may be possible 
+- to open multiple streams using the same device, however this behavior 
+- is implementation defined. Portable applications should assume that 
+- a PaDevice may be simultaneously used by at most one PaStream.
+-
+- Pointers to PaStream objects are passed between PortAudio functions that
+- operate on streams.
+-
+- @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
+- Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
+- Pa_GetStreamTime, Pa_GetStreamCpuLoad
+-
+-*/
+-typedef void PaStream;
+-
+-
+-/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
+- or Pa_OpenDefaultStream() to indicate that the stream callback will
+- accept buffers of any size.
+-*/
+-#define paFramesPerBufferUnspecified  (0)
+-
+-
+-/** Flags used to control the behavior of a stream. They are passed as
+- parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
+- ORed together.
+-
+- @see Pa_OpenStream, Pa_OpenDefaultStream
+- @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
+-  paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
+-*/
+-typedef unsigned long PaStreamFlags;
+-
+-/** @see PaStreamFlags */
+-#define   paNoFlag          ((PaStreamFlags) 0)
+-
+-/** Disable default clipping of out of range samples.
+- @see PaStreamFlags
+-*/
+-#define   paClipOff         ((PaStreamFlags) 0x00000001)
+-
+-/** Disable default dithering.
+- @see PaStreamFlags
+-*/
+-#define   paDitherOff       ((PaStreamFlags) 0x00000002)
+-
+-/** Flag requests that where possible a full duplex stream will not discard
+- overflowed input samples without calling the stream callback. This flag is
+- only valid for full duplex callback streams and only when used in combination
+- with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
+- this flag incorrectly results in a paInvalidFlag error being returned from
+- Pa_OpenStream and Pa_OpenDefaultStream.
+-
+- @see PaStreamFlags, paFramesPerBufferUnspecified
+-*/
+-#define   paNeverDropInput  ((PaStreamFlags) 0x00000004)
+-
+-/** Call the stream callback to fill initial output buffers, rather than the
+- default behavior of priming the buffers with zeros (silence). This flag has
+- no effect for input-only and blocking read/write streams.
+- 
+- @see PaStreamFlags
+-*/
+-#define   paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
+-
+-/** A mask specifying the platform specific bits.
+- @see PaStreamFlags
+-*/
+-#define   paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000)
+-
+-/**
+- Timing information for the buffers passed to the stream callback.
+-*/
+-typedef struct PaStreamCallbackTimeInfo{
+-    PaTime inputBufferAdcTime;
+-    PaTime currentTime;
+-    PaTime outputBufferDacTime;
+-} PaStreamCallbackTimeInfo;
+-
+-
+-/**
+- Flag bit constants for the statusFlags to PaStreamCallback.
+-
+- @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
+- paPrimingOutput
+-*/
+-typedef unsigned long PaStreamCallbackFlags;
+-
+-/** In a stream opened with paFramesPerBufferUnspecified, indicates that
+- input data is all silence (zeros) because no real data is available. In a
+- stream opened without paFramesPerBufferUnspecified, it indicates that one or
+- more zero samples have been inserted into the input buffer to compensate
+- for an input underflow.
+- @see PaStreamCallbackFlags
+-*/
+-#define paInputUnderflow   ((PaStreamCallbackFlags) 0x00000001)
+-
+-/** In a stream opened with paFramesPerBufferUnspecified, indicates that data
+- prior to the first sample of the input buffer was discarded due to an
+- overflow, possibly because the stream callback is using too much CPU time.
+- Otherwise indicates that data prior to one or more samples in the
+- input buffer was discarded.
+- @see PaStreamCallbackFlags
+-*/
+-#define paInputOverflow    ((PaStreamCallbackFlags) 0x00000002)
+-
+-/** Indicates that output data (or a gap) was inserted, possibly because the
+- stream callback is using too much CPU time.
+- @see PaStreamCallbackFlags
+-*/
+-#define paOutputUnderflow  ((PaStreamCallbackFlags) 0x00000004)
+-
+-/** Indicates that output data will be discarded because no room is available.
+- @see PaStreamCallbackFlags
+-*/
+-#define paOutputOverflow   ((PaStreamCallbackFlags) 0x00000008)
+-
+-/** Some of all of the output data will be used to prime the stream, input
+- data may be zero.
+- @see PaStreamCallbackFlags
+-*/
+-#define paPrimingOutput    ((PaStreamCallbackFlags) 0x00000010)
+-
+-/**
+- Allowable return values for the PaStreamCallback.
+- @see PaStreamCallback
+-*/
+-typedef enum PaStreamCallbackResult
+-{
+-    paContinue=0,
+-    paComplete=1,
+-    paAbort=2
+-} PaStreamCallbackResult;
+-
+-
+-/**
+- Functions of type PaStreamCallback are implemented by PortAudio clients.
+- They consume, process or generate audio in response to requests from an
+- active PortAudio stream.
+-     
+- @param input and @param output are arrays of interleaved samples,
+- the format, packing and number of channels used by the buffers are
+- determined by parameters to Pa_OpenStream().
+-     
+- @param frameCount The number of sample frames to be processed by
+- the stream callback.
+-
+- @param timeInfo The time in seconds when the first sample of the input
+- buffer was received at the audio input, the time in seconds when the first
+- sample of the output buffer will begin being played at the audio output, and
+- the time in seconds when the stream callback was called.
+- See also Pa_GetStreamTime()
+-
+- @param statusFlags Flags indicating whether input and/or output buffers
+- have been inserted or will be dropped to overcome underflow or overflow
+- conditions.
+-
+- @param userData The value of a user supplied pointer passed to
+- Pa_OpenStream() intended for storing synthesis data etc.
+-
+- @return
+- The stream callback should return one of the values in the
+- PaStreamCallbackResult enumeration. To ensure that the callback continues
+- to be called, it should return paContinue (0). Either paComplete or paAbort
+- can be returned to finish stream processing, after either of these values is
+- returned the callback will not be called again. If paAbort is returned the
+- stream will finish as soon as possible. If paComplete is returned, the stream
+- will continue until all buffers generated by the callback have been played.
+- This may be useful in applications such as soundfile players where a specific
+- duration of output is required. However, it is not necessary to utilise this
+- mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
+- be used to stop the stream. The callback must always fill the entire output
+- buffer irrespective of its return value.
+-
+- @see Pa_OpenStream, Pa_OpenDefaultStream
+-
+- @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
+- PortAudio API functions from within the stream callback.
+-*/
+-typedef int PaStreamCallback(
+-    const void *input, void *output,
+-    unsigned long frameCount,
+-    const PaStreamCallbackTimeInfo* timeInfo,
+-    PaStreamCallbackFlags statusFlags,
+-    void *userData );
+-
+-
+-/** Opens a stream for either input, output or both.
+-     
+- @param stream The address of a PaStream pointer which will receive
+- a pointer to the newly opened stream.
+-     
+- @param inputParameters A structure that describes the input parameters used by
+- the opened stream. See PaStreamParameters for a description of these parameters.
+- inputParameters must be NULL for output-only streams.
+-
+- @param outputParameters A structure that describes the output parameters used by
+- the opened stream. See PaStreamParameters for a description of these parameters.
+- outputParameters must be NULL for input-only streams.
+- 
+- @param sampleRate The desired sampleRate. For full-duplex streams it is the
+- sample rate for both input and output
+-     
+- @param framesPerBuffer The number of frames passed to the stream callback
+- function, or the preferred block granularity for a blocking read/write stream.
+- The special value paFramesPerBufferUnspecified (0) may be used to request that
+- the stream callback will recieve an optimal (and possibly varying) number of
+- frames based on host requirements and the requested latency settings.
+- Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
+- stream may introduce an additional layer of buffering which could introduce
+- additional latency. PortAudio guarantees that the additional latency
+- will be kept to the theoretical minimum however, it is strongly recommended
+- that a non-zero framesPerBuffer value only be used when your algorithm
+- requires a fixed number of frames per stream callback.
+- 
+- @param streamFlags Flags which modify the behaviour of the streaming process.
+- This parameter may contain a combination of flags ORed together. Some flags may
+- only be relevant to certain buffer formats.
+-     
+- @param streamCallback A pointer to a client supplied function that is responsible
+- for processing and filling input and output buffers. If this parameter is NULL
+- the stream will be opened in 'blocking read/write' mode. In blocking mode,
+- the client can receive sample data using Pa_ReadStream and write sample data
+- using Pa_WriteStream, the number of samples that may be read or written
+- without blocking is returned by Pa_GetStreamReadAvailable and
+- Pa_GetStreamWriteAvailable respectively.
+-
+- @param userData A client supplied pointer which is passed to the stream callback
+- function. It could for example, contain a pointer to instance data necessary
+- for processing the audio buffers. This parameter is ignored if streamCallback
+- is NULL.
+-     
+- @return
+- Upon success Pa_OpenStream() returns paNoError and places a pointer to a
+- valid PaStream in the stream argument. The stream is inactive (stopped).
+- If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
+- PaError for possible error codes) and the value of stream is invalid.
+-
+- @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
+- Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
+-*/
+-PaError Pa_OpenStream( PaStream** stream,
+-                       const PaStreamParameters *inputParameters,
+-                       const PaStreamParameters *outputParameters,
+-                       double sampleRate,
+-                       unsigned long framesPerBuffer,
+-                       PaStreamFlags streamFlags,
+-                       PaStreamCallback *streamCallback,
+-                       void *userData );
+-
+-
+-/** A simplified version of Pa_OpenStream() that opens the default input
+- and/or output devices.
+-
+- @param stream The address of a PaStream pointer which will receive
+- a pointer to the newly opened stream.
+- 
+- @param numInputChannels  The number of channels of sound that will be supplied
+- to the stream callback or returned by Pa_ReadStream. It can range from 1 to
+- the value of maxInputChannels in the PaDeviceInfo record for the default input
+- device. If 0 the stream is opened as an output-only stream.
+-
+- @param numOutputChannels The number of channels of sound to be delivered to the
+- stream callback or passed to Pa_WriteStream. It can range from 1 to the value
+- of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
+- If 0 the stream is opened as an output-only stream.
+-
+- @param sampleFormat The sample format of both the input and output buffers
+- provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
+- sampleFormat may be any of the formats described by the PaSampleFormat
+- enumeration.
+- 
+- @param sampleRate Same as Pa_OpenStream parameter of the same name.
+- @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
+- @param streamCallback Same as Pa_OpenStream parameter of the same name.
+- @param userData Same as Pa_OpenStream parameter of the same name.
+-
+- @return As for Pa_OpenStream
+-
+- @see Pa_OpenStream, PaStreamCallback
+-*/
+-PaError Pa_OpenDefaultStream( PaStream** stream,
+-                              int numInputChannels,
+-                              int numOutputChannels,
+-                              PaSampleFormat sampleFormat,
+-                              double sampleRate,
+-                              unsigned long framesPerBuffer,
+-                              PaStreamCallback *streamCallback,
+-                              void *userData );
+-
+-
+-/** Closes an audio stream. If the audio stream is active it
+- discards any pending buffers as if Pa_AbortStream() had been called.
+-*/
+-PaError Pa_CloseStream( PaStream *stream );
+-
+-
+-/** Functions of type PaStreamFinishedCallback are implemented by PortAudio 
+- clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
+- function. Once registered they are called when the stream becomes inactive
+- (ie once a call to Pa_StopStream() will not block).
+- A stream will become inactive after the stream callback returns non-zero,
+- or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
+- output, if the stream callback returns paComplete, or Pa_StopStream is called,
+- the stream finished callback will not be called until all generated sample data
+- has been played.
+- 
+- @param userData The userData parameter supplied to Pa_OpenStream()
+-
+- @see Pa_SetStreamFinishedCallback
+-*/
+-typedef void PaStreamFinishedCallback( void *userData );
+-
+-
+-/** Register a stream finished callback function which will be called when the 
+- stream becomes inactive. See the description of PaStreamFinishedCallback for 
+- further details about when the callback will be called.
+-
+- @param stream a pointer to a PaStream that is in the stopped state - if the
+- stream is not stopped, the stream's finished callback will remain unchanged 
+- and an error code will be returned.
+-
+- @param streamFinishedCallback a pointer to a function with the same signature
+- as PaStreamFinishedCallback, that will be called when the stream becomes
+- inactive. Passing NULL for this parameter will un-register a previously
+- registered stream finished callback function.
+-
+- @return on success returns paNoError, otherwise an error code indicating the cause
+- of the error.
+-
+- @see PaStreamFinishedCallback
+-*/
+-PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); 
+-
+-
+-/** Commences audio processing.
+-*/
+-PaError Pa_StartStream( PaStream *stream );
+-
+-
+-/** Terminates audio processing. It waits until all pending
+- audio buffers have been played before it returns.
+-*/
+-PaError Pa_StopStream( PaStream *stream );
+-
+-
+-/** Terminates audio processing immediately without waiting for pending
+- buffers to complete.
+-*/
+-PaError Pa_AbortStream( PaStream *stream );
+-
+-
+-/** Determine whether the stream is stopped.
+- A stream is considered to be stopped prior to a successful call to
+- Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
+- If a stream callback returns a value other than paContinue the stream is NOT
+- considered to be stopped.
+-
+- @return Returns one (1) when the stream is stopped, zero (0) when
+- the stream is running or, a PaErrorCode (which are always negative) if
+- PortAudio is not initialized or an error is encountered.
+-
+- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
+-*/
+-PaError Pa_IsStreamStopped( PaStream *stream );
+-
+-
+-/** Determine whether the stream is active.
+- A stream is active after a successful call to Pa_StartStream(), until it
+- becomes inactive either as a result of a call to Pa_StopStream() or
+- Pa_AbortStream(), or as a result of a return value other than paContinue from
+- the stream callback. In the latter case, the stream is considered inactive
+- after the last buffer has finished playing.
+-
+- @return Returns one (1) when the stream is active (ie playing or recording
+- audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
+- if PortAudio is not initialized or an error is encountered.
+-
+- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
+-*/
+-PaError Pa_IsStreamActive( PaStream *stream );
+-
+-
+-
+-/** A structure containing unchanging information about an open stream.
+- @see Pa_GetStreamInfo
+-*/
+-
+-typedef struct PaStreamInfo
+-{
+-    /** this is struct version 1 */
+-    int structVersion;
+-
+-    /** The input latency of the stream in seconds. This value provides the most
+-     accurate estimate of input latency available to the implementation. It may
+-     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+-     The value of this field will be zero (0.) for output-only streams.
+-     @see PaTime
+-    */
+-    PaTime inputLatency;
+-
+-    /** The output latency of the stream in seconds. This value provides the most
+-     accurate estimate of output latency available to the implementation. It may
+-     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+-     The value of this field will be zero (0.) for input-only streams.
+-     @see PaTime
+-    */
+-    PaTime outputLatency;
+-
+-    /** The sample rate of the stream in Hertz (samples per second). In cases
+-     where the hardware sample rate is inaccurate and PortAudio is aware of it,
+-     the value of this field may be different from the sampleRate parameter
+-     passed to Pa_OpenStream(). If information about the actual hardware sample
+-     rate is not available, this field will have the same value as the sampleRate
+-     parameter passed to Pa_OpenStream().
+-    */
+-    double sampleRate;
+-    
+-} PaStreamInfo;
+-
+-
+-/** Retrieve a pointer to a PaStreamInfo structure containing information
+- about the specified stream.
+- @return A pointer to an immutable PaStreamInfo structure. If the stream
+- parameter invalid, or an error is encountered, the function returns NULL.
+-
+- @param stream A pointer to an open stream previously created with Pa_OpenStream.
+-
+- @note PortAudio manages the memory referenced by the returned pointer,
+- the client must not manipulate or free the memory. The pointer is only
+- guaranteed to be valid until the specified stream is closed.
+-
+- @see PaStreamInfo
+-*/
+-const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
+-
+-
+-/** Determine the current time for the stream according to the same clock used
+- to generate buffer timestamps. This time may be used for syncronising other
+- events to the audio stream, for example synchronizing audio to MIDI.
+-                                        
+- @return The stream's current time in seconds, or 0 if an error occurred.
+-
+- @see PaTime, PaStreamCallback
+-*/
+-PaTime Pa_GetStreamTime( PaStream *stream );
+-
+-
+-/** Retrieve CPU usage information for the specified stream.
+- The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
+- audio processing routines including, but not limited to the client supplied
+- stream callback. This function does not work with blocking read/write streams.
+-
+- This function may be called from the stream callback function or the
+- application.
+-     
+- @return
+- A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
+- that the stream callback is consuming the maximum number of CPU cycles possible
+- to maintain real-time operation. A value of 0.5 would imply that PortAudio and
+- the stream callback was consuming roughly 50% of the available CPU time. The
+- return value may exceed 1.0. A value of 0.0 will always be returned for a
+- blocking read/write stream, or if an error occurrs.
+-*/
+-double Pa_GetStreamCpuLoad( PaStream* stream );
+-
+-
+-/** Read samples from an input stream. The function doesn't return until
+- the entire buffer has been filled - this may involve waiting for the operating
+- system to supply the data.
+-
+- @param stream A pointer to an open stream previously created with Pa_OpenStream.
+- 
+- @param buffer A pointer to a buffer of sample frames. The buffer contains
+- samples in the format specified by the inputParameters->sampleFormat field
+- used to open the stream, and the number of channels specified by
+- inputParameters->numChannels. If non-interleaved samples were requested,
+- buffer is a pointer to the first element of an array of non-interleaved
+- buffer pointers, one for each channel.
+-
+- @param frames The number of frames to be read into buffer. This parameter
+- is not constrained to a specific range, however high performance applications
+- will want to match this parameter to the framesPerBuffer parameter used
+- when opening the stream.
+-
+- @return On success PaNoError will be returned, or PaInputOverflowed if input
+- data was discarded by PortAudio after the previous call and before this call.
+-*/
+-PaError Pa_ReadStream( PaStream* stream,
+-                       void *buffer,
+-                       unsigned long frames );
+-
+-
+-/** Write samples to an output stream. This function doesn't return until the
+- entire buffer has been consumed - this may involve waiting for the operating
+- system to consume the data.
+-
+- @param stream A pointer to an open stream previously created with Pa_OpenStream.
+-
+- @param buffer A pointer to a buffer of sample frames. The buffer contains
+- samples in the format specified by the outputParameters->sampleFormat field
+- used to open the stream, and the number of channels specified by
+- outputParameters->numChannels. If non-interleaved samples were requested,
+- buffer is a pointer to the first element of an array of non-interleaved
+- buffer pointers, one for each channel.
+-
+- @param frames The number of frames to be written from buffer. This parameter
+- is not constrained to a specific range, however high performance applications
+- will want to match this parameter to the framesPerBuffer parameter used
+- when opening the stream.
+-
+- @return On success PaNoError will be returned, or paOutputUnderflowed if
+- additional output data was inserted after the previous call and before this
+- call.
+-*/
+-PaError Pa_WriteStream( PaStream* stream,
+-                        const void *buffer,
+-                        unsigned long frames );
+-
+-
+-/** Retrieve the number of frames that can be read from the stream without
+- waiting.
+-
+- @return Returns a non-negative value representing the maximum number of frames
+- that can be read from the stream without blocking or busy waiting or, a
+- PaErrorCode (which are always negative) if PortAudio is not initialized or an
+- error is encountered.
+-*/
+-signed long Pa_GetStreamReadAvailable( PaStream* stream );
+-
+-
+-/** Retrieve the number of frames that can be written to the stream without
+- waiting.
+-
+- @return Returns a non-negative value representing the maximum number of frames
+- that can be written to the stream without blocking or busy waiting or, a
+- PaErrorCode (which are always negative) if PortAudio is not initialized or an
+- error is encountered.
+-*/
+-signed long Pa_GetStreamWriteAvailable( PaStream* stream );
+-
+-
+-/* Miscellaneous utilities */
+-
+-
+-/** Retrieve the size of a given sample format in bytes.
+-
+- @return The size in bytes of a single sample in the specified format,
+- or paSampleFormatNotSupported if the format is not supported.
+-*/
+-PaError Pa_GetSampleSize( PaSampleFormat format );
+-
+-
+-/** Put the caller to sleep for at least 'msec' milliseconds. This function is
+- provided only as a convenience for authors of portable code (such as the tests
+- and examples in the PortAudio distribution.)
+-
+- The function may sleep longer than requested so don't rely on this for accurate
+- musical timing.
+-*/
+-void Pa_Sleep( long msec );
+-
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif /* __cplusplus */
+-#endif /* PORTAUDIO_H */
+--- a/src/wave.cpp
++++ b/src/wave.cpp
+@@ -31,7 +31,10 @@
+ #include <sys/time.h>
+ #include <time.h>
+-#include "portaudio.h"
++#ifdef USE_PORTAUDIO
++#include <portaudio.h>
++#endif
++
+ #ifdef PLATFORM_WINDOWS
+ #include <windows.h>
+ #else
+--- a/src/wavegen.cpp
++++ b/src/wavegen.cpp
+@@ -40,7 +40,7 @@
+ #endif
+ #ifdef USE_PORTAUDIO
+-#include "portaudio.h"
++#include <portaudio.h>
+ #undef USE_PORTAUDIO
+ // determine portaudio version by looking for a #define which is not in V18
+ #ifdef paNeverDropInput
diff --git a/sound/forked-daapd/Makefile b/sound/forked-daapd/Makefile
new file mode 100644 (file)
index 0000000..4821483
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=forked-daapd
+PKG_VERSION:=22.2
+PKG_RELEASE:=20150129
+PKG_REV:=77f206c11855d2d84688a6e7cd9c8932e8a89205
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/ejurgensen/forked-daapd.git
+PKG_SOURCE_VERSION:=$(PKG_REV)
+
+PKG_BUILD_DEPENDS:=gperf/host
+PKG_FIXUP:=autoreconf
+PKG_USE_MIPS16:=0
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/forked-daapd
+SECTION:=sound
+CATEGORY:=Sound
+TITLE:=iTunes (DAAP) server for Apple Remote and AirPlay
+URL:=https://github.com/ejurgensen/forked-daapd
+DEPENDS:=+libgpg-error +libgcrypt +libgdbm +zlib +libexpat +libunistring \
+       +libevent2 +libdaemon +libantlr3c +confuse +glib2 +alsa-lib +libffmpeg-full \
+       +mxml +libavl +libavahi-client +sqlite3-cli +libplist +libcurl
+endef
+
+define Package/forked-daapd/conffiles
+/etc/forked-daapd.conf
+endef
+
+CONFIGURE_ARGS += \
+       --enable-itunes \
+       --enable-lastfm
+
+TARGET_CFLAGS += $(FPIC)
+TARGET_LDFLAGS += -Wl,-rpath-link,$(STAGING_DIR)/usr/lib
+
+define Package/forked-daapd/install
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) ./files/forked-daapd.conf $(1)/etc/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/forked-daapd
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/forked-daapd/* $(1)/usr/lib/forked-daapd/
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/forked-daapd $(1)/usr/sbin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/forked-daapd.init $(1)/etc/init.d/forked-daapd
+endef
+
+$(eval $(call BuildPackage,forked-daapd))
diff --git a/sound/forked-daapd/files/forked-daapd.conf b/sound/forked-daapd/files/forked-daapd.conf
new file mode 100644 (file)
index 0000000..63c0ac3
--- /dev/null
@@ -0,0 +1,193 @@
+# A quick guide to configuring forked-daapd:
+#
+# For regular use, the most important setting to configure is "directories",
+# which should be the location of your media. Whatever user you have set as
+# "uid" must have read access to this location. If the location is a network
+# mount, please see the README.
+#
+# In all likelihood, that's all you need to do!
+
+general {
+       # Username
+       # Make sure the user has read access to the library directories you set
+       # below, and full access to the databases, log and local audio
+       uid = "daapd"
+
+       # Database location
+#      db_path = "/var/cache/forked-daapd/songs3.db"
+
+       # Log file and level
+       # Available levels: fatal, log, warning, info, debug, spam
+       logfile = "/var/log/forked-daapd.log"
+       loglevel = log
+
+       # Admin password for the non-existent web interface
+       admin_password = "unused"
+
+       # Enable/disable IPv6
+       ipv6 = no
+
+       # Location of cache database
+#      cache_path = "/var/cache/forked-daapd/cache.db"
+
+       # DAAP requests that take longer than this threshold (in msec) get their
+       # replies cached for next time. Set to 0 to disable caching.
+#      cache_daap_threshold = 1000
+}
+
+# Library configuration
+library {
+       # Name of the library as displayed by the clients
+       # %h: hostname, %v: version
+       name = "My Music on %h"
+
+       # TCP port to listen on. Default port is 3689 (daap)
+       port = 3689
+
+       # Password for the library. Optional.
+#      password = ""
+
+       # Directories to index
+       directories = { "/srv/music" }
+
+       # Directories containing podcasts
+       # For each directory that is indexed the path is matched against these
+       # names. If there is a match all items in the directory are marked as 
+       # podcasts. Eg. if you index /srv/music, and your podcasts are in
+       # /srv/music/Podcasts, you can set this to "/Podcasts".
+       # (changing this setting only takes effect after rescan, see the README)
+       podcasts = { "/Podcasts" }
+
+       # Directories containing audiobooks
+       # For each directory that is indexed the path is matched against these
+       # names. If there is a match all items in the directory are marked as 
+       # audiobooks.
+       # (changing this setting only takes effect after rescan, see the README)
+       audiobooks = { "/Audiobooks" }
+
+       # Directories containing compilations (eg soundtracks)
+       # For each directory that is indexed the path is matched against these
+       # names. If there is a match all items in the directory are marked as 
+       # compilations.
+       # (changing this setting only takes effect after rescan, see the README)
+       compilations = { "/Compilations" }
+
+       # Compilations usually have many artists, and if you don't want every
+       # artist to be listed when artist browsing in Remote, you can set
+       # a single name which will be used for all music in the compilation dir
+       # (changing this setting only takes effect after rescan, see the README)
+       compilation_artist = "Various artists"
+
+       # There are 5 default playlists: "Library", "Music", "Movies", "TV Shows"
+       # and "Podcasts". Here you can change the names of these playlists.
+#      name_library    = "Library"
+#      name_music      = "Music"
+#      name_movies     = "Movies"
+#      name_tvshows    = "TV Shows"
+#      name_podcasts   = "Podcasts"
+#      name_audiobooks = "Audiobooks"
+
+       # Artwork file names (without file type extension)
+       # forked-daapd will look for jpg and png files with these base names
+#      artwork_basenames = { "artwork", "cover", "Folder" }
+
+       # Enable searching for artwork corresponding to each individual media
+       # file instead of only looking for album artwork. This is disabled by
+       # default to reduce cache size.
+#      artwork_individual = false
+
+       # File types the scanner should ignore
+       # Non-audio files will never be added to the database, but here you
+       # can prevent the scanner from even probing them. This might improve
+       # scan time. By default .db, .ini, .db-journal and .pdf are ignored.
+#      filetypes_ignore = { ".db", ".ini", ".db-journal", ".pdf" }
+
+       # File paths the scanner should ignore
+       # If you want to exclude files on a more advanced basis you can enter
+       # one or more POSIX regular expressions, and any file with a matching
+       # path will be ignored.
+#      filepath_ignore = { "myregex" }
+
+       # Disable startup file scanning
+       # When forked-daapd starts it will do an initial file scan of your
+       # library (and then watch it for changes). If you are sure your library
+       # never changes while forked-daapd is not running, you can disable the
+       # initial file scan and save some system ressources. Disabling this scan
+       # may lead to forked-daapd's database coming out of sync with the
+       # library. If that happens read the instructions in the README on how
+       # to trigger a rescan.
+#      filescan_disable = false
+
+       # Should iTunes metadata override ours?
+#      itunes_overrides = false
+
+       # Formats: mp4a, mp4v, mpeg, alac, flac, mpc, ogg, wma, wmal, wmav, aif, wav
+       # Formats that should never be transcoded
+#      no_transcode = { "alac", "mp4a" }
+       # Formats that should always be transcoded
+#      force_transcode = { "ogg", "flac" }
+}
+
+# Local audio output
+audio {
+       # Name - used in the speaker list in Remote
+       nickname = "OpenWrt"
+
+       # Audio device name for local audio output
+#      card = "default"
+
+       # Mixer channel to use for volume control - ALSA/Linux only
+       # If not set, PCM will be used if available, otherwise Master.
+#      mixer = ""
+}
+
+# AirPlay/Airport Express device settings
+# (make sure you get the capitalization of the device name right)
+#airplay "My AirPlay device" {
+       # forked-daapd's volume goes to 11! If that's more than you can handle
+       # you can set a lower value here
+#      max_volume = 11
+
+       # AirPlay password
+#      password = "s1kr3t"
+#}
+
+# Spotify settings (only have effect if Spotify enabled - see README/INSTALL)
+spotify {
+       # Directory where user settings should be stored (credentials)
+#      settings_dir = "/var/cache/forked-daapd/libspotify"
+
+       # Cache directory
+#      cache_dir = "/tmp"
+
+       # Set preferred bitrate for music streaming
+       # 0: No preference (default), 1: 96kbps, 2: 160kbps, 3: 320kbps
+#      bitrate = 0
+}
+
+# SQLite configuration (allows to modify the operation of the SQLite databases)
+# Make sure to read the SQLite documentation for the corresponding PRAGMA statements as
+# changing them from the defaults may increase the possibility of database corruptions!
+# By default the SQLite default values are used. 
+sqlite {
+       # Cache size in number of db pages for the library database
+       # (SQLite default page size is 1024 bytes and cache size is 2000 pages)
+#      pragma_cache_size_library = 2000
+       
+       # Cache size in number of db pages for the daap cache database
+       # (SQLite default page size is 1024 bytes and cache size is 2000 pages)
+#      pragma_cache_size_cache = 2000
+       
+       # Sets the journal mode for the database
+       # DELETE (default), TRUNCATE, PERSIST, MEMORY, WAL, OFF 
+#      pragma_journal_mode = DELETE
+       
+       # Change the setting of the "synchronous" flag
+       # 0: OFF, 1: NORMAL, 2: FULL (default)
+#      pragma_synchronous = 2
+
+       # Should the database be vacuumed on startup? (increases startup time,
+       # but may reduce database size). Default is yes.
+#      vacuum = yes
+}
+
diff --git a/sound/forked-daapd/files/forked-daapd.init b/sound/forked-daapd/files/forked-daapd.init
new file mode 100644 (file)
index 0000000..3ae38f9
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=99
+BIN=/usr/sbin/forked-daapd
+PID=/var/run/forked-daapd.pid
+SSD=start-stop-daemon
+
+start() {
+        $SSD -p $PID -S -x $BIN -- -P $PID
+}
+       
+stop() {
+        $SSD -p $PID -K -s SIGINT
+}
diff --git a/sound/forked-daapd/patches/010-include_pregen.patch b/sound/forked-daapd/patches/010-include_pregen.patch
new file mode 100644 (file)
index 0000000..2518dda
--- /dev/null
@@ -0,0 +1,14782 @@
+diff --git a/src/pregen/DAAP.u b/src/pregen/DAAP.u
+new file mode 100644
+index 0000000..3de527b
+--- /dev/null
++++ b/src/pregen/DAAP.u
+@@ -0,0 +1,6 @@
++DAAPParser.c : DAAP.g
++./DAAP.tokens : DAAP.g
++DAAPParser.h : DAAP.g
++DAAPLexer.c : DAAP.g
++DAAPLexer.h : DAAP.g
++ANTLR_PRODUCTS += DAAPParser.c ./DAAP.tokens DAAPParser.h DAAPLexer.c DAAPLexer.h 
+\ No newline at end of file
+diff --git a/src/pregen/DAAP2SQL.c b/src/pregen/DAAP2SQL.c
+new file mode 100644
+index 0000000..3f94589
+--- /dev/null
++++ b/src/pregen/DAAP2SQL.c
+@@ -0,0 +1,929 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP2SQL.g
++ *     -                            On : 2014-09-30 21:42:43
++ *     -           for the tree parser : DAAP2SQLTreeParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 what the grammar programmer asked us to put at the top of every file.
++ */
++
++      #include <stdio.h>
++      #include <stdlib.h>
++      #include <string.h>
++      #include <limits.h>
++      #include <errno.h>
++
++      #include "logger.h"
++      #include "db.h"
++      #include "daap_query.h"
++
++/* End of Header action.
++ * =============================================================================
++ */
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "DAAP2SQL.h"
++/* ----------------------------------------- */
++
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pDAAP2SQL_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pDAAP2SQL_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pDAAP2SQL_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pDAAP2SQL_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++/* Macros for accessing things in the parser
++ */
++ 
++#undef            PARSER
++#undef            RECOGNIZER              
++#undef            HAVEPARSEDRULE
++#undef            INPUT
++#undef            STRSTREAM
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            MATCHT
++#undef            MATCHANYT
++#undef            FOLLOWSTACK
++#undef            FOLLOWPUSH
++#undef            FOLLOWPOP
++#undef            PRECOVER
++#undef            PREPORTERROR
++#undef            LA
++#undef            LT
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            PERRORRECOVERY
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            RECOVERFROMMISMATCHEDSET
++#undef            RECOVERFROMMISMATCHEDELEMENT
++#undef            BACKTRACKING
++#undef      ADAPTOR
++#undef            RULEMEMO            
++#undef                SEEK    
++#undef                INDEX
++#undef                DBG
++
++#define           PARSER                                                      ctx->pTreeParser  
++#define           RECOGNIZER                                          PARSER->rec
++#define               PSRSTATE                                                RECOGNIZER->state
++#define           HAVEPARSEDRULE(r)                           RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define           INPUT                                                       PARSER->ctnstream
++#define               ISTREAM                                                 INPUT->tnstream->istream
++#define           STRSTREAM                                           INPUT->tnstream
++#define           HASEXCEPTION()                                      (PSRSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                                           PSRSTATE->exception
++#define           MATCHT(t, fs)                                       RECOGNIZER->match(RECOGNIZER, t, fs)
++#define           MATCHANYT()                                         RECOGNIZER->matchAny(RECOGNIZER)
++#define           FOLLOWSTACK                                     PSRSTATE->following
++#define           FOLLOWPUSH(x)                                       FOLLOWSTACK->push(FOLLOWSTACK, ((void *)(&(x))), NULL)
++#define           FOLLOWPOP()                                         FOLLOWSTACK->pop(FOLLOWSTACK)
++#define           PRECOVER()                                          RECOGNIZER->recover(RECOGNIZER)
++#define           PREPORTERROR()                                      RECOGNIZER->reportError(RECOGNIZER)
++#define           LA(n)                                                       ISTREAM->_LA(ISTREAM, n)
++#define           LT(n)                                                       INPUT->tnstream->_LT(INPUT->tnstream, n)
++#define           CONSTRUCTEX()                                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           CONSUME()                                           ISTREAM->consume(ISTREAM)
++#define           MARK()                                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                                        ISTREAM->rewindLast(ISTREAM)
++#define           PERRORRECOVERY                                      PSRSTATE->errorRecovery
++#define           FAILEDFLAG                                          PSRSTATE->failed
++#define           HASFAILED()                                         (FAILEDFLAG == ANTLR3_TRUE)
++#define           BACKTRACKING                                        PSRSTATE->backtracking
++#define           RECOVERFROMMISMATCHEDSET(s)         RECOGNIZER->recoverFromMismatchedSet(RECOGNIZER, s)
++#define           RECOVERFROMMISMATCHEDELEMENT(e)     RECOGNIZER->recoverFromMismatchedElement(RECOGNIZER, s)
++#define     ADAPTOR                         INPUT->adaptor
++#define               RULEMEMO                                                PSRSTATE->ruleMemo
++#define               SEEK(n)                                                 ISTREAM->seek(ISTREAM, n)
++#define               INDEX()                                                 ISTREAM->index(ISTREAM)
++#define               DBG                                                             RECOGNIZER->debugger
++
++
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++
++/** \brief Table of all token names in symbolic order, mainly used for
++ *         error reporting.
++ */
++pANTLR3_UINT8   DAAP2SQLTokenNames[8+4]
++     = {
++        (pANTLR3_UINT8) "<invalid>",       /* String to print to indicate an invalid token */
++        (pANTLR3_UINT8) "<EOR>",
++        (pANTLR3_UINT8) "<DOWN>", 
++        (pANTLR3_UINT8) "<UP>", 
++        (pANTLR3_UINT8) "NEWLINE",
++        (pANTLR3_UINT8) "OPOR",
++        (pANTLR3_UINT8) "OPAND",
++        (pANTLR3_UINT8) "LPAR",
++        (pANTLR3_UINT8) "RPAR",
++        (pANTLR3_UINT8) "STR",
++        (pANTLR3_UINT8) "QUOTE",
++        (pANTLR3_UINT8) "ESCAPED"
++       };
++
++        
++
++// Forward declare the locally static matching functions we have generated.
++//
++static pANTLR3_STRING query    (pDAAP2SQL ctx);
++static DAAP2SQL_expr_return   expr    (pDAAP2SQL ctx);
++static void   DAAP2SQLFree(pDAAP2SQL ctx);
++/* For use in tree output where we are accumulating rule labels via label += ruleRef
++ * we need a function that knows how to free a return scope when the list is destroyed. 
++ * We cannot just use ANTLR3_FREE because in debug tracking mode, this is a macro.
++ */
++static        void ANTLR3_CDECL freeScope(void * scope)
++{
++    ANTLR3_FREE(scope);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "DAAP2SQL.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++/** \brief Create a new DAAP2SQL parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pDAAP2SQL
++DAAP2SQLNew   (pANTLR3_COMMON_TREE_NODE_STREAM instream)
++{
++      // See if we can create a new parser with the standard constructor
++      //
++      return DAAP2SQLNewSSD(instream, NULL);
++}
++
++/** \brief Create a new DAAP2SQL parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pDAAP2SQL
++DAAP2SQLNewSSD   (pANTLR3_COMMON_TREE_NODE_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pDAAP2SQL ctx;        /* Context structure we will build and return   */
++    
++    ctx       = (pDAAP2SQL) ANTLR3_CALLOC(1, sizeof(DAAP2SQL));
++    
++    if        (ctx == NULL)
++    {
++              // Failed to allocate memory for parser context
++              //
++        return  NULL;
++    }
++    
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * the base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 parser function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in DAAP2SQL.h here, in order that you can get a sense
++     * of what goes where.
++     */
++
++    /* Create a base Tree parser/recognizer, using the supplied tree node stream
++     */
++    ctx->pTreeParser          = antlr3TreeParserNewStream(ANTLR3_SIZE_HINT, instream, state);
++    /* Install the implementation of our DAAP2SQL interface
++     */
++    ctx->query        = query;
++    ctx->expr = expr;
++    ctx->free                 = DAAP2SQLFree;
++    ctx->getGrammarFileName   = getGrammarFileName;
++    
++    /* Install the scope pushing methods.
++     */
++
++        
++    
++
++      
++    /* Install the token table
++     */
++    PSRSTATE->tokenNames   = DAAP2SQLTokenNames;
++    
++    
++    /* Return the newly built parser to the caller
++     */
++    return  ctx;
++}
++
++/** Free the parser resources
++ */
++ static void
++ DAAP2SQLFree(pDAAP2SQL ctx)
++ {
++    /* Free any scope memory
++     */
++    
++        
++      // Free this parser
++      //
++    ctx->pTreeParser->free(ctx->pTreeParser);
++    ANTLR3_FREE(ctx);
++
++    /* Everything is released, so we can return
++     */
++    return;
++ }
++ 
++/** Return token names used by this tree parser
++ *
++ * The returned pointer is used as an index into the token names table (using the token 
++ * number as the index).
++ * 
++ * \return Pointer to first char * in the table.
++ */
++static pANTLR3_UINT8    *getTokenNames() 
++{
++        return DAAP2SQLTokenNames; 
++}
++
++
++      struct dmap_query_field_map {
++        char *dmap_field;
++        char *db_col;
++        int as_int;
++      };
++
++      /* gperf static hash, daap_query.gperf */
++      #include "daap_query_hash.c"
++
++    
++/* Declare the bitsets
++ */
++
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_query70  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_query70_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_query70     = { FOLLOW_expr_in_query70_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OPAND_in_expr95  */
++static        ANTLR3_BITWORD FOLLOW_OPAND_in_expr95_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_OPAND_in_expr95     = { FOLLOW_OPAND_in_expr95_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr101  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr101_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000260) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr101     = { FOLLOW_expr_in_expr101_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr107  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr107_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr107     = { FOLLOW_expr_in_expr107_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OPOR_in_expr118  */
++static        ANTLR3_BITWORD FOLLOW_OPOR_in_expr118_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_OPOR_in_expr118     = { FOLLOW_OPOR_in_expr118_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr124  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr124_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000260) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr124     = { FOLLOW_expr_in_expr124_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr130  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr130_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr130     = { FOLLOW_expr_in_expr130_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STR_in_expr140  */
++static        ANTLR3_BITWORD FOLLOW_STR_in_expr140_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_STR_in_expr140      = { FOLLOW_STR_in_expr140_bits, 1       };
++     
++
++ 
++ 
++/* ==============================================
++ * Parsing rules
++ */
++/** 
++ * $ANTLR start query
++ * DAAP2SQL.g:50:1: query returns [ pANTLR3_STRING result ] : e= expr ;
++ */
++static pANTLR3_STRING
++query(pDAAP2SQL ctx)
++{   
++    pANTLR3_STRING result = NULL;
++
++    DAAP2SQL_expr_return e;
++    #undef    RETURN_TYPE_e
++    #define   RETURN_TYPE_e DAAP2SQL_expr_return
++
++    /* Initialize rule variables
++     */
++
++
++     result= NULL; 
++    {
++        // DAAP2SQL.g:52:2: (e= expr )
++        // DAAP2SQL.g:52:4: e= expr
++        {
++            FOLLOWPUSH(FOLLOW_expr_in_query70);
++            e=expr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++
++            {
++
++                                      if (!e.valid)
++                                      {
++                                              result= NULL;
++                                      }
++                                      else
++                                      {
++                                              result= e.result->factory->newRaw(e.result->factory);
++                                              result->append8(result, "(");
++                                              result->appendS(result, e.result);
++                                              result->append8(result, ")");
++                                      }
++                              
++            }
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulequeryEx; /* Prevent compiler warnings */
++    rulequeryEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return result;
++}
++/* $ANTLR end query */
++
++/** 
++ * $ANTLR start expr
++ * DAAP2SQL.g:68:1: expr returns [ pANTLR3_STRING result, int valid ] : ( ^( OPAND a= expr b= expr ) | ^( OPOR a= expr b= expr ) | STR );
++ */
++static DAAP2SQL_expr_return
++expr(pDAAP2SQL ctx)
++{   
++    DAAP2SQL_expr_return retval;
++
++    pANTLR3_BASE_TREE    STR1;
++    DAAP2SQL_expr_return a;
++    #undef    RETURN_TYPE_a
++    #define   RETURN_TYPE_a DAAP2SQL_expr_return
++
++    DAAP2SQL_expr_return b;
++    #undef    RETURN_TYPE_b
++    #define   RETURN_TYPE_b DAAP2SQL_expr_return
++
++    /* Initialize rule variables
++     */
++
++
++     retval.result= NULL; retval.valid= 1; 
++    STR1       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        {
++            //  DAAP2SQL.g:70:2: ( ^( OPAND a= expr b= expr ) | ^( OPOR a= expr b= expr ) | STR )
++            
++            ANTLR3_UINT32 alt1;
++
++            alt1=3;
++
++            switch ( LA(1) ) 
++            {
++            case OPAND:
++              {
++                      alt1=1;
++              }
++                break;
++            case OPOR:
++              {
++                      alt1=2;
++              }
++                break;
++            case STR:
++              {
++                      alt1=3;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 1;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleexprEx;
++            }
++
++            switch (alt1) 
++            {
++              case 1:
++                  // DAAP2SQL.g:70:4: ^( OPAND a= expr b= expr )
++                  {
++                       MATCHT(OPAND, &FOLLOW_OPAND_in_expr95); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr101);
++                      a=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr107);
++                      b=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!a.valid || !b.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= a.result->factory->newRaw(a.result->factory);
++                                                      retval.result->append8(retval.result, "(");
++                                                      retval.result->appendS(retval.result, a.result);
++                                                      retval.result->append8(retval.result, " AND ");
++                                                      retval.result->appendS(retval.result, b.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // DAAP2SQL.g:86:4: ^( OPOR a= expr b= expr )
++                  {
++                       MATCHT(OPOR, &FOLLOW_OPOR_in_expr118); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr124);
++                      a=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr130);
++                      b=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!a.valid || !b.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= a.result->factory->newRaw(a.result->factory);
++                                                      retval.result->append8(retval.result, "(");
++                                                      retval.result->appendS(retval.result, a.result);
++                                                      retval.result->append8(retval.result, " OR ");
++                                                      retval.result->appendS(retval.result, b.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 3:
++                  // DAAP2SQL.g:102:4: STR
++                  {
++                      STR1 = (pANTLR3_BASE_TREE) MATCHT(STR, &FOLLOW_STR_in_expr140); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              pANTLR3_STRING str;
++                                              pANTLR3_UINT8 field;
++                                              pANTLR3_UINT8 val;
++                                              pANTLR3_UINT8 escaped;
++                                              ANTLR3_UINT8 op;
++                                              int neg_op;
++                                              const struct dmap_query_field_map *dqfm;
++                                              char *end;
++                                              long long llval;
++
++                                              escaped = NULL;
++
++                                              retval.result= (STR1->getText(STR1))->factory->newRaw((STR1->getText(STR1))->factory);
++
++                                              str = (STR1->getText(STR1))->toUTF8((STR1->getText(STR1)));
++
++                                              /* NOTE: the lexer delivers the string without quotes
++                                              which may not be obvious from the grammar due to embedded code
++                                              */
++
++                                              /* Make daap.songalbumid:0 a no-op */
++                                              if (strcmp((char *)str->chars, "daap.songalbumid:0") == 0)
++                                              {
++                                                      retval.result->append8(retval.result, "1 = 1");
++
++                                                      goto STR_out;
++                                              }
++
++                                              field = str->chars;
++
++                                              val = field;
++                                              while ((*val != '\0') && ((*val == '.')
++                                                      || (*val == '-')
++                                                      || ((*val >= 'a') && (*val <= 'z'))
++                                                      || ((*val >= 'A') && (*val <= 'Z'))
++                                                      || ((*val >= '0') && (*val <= '9'))))
++                                              {
++                                                      val++;
++                                              }
++
++                                              if (*field == '\0')
++                                              {
++                                                      DPRINTF(E_LOG, L_DAAP, "No field name found in clause '%s'\n", field);
++                                                      retval.valid= 0;
++                                                      goto STR_result_valid_0; /* ABORT */
++                                              }
++
++                                              if (*val == '\0')
++                                              {
++                                                      DPRINTF(E_LOG, L_DAAP, "No operator found in clause '%s'\n", field);
++                                                      retval.valid= 0;
++                                                      goto STR_result_valid_0; /* ABORT */
++                                              }
++
++                                              op = *val;
++                                              *val = '\0';
++                                              val++;
++
++                                              if (op == '!')
++                                              {
++                                                      if (*val == '\0')
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "Negation found but operator missing in clause '%s%c'\n", field, op);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      neg_op = 1;
++                                                      op = *val;
++                                                      val++;
++                                              }
++                                              else
++                                                      neg_op = 0;
++
++                                              /* Lookup DMAP field in the query field map */
++                                              dqfm = daap_query_field_lookup((char *)field, strlen((char *)field));
++                                              if (!dqfm)
++                                              {
++                                                      DPRINTF(E_LOG, L_DAAP, "DMAP field '%s' is not a valid field in queries\n", field);
++                                                      retval.valid= 0;
++                                                      goto STR_result_valid_0; /* ABORT */
++                                              }
++
++                                              /* Empty values OK for string fields, NOK for integer */
++                                              if (*val == '\0')
++                                              {
++                                                      if (dqfm->as_int)
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "No value given in clause '%s%s%c'\n", field, (neg_op) ? "!" : "", op);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      /* Need to check against NULL too */
++                                                      if (op == ':')
++                                                              retval.result->append8(retval.result, "(");
++                                              }
++
++                                              retval.result->append8(retval.result, dqfm->db_col);
++
++                                              /* Int field: check integer conversion */
++                                              if (dqfm->as_int)
++                                              {
++                                                      errno = 0;
++                                                      llval = strtoll((const char *)val, &end, 10);
++
++                                                      if (((errno == ERANGE) && ((llval == LLONG_MAX) || (llval == LLONG_MIN)))
++                                                              || ((errno != 0) && (llval == 0)))
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "Value '%s' in clause '%s%s%c%s' does not convert to an integer type\n",
++                                                              val, field, (neg_op) ? "!" : "", op, val);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      if (end == (char *)val)
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "Value '%s' in clause '%s%s%c%s' does not represent an integer value\n",
++                                                              val, field, (neg_op) ? "!" : "", op, val);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      *end = '\0'; /* Cut out potential garbage - we're being kind */
++                                              }
++                                              /* String field: escape string, check for '*' */
++                                              else
++                                              {
++                                                      if (op != ':')
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "Operation '%c' not valid for string values\n", op);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      escaped = (pANTLR3_UINT8)db_escape_string((char *)val);
++                                                      if (!escaped)
++                                                      {
++                                                              DPRINTF(E_LOG, L_DAAP, "Could not escape value\n");
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                      }
++
++                                                      val = escaped;
++
++                                                      if (val[0] == '*')
++                                                      {
++                                                              op = '%';
++                                                              val[0] = '%';
++                                                      }
++
++                                                      if (val[strlen((char *)val) - 1] == '*')
++                                                      {
++                                                              op = '%';
++                                                              val[strlen((char *)val) - 1] = '%';
++                                                      }
++                                              }
++
++                                              switch(op)
++                                              {
++                                                      case ':':
++                                                              if (neg_op)
++                                                                      retval.result->append8(retval.result, " <> ");
++                                                              else
++                                                                      retval.result->append8(retval.result, " = ");
++                                                              break;
++
++                                                      case '+':
++                                                              if (neg_op)
++                                                                      retval.result->append8(retval.result, " <= ");
++                                                              else
++                                                                      retval.result->append8(retval.result, " > ");
++                                                              break;
++
++                                                      case '-':
++                                                              if (neg_op)
++                                                                      retval.result->append8(retval.result, " >= ");
++                                                              else
++                                                                      retval.result->append8(retval.result, " < ");
++                                                              break;
++
++                                                      case '%':
++                                                              retval.result->append8(retval.result, " LIKE ");
++                                                              break;
++
++                                                      default:
++                                                              if (neg_op)
++                                                                      DPRINTF(E_LOG, L_DAAP, "Missing or unknown operator '%c' in clause '%s!%c%s'\n", op, field, op, val);
++                                                              else
++                                                                      DPRINTF(E_LOG, L_DAAP, "Unknown operator '%c' in clause '%s%c%s'\n", op, field, op, val);
++                                                              retval.valid= 0;
++                                                              goto STR_result_valid_0; /* ABORT */
++                                                              break;
++                                              }
++
++                                              if (!dqfm->as_int)
++                                                      retval.result->append8(retval.result, "'");
++                              
++                                              retval.result->append8(retval.result, (const char *)val);
++                              
++                                              if (!dqfm->as_int)
++                                                      retval.result->append8(retval.result, "'");
++
++                                              /* For empty string value, we need to check against NULL too */
++                                              if ((*val == '\0') && (op == ':'))
++                                              {
++                                                      if (neg_op)
++                                                              retval.result->append8(retval.result, " AND ");
++                                                      else
++                                                              retval.result->append8(retval.result, " OR ");
++
++                                                      retval.result->append8(retval.result, dqfm->db_col);
++
++                                                      if (neg_op)
++                                                              retval.result->append8(retval.result, " IS NOT NULL");
++                                                      else
++                                                              retval.result->append8(retval.result, " IS NULL");
++
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++
++                                              STR_result_valid_0: /* bail out label */
++                                                      ;
++
++                                              if (escaped)
++                                                      free(escaped);
++
++                                              STR_out: /* get out of here */
++                                                      ;
++                                      
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleexprEx; /* Prevent compiler warnings */
++    ruleexprEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end expr */
++/* End of parsing rules
++ * ==============================================
++ */
++
++/* ==============================================
++ * Syntactic predicates
++ */
++/* End of syntactic predicates
++ * ==============================================
++ */
++
++ 
++ 
++
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/DAAP2SQL.h b/src/pregen/DAAP2SQL.h
+new file mode 100644
+index 0000000..e170f6c
+--- /dev/null
++++ b/src/pregen/DAAP2SQL.h
+@@ -0,0 +1,195 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP2SQL.g
++ *     -                            On : 2014-09-30 21:42:43
++ *     -           for the tree parser : DAAP2SQLTreeParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The tree parser DAAP2SQL has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pDAAP2SQL, which is returned from a call to DAAP2SQLNew().
++ *
++ * The methods in pDAAP2SQL are  as follows:
++ *
++ *  - pANTLR3_STRING      pDAAP2SQL->query(pDAAP2SQL)
++ *  - DAAP2SQL_expr_return      pDAAP2SQL->expr(pDAAP2SQL)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _DAAP2SQL_H
++#define _DAAP2SQL_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct DAAP2SQL_Ctx_struct DAAP2SQL, * pDAAP2SQL;
++
++
++
++      #include <stdio.h>
++      #include <stdlib.h>
++      #include <string.h>
++      #include <limits.h>
++      #include <errno.h>
++
++      #include "logger.h"
++      #include "db.h"
++      #include "daap_query.h"
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++typedef struct DAAP2SQL_expr_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    pANTLR3_STRING result;
++    int valid;
++}
++    DAAP2SQL_expr_return;
++
++
++
++/** Context tracking structure for DAAP2SQL
++ */
++struct DAAP2SQL_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_TREE_PARSER           pTreeParser;
++
++
++     pANTLR3_STRING (*query)  (struct DAAP2SQL_Ctx_struct * ctx);
++     DAAP2SQL_expr_return (*expr)     (struct DAAP2SQL_Ctx_struct * ctx);
++    // Delegated rules
++    const char * (*getGrammarFileName)();
++    void          (*free)   (struct DAAP2SQL_Ctx_struct * ctx);
++        
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pDAAP2SQL DAAP2SQLNew         (pANTLR3_COMMON_TREE_NODE_STREAM instream);
++ANTLR3_API pDAAP2SQL DAAP2SQLNewSSD      (pANTLR3_COMMON_TREE_NODE_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the tree parser will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STR      9
++#define QUOTE      10
++#define NEWLINE      4
++#define LPAR      7
++#define OPOR      5
++#define RPAR      8
++#define ESCAPED      11
++#define OPAND      6
++#define EOF      -1
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for DAAP2SQL
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
+diff --git a/src/pregen/DAAP2SQL.u b/src/pregen/DAAP2SQL.u
+new file mode 100644
+index 0000000..385d80b
+--- /dev/null
++++ b/src/pregen/DAAP2SQL.u
+@@ -0,0 +1,5 @@
++DAAP2SQL.g: DAAP.tokens
++DAAP2SQL.c : DAAP2SQL.g
++./DAAP2SQL.tokens : DAAP2SQL.g
++DAAP2SQL.h : DAAP2SQL.g
++ANTLR_PRODUCTS += DAAP2SQL.c ./DAAP2SQL.tokens DAAP2SQL.h 
+\ No newline at end of file
+diff --git a/src/pregen/DAAPLexer.c b/src/pregen/DAAPLexer.c
+new file mode 100644
+index 0000000..12e7ef3
+--- /dev/null
++++ b/src/pregen/DAAPLexer.c
+@@ -0,0 +1,1101 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP.g
++ *     -                            On : 2014-09-30 21:42:40
++ *     -                 for the lexer : DAAPLexerLexer *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
++
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "DAAPLexer.h"
++/* ----------------------------------------- */
++
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pDAAPLexer_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pDAAPLexer_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pDAAPLexer_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pDAAPLexer_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++ 
++/* Macros for accessing things in a lexer
++ */
++#undef            LEXER
++#undef            RECOGNIZER              
++#undef            RULEMEMO                
++#undef            GETCHARINDEX
++#undef            GETLINE
++#undef            GETCHARPOSITIONINLINE
++#undef            EMIT
++#undef            EMITNEW
++#undef            MATCHC
++#undef            MATCHS
++#undef            MATCHRANGE
++#undef            LTOKEN
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            INPUT
++#undef            STRSTREAM
++#undef            LA
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            LRECOVER
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            BACKTRACKING
++#undef                MATCHANY
++#undef                MEMOIZE
++#undef                HAVEPARSEDRULE
++#undef                GETTEXT
++#undef                INDEX
++#undef                SEEK
++#undef                PUSHSTREAM
++#undef                POPSTREAM
++#undef                SETTEXT
++#undef                SETTEXT8
++
++#define           LEXER                                       ctx->pLexer
++#define           RECOGNIZER                      LEXER->rec
++#define               LEXSTATE                                RECOGNIZER->state
++#define               TOKSOURCE                               LEXSTATE->tokSource
++#define           GETCHARINDEX()                      LEXER->getCharIndex(LEXER)
++#define           GETLINE()                           LEXER->getLine(LEXER)
++#define           GETTEXT()                           LEXER->getText(LEXER)
++#define           GETCHARPOSITIONINLINE() LEXER->getCharPositionInLine(LEXER)
++#define           EMIT()                                      LEXSTATE->type = _type; LEXER->emit(LEXER)
++#define           EMITNEW(t)                          LEXER->emitNew(LEXER, t)
++#define           MATCHC(c)                           LEXER->matchc(LEXER, c)
++#define           MATCHS(s)                           LEXER->matchs(LEXER, s)
++#define           MATCHRANGE(c1,c2)       LEXER->matchRange(LEXER, c1, c2)
++#define           MATCHANY()                          LEXER->matchAny(LEXER)
++#define           LTOKEN                              LEXSTATE->token
++#define           HASFAILED()                         (LEXSTATE->failed == ANTLR3_TRUE)
++#define           BACKTRACKING                        LEXSTATE->backtracking
++#define           FAILEDFLAG                          LEXSTATE->failed
++#define           INPUT                                       LEXER->input
++#define           STRSTREAM                           INPUT
++#define               ISTREAM                                 INPUT->istream
++#define               INDEX()                                 ISTREAM->index(ISTREAM)
++#define               SEEK(n)                                 ISTREAM->seek(ISTREAM, n)
++#define           EOF_TOKEN                           &(LEXSTATE->tokSource->eofToken)
++#define           HASEXCEPTION()                      (LEXSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                           LEXSTATE->exception
++#define           CONSTRUCTEX()                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           LRECOVER()                          LEXER->recover(LEXER)
++#define           MARK()                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                        ISTREAM->rewindLast(ISTREAM)
++#define               MEMOIZE(ri,si)                  RECOGNIZER->memoize(RECOGNIZER, ri, si)
++#define               HAVEPARSEDRULE(r)               RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define               PUSHSTREAM(str)                 LEXER->pushCharStream(LEXER, str)
++#define               POPSTREAM()                             LEXER->popCharStream(LEXER)
++#define               SETTEXT(str)                    LEXSTATE->text = str
++#define               SKIP()                                  LEXSTATE->token = &(TOKSOURCE->skipToken)
++#define               USER1                                   LEXSTATE->user1
++#define               USER2                                   LEXSTATE->user2
++#define               USER3                                   LEXSTATE->user3
++#define               CUSTOM                                  LEXSTATE->custom
++#define               RULEMEMO                                LEXSTATE->ruleMemo
++#define               DBG                                             RECOGNIZER->debugger
++
++/* If we have been told we can rely on the standard 8 bit or 16 bit input
++ * stream, then we can define our macros to use the direct pointers
++ * in the input object, which is much faster than indirect calls. This
++ * is really only significant to lexers with a lot of fragment rules (which
++ * do not place LA(1) in a temporary at the moment) and even then
++ * only if there is a lot of input (order of say 1M or so).
++ */
++#if   defined(ANTLR3_INLINE_INPUT_ASCII) || defined(ANTLR3_INLINE_INPUT_UTF16)
++
++# ifdef       ANTLR3_INLINE_INPUT_ASCII
++
++/* 8 bit "ASCII" (actually any 8 bit character set) */
++
++#  define         NEXTCHAR                    ((pANTLR3_UINT8)(INPUT->nextChar))
++#  define         DATAP                               ((pANTLR3_UINT8)(INPUT->data))
++
++# else
++
++#  define         NEXTCHAR                    ((pANTLR3_UINT16)(INPUT->nextChar)) 
++#  define         DATAP                               ((pANTLR3_UINT16)(INPUT->data))
++
++# endif
++
++# define          LA(n) ((NEXTCHAR + n) > (DATAP + INPUT->sizeBuf) ? ANTLR3_CHARSTREAM_EOF : (ANTLR3_UCHAR)(*(NEXTCHAR + n - 1)))
++# define          CONSUME()                                                                                   \
++{                                                                                                                                     \
++    if        (NEXTCHAR < (DATAP + INPUT->sizeBuf))                                           \
++    {                                                                                                                         \
++              INPUT->charPositionInLine++;                                                            \
++              if  ((ANTLR3_UCHAR)(*NEXTCHAR) == INPUT->newlineChar)           \
++              {                                                                                                                       \
++                      INPUT->line++;                                                                                  \
++                      INPUT->charPositionInLine       = 0;                                            \
++                      INPUT->currentLine              = (void *)(NEXTCHAR + 1);               \
++              }                                                                                                                       \
++              INPUT->nextChar = (void *)(NEXTCHAR + 1);                                       \
++    }                                                                                                                         \
++}
++
++#else
++
++// Pick up the input character by calling the input stream implementation.
++//
++#define           CONSUME()                           INPUT->istream->consume(INPUT->istream)
++#define           LA(n)                                       INPUT->istream->_LA(INPUT->istream, n)
++
++#endif
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++/* Forward declare the locally static matching functions we have generated and any predicate functions.
++ */
++static ANTLR3_INLINE  void    mQUOTE    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mLPAR    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mRPAR    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mOPAND    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mOPOR    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mNEWLINE    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mSTR    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mESCAPED    (pDAAPLexer ctx);
++static ANTLR3_INLINE  void    mTokens    (pDAAPLexer ctx);
++static void   DAAPLexerFree(pDAAPLexer ctx);
++
++/* =========================================================================
++ * Lexer matching rules end.
++ * =========================================================================
++ */
++
++
++
++static void
++DAAPLexerFree  (pDAAPLexer ctx)
++{
++    LEXER->free(LEXER);
++    
++    ANTLR3_FREE(ctx);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "DAAP.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++
++/** \brief Create a new lexer called DAAPLexer
++ *
++ * \param[in]    instream Pointer to an initialized input stream
++ * \return 
++ *     - Success pDAAPLexer initialized for the lex start
++ *     - Fail NULL
++ */
++ANTLR3_API pDAAPLexer DAAPLexerNew         
++(pANTLR3_INPUT_STREAM instream)
++{
++      // See if we can create a new lexer with the standard constructor
++      //
++      return DAAPLexerNewSSD(instream, NULL);
++}
++
++/** \brief Create a new lexer called DAAPLexer
++ *
++ * \param[in]    instream Pointer to an initialized input stream
++ * \param[state] state Previously created shared recognizer stat
++ * \return 
++ *     - Success pDAAPLexer initialized for the lex start
++ *     - Fail NULL
++ */
++ANTLR3_API pDAAPLexer DAAPLexerNewSSD         
++(pANTLR3_INPUT_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pDAAPLexer ctx; // Context structure we will build and return
++
++    ctx = (pDAAPLexer) ANTLR3_CALLOC(1, sizeof(DAAPLexer));
++
++    if  (ctx == NULL)
++    {
++        // Failed to allocate memory for lexer context
++        return  NULL;
++    }
++
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * in base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 lexer function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in DAAPLexer.h here so you can get a sense
++     * of what goes where.
++     */
++    
++    /* Create a base lexer, using the supplied input stream
++     */
++    ctx->pLexer       = antlr3LexerNewStream(ANTLR3_SIZE_HINT, instream, state);
++    
++    /* Check that we allocated the memory correctly
++     */
++    if        (ctx->pLexer == NULL)
++    {
++              ANTLR3_FREE(ctx);
++              return  NULL;
++    }
++    /* Install the implementation of our DAAPLexer interface
++     */
++    ctx->mQUOTE       = mQUOTE;
++    ctx->mLPAR        = mLPAR;
++    ctx->mRPAR        = mRPAR;
++    ctx->mOPAND       = mOPAND;
++    ctx->mOPOR        = mOPOR;
++    ctx->mNEWLINE     = mNEWLINE;
++    ctx->mSTR = mSTR;
++    ctx->mESCAPED     = mESCAPED;
++    ctx->mTokens      = mTokens;
++    
++    /** When the nextToken() call is made to this lexer's pANTLR3_TOKEN_SOURCE
++     *  it will call mTokens() in this generated code, and will pass it the ctx
++     * pointer of this lexer, not the context of the base lexer, so store that now.
++     */
++    ctx->pLexer->ctx      = ctx;
++    
++    /**Install the token matching function
++     */
++    ctx->pLexer->mTokens = (void (*) (void *))(mTokens);
++    
++    ctx->getGrammarFileName   = getGrammarFileName;
++    ctx->free         = DAAPLexerFree;
++
++    
++    
++
++
++    /* Return the newly built lexer to the caller
++     */
++    return  ctx;
++}
++ 
++
++/* =========================================================================
++ * Functions to match the lexer grammar defined tokens from the input stream
++ */
++
++//   Comes from: 40:7: ( '\\'' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start QUOTE
++ *
++ * Looks to match the characters the constitute the token QUOTE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mQUOTE(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = QUOTE;
++       
++    
++    // DAAP.g:40:7: ( '\\'' )
++    // DAAP.g:40:9: '\\''
++    {
++        MATCHC('\''); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleQUOTEEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleQUOTEEx; /* Prevent compiler warnings */
++    ruleQUOTEEx: ;
++
++}
++// $ANTLR end QUOTE
++
++//   Comes from: 41:6: ( '(' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start LPAR
++ *
++ * Looks to match the characters the constitute the token LPAR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mLPAR(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = LPAR;
++       
++    
++    // DAAP.g:41:6: ( '(' )
++    // DAAP.g:41:8: '('
++    {
++        MATCHC('('); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleLPAREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleLPAREx; /* Prevent compiler warnings */
++    ruleLPAREx: ;
++
++}
++// $ANTLR end LPAR
++
++//   Comes from: 42:6: ( ')' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start RPAR
++ *
++ * Looks to match the characters the constitute the token RPAR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mRPAR(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = RPAR;
++       
++    
++    // DAAP.g:42:6: ( ')' )
++    // DAAP.g:42:8: ')'
++    {
++        MATCHC(')'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleRPAREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleRPAREx; /* Prevent compiler warnings */
++    ruleRPAREx: ;
++
++}
++// $ANTLR end RPAR
++
++//   Comes from: 44:7: ( '+' | ' ' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start OPAND
++ *
++ * Looks to match the characters the constitute the token OPAND
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mOPAND(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = OPAND;
++       
++    
++    // DAAP.g:44:7: ( '+' | ' ' )
++    // DAAP.g:
++    {
++        if ( LA(1) == ' ' || LA(1) == '+' )
++        {
++            CONSUME();
++
++        }
++        else 
++        {
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++            EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++
++            LRECOVER();    goto ruleOPANDEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleOPANDEx; /* Prevent compiler warnings */
++    ruleOPANDEx: ;
++
++}
++// $ANTLR end OPAND
++
++//   Comes from: 45:6: ( ',' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start OPOR
++ *
++ * Looks to match the characters the constitute the token OPOR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mOPOR(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = OPOR;
++       
++    
++    // DAAP.g:45:6: ( ',' )
++    // DAAP.g:45:8: ','
++    {
++        MATCHC(','); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleOPOREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleOPOREx; /* Prevent compiler warnings */
++    ruleOPOREx: ;
++
++}
++// $ANTLR end OPOR
++
++//   Comes from: 47:9: ( ( '\\r' )? '\\n' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start NEWLINE
++ *
++ * Looks to match the characters the constitute the token NEWLINE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mNEWLINE(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = NEWLINE;
++       
++    
++    // DAAP.g:47:9: ( ( '\\r' )? '\\n' )
++    // DAAP.g:47:11: ( '\\r' )? '\\n'
++    {
++
++        // DAAP.g:47:11: ( '\\r' )?
++        {
++            int alt1=2;
++            switch ( LA(1) ) 
++            {
++                case '\r':
++                      {
++                              alt1=1;
++                      }
++                    break;
++            }
++
++            switch (alt1) 
++            {
++              case 1:
++                  // DAAP.g:47:11: '\\r'
++                  {
++                      MATCHC('\r'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleNEWLINEEx;
++                      }
++
++
++                  }
++                  break;
++
++            }
++        }
++        MATCHC('\n'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleNEWLINEEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleNEWLINEEx; /* Prevent compiler warnings */
++    ruleNEWLINEEx: ;
++
++}
++// $ANTLR end NEWLINE
++
++//   Comes from: 55:2: ( QUOTE (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+ QUOTE )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start STR
++ *
++ * Looks to match the characters the constitute the token STR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mSTR(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++    pANTLR3_COMMON_TOKEN esc;
++    ANTLR3_UINT32 reg;
++
++
++    esc = NULL;
++
++    _type         = STR;
++       
++     pANTLR3_STRING unesc = GETTEXT()->factory->newRaw(GETTEXT()->factory); 
++    
++    // DAAP.g:55:2: ( QUOTE (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+ QUOTE )
++    // DAAP.g:55:4: QUOTE (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+ QUOTE
++    {
++        /* 55:4: QUOTE (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+ QUOTE */
++        mQUOTE(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleSTREx;
++        }
++
++        // DAAP.g:55:10: (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+
++        {
++            int cnt2=0;
++
++            for (;;)
++            {
++                int alt2=3;
++              {
++                 /* dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)
++                  */
++                  int LA2_0 = LA(1);
++                  if ( (((LA2_0 >= 0x0000) && (LA2_0 <= '&')) || ((LA2_0 >= '(') && (LA2_0 <= '[')) || ((LA2_0 >= ']') && (LA2_0 <= 0xFFFF))) ) 
++                  {
++                      alt2=1;
++                  }
++                  else if ( (LA2_0 == '\\') ) 
++                  {
++                      alt2=2;
++                  }
++
++              }
++              switch (alt2) 
++              {
++                  case 1:
++                      // DAAP.g:55:12: reg=~ ( '\\\\' | '\\'' )
++                      {
++                          reg= LA(1);
++                          if ( ((LA(1) >= 0x0000) && (LA(1) <= '&')) || ((LA(1) >= '(') && (LA(1) <= '[')) || ((LA(1) >= ']') && (LA(1) <= 0xFFFF)) )
++                          {
++                              CONSUME();
++
++                          }
++                          else 
++                          {
++                              CONSTRUCTEX();
++                              EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                              EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++
++                              LRECOVER();    goto ruleSTREx;
++                          }
++
++                          {
++                               unesc->addc(unesc, reg); 
++                          }
++
++                      }
++                      break;
++                  case 2:
++                      // DAAP.g:56:6: esc= ESCAPED
++                      {
++                          /* 56:6: esc= ESCAPED */
++                          {
++                              ANTLR3_MARKER escStart118 = GETCHARINDEX();
++                          mESCAPED(ctx ); 
++                              if  (HASEXCEPTION())
++                              {
++                                  goto ruleSTREx;
++                              }
++
++                              esc = LEXSTATE->tokFactory->newToken(LEXSTATE->tokFactory);
++                              esc->setType(esc, ANTLR3_TOKEN_INVALID);
++                              esc->setStartIndex(esc, escStart118);
++                              esc->setStopIndex(esc, GETCHARINDEX()-1);
++                              esc->input = INPUT;
++                          }
++                          {
++                               unesc->appendS(unesc, GETTEXT()); 
++                          }
++
++                      }
++                      break;
++
++                  default:
++                  
++                      if ( cnt2 >= 1 )
++                      {
++                          goto loop2;
++                      }
++                      /* mismatchedSetEx()
++                       */
++                      CONSTRUCTEX();
++                      EXCEPTION->type = ANTLR3_EARLY_EXIT_EXCEPTION;
++                      EXCEPTION->name = (void *)ANTLR3_EARLY_EXIT_NAME;
++
++
++                      goto ruleSTREx;
++              }
++              cnt2++;
++            }
++            loop2: ;  /* Jump to here if this rule does not match */
++        }
++        /* 55:4: QUOTE (reg=~ ( '\\\\' | '\\'' ) | esc= ESCAPED )+ QUOTE */
++        mQUOTE(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleSTREx;
++        }
++
++        {
++             SETTEXT(unesc); 
++        }
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleSTREx; /* Prevent compiler warnings */
++    ruleSTREx: ;
++
++    esc = NULL;
++
++}
++// $ANTLR end STR
++
++//   Comes from: 59:9: ( '\\\\' ( '\\\\' | '\\'' ) )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start ESCAPED
++ *
++ * Looks to match the characters the constitute the token ESCAPED
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mESCAPED(pDAAPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++        
++    // DAAP.g:59:9: ( '\\\\' ( '\\\\' | '\\'' ) )
++    // DAAP.g:59:11: '\\\\' ( '\\\\' | '\\'' )
++    {
++        MATCHC('\\'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleESCAPEDEx;
++        }
++
++
++        // DAAP.g:60:3: ( '\\\\' | '\\'' )
++        {
++            int alt3=2;
++            switch ( LA(1) ) 
++            {
++            case '\\':
++              {
++                      alt3=1;
++              }
++                break;
++            case '\'':
++              {
++                      alt3=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 3;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleESCAPEDEx;
++            }
++
++            switch (alt3) 
++            {
++              case 1:
++                  // DAAP.g:60:5: '\\\\'
++                  {
++                      MATCHC('\\'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleESCAPEDEx;
++                      }
++
++                      {
++                           SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\\")); 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // DAAP.g:61:5: '\\''
++                  {
++                      MATCHC('\''); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleESCAPEDEx;
++                      }
++
++                      {
++                           SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\'")); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++
++    }
++
++
++
++    // This is where rules clean up and exit
++    //
++    goto ruleESCAPEDEx; /* Prevent compiler warnings */
++    ruleESCAPEDEx: ;
++
++}
++// $ANTLR end ESCAPED
++
++/** This is the entry point in to the lexer from an object that
++ *  wants to generate the next token, such as a pCOMMON_TOKEN_STREAM
++ */
++static void 
++mTokens(pDAAPLexer ctx)
++{
++    {
++        //  DAAP.g:1:8: ( QUOTE | LPAR | RPAR | OPAND | OPOR | NEWLINE | STR )
++        
++        ANTLR3_UINT32 alt4;
++
++        alt4=7;
++
++        switch ( LA(1) ) 
++        {
++        case '\'':
++              {
++
++                      {
++                          int LA4_1 = LA(2);
++                          if ( (((LA4_1 >= 0x0000) && (LA4_1 <= '&')) || ((LA4_1 >= '(') && (LA4_1 <= 0xFFFF))) ) 
++                          {
++                              alt4=7;
++                          }
++                          else 
++                          {
++                              alt4=1;    }
++                      }
++              }
++            break;
++        case '(':
++              {
++                      alt4=2;
++              }
++            break;
++        case ')':
++              {
++                      alt4=3;
++              }
++            break;
++        case ' ':
++        case '+':
++              {
++                      alt4=4;
++              }
++            break;
++        case ',':
++              {
++                      alt4=5;
++              }
++            break;
++        case '\n':
++        case '\r':
++              {
++                      alt4=6;
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 4;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleTokensEx;
++        }
++
++        switch (alt4) 
++        {
++      case 1:
++          // DAAP.g:1:10: QUOTE
++          {
++              /* 1:10: QUOTE */
++              mQUOTE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 2:
++          // DAAP.g:1:16: LPAR
++          {
++              /* 1:16: LPAR */
++              mLPAR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 3:
++          // DAAP.g:1:21: RPAR
++          {
++              /* 1:21: RPAR */
++              mRPAR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 4:
++          // DAAP.g:1:26: OPAND
++          {
++              /* 1:26: OPAND */
++              mOPAND(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 5:
++          // DAAP.g:1:32: OPOR
++          {
++              /* 1:32: OPOR */
++              mOPOR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 6:
++          // DAAP.g:1:37: NEWLINE
++          {
++              /* 1:37: NEWLINE */
++              mNEWLINE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 7:
++          // DAAP.g:1:45: STR
++          {
++              /* 1:45: STR */
++              mSTR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++
++        }
++    }
++
++    
++    goto ruleTokensEx; /* Prevent compiler warnings */
++ruleTokensEx: ;
++}
++
++/* =========================================================================
++ * Lexer matching rules end.
++ * =========================================================================
++ */
++/* End of Lexer code
++ * ================================================
++ * ================================================
++ */ 
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/DAAPLexer.h b/src/pregen/DAAPLexer.h
+new file mode 100644
+index 0000000..ba8f58b
+--- /dev/null
++++ b/src/pregen/DAAPLexer.h
+@@ -0,0 +1,188 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP.g
++ *     -                            On : 2014-09-30 21:42:40
++ *     -                 for the lexer : DAAPLexerLexer *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The lexer DAAPLexer has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pDAAPLexer, which is returned from a call to DAAPLexerNew().
++ *
++ * As this is a generated lexer, it is unlikely you will call it 'manually'. However
++ * the methods are provided anyway.
++ * * The methods in pDAAPLexer are  as follows:
++ *
++ *  -  void      pDAAPLexer->QUOTE(pDAAPLexer)
++ *  -  void      pDAAPLexer->LPAR(pDAAPLexer)
++ *  -  void      pDAAPLexer->RPAR(pDAAPLexer)
++ *  -  void      pDAAPLexer->OPAND(pDAAPLexer)
++ *  -  void      pDAAPLexer->OPOR(pDAAPLexer)
++ *  -  void      pDAAPLexer->NEWLINE(pDAAPLexer)
++ *  -  void      pDAAPLexer->STR(pDAAPLexer)
++ *  -  void      pDAAPLexer->ESCAPED(pDAAPLexer)
++ *  -  void      pDAAPLexer->Tokens(pDAAPLexer)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _DAAPLexer_H
++#define _DAAPLexer_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct DAAPLexer_Ctx_struct DAAPLexer, * pDAAPLexer;
++
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++
++/** Context tracking structure for DAAPLexer
++ */
++struct DAAPLexer_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_LEXER    pLexer;
++
++
++     void (*mQUOTE)   (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mLPAR)    (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mRPAR)    (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mOPAND)   (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mOPOR)    (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mNEWLINE) (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mSTR)     (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mESCAPED) (struct DAAPLexer_Ctx_struct * ctx);
++     void (*mTokens)  (struct DAAPLexer_Ctx_struct * ctx);    const char * (*getGrammarFileName)();
++    void          (*free)   (struct DAAPLexer_Ctx_struct * ctx);
++        
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pDAAPLexer DAAPLexerNew         (pANTLR3_INPUT_STREAM instream);
++ANTLR3_API pDAAPLexer DAAPLexerNewSSD      (pANTLR3_INPUT_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the lexer will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STR      9
++#define QUOTE      10
++#define NEWLINE      4
++#define LPAR      7
++#define OPOR      5
++#define RPAR      8
++#define ESCAPED      11
++#define OPAND      6
++#define EOF      -1
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for DAAPLexer
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
+diff --git a/src/pregen/DAAPParser.c b/src/pregen/DAAPParser.c
+new file mode 100644
+index 0000000..6d0239d
+--- /dev/null
++++ b/src/pregen/DAAPParser.c
+@@ -0,0 +1,1014 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP.g
++ *     -                            On : 2014-09-30 21:42:39
++ *     -                for the parser : DAAPParserParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
++
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "DAAPParser.h"
++/* ----------------------------------------- */
++
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pDAAPParser_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pDAAPParser_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pDAAPParser_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pDAAPParser_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++/* Macros for accessing things in the parser
++ */
++ 
++#undef            PARSER                  
++#undef            RECOGNIZER              
++#undef            HAVEPARSEDRULE
++#undef                MEMOIZE
++#undef            INPUT
++#undef            STRSTREAM
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            MATCHT
++#undef            MATCHANYT
++#undef            FOLLOWSTACK
++#undef            FOLLOWPUSH
++#undef            FOLLOWPOP
++#undef            PRECOVER
++#undef            PREPORTERROR
++#undef            LA
++#undef            LT
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            PERRORRECOVERY
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            RECOVERFROMMISMATCHEDSET
++#undef            RECOVERFROMMISMATCHEDELEMENT
++#undef                INDEX
++#undef      ADAPTOR
++#undef                SEEK
++#undef            RULEMEMO                
++#undef                DBG
++
++#define           PARSER                                                      ctx->pParser  
++#define           RECOGNIZER                                          PARSER->rec
++#define               PSRSTATE                                                RECOGNIZER->state
++#define           HAVEPARSEDRULE(r)                           RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define               MEMOIZE(ri,si)                                  RECOGNIZER->memoize(RECOGNIZER, ri, si)
++#define           INPUT                                                       PARSER->tstream
++#define           STRSTREAM                                           INPUT
++#define               ISTREAM                                                 INPUT->istream
++#define               INDEX()                                                 ISTREAM->index(INPUT->istream)
++#define           HASEXCEPTION()                                      (PSRSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                                           PSRSTATE->exception
++#define           MATCHT(t, fs)                                       RECOGNIZER->match(RECOGNIZER, t, fs)
++#define           MATCHANYT()                                         RECOGNIZER->matchAny(RECOGNIZER)
++#define           FOLLOWSTACK                                     PSRSTATE->following
++#define           FOLLOWPUSH(x)                                       FOLLOWSTACK->push(FOLLOWSTACK, ((void *)(&(x))), NULL)
++#define           FOLLOWPOP()                                         FOLLOWSTACK->pop(FOLLOWSTACK)
++#define           PRECOVER()                                          RECOGNIZER->recover(RECOGNIZER)
++#define           PREPORTERROR()                                      RECOGNIZER->reportError(RECOGNIZER)
++#define           LA(n)                                                       INPUT->istream->_LA(ISTREAM, n)
++#define           LT(n)                                                       INPUT->_LT(INPUT, n)
++#define           CONSTRUCTEX()                                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           CONSUME()                                           ISTREAM->consume(ISTREAM)
++#define           MARK()                                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                                        ISTREAM->rewindLast(ISTREAM)
++#define               SEEK(n)                                                 ISTREAM->seek(ISTREAM, n)
++#define           PERRORRECOVERY                                      PSRSTATE->errorRecovery
++#define           FAILEDFLAG                                          PSRSTATE->failed
++#define           HASFAILED()                                         (FAILEDFLAG == ANTLR3_TRUE)
++#define           BACKTRACKING                                        PSRSTATE->backtracking
++#define           RECOVERFROMMISMATCHEDSET(s)         RECOGNIZER->recoverFromMismatchedSet(RECOGNIZER, s)
++#define           RECOVERFROMMISMATCHEDELEMENT(e)     RECOGNIZER->recoverFromMismatchedElement(RECOGNIZER, s)
++#define     ADAPTOR                         ctx->adaptor
++#define               RULEMEMO                                                PSRSTATE->ruleMemo
++#define               DBG                                                             RECOGNIZER->debugger
++
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++
++/** \brief Table of all token names in symbolic order, mainly used for
++ *         error reporting.
++ */
++pANTLR3_UINT8   DAAPParserTokenNames[8+4]
++     = {
++        (pANTLR3_UINT8) "<invalid>",       /* String to print to indicate an invalid token */
++        (pANTLR3_UINT8) "<EOR>",
++        (pANTLR3_UINT8) "<DOWN>", 
++        (pANTLR3_UINT8) "<UP>", 
++        (pANTLR3_UINT8) "NEWLINE",
++        (pANTLR3_UINT8) "OPOR",
++        (pANTLR3_UINT8) "OPAND",
++        (pANTLR3_UINT8) "LPAR",
++        (pANTLR3_UINT8) "RPAR",
++        (pANTLR3_UINT8) "STR",
++        (pANTLR3_UINT8) "QUOTE",
++        (pANTLR3_UINT8) "ESCAPED"
++       };
++
++        
++
++// Forward declare the locally static matching functions we have generated.
++//
++static DAAPParser_query_return        query    (pDAAPParser ctx);
++static DAAPParser_expr_return expr    (pDAAPParser ctx);
++static DAAPParser_aexpr_return        aexpr    (pDAAPParser ctx);
++static DAAPParser_crit_return crit    (pDAAPParser ctx);
++static void   DAAPParserFree(pDAAPParser ctx);
++/* For use in tree output where we are accumulating rule labels via label += ruleRef
++ * we need a function that knows how to free a return scope when the list is destroyed. 
++ * We cannot just use ANTLR3_FREE because in debug tracking mode, this is a macro.
++ */
++static        void ANTLR3_CDECL freeScope(void * scope)
++{
++    ANTLR3_FREE(scope);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "DAAP.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++/** \brief Create a new DAAPParser parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pDAAPParser
++DAAPParserNew   (pANTLR3_COMMON_TOKEN_STREAM instream)
++{
++      // See if we can create a new parser with the standard constructor
++      //
++      return DAAPParserNewSSD(instream, NULL);
++}
++
++/** \brief Create a new DAAPParser parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pDAAPParser
++DAAPParserNewSSD   (pANTLR3_COMMON_TOKEN_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pDAAPParser ctx;      /* Context structure we will build and return   */
++    
++    ctx       = (pDAAPParser) ANTLR3_CALLOC(1, sizeof(DAAPParser));
++    
++    if        (ctx == NULL)
++    {
++              // Failed to allocate memory for parser context
++              //
++        return  NULL;
++    }
++    
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * the base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 parser function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in DAAPParser.h here, in order that you can get a sense
++     * of what goes where.
++     */
++
++    /* Create a base parser/recognizer, using the supplied token stream
++     */
++    ctx->pParser          = antlr3ParserNewStream(ANTLR3_SIZE_HINT, instream->tstream, state);
++    /* Install the implementation of our DAAPParser interface
++     */
++    ctx->query        = query;
++    ctx->expr = expr;
++    ctx->aexpr        = aexpr;
++    ctx->crit = crit;
++    ctx->free                 = DAAPParserFree;
++    ctx->getGrammarFileName   = getGrammarFileName;
++    
++    /* Install the scope pushing methods.
++     */
++    ADAPTOR   = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);
++    ctx->vectors      = antlr3VectorFactoryNew(0);
++    
++
++      
++    /* Install the token table
++     */
++    PSRSTATE->tokenNames   = DAAPParserTokenNames;
++    
++    
++    /* Return the newly built parser to the caller
++     */
++    return  ctx;
++}
++
++/** Free the parser resources
++ */
++ static void
++ DAAPParserFree(pDAAPParser ctx)
++ {
++    /* Free any scope memory
++     */
++    
++    ctx->vectors->close(ctx->vectors);
++    /* We created the adaptor so we must free it
++     */
++    ADAPTOR->free(ADAPTOR);
++      // Free this parser
++      //
++    ctx->pParser->free(ctx->pParser);
++    ANTLR3_FREE(ctx);
++
++    /* Everything is released, so we can return
++     */
++    return;
++ }
++ 
++/** Return token names used by this parser
++ *
++ * The returned pointer is used as an index into the token names table (using the token 
++ * number as the index).
++ * 
++ * \return Pointer to first char * in the table.
++ */
++static pANTLR3_UINT8    *getTokenNames() 
++{
++        return DAAPParserTokenNames; 
++}
++
++    
++/* Declare the bitsets
++ */
++
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_query42  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_query42_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000010) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_query42     = { FOLLOW_expr_in_query42_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NEWLINE_in_query44  */
++static        ANTLR3_BITWORD FOLLOW_NEWLINE_in_query44_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000000) };
++static  ANTLR3_BITSET_LIST FOLLOW_NEWLINE_in_query44  = { FOLLOW_NEWLINE_in_query44_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_EOF_in_query47  */
++static        ANTLR3_BITWORD FOLLOW_EOF_in_query47_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_EOF_in_query47      = { FOLLOW_EOF_in_query47_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_aexpr_in_expr62  */
++static        ANTLR3_BITWORD FOLLOW_aexpr_in_expr62_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000022) };
++static  ANTLR3_BITSET_LIST FOLLOW_aexpr_in_expr62     = { FOLLOW_aexpr_in_expr62_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OPOR_in_expr65  */
++static        ANTLR3_BITWORD FOLLOW_OPOR_in_expr65_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_OPOR_in_expr65      = { FOLLOW_OPOR_in_expr65_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_aexpr_in_expr68  */
++static        ANTLR3_BITWORD FOLLOW_aexpr_in_expr68_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000022) };
++static  ANTLR3_BITSET_LIST FOLLOW_aexpr_in_expr68     = { FOLLOW_aexpr_in_expr68_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_crit_in_aexpr80  */
++static        ANTLR3_BITWORD FOLLOW_crit_in_aexpr80_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000042) };
++static  ANTLR3_BITSET_LIST FOLLOW_crit_in_aexpr80     = { FOLLOW_crit_in_aexpr80_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OPAND_in_aexpr83  */
++static        ANTLR3_BITWORD FOLLOW_OPAND_in_aexpr83_bits[]   = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_OPAND_in_aexpr83    = { FOLLOW_OPAND_in_aexpr83_bits, 1     };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_crit_in_aexpr86  */
++static        ANTLR3_BITWORD FOLLOW_crit_in_aexpr86_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000042) };
++static  ANTLR3_BITSET_LIST FOLLOW_crit_in_aexpr86     = { FOLLOW_crit_in_aexpr86_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_LPAR_in_crit98  */
++static        ANTLR3_BITWORD FOLLOW_LPAR_in_crit98_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_LPAR_in_crit98      = { FOLLOW_LPAR_in_crit98_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_crit100  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_crit100_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000100) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_crit100     = { FOLLOW_expr_in_crit100_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_RPAR_in_crit102  */
++static        ANTLR3_BITWORD FOLLOW_RPAR_in_crit102_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_RPAR_in_crit102     = { FOLLOW_RPAR_in_crit102_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STR_in_crit112  */
++static        ANTLR3_BITWORD FOLLOW_STR_in_crit112_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_STR_in_crit112      = { FOLLOW_STR_in_crit112_bits, 1       };
++     
++
++ 
++ 
++/* ==============================================
++ * Parsing rules
++ */
++/** 
++ * $ANTLR start query
++ * DAAP.g:27:1: query : expr ( NEWLINE )? EOF -> expr ;
++ */
++static DAAPParser_query_return
++query(pDAAPParser ctx)
++{   
++    DAAPParser_query_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    NEWLINE2;
++    pANTLR3_COMMON_TOKEN    EOF3;
++    DAAPParser_expr_return expr1;
++    #undef    RETURN_TYPE_expr1
++    #define   RETURN_TYPE_expr1 DAAPParser_expr_return
++
++    pANTLR3_BASE_TREE NEWLINE2_tree;
++    pANTLR3_BASE_TREE EOF3_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_NEWLINE;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_EOF;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_expr;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    NEWLINE2       = NULL;
++    EOF3       = NULL;
++    expr1.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    NEWLINE2_tree   = NULL;
++    EOF3_tree   = NULL;
++
++    stream_NEWLINE   = NULL;
++    #define CREATE_stream_NEWLINE  if (stream_NEWLINE == NULL) {stream_NEWLINE = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token NEWLINE"); } 
++    stream_EOF   = NULL;
++    #define CREATE_stream_EOF  if (stream_EOF == NULL) {stream_EOF = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token EOF"); } 
++    stream_expr   = NULL;
++    #define CREATE_stream_expr  if (stream_expr == NULL) {stream_expr = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule expr"); }
++
++    retval.tree  = NULL;
++    {
++        // DAAP.g:27:7: ( expr ( NEWLINE )? EOF -> expr )
++        // DAAP.g:27:9: expr ( NEWLINE )? EOF
++        {
++            FOLLOWPUSH(FOLLOW_expr_in_query42);
++            expr1=expr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++
++            CREATE_stream_expr; stream_expr->add(stream_expr, expr1.tree, NULL);
++
++            // DAAP.g:27:14: ( NEWLINE )?
++            {
++                int alt1=2;
++                switch ( LA(1) ) 
++                {
++                    case NEWLINE:
++                      {
++                              alt1=1;
++                      }
++                        break;
++                }
++
++                switch (alt1) 
++                {
++              case 1:
++                  // DAAP.g:27:14: NEWLINE
++                  {
++                      NEWLINE2 = (pANTLR3_COMMON_TOKEN) MATCHT(NEWLINE, &FOLLOW_NEWLINE_in_query44); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulequeryEx;
++                      }
++                       
++                      CREATE_stream_NEWLINE; stream_NEWLINE->add(stream_NEWLINE, NEWLINE2, NULL);
++
++
++                  }
++                  break;
++
++                }
++            }
++            EOF3 = (pANTLR3_COMMON_TOKEN) MATCHT(EOF, &FOLLOW_EOF_in_query47); 
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++             
++            CREATE_stream_EOF; stream_EOF->add(stream_EOF, EOF3, NULL);
++
++
++             
++            /* AST REWRITE
++             * elements          : expr
++             * token labels      : 
++             * rule labels       : retval
++             * token list labels : 
++             * rule list labels  : 
++             */
++            {
++              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++              retval.tree    = root_0;
++              // 27:27: -> expr
++              {
++                  ADAPTOR->addChild(ADAPTOR, root_0, stream_expr == NULL ? NULL : stream_expr->nextTree(stream_expr));
++
++              }
++
++              retval.tree = root_0; // set result root
++              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++            }
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulequeryEx; /* Prevent compiler warnings */
++    rulequeryEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_NEWLINE != NULL) stream_NEWLINE->free(stream_NEWLINE);
++        if (stream_EOF != NULL) stream_EOF->free(stream_EOF);
++        if (stream_expr != NULL) stream_expr->free(stream_expr);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end query */
++
++/** 
++ * $ANTLR start expr
++ * DAAP.g:30:1: expr : aexpr ( OPOR aexpr )* ;
++ */
++static DAAPParser_expr_return
++expr(pDAAPParser ctx)
++{   
++    DAAPParser_expr_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    OPOR5;
++    DAAPParser_aexpr_return aexpr4;
++    #undef    RETURN_TYPE_aexpr4
++    #define   RETURN_TYPE_aexpr4 DAAPParser_aexpr_return
++
++    DAAPParser_aexpr_return aexpr6;
++    #undef    RETURN_TYPE_aexpr6
++    #define   RETURN_TYPE_aexpr6 DAAPParser_aexpr_return
++
++    pANTLR3_BASE_TREE OPOR5_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    OPOR5       = NULL;
++    aexpr4.tree = NULL;
++
++    aexpr6.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    OPOR5_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // DAAP.g:30:6: ( aexpr ( OPOR aexpr )* )
++        // DAAP.g:30:8: aexpr ( OPOR aexpr )*
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            FOLLOWPUSH(FOLLOW_aexpr_in_expr62);
++            aexpr4=aexpr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruleexprEx;
++            }
++
++            ADAPTOR->addChild(ADAPTOR, root_0, aexpr4.tree);
++
++            // DAAP.g:30:14: ( OPOR aexpr )*
++
++            for (;;)
++            {
++                int alt2=2;
++                switch ( LA(1) ) 
++                {
++                case OPOR:
++                      {
++                              alt2=1;
++                      }
++                    break;
++
++                }
++
++                switch (alt2) 
++                {
++              case 1:
++                  // DAAP.g:30:15: OPOR aexpr
++                  {
++                      OPOR5 = (pANTLR3_COMMON_TOKEN) MATCHT(OPOR, &FOLLOW_OPOR_in_expr65); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      OPOR5_tree = (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, OPOR5));
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, OPOR5_tree, root_0));
++
++                      FOLLOWPUSH(FOLLOW_aexpr_in_expr68);
++                      aexpr6=aexpr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, aexpr6.tree);
++
++                  }
++                  break;
++
++              default:
++                  goto loop2; /* break out of the loop */
++                  break;
++                }
++            }
++            loop2: ; /* Jump out to here if this rule does not match */
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleexprEx; /* Prevent compiler warnings */
++    ruleexprEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end expr */
++
++/** 
++ * $ANTLR start aexpr
++ * DAAP.g:33:1: aexpr : crit ( OPAND crit )* ;
++ */
++static DAAPParser_aexpr_return
++aexpr(pDAAPParser ctx)
++{   
++    DAAPParser_aexpr_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    OPAND8;
++    DAAPParser_crit_return crit7;
++    #undef    RETURN_TYPE_crit7
++    #define   RETURN_TYPE_crit7 DAAPParser_crit_return
++
++    DAAPParser_crit_return crit9;
++    #undef    RETURN_TYPE_crit9
++    #define   RETURN_TYPE_crit9 DAAPParser_crit_return
++
++    pANTLR3_BASE_TREE OPAND8_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    OPAND8       = NULL;
++    crit7.tree = NULL;
++
++    crit9.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    OPAND8_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // DAAP.g:33:7: ( crit ( OPAND crit )* )
++        // DAAP.g:33:9: crit ( OPAND crit )*
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            FOLLOWPUSH(FOLLOW_crit_in_aexpr80);
++            crit7=crit(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruleaexprEx;
++            }
++
++            ADAPTOR->addChild(ADAPTOR, root_0, crit7.tree);
++
++            // DAAP.g:33:14: ( OPAND crit )*
++
++            for (;;)
++            {
++                int alt3=2;
++                switch ( LA(1) ) 
++                {
++                case OPAND:
++                      {
++                              alt3=1;
++                      }
++                    break;
++
++                }
++
++                switch (alt3) 
++                {
++              case 1:
++                  // DAAP.g:33:15: OPAND crit
++                  {
++                      OPAND8 = (pANTLR3_COMMON_TOKEN) MATCHT(OPAND, &FOLLOW_OPAND_in_aexpr83); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleaexprEx;
++                      }
++
++                      OPAND8_tree = (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, OPAND8));
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, OPAND8_tree, root_0));
++
++                      FOLLOWPUSH(FOLLOW_crit_in_aexpr86);
++                      crit9=crit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleaexprEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, crit9.tree);
++
++                  }
++                  break;
++
++              default:
++                  goto loop3; /* break out of the loop */
++                  break;
++                }
++            }
++            loop3: ; /* Jump out to here if this rule does not match */
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleaexprEx; /* Prevent compiler warnings */
++    ruleaexprEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end aexpr */
++
++/** 
++ * $ANTLR start crit
++ * DAAP.g:36:1: crit : ( LPAR expr RPAR -> expr | STR );
++ */
++static DAAPParser_crit_return
++crit(pDAAPParser ctx)
++{   
++    DAAPParser_crit_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    LPAR10;
++    pANTLR3_COMMON_TOKEN    RPAR12;
++    pANTLR3_COMMON_TOKEN    STR13;
++    DAAPParser_expr_return expr11;
++    #undef    RETURN_TYPE_expr11
++    #define   RETURN_TYPE_expr11 DAAPParser_expr_return
++
++    pANTLR3_BASE_TREE LPAR10_tree;
++    pANTLR3_BASE_TREE RPAR12_tree;
++    pANTLR3_BASE_TREE STR13_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_RPAR;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_LPAR;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_expr;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    LPAR10       = NULL;
++    RPAR12       = NULL;
++    STR13       = NULL;
++    expr11.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    LPAR10_tree   = NULL;
++    RPAR12_tree   = NULL;
++    STR13_tree   = NULL;
++
++    stream_RPAR   = NULL;
++    #define CREATE_stream_RPAR  if (stream_RPAR == NULL) {stream_RPAR = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token RPAR"); } 
++    stream_LPAR   = NULL;
++    #define CREATE_stream_LPAR  if (stream_LPAR == NULL) {stream_LPAR = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token LPAR"); } 
++    stream_expr   = NULL;
++    #define CREATE_stream_expr  if (stream_expr == NULL) {stream_expr = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule expr"); }
++
++    retval.tree  = NULL;
++    {
++        {
++            //  DAAP.g:36:6: ( LPAR expr RPAR -> expr | STR )
++            
++            ANTLR3_UINT32 alt4;
++
++            alt4=2;
++
++            switch ( LA(1) ) 
++            {
++            case LPAR:
++              {
++                      alt4=1;
++              }
++                break;
++            case STR:
++              {
++                      alt4=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 4;
++                EXCEPTION->state        = 0;
++
++
++                goto rulecritEx;
++            }
++
++            switch (alt4) 
++            {
++              case 1:
++                  // DAAP.g:36:8: LPAR expr RPAR
++                  {
++                      LPAR10 = (pANTLR3_COMMON_TOKEN) MATCHT(LPAR, &FOLLOW_LPAR_in_crit98); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++                       
++                      CREATE_stream_LPAR; stream_LPAR->add(stream_LPAR, LPAR10, NULL);
++
++                      FOLLOWPUSH(FOLLOW_expr_in_crit100);
++                      expr11=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      CREATE_stream_expr; stream_expr->add(stream_expr, expr11.tree, NULL);
++                      RPAR12 = (pANTLR3_COMMON_TOKEN) MATCHT(RPAR, &FOLLOW_RPAR_in_crit102); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++                       
++                      CREATE_stream_RPAR; stream_RPAR->add(stream_RPAR, RPAR12, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : expr
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 36:24: -> expr
++                              {
++                                  ADAPTOR->addChild(ADAPTOR, root_0, stream_expr == NULL ? NULL : stream_expr->nextTree(stream_expr));
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++              case 2:
++                  // DAAP.g:37:4: STR
++                  {
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++                      STR13 = (pANTLR3_COMMON_TOKEN) MATCHT(STR, &FOLLOW_STR_in_crit112); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      STR13_tree = (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, STR13));
++                      ADAPTOR->addChild(ADAPTOR, root_0, STR13_tree);
++
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulecritEx; /* Prevent compiler warnings */
++    rulecritEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_RPAR != NULL) stream_RPAR->free(stream_RPAR);
++        if (stream_LPAR != NULL) stream_LPAR->free(stream_LPAR);
++        if (stream_expr != NULL) stream_expr->free(stream_expr);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end crit */
++/* End of parsing rules
++ * ==============================================
++ */
++
++/* ==============================================
++ * Syntactic predicates
++ */
++/* End of syntactic predicates
++ * ==============================================
++ */
++
++ 
++ 
++
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/DAAPParser.h b/src/pregen/DAAPParser.h
+new file mode 100644
+index 0000000..dcc664f
+--- /dev/null
++++ b/src/pregen/DAAPParser.h
+@@ -0,0 +1,226 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : DAAP.g
++ *     -                            On : 2014-09-30 21:42:39
++ *     -                for the parser : DAAPParserParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The parser DAAPParser has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pDAAPParser, which is returned from a call to DAAPParserNew().
++ *
++ * The methods in pDAAPParser are  as follows:
++ *
++ *  - DAAPParser_query_return      pDAAPParser->query(pDAAPParser)
++ *  - DAAPParser_expr_return      pDAAPParser->expr(pDAAPParser)
++ *  - DAAPParser_aexpr_return      pDAAPParser->aexpr(pDAAPParser)
++ *  - DAAPParser_crit_return      pDAAPParser->crit(pDAAPParser)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _DAAPParser_H
++#define _DAAPParser_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct DAAPParser_Ctx_struct DAAPParser, * pDAAPParser;
++
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++typedef struct DAAPParser_query_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    DAAPParser_query_return;
++
++typedef struct DAAPParser_expr_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    DAAPParser_expr_return;
++
++typedef struct DAAPParser_aexpr_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    DAAPParser_aexpr_return;
++
++typedef struct DAAPParser_crit_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    DAAPParser_crit_return;
++
++
++
++/** Context tracking structure for DAAPParser
++ */
++struct DAAPParser_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_PARSER   pParser;
++
++
++     DAAPParser_query_return (*query) (struct DAAPParser_Ctx_struct * ctx);
++     DAAPParser_expr_return (*expr)   (struct DAAPParser_Ctx_struct * ctx);
++     DAAPParser_aexpr_return (*aexpr) (struct DAAPParser_Ctx_struct * ctx);
++     DAAPParser_crit_return (*crit)   (struct DAAPParser_Ctx_struct * ctx);
++    // Delegated rules
++    const char * (*getGrammarFileName)();
++    void          (*free)   (struct DAAPParser_Ctx_struct * ctx);
++    /* @headerFile.members() */
++    pANTLR3_BASE_TREE_ADAPTOR adaptor;
++    pANTLR3_VECTOR_FACTORY            vectors;
++    /* End @headerFile.members() */
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pDAAPParser DAAPParserNew         (pANTLR3_COMMON_TOKEN_STREAM instream);
++ANTLR3_API pDAAPParser DAAPParserNewSSD      (pANTLR3_COMMON_TOKEN_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the parser will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STR      9
++#define QUOTE      10
++#define LPAR      7
++#define NEWLINE      4
++#define OPOR      5
++#define RPAR      8
++#define ESCAPED      11
++#define OPAND      6
++#define EOF      -1
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for DAAPParser
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
+diff --git a/src/pregen/RSP.u b/src/pregen/RSP.u
+new file mode 100644
+index 0000000..89256ff
+--- /dev/null
++++ b/src/pregen/RSP.u
+@@ -0,0 +1,6 @@
++RSPParser.c : RSP.g
++./RSP.tokens : RSP.g
++RSPParser.h : RSP.g
++RSPLexer.c : RSP.g
++RSPLexer.h : RSP.g
++ANTLR_PRODUCTS += RSPParser.c ./RSP.tokens RSPParser.h RSPLexer.c RSPLexer.h 
+\ No newline at end of file
+diff --git a/src/pregen/RSP2SQL.c b/src/pregen/RSP2SQL.c
+new file mode 100644
+index 0000000..b5c9550
+--- /dev/null
++++ b/src/pregen/RSP2SQL.c
+@@ -0,0 +1,2546 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP2SQL.g
++ *     -                            On : 2014-09-30 21:42:42
++ *     -           for the tree parser : RSP2SQLTreeParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 what the grammar programmer asked us to put at the top of every file.
++ */
++
++      /* Needs #define _GNU_SOURCE for strptime() */
++
++      #include <stdio.h>
++      #include <string.h>
++      #include <time.h>
++      #include <stdint.h>
++
++      #include "logger.h"
++      #include "db.h"
++      #include "misc.h"
++      #include "rsp_query.h"
++
++/* End of Header action.
++ * =============================================================================
++ */
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "RSP2SQL.h"
++/* ----------------------------------------- */
++
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pRSP2SQL_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pRSP2SQL_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pRSP2SQL_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pRSP2SQL_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++/* Macros for accessing things in the parser
++ */
++ 
++#undef            PARSER
++#undef            RECOGNIZER              
++#undef            HAVEPARSEDRULE
++#undef            INPUT
++#undef            STRSTREAM
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            MATCHT
++#undef            MATCHANYT
++#undef            FOLLOWSTACK
++#undef            FOLLOWPUSH
++#undef            FOLLOWPOP
++#undef            PRECOVER
++#undef            PREPORTERROR
++#undef            LA
++#undef            LT
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            PERRORRECOVERY
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            RECOVERFROMMISMATCHEDSET
++#undef            RECOVERFROMMISMATCHEDELEMENT
++#undef            BACKTRACKING
++#undef      ADAPTOR
++#undef            RULEMEMO            
++#undef                SEEK    
++#undef                INDEX
++#undef                DBG
++
++#define           PARSER                                                      ctx->pTreeParser  
++#define           RECOGNIZER                                          PARSER->rec
++#define               PSRSTATE                                                RECOGNIZER->state
++#define           HAVEPARSEDRULE(r)                           RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define           INPUT                                                       PARSER->ctnstream
++#define               ISTREAM                                                 INPUT->tnstream->istream
++#define           STRSTREAM                                           INPUT->tnstream
++#define           HASEXCEPTION()                                      (PSRSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                                           PSRSTATE->exception
++#define           MATCHT(t, fs)                                       RECOGNIZER->match(RECOGNIZER, t, fs)
++#define           MATCHANYT()                                         RECOGNIZER->matchAny(RECOGNIZER)
++#define           FOLLOWSTACK                                     PSRSTATE->following
++#define           FOLLOWPUSH(x)                                       FOLLOWSTACK->push(FOLLOWSTACK, ((void *)(&(x))), NULL)
++#define           FOLLOWPOP()                                         FOLLOWSTACK->pop(FOLLOWSTACK)
++#define           PRECOVER()                                          RECOGNIZER->recover(RECOGNIZER)
++#define           PREPORTERROR()                                      RECOGNIZER->reportError(RECOGNIZER)
++#define           LA(n)                                                       ISTREAM->_LA(ISTREAM, n)
++#define           LT(n)                                                       INPUT->tnstream->_LT(INPUT->tnstream, n)
++#define           CONSTRUCTEX()                                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           CONSUME()                                           ISTREAM->consume(ISTREAM)
++#define           MARK()                                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                                        ISTREAM->rewindLast(ISTREAM)
++#define           PERRORRECOVERY                                      PSRSTATE->errorRecovery
++#define           FAILEDFLAG                                          PSRSTATE->failed
++#define           HASFAILED()                                         (FAILEDFLAG == ANTLR3_TRUE)
++#define           BACKTRACKING                                        PSRSTATE->backtracking
++#define           RECOVERFROMMISMATCHEDSET(s)         RECOGNIZER->recoverFromMismatchedSet(RECOGNIZER, s)
++#define           RECOVERFROMMISMATCHEDELEMENT(e)     RECOGNIZER->recoverFromMismatchedElement(RECOGNIZER, s)
++#define     ADAPTOR                         INPUT->adaptor
++#define               RULEMEMO                                                PSRSTATE->ruleMemo
++#define               SEEK(n)                                                 ISTREAM->seek(ISTREAM, n)
++#define               INDEX()                                                 ISTREAM->index(ISTREAM)
++#define               DBG                                                             RECOGNIZER->debugger
++
++
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++
++/** \brief Table of all token names in symbolic order, mainly used for
++ *         error reporting.
++ */
++pANTLR3_UINT8   RSP2SQLTokenNames[30+4]
++     = {
++        (pANTLR3_UINT8) "<invalid>",       /* String to print to indicate an invalid token */
++        (pANTLR3_UINT8) "<EOR>",
++        (pANTLR3_UINT8) "<DOWN>", 
++        (pANTLR3_UINT8) "<UP>", 
++        (pANTLR3_UINT8) "NEWLINE",
++        (pANTLR3_UINT8) "OR",
++        (pANTLR3_UINT8) "AND",
++        (pANTLR3_UINT8) "LPAR",
++        (pANTLR3_UINT8) "RPAR",
++        (pANTLR3_UINT8) "FIELD",
++        (pANTLR3_UINT8) "STR",
++        (pANTLR3_UINT8) "NOT",
++        (pANTLR3_UINT8) "EQUAL",
++        (pANTLR3_UINT8) "INCLUDES",
++        (pANTLR3_UINT8) "STARTSW",
++        (pANTLR3_UINT8) "ENDSW",
++        (pANTLR3_UINT8) "INT",
++        (pANTLR3_UINT8) "LESS",
++        (pANTLR3_UINT8) "GREATER",
++        (pANTLR3_UINT8) "LTE",
++        (pANTLR3_UINT8) "GTE",
++        (pANTLR3_UINT8) "BEFORE",
++        (pANTLR3_UINT8) "AFTER",
++        (pANTLR3_UINT8) "DATE",
++        (pANTLR3_UINT8) "TODAY",
++        (pANTLR3_UINT8) "DAY",
++        (pANTLR3_UINT8) "WEEK",
++        (pANTLR3_UINT8) "MONTH",
++        (pANTLR3_UINT8) "YEAR",
++        (pANTLR3_UINT8) "QUOTE",
++        (pANTLR3_UINT8) "WS",
++        (pANTLR3_UINT8) "DIGIT19",
++        (pANTLR3_UINT8) "DIGIT09",
++        (pANTLR3_UINT8) "ESCAPED"
++       };
++
++        
++
++// Forward declare the locally static matching functions we have generated.
++//
++static pANTLR3_STRING query    (pRSP2SQL ctx);
++static RSP2SQL_expr_return    expr    (pRSP2SQL ctx);
++static RSP2SQL_strcrit_return strcrit    (pRSP2SQL ctx);
++static pANTLR3_COMMON_TOKEN   strop    (pRSP2SQL ctx);
++static RSP2SQL_intcrit_return intcrit    (pRSP2SQL ctx);
++static pANTLR3_COMMON_TOKEN   intop    (pRSP2SQL ctx);
++static RSP2SQL_datecrit_return        datecrit    (pRSP2SQL ctx);
++static pANTLR3_COMMON_TOKEN   dateop    (pRSP2SQL ctx);
++static RSP2SQL_datespec_return        datespec    (pRSP2SQL ctx);
++static RSP2SQL_dateref_return dateref    (pRSP2SQL ctx);
++static RSP2SQL_dateintval_return      dateintval    (pRSP2SQL ctx);
++static void   RSP2SQLFree(pRSP2SQL ctx);
++/* For use in tree output where we are accumulating rule labels via label += ruleRef
++ * we need a function that knows how to free a return scope when the list is destroyed. 
++ * We cannot just use ANTLR3_FREE because in debug tracking mode, this is a macro.
++ */
++static        void ANTLR3_CDECL freeScope(void * scope)
++{
++    ANTLR3_FREE(scope);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "RSP2SQL.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++/** \brief Create a new RSP2SQL parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pRSP2SQL
++RSP2SQLNew   (pANTLR3_COMMON_TREE_NODE_STREAM instream)
++{
++      // See if we can create a new parser with the standard constructor
++      //
++      return RSP2SQLNewSSD(instream, NULL);
++}
++
++/** \brief Create a new RSP2SQL parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pRSP2SQL
++RSP2SQLNewSSD   (pANTLR3_COMMON_TREE_NODE_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pRSP2SQL ctx;         /* Context structure we will build and return   */
++    
++    ctx       = (pRSP2SQL) ANTLR3_CALLOC(1, sizeof(RSP2SQL));
++    
++    if        (ctx == NULL)
++    {
++              // Failed to allocate memory for parser context
++              //
++        return  NULL;
++    }
++    
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * the base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 parser function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in RSP2SQL.h here, in order that you can get a sense
++     * of what goes where.
++     */
++
++    /* Create a base Tree parser/recognizer, using the supplied tree node stream
++     */
++    ctx->pTreeParser          = antlr3TreeParserNewStream(ANTLR3_SIZE_HINT, instream, state);
++    /* Install the implementation of our RSP2SQL interface
++     */
++    ctx->query        = query;
++    ctx->expr = expr;
++    ctx->strcrit      = strcrit;
++    ctx->strop        = strop;
++    ctx->intcrit      = intcrit;
++    ctx->intop        = intop;
++    ctx->datecrit     = datecrit;
++    ctx->dateop       = dateop;
++    ctx->datespec     = datespec;
++    ctx->dateref      = dateref;
++    ctx->dateintval   = dateintval;
++    ctx->free                 = RSP2SQLFree;
++    ctx->getGrammarFileName   = getGrammarFileName;
++    
++    /* Install the scope pushing methods.
++     */
++
++        
++    
++
++      
++    /* Install the token table
++     */
++    PSRSTATE->tokenNames   = RSP2SQLTokenNames;
++    
++    
++    /* Return the newly built parser to the caller
++     */
++    return  ctx;
++}
++
++/** Free the parser resources
++ */
++ static void
++ RSP2SQLFree(pRSP2SQL ctx)
++ {
++    /* Free any scope memory
++     */
++    
++        
++      // Free this parser
++      //
++    ctx->pTreeParser->free(ctx->pTreeParser);
++    ANTLR3_FREE(ctx);
++
++    /* Everything is released, so we can return
++     */
++    return;
++ }
++ 
++/** Return token names used by this tree parser
++ *
++ * The returned pointer is used as an index into the token names table (using the token 
++ * number as the index).
++ * 
++ * \return Pointer to first char * in the table.
++ */
++static pANTLR3_UINT8    *getTokenNames() 
++{
++        return RSP2SQLTokenNames; 
++}
++
++
++      #define RSP_TYPE_STRING 0
++      #define RSP_TYPE_INT    1
++      #define RSP_TYPE_DATE   2
++
++      struct rsp_query_field_map {
++        char *rsp_field;
++        int field_type;
++        /* RSP fields are named after the DB columns - or vice versa */
++      };
++
++      /* gperf static hash, rsp_query.gperf */
++      #include "rsp_query_hash.c"
++
++    
++/* Declare the bitsets
++ */
++
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_query70  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_query70_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_query70     = { FOLLOW_expr_in_query70_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_AND_in_expr95  */
++static        ANTLR3_BITWORD FOLLOW_AND_in_expr95_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_AND_in_expr95       = { FOLLOW_AND_in_expr95_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr101  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr101_bits[]    = { ANTLR3_UINT64_LIT(0x00000000007EF860) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr101     = { FOLLOW_expr_in_expr101_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr107  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr107_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr107     = { FOLLOW_expr_in_expr107_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OR_in_expr118  */
++static        ANTLR3_BITWORD FOLLOW_OR_in_expr118_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_OR_in_expr118       = { FOLLOW_OR_in_expr118_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr124  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr124_bits[]    = { ANTLR3_UINT64_LIT(0x00000000007EF860) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr124     = { FOLLOW_expr_in_expr124_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_expr130  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_expr130_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_expr130     = { FOLLOW_expr_in_expr130_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strcrit_in_expr144  */
++static        ANTLR3_BITWORD FOLLOW_strcrit_in_expr144_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_strcrit_in_expr144  = { FOLLOW_strcrit_in_expr144_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NOT_in_expr154  */
++static        ANTLR3_BITWORD FOLLOW_NOT_in_expr154_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_NOT_in_expr154      = { FOLLOW_NOT_in_expr154_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strcrit_in_expr160  */
++static        ANTLR3_BITWORD FOLLOW_strcrit_in_expr160_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_strcrit_in_expr160  = { FOLLOW_strcrit_in_expr160_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intcrit_in_expr174  */
++static        ANTLR3_BITWORD FOLLOW_intcrit_in_expr174_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_intcrit_in_expr174  = { FOLLOW_intcrit_in_expr174_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NOT_in_expr184  */
++static        ANTLR3_BITWORD FOLLOW_NOT_in_expr184_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_NOT_in_expr184      = { FOLLOW_NOT_in_expr184_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intcrit_in_expr190  */
++static        ANTLR3_BITWORD FOLLOW_intcrit_in_expr190_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_intcrit_in_expr190  = { FOLLOW_intcrit_in_expr190_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_datecrit_in_expr204  */
++static        ANTLR3_BITWORD FOLLOW_datecrit_in_expr204_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_datecrit_in_expr204 = { FOLLOW_datecrit_in_expr204_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strop_in_strcrit233  */
++static        ANTLR3_BITWORD FOLLOW_strop_in_strcrit233_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_strop_in_strcrit233 = { FOLLOW_strop_in_strcrit233_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_strcrit239  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_strcrit239_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000400) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_strcrit239 = { FOLLOW_FIELD_in_strcrit239_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STR_in_strcrit245  */
++static        ANTLR3_BITWORD FOLLOW_STR_in_strcrit245_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_STR_in_strcrit245   = { FOLLOW_STR_in_strcrit245_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_EQUAL_in_strop274  */
++static        ANTLR3_BITWORD FOLLOW_EQUAL_in_strop274_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_EQUAL_in_strop274   = { FOLLOW_EQUAL_in_strop274_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INCLUDES_in_strop287  */
++static        ANTLR3_BITWORD FOLLOW_INCLUDES_in_strop287_bits[]       = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_INCLUDES_in_strop287        = { FOLLOW_INCLUDES_in_strop287_bits, 1 };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STARTSW_in_strop300  */
++static        ANTLR3_BITWORD FOLLOW_STARTSW_in_strop300_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_STARTSW_in_strop300 = { FOLLOW_STARTSW_in_strop300_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_ENDSW_in_strop313  */
++static        ANTLR3_BITWORD FOLLOW_ENDSW_in_strop313_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_ENDSW_in_strop313   = { FOLLOW_ENDSW_in_strop313_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intop_in_intcrit342  */
++static        ANTLR3_BITWORD FOLLOW_intop_in_intcrit342_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_intop_in_intcrit342 = { FOLLOW_intop_in_intcrit342_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_intcrit348  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_intcrit348_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000010000) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_intcrit348 = { FOLLOW_FIELD_in_intcrit348_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INT_in_intcrit354  */
++static        ANTLR3_BITWORD FOLLOW_INT_in_intcrit354_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_INT_in_intcrit354   = { FOLLOW_INT_in_intcrit354_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_EQUAL_in_intop383  */
++static        ANTLR3_BITWORD FOLLOW_EQUAL_in_intop383_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_EQUAL_in_intop383   = { FOLLOW_EQUAL_in_intop383_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_LESS_in_intop396  */
++static        ANTLR3_BITWORD FOLLOW_LESS_in_intop396_bits[]   = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_LESS_in_intop396    = { FOLLOW_LESS_in_intop396_bits, 1     };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_GREATER_in_intop409  */
++static        ANTLR3_BITWORD FOLLOW_GREATER_in_intop409_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_GREATER_in_intop409 = { FOLLOW_GREATER_in_intop409_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_LTE_in_intop422  */
++static        ANTLR3_BITWORD FOLLOW_LTE_in_intop422_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_LTE_in_intop422     = { FOLLOW_LTE_in_intop422_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_GTE_in_intop435  */
++static        ANTLR3_BITWORD FOLLOW_GTE_in_intop435_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_GTE_in_intop435     = { FOLLOW_GTE_in_intop435_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateop_in_datecrit464  */
++static        ANTLR3_BITWORD FOLLOW_dateop_in_datecrit464_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateop_in_datecrit464       = { FOLLOW_dateop_in_datecrit464_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_datecrit470  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_datecrit470_bits[]       = { ANTLR3_UINT64_LIT(0x0000000001FEF860) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_datecrit470        = { FOLLOW_FIELD_in_datecrit470_bits, 1 };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_datespec_in_datecrit476  */
++static        ANTLR3_BITWORD FOLLOW_datespec_in_datecrit476_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_datespec_in_datecrit476     = { FOLLOW_datespec_in_datecrit476_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_BEFORE_in_dateop505  */
++static        ANTLR3_BITWORD FOLLOW_BEFORE_in_dateop505_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_BEFORE_in_dateop505 = { FOLLOW_BEFORE_in_dateop505_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_AFTER_in_dateop518  */
++static        ANTLR3_BITWORD FOLLOW_AFTER_in_dateop518_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_AFTER_in_dateop518  = { FOLLOW_AFTER_in_dateop518_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateref_in_datespec546  */
++static        ANTLR3_BITWORD FOLLOW_dateref_in_datespec546_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateref_in_datespec546      = { FOLLOW_dateref_in_datespec546_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateop_in_datespec560  */
++static        ANTLR3_BITWORD FOLLOW_dateop_in_datespec560_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000004) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateop_in_datespec560       = { FOLLOW_dateop_in_datespec560_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateref_in_datespec566  */
++static        ANTLR3_BITWORD FOLLOW_dateref_in_datespec566_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000010000) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateref_in_datespec566      = { FOLLOW_dateref_in_datespec566_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INT_in_datespec572  */
++static        ANTLR3_BITWORD FOLLOW_INT_in_datespec572_bits[] = { ANTLR3_UINT64_LIT(0x000000001E000000) };
++static  ANTLR3_BITSET_LIST FOLLOW_INT_in_datespec572  = { FOLLOW_INT_in_datespec572_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateintval_in_datespec578  */
++static        ANTLR3_BITWORD FOLLOW_dateintval_in_datespec578_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000008) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateintval_in_datespec578   = { FOLLOW_dateintval_in_datespec578_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_DATE_in_dateref607  */
++static        ANTLR3_BITWORD FOLLOW_DATE_in_dateref607_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_DATE_in_dateref607  = { FOLLOW_DATE_in_dateref607_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_TODAY_in_dateref616  */
++static        ANTLR3_BITWORD FOLLOW_TODAY_in_dateref616_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_TODAY_in_dateref616 = { FOLLOW_TODAY_in_dateref616_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_DAY_in_dateintval640  */
++static        ANTLR3_BITWORD FOLLOW_DAY_in_dateintval640_bits[]       = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_DAY_in_dateintval640        = { FOLLOW_DAY_in_dateintval640_bits, 1 };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_WEEK_in_dateintval649  */
++static        ANTLR3_BITWORD FOLLOW_WEEK_in_dateintval649_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_WEEK_in_dateintval649       = { FOLLOW_WEEK_in_dateintval649_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_MONTH_in_dateintval658  */
++static        ANTLR3_BITWORD FOLLOW_MONTH_in_dateintval658_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_MONTH_in_dateintval658      = { FOLLOW_MONTH_in_dateintval658_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_YEAR_in_dateintval667  */
++static        ANTLR3_BITWORD FOLLOW_YEAR_in_dateintval667_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_YEAR_in_dateintval667       = { FOLLOW_YEAR_in_dateintval667_bits, 1        };
++     
++
++ 
++ 
++/* ==============================================
++ * Parsing rules
++ */
++/** 
++ * $ANTLR start query
++ * RSP2SQL.g:56:1: query returns [ pANTLR3_STRING result ] : e= expr ;
++ */
++static pANTLR3_STRING
++query(pRSP2SQL ctx)
++{   
++    pANTLR3_STRING result = NULL;
++
++    RSP2SQL_expr_return e;
++    #undef    RETURN_TYPE_e
++    #define   RETURN_TYPE_e RSP2SQL_expr_return
++
++    /* Initialize rule variables
++     */
++
++
++     result= NULL; 
++    {
++        // RSP2SQL.g:58:2: (e= expr )
++        // RSP2SQL.g:58:4: e= expr
++        {
++            FOLLOWPUSH(FOLLOW_expr_in_query70);
++            e=expr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++
++            {
++
++                                      if (!e.valid)
++                                      {
++                                              result= NULL;
++                                      }
++                                      else
++                                      {
++                                              result= e.result->factory->newRaw(e.result->factory);
++                                              result->append8(result, "(");
++                                              result->appendS(result, e.result);
++                                              result->append8(result, ")");
++                                      }
++                              
++            }
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulequeryEx; /* Prevent compiler warnings */
++    rulequeryEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return result;
++}
++/* $ANTLR end query */
++
++/** 
++ * $ANTLR start expr
++ * RSP2SQL.g:74:1: expr returns [ pANTLR3_STRING result, int valid ] : ( ^( AND a= expr b= expr ) | ^( OR a= expr b= expr ) | c= strcrit | ^( NOT c= strcrit ) | i= intcrit | ^( NOT i= intcrit ) | d= datecrit );
++ */
++static RSP2SQL_expr_return
++expr(pRSP2SQL ctx)
++{   
++    RSP2SQL_expr_return retval;
++
++    RSP2SQL_expr_return a;
++    #undef    RETURN_TYPE_a
++    #define   RETURN_TYPE_a RSP2SQL_expr_return
++
++    RSP2SQL_expr_return b;
++    #undef    RETURN_TYPE_b
++    #define   RETURN_TYPE_b RSP2SQL_expr_return
++
++    RSP2SQL_strcrit_return c;
++    #undef    RETURN_TYPE_c
++    #define   RETURN_TYPE_c RSP2SQL_strcrit_return
++
++    RSP2SQL_intcrit_return i;
++    #undef    RETURN_TYPE_i
++    #define   RETURN_TYPE_i RSP2SQL_intcrit_return
++
++    RSP2SQL_datecrit_return d;
++    #undef    RETURN_TYPE_d
++    #define   RETURN_TYPE_d RSP2SQL_datecrit_return
++
++    /* Initialize rule variables
++     */
++
++
++     retval.result= NULL; retval.valid= 1; 
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        {
++            //  RSP2SQL.g:76:2: ( ^( AND a= expr b= expr ) | ^( OR a= expr b= expr ) | c= strcrit | ^( NOT c= strcrit ) | i= intcrit | ^( NOT i= intcrit ) | d= datecrit )
++            
++            ANTLR3_UINT32 alt1;
++
++            alt1=7;
++
++            switch ( LA(1) ) 
++            {
++            case AND:
++              {
++                      alt1=1;
++              }
++                break;
++            case OR:
++              {
++                      alt1=2;
++              }
++                break;
++            case EQUAL:
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case DOWN:
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case FIELD:
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case INT:
++                                                              {
++                                                                      alt1=5;
++                                                              }
++                                                          break;
++                                                      case STR:
++                                                              {
++                                                                      alt1=3;
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 1;
++                                                          EXCEPTION->state        = 10;
++
++
++                                                          goto ruleexprEx;
++                                                      }
++
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 1;
++                                          EXCEPTION->state        = 8;
++
++
++                                          goto ruleexprEx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 1;
++                          EXCEPTION->state        = 3;
++
++
++                          goto ruleexprEx;
++                      }
++
++              }
++                break;
++            case INCLUDES:
++            case STARTSW:
++            case ENDSW:
++              {
++                      alt1=3;
++              }
++                break;
++            case NOT:
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case DOWN:
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case EQUAL:
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case DOWN:
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case FIELD:
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case STR:
++                                                                                              {
++                                                                                                      alt1=4;
++                                                                                              }
++                                                                                          break;
++                                                                                      case INT:
++                                                                                              {
++                                                                                                      alt1=6;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          CONSTRUCTEX();
++                                                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                                                          EXCEPTION->message      = (void *)"";
++                                                                                          EXCEPTION->decisionNum  = 1;
++                                                                                          EXCEPTION->state        = 15;
++
++
++                                                                                          goto ruleexprEx;
++                                                                                      }
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          CONSTRUCTEX();
++                                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                                          EXCEPTION->message      = (void *)"";
++                                                                          EXCEPTION->decisionNum  = 1;
++                                                                          EXCEPTION->state        = 14;
++
++
++                                                                          goto ruleexprEx;
++                                                                      }
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 1;
++                                                          EXCEPTION->state        = 11;
++
++
++                                                          goto ruleexprEx;
++                                                      }
++
++                                              }
++                                          break;
++                                      case LESS:
++                                      case GREATER:
++                                      case LTE:
++                                      case GTE:
++                                              {
++                                                      alt1=6;
++                                              }
++                                          break;
++                                      case INCLUDES:
++                                      case STARTSW:
++                                      case ENDSW:
++                                              {
++                                                      alt1=4;
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 1;
++                                          EXCEPTION->state        = 9;
++
++
++                                          goto ruleexprEx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 1;
++                          EXCEPTION->state        = 5;
++
++
++                          goto ruleexprEx;
++                      }
++
++              }
++                break;
++            case LESS:
++            case GREATER:
++            case LTE:
++            case GTE:
++              {
++                      alt1=5;
++              }
++                break;
++            case BEFORE:
++            case AFTER:
++              {
++                      alt1=7;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 1;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleexprEx;
++            }
++
++            switch (alt1) 
++            {
++              case 1:
++                  // RSP2SQL.g:76:4: ^( AND a= expr b= expr )
++                  {
++                       MATCHT(AND, &FOLLOW_AND_in_expr95); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr101);
++                      a=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr107);
++                      b=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!a.valid || !b.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= a.result->factory->newRaw(a.result->factory);
++                                                      retval.result->append8(retval.result, "(");
++                                                      retval.result->appendS(retval.result, a.result);
++                                                      retval.result->append8(retval.result, " AND ");
++                                                      retval.result->appendS(retval.result, b.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:92:4: ^( OR a= expr b= expr )
++                  {
++                       MATCHT(OR, &FOLLOW_OR_in_expr118); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr124);
++                      a=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_expr_in_expr130);
++                      b=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!a.valid || !b.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= a.result->factory->newRaw(a.result->factory);
++                                                      retval.result->append8(retval.result, "(");
++                                                      retval.result->appendS(retval.result, a.result);
++                                                      retval.result->append8(retval.result, " OR ");
++                                                      retval.result->appendS(retval.result, b.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 3:
++                  // RSP2SQL.g:108:4: c= strcrit
++                  {
++                      FOLLOWPUSH(FOLLOW_strcrit_in_expr144);
++                      c=strcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              retval.valid= c.valid;
++                                              retval.result= c.result;
++                                      
++                      }
++
++                  }
++                  break;
++              case 4:
++                  // RSP2SQL.g:113:4: ^( NOT c= strcrit )
++                  {
++                       MATCHT(NOT, &FOLLOW_NOT_in_expr154); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_strcrit_in_expr160);
++                      c=strcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!c.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= c.result->factory->newRaw(c.result->factory);
++                                                      retval.result->append8(retval.result, "(NOT ");
++                                                      retval.result->appendS(retval.result, c.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 5:
++                  // RSP2SQL.g:127:4: i= intcrit
++                  {
++                      FOLLOWPUSH(FOLLOW_intcrit_in_expr174);
++                      i=intcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              retval.valid= i.valid;
++                                              retval.result= i.result;
++                                      
++                      }
++
++                  }
++                  break;
++              case 6:
++                  // RSP2SQL.g:132:4: ^( NOT i= intcrit )
++                  {
++                       MATCHT(NOT, &FOLLOW_NOT_in_expr184); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_intcrit_in_expr190);
++                      i=intcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              if (!i.valid)
++                                              {
++                                                      retval.valid= 0;
++                                              }
++                                              else
++                                              {
++                                                      retval.result= i.result->factory->newRaw(i.result->factory);
++                                                      retval.result->append8(retval.result, "(NOT ");
++                                                      retval.result->appendS(retval.result, i.result);
++                                                      retval.result->append8(retval.result, ")");
++                                              }
++                                      
++                      }
++
++                  }
++                  break;
++              case 7:
++                  // RSP2SQL.g:146:4: d= datecrit
++                  {
++                      FOLLOWPUSH(FOLLOW_datecrit_in_expr204);
++                      d=datecrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      {
++
++                                              retval.valid= d.valid;
++                                              retval.result= d.result;
++                                      
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleexprEx; /* Prevent compiler warnings */
++    ruleexprEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end expr */
++
++/** 
++ * $ANTLR start strcrit
++ * RSP2SQL.g:153:1: strcrit returns [ pANTLR3_STRING result, int valid ] : ^(o= strop f= FIELD s= STR ) ;
++ */
++static RSP2SQL_strcrit_return
++strcrit(pRSP2SQL ctx)
++{   
++    RSP2SQL_strcrit_return retval;
++
++    pANTLR3_BASE_TREE    f;
++    pANTLR3_BASE_TREE    s;
++    pANTLR3_COMMON_TOKEN o;
++    #undef    RETURN_TYPE_o
++    #define   RETURN_TYPE_o pANTLR3_COMMON_TOKEN
++
++    /* Initialize rule variables
++     */
++
++
++     retval.result= NULL; retval.valid= 1; 
++    f       = NULL;
++    s       = NULL;
++    o = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        // RSP2SQL.g:155:2: ( ^(o= strop f= FIELD s= STR ) )
++        // RSP2SQL.g:155:4: ^(o= strop f= FIELD s= STR )
++        {
++            FOLLOWPUSH(FOLLOW_strop_in_strcrit233);
++            o=strop(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto rulestrcritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto rulestrcritEx;
++            }
++
++            f = (pANTLR3_BASE_TREE) MATCHT(FIELD, &FOLLOW_FIELD_in_strcrit239); 
++            if  (HASEXCEPTION())
++            {
++                goto rulestrcritEx;
++            }
++
++            s = (pANTLR3_BASE_TREE) MATCHT(STR, &FOLLOW_STR_in_strcrit245); 
++            if  (HASEXCEPTION())
++            {
++                goto rulestrcritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_UP, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto rulestrcritEx;
++            }
++
++            {
++
++                                      char *op;
++                                      const struct rsp_query_field_map *rqfp;
++                                      pANTLR3_STRING field;
++                                      char *escaped;
++                                      ANTLR3_UINT32 optok;
++
++                                      escaped = NULL;
++
++                                      op = NULL;
++                                      optok = o->getType(o);
++                                      switch (optok)
++                                      {
++                                              case EQUAL:
++                                                      op = " = ";
++                                                      break;
++
++                                              case INCLUDES:
++                                              case STARTSW:
++                                              case ENDSW:
++                                                      op = " LIKE ";
++                                                      break;
++                                      }
++
++                                      field = f->getText(f);
++
++                                      /* Field lookup */
++                                      rqfp = rsp_query_field_lookup((char *)field->chars, strlen((char *)field->chars));
++                                      if (!rqfp)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not a valid field in queries\n", field->chars);
++                                              retval.valid= 0;
++                                              goto strcrit_valid_0; /* ABORT */
++                                      }
++
++                                      /* Check field type */
++                                      if (rqfp->field_type != RSP_TYPE_STRING)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not a string field\n", field->chars);
++                                              retval.valid= 0;
++                                              goto strcrit_valid_0; /* ABORT */
++                                      }
++
++                                      escaped = db_escape_string((char *)s->getText(s)->chars);
++                                      if (!escaped)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Could not escape value\n");
++                                              retval.valid= 0;
++                                              goto strcrit_valid_0; /* ABORT */
++                                      }
++
++                                      retval.result= field->factory->newRaw(field->factory);
++                                      retval.result->append8(retval.result, "f.");
++                                      retval.result->appendS(retval.result, field);
++                                      retval.result->append8(retval.result, op);
++                                      retval.result->append8(retval.result, "'");
++                                      if ((optok == INCLUDES) || (optok == STARTSW))
++                                              retval.result->append8(retval.result, "%");
++
++                                      retval.result->append8(retval.result, escaped);
++
++                                      if ((optok == INCLUDES) || (optok == ENDSW))
++                                              retval.result->append8(retval.result, "%");
++                                      retval.result->append8(retval.result, "'");
++
++                                      strcrit_valid_0:
++                                              ;
++
++                                      if (escaped)
++                                              free(escaped);
++                              
++            }
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulestrcritEx; /* Prevent compiler warnings */
++    rulestrcritEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end strcrit */
++
++/** 
++ * $ANTLR start strop
++ * RSP2SQL.g:229:1: strop returns [ pANTLR3_COMMON_TOKEN op ] : (n= EQUAL | n= INCLUDES | n= STARTSW | n= ENDSW );
++ */
++static pANTLR3_COMMON_TOKEN
++strop(pRSP2SQL ctx)
++{   
++    pANTLR3_COMMON_TOKEN op = NULL;
++
++    pANTLR3_BASE_TREE    n;
++
++    /* Initialize rule variables
++     */
++
++
++     op= NULL; 
++    n       = NULL;
++
++    {
++        {
++            //  RSP2SQL.g:231:2: (n= EQUAL | n= INCLUDES | n= STARTSW | n= ENDSW )
++            
++            ANTLR3_UINT32 alt2;
++
++            alt2=4;
++
++            switch ( LA(1) ) 
++            {
++            case EQUAL:
++              {
++                      alt2=1;
++              }
++                break;
++            case INCLUDES:
++              {
++                      alt2=2;
++              }
++                break;
++            case STARTSW:
++              {
++                      alt2=3;
++              }
++                break;
++            case ENDSW:
++              {
++                      alt2=4;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 2;
++                EXCEPTION->state        = 0;
++
++
++                goto rulestropEx;
++            }
++
++            switch (alt2) 
++            {
++              case 1:
++                  // RSP2SQL.g:231:4: n= EQUAL
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(EQUAL, &FOLLOW_EQUAL_in_strop274); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestropEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:233:4: n= INCLUDES
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(INCLUDES, &FOLLOW_INCLUDES_in_strop287); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestropEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 3:
++                  // RSP2SQL.g:235:4: n= STARTSW
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(STARTSW, &FOLLOW_STARTSW_in_strop300); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestropEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 4:
++                  // RSP2SQL.g:237:4: n= ENDSW
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(ENDSW, &FOLLOW_ENDSW_in_strop313); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestropEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulestropEx; /* Prevent compiler warnings */
++    rulestropEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return op;
++}
++/* $ANTLR end strop */
++
++/** 
++ * $ANTLR start intcrit
++ * RSP2SQL.g:241:1: intcrit returns [ pANTLR3_STRING result, int valid ] : ^(o= intop f= FIELD i= INT ) ;
++ */
++static RSP2SQL_intcrit_return
++intcrit(pRSP2SQL ctx)
++{   
++    RSP2SQL_intcrit_return retval;
++
++    pANTLR3_BASE_TREE    f;
++    pANTLR3_BASE_TREE    i;
++    pANTLR3_COMMON_TOKEN o;
++    #undef    RETURN_TYPE_o
++    #define   RETURN_TYPE_o pANTLR3_COMMON_TOKEN
++
++    /* Initialize rule variables
++     */
++
++
++     retval.result= NULL; retval.valid= 1; 
++    f       = NULL;
++    i       = NULL;
++    o = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        // RSP2SQL.g:243:2: ( ^(o= intop f= FIELD i= INT ) )
++        // RSP2SQL.g:243:4: ^(o= intop f= FIELD i= INT )
++        {
++            FOLLOWPUSH(FOLLOW_intop_in_intcrit342);
++            o=intop(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruleintcritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto ruleintcritEx;
++            }
++
++            f = (pANTLR3_BASE_TREE) MATCHT(FIELD, &FOLLOW_FIELD_in_intcrit348); 
++            if  (HASEXCEPTION())
++            {
++                goto ruleintcritEx;
++            }
++
++            i = (pANTLR3_BASE_TREE) MATCHT(INT, &FOLLOW_INT_in_intcrit354); 
++            if  (HASEXCEPTION())
++            {
++                goto ruleintcritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_UP, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto ruleintcritEx;
++            }
++
++            {
++
++                                      char *op;
++                                      const struct rsp_query_field_map *rqfp;
++                                      pANTLR3_STRING field;
++
++                                      op = NULL;
++                                      switch (o->getType(o))
++                                      {
++                                              case EQUAL:
++                                                      op = " = ";
++                                                      break;
++
++                                              case LESS:
++                                                      op = " < ";
++                                                      break;
++
++                                              case GREATER:
++                                                      op = " > ";
++                                                      break;
++
++                                              case LTE:
++                                                      op = " <= ";
++                                                      break;
++
++                                              case GTE:
++                                                      op = " >= ";
++                                                      break;
++                                      }
++
++                                      field = f->getText(f);
++
++                                      /* Field lookup */
++                                      rqfp = rsp_query_field_lookup((char *)field->chars, strlen((char *)field->chars));
++                                      if (!rqfp)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not a valid field in queries\n", field->chars);
++                                              retval.valid= 0;
++                                              goto intcrit_valid_0; /* ABORT */
++                                      }
++
++                                      /* Check field type */
++                                      if (rqfp->field_type != RSP_TYPE_INT)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not an integer field\n", field->chars);
++                                              retval.valid= 0;
++                                              goto intcrit_valid_0; /* ABORT */
++                                      }
++
++                                      retval.result= field->factory->newRaw(field->factory);
++                                      retval.result->append8(retval.result, "f.");
++                                      retval.result->appendS(retval.result, field);
++                                      retval.result->append8(retval.result, op);
++                                      retval.result->appendS(retval.result, i->getText(i));
++
++                                      intcrit_valid_0:
++                                              ;
++                              
++            }
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleintcritEx; /* Prevent compiler warnings */
++    ruleintcritEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end intcrit */
++
++/** 
++ * $ANTLR start intop
++ * RSP2SQL.g:303:1: intop returns [ pANTLR3_COMMON_TOKEN op ] : (n= EQUAL | n= LESS | n= GREATER | n= LTE | n= GTE );
++ */
++static pANTLR3_COMMON_TOKEN
++intop(pRSP2SQL ctx)
++{   
++    pANTLR3_COMMON_TOKEN op = NULL;
++
++    pANTLR3_BASE_TREE    n;
++
++    /* Initialize rule variables
++     */
++
++
++     op= NULL; 
++    n       = NULL;
++
++    {
++        {
++            //  RSP2SQL.g:305:2: (n= EQUAL | n= LESS | n= GREATER | n= LTE | n= GTE )
++            
++            ANTLR3_UINT32 alt3;
++
++            alt3=5;
++
++            switch ( LA(1) ) 
++            {
++            case EQUAL:
++              {
++                      alt3=1;
++              }
++                break;
++            case LESS:
++              {
++                      alt3=2;
++              }
++                break;
++            case GREATER:
++              {
++                      alt3=3;
++              }
++                break;
++            case LTE:
++              {
++                      alt3=4;
++              }
++                break;
++            case GTE:
++              {
++                      alt3=5;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 3;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleintopEx;
++            }
++
++            switch (alt3) 
++            {
++              case 1:
++                  // RSP2SQL.g:305:4: n= EQUAL
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(EQUAL, &FOLLOW_EQUAL_in_intop383); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:307:4: n= LESS
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(LESS, &FOLLOW_LESS_in_intop396); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 3:
++                  // RSP2SQL.g:309:4: n= GREATER
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(GREATER, &FOLLOW_GREATER_in_intop409); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 4:
++                  // RSP2SQL.g:311:4: n= LTE
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(LTE, &FOLLOW_LTE_in_intop422); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 5:
++                  // RSP2SQL.g:313:4: n= GTE
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(GTE, &FOLLOW_GTE_in_intop435); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleintopEx; /* Prevent compiler warnings */
++    ruleintopEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return op;
++}
++/* $ANTLR end intop */
++
++/** 
++ * $ANTLR start datecrit
++ * RSP2SQL.g:317:1: datecrit returns [ pANTLR3_STRING result, int valid ] : ^(o= dateop f= FIELD d= datespec ) ;
++ */
++static RSP2SQL_datecrit_return
++datecrit(pRSP2SQL ctx)
++{   
++    RSP2SQL_datecrit_return retval;
++
++    pANTLR3_BASE_TREE    f;
++    pANTLR3_COMMON_TOKEN o;
++    #undef    RETURN_TYPE_o
++    #define   RETURN_TYPE_o pANTLR3_COMMON_TOKEN
++
++    RSP2SQL_datespec_return d;
++    #undef    RETURN_TYPE_d
++    #define   RETURN_TYPE_d RSP2SQL_datespec_return
++
++    /* Initialize rule variables
++     */
++
++
++     retval.result= NULL; retval.valid= 1; 
++    f       = NULL;
++    o = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        // RSP2SQL.g:319:2: ( ^(o= dateop f= FIELD d= datespec ) )
++        // RSP2SQL.g:319:4: ^(o= dateop f= FIELD d= datespec )
++        {
++            FOLLOWPUSH(FOLLOW_dateop_in_datecrit464);
++            o=dateop(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++            f = (pANTLR3_BASE_TREE) MATCHT(FIELD, &FOLLOW_FIELD_in_datecrit470); 
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++            FOLLOWPUSH(FOLLOW_datespec_in_datecrit476);
++            d=datespec(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++
++            MATCHT(ANTLR3_TOKEN_UP, NULL); 
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++            {
++
++                                      char *op;
++                                      const struct rsp_query_field_map *rqfp;
++                                      pANTLR3_STRING field;
++                                      char buf[32];
++                                      int ret;
++
++                                      op = NULL;
++                                      switch (o->getType(o))
++                                      {
++                                              case BEFORE:
++                                                      op = " < ";
++                                                      break;
++
++                                              case AFTER:
++                                                      op = " > ";
++                                                      break;
++                                      }
++
++                                      field = f->getText(f);
++
++                                      /* Field lookup */
++                                      rqfp = rsp_query_field_lookup((char *)field->chars, strlen((char *)field->chars));
++                                      if (!rqfp)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not a valid field in queries\n", field->chars);
++                                              retval.valid= 0;
++                                              goto datecrit_valid_0; /* ABORT */
++                                      }
++
++                                      /* Check field type */
++                                      if (rqfp->field_type != RSP_TYPE_DATE)
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Field '%s' is not a date field\n", field->chars);
++                                              retval.valid= 0;
++                                              goto datecrit_valid_0; /* ABORT */
++                                      }
++
++                                      ret = snprintf(buf, sizeof(buf), "%ld", d.date);
++                                      if ((ret < 0) || (ret >= sizeof(buf)))
++                                      {
++                                              DPRINTF(E_LOG, L_RSP, "Date %ld too large for buffer, oops!\n", d.date);
++                                              retval.valid= 0;
++                                              goto datecrit_valid_0; /* ABORT */
++                                      }
++
++                                      retval.result= field->factory->newRaw(field->factory);
++                                      retval.result->append8(retval.result, "f.");
++                                      retval.result->appendS(retval.result, field);
++                                      retval.result->append8(retval.result, op);
++                                      retval.result->append8(retval.result, buf);
++
++                                      datecrit_valid_0:
++                                              ;
++                              
++            }
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledatecritEx; /* Prevent compiler warnings */
++    ruledatecritEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end datecrit */
++
++/** 
++ * $ANTLR start dateop
++ * RSP2SQL.g:377:1: dateop returns [ pANTLR3_COMMON_TOKEN op ] : (n= BEFORE | n= AFTER );
++ */
++static pANTLR3_COMMON_TOKEN
++dateop(pRSP2SQL ctx)
++{   
++    pANTLR3_COMMON_TOKEN op = NULL;
++
++    pANTLR3_BASE_TREE    n;
++
++    /* Initialize rule variables
++     */
++
++
++     op= NULL; 
++    n       = NULL;
++
++    {
++        {
++            //  RSP2SQL.g:379:2: (n= BEFORE | n= AFTER )
++            
++            ANTLR3_UINT32 alt4;
++
++            alt4=2;
++
++            switch ( LA(1) ) 
++            {
++            case BEFORE:
++              {
++                      alt4=1;
++              }
++                break;
++            case AFTER:
++              {
++                      alt4=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 4;
++                EXCEPTION->state        = 0;
++
++
++                goto ruledateopEx;
++            }
++
++            switch (alt4) 
++            {
++              case 1:
++                  // RSP2SQL.g:379:4: n= BEFORE
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(BEFORE, &FOLLOW_BEFORE_in_dateop505); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:381:4: n= AFTER
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(AFTER, &FOLLOW_AFTER_in_dateop518); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateopEx;
++                      }
++
++                      {
++                           op= n->getToken(n); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledateopEx; /* Prevent compiler warnings */
++    ruledateopEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return op;
++}
++/* $ANTLR end dateop */
++
++/** 
++ * $ANTLR start datespec
++ * RSP2SQL.g:385:1: datespec returns [ time_t date, int valid ] : (r= dateref | ^(o= dateop r= dateref m= INT i= dateintval ) );
++ */
++static RSP2SQL_datespec_return
++datespec(pRSP2SQL ctx)
++{   
++    RSP2SQL_datespec_return retval;
++
++    pANTLR3_BASE_TREE    m;
++    RSP2SQL_dateref_return r;
++    #undef    RETURN_TYPE_r
++    #define   RETURN_TYPE_r RSP2SQL_dateref_return
++
++    pANTLR3_COMMON_TOKEN o;
++    #undef    RETURN_TYPE_o
++    #define   RETURN_TYPE_o pANTLR3_COMMON_TOKEN
++
++    RSP2SQL_dateintval_return i;
++    #undef    RETURN_TYPE_i
++    #define   RETURN_TYPE_i RSP2SQL_dateintval_return
++
++    /* Initialize rule variables
++     */
++
++
++     retval.date= 0; retval.valid= 1; 
++    m       = NULL;
++    o = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        {
++            //  RSP2SQL.g:387:2: (r= dateref | ^(o= dateop r= dateref m= INT i= dateintval ) )
++            
++            ANTLR3_UINT32 alt5;
++
++            alt5=2;
++
++            switch ( LA(1) ) 
++            {
++            case DATE:
++            case TODAY:
++              {
++                      alt5=1;
++              }
++                break;
++            case BEFORE:
++            case AFTER:
++              {
++                      alt5=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 5;
++                EXCEPTION->state        = 0;
++
++
++                goto ruledatespecEx;
++            }
++
++            switch (alt5) 
++            {
++              case 1:
++                  // RSP2SQL.g:387:4: r= dateref
++                  {
++                      FOLLOWPUSH(FOLLOW_dateref_in_datespec546);
++                      r=dateref(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      {
++
++                                              if (!r.valid)
++                                                      retval.valid= 0;
++                                              else
++                                                      retval.date= r.date;
++                                      
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:394:4: ^(o= dateop r= dateref m= INT i= dateintval )
++                  {
++                      FOLLOWPUSH(FOLLOW_dateop_in_datespec560);
++                      o=dateop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_DOWN, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_dateref_in_datespec566);
++                      r=dateref(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      m = (pANTLR3_BASE_TREE) MATCHT(INT, &FOLLOW_INT_in_datespec572); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      FOLLOWPUSH(FOLLOW_dateintval_in_datespec578);
++                      i=dateintval(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++
++                      MATCHT(ANTLR3_TOKEN_UP, NULL); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      {
++
++                                              int32_t val;
++                                              int ret;
++
++                                              if (!r.valid || !i.valid)
++                                              {
++                                                      retval.valid= 0;
++                                                      goto datespec_valid_0; /* ABORT */
++                                              }
++
++                                              ret = safe_atoi32((char *)m->getText(m)->chars, &val);
++                                              if (ret < 0)
++                                              {
++                                                      DPRINTF(E_LOG, L_RSP, "Could not convert '%s' to integer\n", (char *)m->getText(m));
++                                                      retval.valid= 0;
++                                                      goto datespec_valid_0; /* ABORT */
++                                              }
++
++                                              switch (o->getType(o))
++                                              {
++                                                      case BEFORE:
++                                                              retval.date= r.date - (val * i.period);
++                                                              break;
++
++                                                      case AFTER:
++                                                              retval.date= r.date + (val * i.period);
++                                                              break;
++                                              }
++
++                                              datespec_valid_0:
++                                                      ;
++                                      
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledatespecEx; /* Prevent compiler warnings */
++    ruledatespecEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end datespec */
++
++/** 
++ * $ANTLR start dateref
++ * RSP2SQL.g:429:1: dateref returns [ time_t date, int valid ] : (n= DATE | TODAY );
++ */
++static RSP2SQL_dateref_return
++dateref(pRSP2SQL ctx)
++{   
++    RSP2SQL_dateref_return retval;
++
++    pANTLR3_BASE_TREE    n;
++
++    /* Initialize rule variables
++     */
++
++
++     retval.date= 0; retval.valid= 1; 
++    n       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        {
++            //  RSP2SQL.g:431:2: (n= DATE | TODAY )
++            
++            ANTLR3_UINT32 alt6;
++
++            alt6=2;
++
++            switch ( LA(1) ) 
++            {
++            case DATE:
++              {
++                      alt6=1;
++              }
++                break;
++            case TODAY:
++              {
++                      alt6=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 6;
++                EXCEPTION->state        = 0;
++
++
++                goto ruledaterefEx;
++            }
++
++            switch (alt6) 
++            {
++              case 1:
++                  // RSP2SQL.g:431:4: n= DATE
++                  {
++                      n = (pANTLR3_BASE_TREE) MATCHT(DATE, &FOLLOW_DATE_in_dateref607); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledaterefEx;
++                      }
++
++                      {
++
++                                              struct tm tm;
++                                              char *ret;
++
++                                              ret = strptime((char *)n->getText(n), "%Y-%m-%d", &tm);
++                                              if (!ret)
++                                              {
++                                                      DPRINTF(E_LOG, L_RSP, "Date '%s' could not be interpreted\n", (char *)n->getText(n));
++                                                      retval.valid= 0;
++                                                      goto dateref_valid_0; /* ABORT */
++                                              }
++                                              else
++                                              {
++                                                      if (*ret != '\0')
++                                                              DPRINTF(E_LOG, L_RSP, "Garbage at end of date '%s' ?!\n", (char *)n->getText(n));
++
++                                                      retval.date= mktime(&tm);
++                                                      if (retval.date == (time_t) -1)
++                                                      {
++                                                              DPRINTF(E_LOG, L_RSP, "Date '%s' could not be converted to an epoch\n", (char *)n->getText(n));
++                                                              retval.valid= 0;
++                                                              goto dateref_valid_0; /* ABORT */
++                                                      }
++                                              }
++
++                                              dateref_valid_0:
++                                                      ;
++                                      
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:460:4: TODAY
++                  {
++                       MATCHT(TODAY, &FOLLOW_TODAY_in_dateref616); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledaterefEx;
++                      }
++
++                      {
++                           retval.date= time(NULL); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledaterefEx; /* Prevent compiler warnings */
++    ruledaterefEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end dateref */
++
++/** 
++ * $ANTLR start dateintval
++ * RSP2SQL.g:464:1: dateintval returns [ time_t period, int valid ] : ( DAY | WEEK | MONTH | YEAR );
++ */
++static RSP2SQL_dateintval_return
++dateintval(pRSP2SQL ctx)
++{   
++    RSP2SQL_dateintval_return retval;
++
++    /* Initialize rule variables
++     */
++
++
++     retval.period= 0; retval.valid= 1; 
++    retval.start = LT(1); retval.stop = retval.start;
++
++    {
++        {
++            //  RSP2SQL.g:466:2: ( DAY | WEEK | MONTH | YEAR )
++            
++            ANTLR3_UINT32 alt7;
++
++            alt7=4;
++
++            switch ( LA(1) ) 
++            {
++            case DAY:
++              {
++                      alt7=1;
++              }
++                break;
++            case WEEK:
++              {
++                      alt7=2;
++              }
++                break;
++            case MONTH:
++              {
++                      alt7=3;
++              }
++                break;
++            case YEAR:
++              {
++                      alt7=4;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 7;
++                EXCEPTION->state        = 0;
++
++
++                goto ruledateintvalEx;
++            }
++
++            switch (alt7) 
++            {
++              case 1:
++                  // RSP2SQL.g:466:4: DAY
++                  {
++                       MATCHT(DAY, &FOLLOW_DAY_in_dateintval640); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateintvalEx;
++                      }
++
++                      {
++                           retval.period= 24 * 60 * 60; 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP2SQL.g:468:4: WEEK
++                  {
++                       MATCHT(WEEK, &FOLLOW_WEEK_in_dateintval649); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateintvalEx;
++                      }
++
++                      {
++                           retval.period= 7 * 24 * 60 * 60; 
++                      }
++
++                  }
++                  break;
++              case 3:
++                  // RSP2SQL.g:470:4: MONTH
++                  {
++                       MATCHT(MONTH, &FOLLOW_MONTH_in_dateintval658); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateintvalEx;
++                      }
++
++                      {
++                           retval.period= 30 * 24 * 60 * 60; 
++                      }
++
++                  }
++                  break;
++              case 4:
++                  // RSP2SQL.g:472:4: YEAR
++                  {
++                       MATCHT(YEAR, &FOLLOW_YEAR_in_dateintval667); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledateintvalEx;
++                      }
++
++                      {
++                           retval.period= 365 * 24 * 60 * 60; 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledateintvalEx; /* Prevent compiler warnings */
++    ruledateintvalEx: ;
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++            }
++
++
++    return retval;
++}
++/* $ANTLR end dateintval */
++/* End of parsing rules
++ * ==============================================
++ */
++
++/* ==============================================
++ * Syntactic predicates
++ */
++/* End of syntactic predicates
++ * ==============================================
++ */
++
++ 
++ 
++
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/RSP2SQL.h b/src/pregen/RSP2SQL.h
+new file mode 100644
+index 0000000..2789fc7
+--- /dev/null
++++ b/src/pregen/RSP2SQL.h
+@@ -0,0 +1,291 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP2SQL.g
++ *     -                            On : 2014-09-30 21:42:42
++ *     -           for the tree parser : RSP2SQLTreeParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The tree parser RSP2SQL has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pRSP2SQL, which is returned from a call to RSP2SQLNew().
++ *
++ * The methods in pRSP2SQL are  as follows:
++ *
++ *  - pANTLR3_STRING      pRSP2SQL->query(pRSP2SQL)
++ *  - RSP2SQL_expr_return      pRSP2SQL->expr(pRSP2SQL)
++ *  - RSP2SQL_strcrit_return      pRSP2SQL->strcrit(pRSP2SQL)
++ *  - pANTLR3_COMMON_TOKEN      pRSP2SQL->strop(pRSP2SQL)
++ *  - RSP2SQL_intcrit_return      pRSP2SQL->intcrit(pRSP2SQL)
++ *  - pANTLR3_COMMON_TOKEN      pRSP2SQL->intop(pRSP2SQL)
++ *  - RSP2SQL_datecrit_return      pRSP2SQL->datecrit(pRSP2SQL)
++ *  - pANTLR3_COMMON_TOKEN      pRSP2SQL->dateop(pRSP2SQL)
++ *  - RSP2SQL_datespec_return      pRSP2SQL->datespec(pRSP2SQL)
++ *  - RSP2SQL_dateref_return      pRSP2SQL->dateref(pRSP2SQL)
++ *  - RSP2SQL_dateintval_return      pRSP2SQL->dateintval(pRSP2SQL)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _RSP2SQL_H
++#define _RSP2SQL_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct RSP2SQL_Ctx_struct RSP2SQL, * pRSP2SQL;
++
++
++
++      /* Needs #define _GNU_SOURCE for strptime() */
++
++      #include <stdio.h>
++      #include <string.h>
++      #include <time.h>
++      #include <stdint.h>
++
++      #include "logger.h"
++      #include "db.h"
++      #include "misc.h"
++      #include "rsp_query.h"
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++typedef struct RSP2SQL_expr_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    pANTLR3_STRING result;
++    int valid;
++}
++    RSP2SQL_expr_return;
++
++typedef struct RSP2SQL_strcrit_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    pANTLR3_STRING result;
++    int valid;
++}
++    RSP2SQL_strcrit_return;
++
++typedef struct RSP2SQL_intcrit_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    pANTLR3_STRING result;
++    int valid;
++}
++    RSP2SQL_intcrit_return;
++
++typedef struct RSP2SQL_datecrit_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    pANTLR3_STRING result;
++    int valid;
++}
++    RSP2SQL_datecrit_return;
++
++typedef struct RSP2SQL_datespec_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    time_t date;
++    int valid;
++}
++    RSP2SQL_datespec_return;
++
++typedef struct RSP2SQL_dateref_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    time_t date;
++    int valid;
++}
++    RSP2SQL_dateref_return;
++
++typedef struct RSP2SQL_dateintval_return_struct
++{
++    pANTLR3_BASE_TREE       start;
++    pANTLR3_BASE_TREE       stop;   
++    time_t period;
++    int valid;
++}
++    RSP2SQL_dateintval_return;
++
++
++
++/** Context tracking structure for RSP2SQL
++ */
++struct RSP2SQL_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_TREE_PARSER           pTreeParser;
++
++
++     pANTLR3_STRING (*query)  (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_expr_return (*expr)      (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_strcrit_return (*strcrit)        (struct RSP2SQL_Ctx_struct * ctx);
++     pANTLR3_COMMON_TOKEN (*strop)    (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_intcrit_return (*intcrit)        (struct RSP2SQL_Ctx_struct * ctx);
++     pANTLR3_COMMON_TOKEN (*intop)    (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_datecrit_return (*datecrit)      (struct RSP2SQL_Ctx_struct * ctx);
++     pANTLR3_COMMON_TOKEN (*dateop)   (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_datespec_return (*datespec)      (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_dateref_return (*dateref)        (struct RSP2SQL_Ctx_struct * ctx);
++     RSP2SQL_dateintval_return (*dateintval)  (struct RSP2SQL_Ctx_struct * ctx);
++    // Delegated rules
++    const char * (*getGrammarFileName)();
++    void          (*free)   (struct RSP2SQL_Ctx_struct * ctx);
++        
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pRSP2SQL RSP2SQLNew         (pANTLR3_COMMON_TREE_NODE_STREAM instream);
++ANTLR3_API pRSP2SQL RSP2SQLNewSSD      (pANTLR3_COMMON_TREE_NODE_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the tree parser will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STARTSW      14
++#define WEEK      26
++#define TODAY      24
++#define YEAR      28
++#define ENDSW      15
++#define GTE      20
++#define BEFORE      21
++#define DAY      25
++#define INT      16
++#define NOT      11
++#define AFTER      22
++#define AND      6
++#define EOF      -1
++#define LTE      19
++#define MONTH      27
++#define DIGIT19      31
++#define INCLUDES      13
++#define STR      10
++#define QUOTE      29
++#define GREATER      18
++#define WS      30
++#define LPAR      7
++#define NEWLINE      4
++#define EQUAL      12
++#define OR      5
++#define LESS      17
++#define FIELD      9
++#define RPAR      8
++#define ESCAPED      33
++#define DATE      23
++#define DIGIT09      32
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for RSP2SQL
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
+diff --git a/src/pregen/RSP2SQL.u b/src/pregen/RSP2SQL.u
+new file mode 100644
+index 0000000..53d8cda
+--- /dev/null
++++ b/src/pregen/RSP2SQL.u
+@@ -0,0 +1,5 @@
++RSP2SQL.g: RSP.tokens
++RSP2SQL.c : RSP2SQL.g
++./RSP2SQL.tokens : RSP2SQL.g
++RSP2SQL.h : RSP2SQL.g
++ANTLR_PRODUCTS += RSP2SQL.c ./RSP2SQL.tokens RSP2SQL.h 
+\ No newline at end of file
+diff --git a/src/pregen/RSPLexer.c b/src/pregen/RSPLexer.c
+new file mode 100644
+index 0000000..ee23c08
+--- /dev/null
++++ b/src/pregen/RSPLexer.c
+@@ -0,0 +1,4867 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP.g
++ *     -                            On : 2014-09-30 21:42:41
++ *     -                 for the lexer : RSPLexerLexer *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
++
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "RSPLexer.h"
++/* ----------------------------------------- */
++
++
++/** String literals used by RSPLexer that we must do things like MATCHS() with.
++ *  C will normally just lay down 8 bit characters, and you can use L"xxx" to
++ *  get wchar_t, but wchar_t is 16 bits on Windows, which is not UTF32 and so
++ *  we perform this little trick of defining the literals as arrays of UINT32
++ *  and passing in the address of these.
++ */
++static ANTLR3_UCHAR   lit_1[]  = { 0x61, 0x6E, 0x64,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_2[]  = { 0x6F, 0x72,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_3[]  = { 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x73,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_4[]  = { 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x77, 0x69, 0x74, 0x68,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_5[]  = { 0x65, 0x6E, 0x64, 0x73, 0x77, 0x69, 0x74, 0x68,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_6[]  = { 0x3E, 0x3D,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_7[]  = { 0x3C, 0x3D,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_8[]  = { 0x62, 0x65, 0x66, 0x6F, 0x72, 0x65,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_9[]  = { 0x61, 0x66, 0x74, 0x65, 0x72,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_10[]  = { 0x64, 0x61, 0x79,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_11[]  = { 0x64, 0x61, 0x79, 0x73,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_12[]  = { 0x77, 0x65, 0x65, 0x6B,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_13[]  = { 0x77, 0x65, 0x65, 0x6B, 0x73,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_14[]  = { 0x6D, 0x6F, 0x6E, 0x74, 0x68,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_15[]  = { 0x6D, 0x6F, 0x6E, 0x74, 0x68, 0x73,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_16[]  = { 0x79, 0x65, 0x61, 0x72,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_17[]  = { 0x79, 0x65, 0x61, 0x72, 0x73,  ANTLR3_STRING_TERMINATOR};
++static ANTLR3_UCHAR   lit_18[]  = { 0x74, 0x6F, 0x64, 0x61, 0x79,  ANTLR3_STRING_TERMINATOR};
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pRSPLexer_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pRSPLexer_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pRSPLexer_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pRSPLexer_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++ 
++/* Macros for accessing things in a lexer
++ */
++#undef            LEXER
++#undef            RECOGNIZER              
++#undef            RULEMEMO                
++#undef            GETCHARINDEX
++#undef            GETLINE
++#undef            GETCHARPOSITIONINLINE
++#undef            EMIT
++#undef            EMITNEW
++#undef            MATCHC
++#undef            MATCHS
++#undef            MATCHRANGE
++#undef            LTOKEN
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            INPUT
++#undef            STRSTREAM
++#undef            LA
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            LRECOVER
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            BACKTRACKING
++#undef                MATCHANY
++#undef                MEMOIZE
++#undef                HAVEPARSEDRULE
++#undef                GETTEXT
++#undef                INDEX
++#undef                SEEK
++#undef                PUSHSTREAM
++#undef                POPSTREAM
++#undef                SETTEXT
++#undef                SETTEXT8
++
++#define           LEXER                                       ctx->pLexer
++#define           RECOGNIZER                      LEXER->rec
++#define               LEXSTATE                                RECOGNIZER->state
++#define               TOKSOURCE                               LEXSTATE->tokSource
++#define           GETCHARINDEX()                      LEXER->getCharIndex(LEXER)
++#define           GETLINE()                           LEXER->getLine(LEXER)
++#define           GETTEXT()                           LEXER->getText(LEXER)
++#define           GETCHARPOSITIONINLINE() LEXER->getCharPositionInLine(LEXER)
++#define           EMIT()                                      LEXSTATE->type = _type; LEXER->emit(LEXER)
++#define           EMITNEW(t)                          LEXER->emitNew(LEXER, t)
++#define           MATCHC(c)                           LEXER->matchc(LEXER, c)
++#define           MATCHS(s)                           LEXER->matchs(LEXER, s)
++#define           MATCHRANGE(c1,c2)       LEXER->matchRange(LEXER, c1, c2)
++#define           MATCHANY()                          LEXER->matchAny(LEXER)
++#define           LTOKEN                              LEXSTATE->token
++#define           HASFAILED()                         (LEXSTATE->failed == ANTLR3_TRUE)
++#define           BACKTRACKING                        LEXSTATE->backtracking
++#define           FAILEDFLAG                          LEXSTATE->failed
++#define           INPUT                                       LEXER->input
++#define           STRSTREAM                           INPUT
++#define               ISTREAM                                 INPUT->istream
++#define               INDEX()                                 ISTREAM->index(ISTREAM)
++#define               SEEK(n)                                 ISTREAM->seek(ISTREAM, n)
++#define           EOF_TOKEN                           &(LEXSTATE->tokSource->eofToken)
++#define           HASEXCEPTION()                      (LEXSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                           LEXSTATE->exception
++#define           CONSTRUCTEX()                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           LRECOVER()                          LEXER->recover(LEXER)
++#define           MARK()                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                        ISTREAM->rewindLast(ISTREAM)
++#define               MEMOIZE(ri,si)                  RECOGNIZER->memoize(RECOGNIZER, ri, si)
++#define               HAVEPARSEDRULE(r)               RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define               PUSHSTREAM(str)                 LEXER->pushCharStream(LEXER, str)
++#define               POPSTREAM()                             LEXER->popCharStream(LEXER)
++#define               SETTEXT(str)                    LEXSTATE->text = str
++#define               SKIP()                                  LEXSTATE->token = &(TOKSOURCE->skipToken)
++#define               USER1                                   LEXSTATE->user1
++#define               USER2                                   LEXSTATE->user2
++#define               USER3                                   LEXSTATE->user3
++#define               CUSTOM                                  LEXSTATE->custom
++#define               RULEMEMO                                LEXSTATE->ruleMemo
++#define               DBG                                             RECOGNIZER->debugger
++
++/* If we have been told we can rely on the standard 8 bit or 16 bit input
++ * stream, then we can define our macros to use the direct pointers
++ * in the input object, which is much faster than indirect calls. This
++ * is really only significant to lexers with a lot of fragment rules (which
++ * do not place LA(1) in a temporary at the moment) and even then
++ * only if there is a lot of input (order of say 1M or so).
++ */
++#if   defined(ANTLR3_INLINE_INPUT_ASCII) || defined(ANTLR3_INLINE_INPUT_UTF16)
++
++# ifdef       ANTLR3_INLINE_INPUT_ASCII
++
++/* 8 bit "ASCII" (actually any 8 bit character set) */
++
++#  define         NEXTCHAR                    ((pANTLR3_UINT8)(INPUT->nextChar))
++#  define         DATAP                               ((pANTLR3_UINT8)(INPUT->data))
++
++# else
++
++#  define         NEXTCHAR                    ((pANTLR3_UINT16)(INPUT->nextChar)) 
++#  define         DATAP                               ((pANTLR3_UINT16)(INPUT->data))
++
++# endif
++
++# define          LA(n) ((NEXTCHAR + n) > (DATAP + INPUT->sizeBuf) ? ANTLR3_CHARSTREAM_EOF : (ANTLR3_UCHAR)(*(NEXTCHAR + n - 1)))
++# define          CONSUME()                                                                                   \
++{                                                                                                                                     \
++    if        (NEXTCHAR < (DATAP + INPUT->sizeBuf))                                           \
++    {                                                                                                                         \
++              INPUT->charPositionInLine++;                                                            \
++              if  ((ANTLR3_UCHAR)(*NEXTCHAR) == INPUT->newlineChar)           \
++              {                                                                                                                       \
++                      INPUT->line++;                                                                                  \
++                      INPUT->charPositionInLine       = 0;                                            \
++                      INPUT->currentLine              = (void *)(NEXTCHAR + 1);               \
++              }                                                                                                                       \
++              INPUT->nextChar = (void *)(NEXTCHAR + 1);                                       \
++    }                                                                                                                         \
++}
++
++#else
++
++// Pick up the input character by calling the input stream implementation.
++//
++#define           CONSUME()                           INPUT->istream->consume(INPUT->istream)
++#define           LA(n)                                       INPUT->istream->_LA(INPUT->istream, n)
++
++#endif
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++/* Forward declare the locally static matching functions we have generated and any predicate functions.
++ */
++static ANTLR3_INLINE  void    mQUOTE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mLPAR    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mRPAR    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mAND    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mOR    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mNOT    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mEQUAL    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mINCLUDES    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mSTARTSW    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mENDSW    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mGREATER    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mLESS    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mGTE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mLTE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mBEFORE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mAFTER    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mDAY    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mWEEK    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mMONTH    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mYEAR    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mTODAY    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mNEWLINE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mWS    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mFIELD    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mINT    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mDATE    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mSTR    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mESCAPED    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mDIGIT09    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mDIGIT19    (pRSPLexer ctx);
++static ANTLR3_INLINE  void    mTokens    (pRSPLexer ctx);
++static void   RSPLexerFree(pRSPLexer ctx);
++
++/* =========================================================================
++ * Lexer matching rules end.
++ * =========================================================================
++ */
++
++
++
++static void
++RSPLexerFree  (pRSPLexer ctx)
++{
++    LEXER->free(LEXER);
++    
++    ANTLR3_FREE(ctx);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "RSP.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++
++/** \brief Create a new lexer called RSPLexer
++ *
++ * \param[in]    instream Pointer to an initialized input stream
++ * \return 
++ *     - Success pRSPLexer initialized for the lex start
++ *     - Fail NULL
++ */
++ANTLR3_API pRSPLexer RSPLexerNew         
++(pANTLR3_INPUT_STREAM instream)
++{
++      // See if we can create a new lexer with the standard constructor
++      //
++      return RSPLexerNewSSD(instream, NULL);
++}
++
++/** \brief Create a new lexer called RSPLexer
++ *
++ * \param[in]    instream Pointer to an initialized input stream
++ * \param[state] state Previously created shared recognizer stat
++ * \return 
++ *     - Success pRSPLexer initialized for the lex start
++ *     - Fail NULL
++ */
++ANTLR3_API pRSPLexer RSPLexerNewSSD         
++(pANTLR3_INPUT_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pRSPLexer ctx; // Context structure we will build and return
++
++    ctx = (pRSPLexer) ANTLR3_CALLOC(1, sizeof(RSPLexer));
++
++    if  (ctx == NULL)
++    {
++        // Failed to allocate memory for lexer context
++        return  NULL;
++    }
++
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * in base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 lexer function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in RSPLexer.h here so you can get a sense
++     * of what goes where.
++     */
++    
++    /* Create a base lexer, using the supplied input stream
++     */
++    ctx->pLexer       = antlr3LexerNewStream(ANTLR3_SIZE_HINT, instream, state);
++    
++    /* Check that we allocated the memory correctly
++     */
++    if        (ctx->pLexer == NULL)
++    {
++              ANTLR3_FREE(ctx);
++              return  NULL;
++    }
++    /* Install the implementation of our RSPLexer interface
++     */
++    ctx->mQUOTE       = mQUOTE;
++    ctx->mLPAR        = mLPAR;
++    ctx->mRPAR        = mRPAR;
++    ctx->mAND = mAND;
++    ctx->mOR  = mOR;
++    ctx->mNOT = mNOT;
++    ctx->mEQUAL       = mEQUAL;
++    ctx->mINCLUDES    = mINCLUDES;
++    ctx->mSTARTSW     = mSTARTSW;
++    ctx->mENDSW       = mENDSW;
++    ctx->mGREATER     = mGREATER;
++    ctx->mLESS        = mLESS;
++    ctx->mGTE = mGTE;
++    ctx->mLTE = mLTE;
++    ctx->mBEFORE      = mBEFORE;
++    ctx->mAFTER       = mAFTER;
++    ctx->mDAY = mDAY;
++    ctx->mWEEK        = mWEEK;
++    ctx->mMONTH       = mMONTH;
++    ctx->mYEAR        = mYEAR;
++    ctx->mTODAY       = mTODAY;
++    ctx->mNEWLINE     = mNEWLINE;
++    ctx->mWS  = mWS;
++    ctx->mFIELD       = mFIELD;
++    ctx->mINT = mINT;
++    ctx->mDATE        = mDATE;
++    ctx->mSTR = mSTR;
++    ctx->mESCAPED     = mESCAPED;
++    ctx->mDIGIT09     = mDIGIT09;
++    ctx->mDIGIT19     = mDIGIT19;
++    ctx->mTokens      = mTokens;
++    
++    /** When the nextToken() call is made to this lexer's pANTLR3_TOKEN_SOURCE
++     *  it will call mTokens() in this generated code, and will pass it the ctx
++     * pointer of this lexer, not the context of the base lexer, so store that now.
++     */
++    ctx->pLexer->ctx      = ctx;
++    
++    /**Install the token matching function
++     */
++    ctx->pLexer->mTokens = (void (*) (void *))(mTokens);
++    
++    ctx->getGrammarFileName   = getGrammarFileName;
++    ctx->free         = RSPLexerFree;
++
++    
++    
++
++
++    /* Return the newly built lexer to the caller
++     */
++    return  ctx;
++}
++ 
++
++/* =========================================================================
++ * Functions to match the lexer grammar defined tokens from the input stream
++ */
++
++//   Comes from: 85:7: ( '\"' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start QUOTE
++ *
++ * Looks to match the characters the constitute the token QUOTE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mQUOTE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = QUOTE;
++       
++    
++    // RSP.g:85:7: ( '\"' )
++    // RSP.g:85:9: '\"'
++    {
++        MATCHC('"'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleQUOTEEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleQUOTEEx; /* Prevent compiler warnings */
++    ruleQUOTEEx: ;
++
++}
++// $ANTLR end QUOTE
++
++//   Comes from: 86:6: ( '(' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start LPAR
++ *
++ * Looks to match the characters the constitute the token LPAR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mLPAR(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = LPAR;
++       
++    
++    // RSP.g:86:6: ( '(' )
++    // RSP.g:86:8: '('
++    {
++        MATCHC('('); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleLPAREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleLPAREx; /* Prevent compiler warnings */
++    ruleLPAREx: ;
++
++}
++// $ANTLR end LPAR
++
++//   Comes from: 87:6: ( ')' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start RPAR
++ *
++ * Looks to match the characters the constitute the token RPAR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mRPAR(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = RPAR;
++       
++    
++    // RSP.g:87:6: ( ')' )
++    // RSP.g:87:8: ')'
++    {
++        MATCHC(')'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleRPAREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleRPAREx; /* Prevent compiler warnings */
++    ruleRPAREx: ;
++
++}
++// $ANTLR end RPAR
++
++//   Comes from: 89:5: ( 'and' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start AND
++ *
++ * Looks to match the characters the constitute the token AND
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mAND(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = AND;
++       
++    
++    // RSP.g:89:5: ( 'and' )
++    // RSP.g:89:7: 'and'
++    {
++        MATCHS(lit_1); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleANDEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleANDEx; /* Prevent compiler warnings */
++    ruleANDEx: ;
++
++}
++// $ANTLR end AND
++
++//   Comes from: 90:4: ( 'or' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start OR
++ *
++ * Looks to match the characters the constitute the token OR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mOR(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = OR;
++       
++    
++    // RSP.g:90:4: ( 'or' )
++    // RSP.g:90:6: 'or'
++    {
++        MATCHS(lit_2); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleOREx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleOREx; /* Prevent compiler warnings */
++    ruleOREx: ;
++
++}
++// $ANTLR end OR
++
++//   Comes from: 91:5: ( '!' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start NOT
++ *
++ * Looks to match the characters the constitute the token NOT
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mNOT(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = NOT;
++       
++    
++    // RSP.g:91:5: ( '!' )
++    // RSP.g:91:7: '!'
++    {
++        MATCHC('!'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleNOTEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleNOTEx; /* Prevent compiler warnings */
++    ruleNOTEx: ;
++
++}
++// $ANTLR end NOT
++
++//   Comes from: 94:7: ( '=' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start EQUAL
++ *
++ * Looks to match the characters the constitute the token EQUAL
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mEQUAL(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = EQUAL;
++       
++    
++    // RSP.g:94:7: ( '=' )
++    // RSP.g:94:9: '='
++    {
++        MATCHC('='); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleEQUALEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleEQUALEx; /* Prevent compiler warnings */
++    ruleEQUALEx: ;
++
++}
++// $ANTLR end EQUAL
++
++//   Comes from: 97:9: ( 'includes' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start INCLUDES
++ *
++ * Looks to match the characters the constitute the token INCLUDES
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mINCLUDES(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = INCLUDES;
++       
++    
++    // RSP.g:97:9: ( 'includes' )
++    // RSP.g:97:11: 'includes'
++    {
++        MATCHS(lit_3); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleINCLUDESEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleINCLUDESEx; /* Prevent compiler warnings */
++    ruleINCLUDESEx: ;
++
++}
++// $ANTLR end INCLUDES
++
++//   Comes from: 98:9: ( 'startswith' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start STARTSW
++ *
++ * Looks to match the characters the constitute the token STARTSW
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mSTARTSW(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = STARTSW;
++       
++    
++    // RSP.g:98:9: ( 'startswith' )
++    // RSP.g:98:11: 'startswith'
++    {
++        MATCHS(lit_4); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleSTARTSWEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleSTARTSWEx; /* Prevent compiler warnings */
++    ruleSTARTSWEx: ;
++
++}
++// $ANTLR end STARTSW
++
++//   Comes from: 99:7: ( 'endswith' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start ENDSW
++ *
++ * Looks to match the characters the constitute the token ENDSW
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mENDSW(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = ENDSW;
++       
++    
++    // RSP.g:99:7: ( 'endswith' )
++    // RSP.g:99:9: 'endswith'
++    {
++        MATCHS(lit_5); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleENDSWEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleENDSWEx; /* Prevent compiler warnings */
++    ruleENDSWEx: ;
++
++}
++// $ANTLR end ENDSW
++
++//   Comes from: 102:9: ( '>' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start GREATER
++ *
++ * Looks to match the characters the constitute the token GREATER
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mGREATER(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = GREATER;
++       
++    
++    // RSP.g:102:9: ( '>' )
++    // RSP.g:102:11: '>'
++    {
++        MATCHC('>'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleGREATEREx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleGREATEREx; /* Prevent compiler warnings */
++    ruleGREATEREx: ;
++
++}
++// $ANTLR end GREATER
++
++//   Comes from: 103:6: ( '<' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start LESS
++ *
++ * Looks to match the characters the constitute the token LESS
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mLESS(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = LESS;
++       
++    
++    // RSP.g:103:6: ( '<' )
++    // RSP.g:103:8: '<'
++    {
++        MATCHC('<'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleLESSEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleLESSEx; /* Prevent compiler warnings */
++    ruleLESSEx: ;
++
++}
++// $ANTLR end LESS
++
++//   Comes from: 104:5: ( '>=' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start GTE
++ *
++ * Looks to match the characters the constitute the token GTE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mGTE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = GTE;
++       
++    
++    // RSP.g:104:5: ( '>=' )
++    // RSP.g:104:7: '>='
++    {
++        MATCHS(lit_6); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleGTEEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleGTEEx; /* Prevent compiler warnings */
++    ruleGTEEx: ;
++
++}
++// $ANTLR end GTE
++
++//   Comes from: 105:5: ( '<=' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start LTE
++ *
++ * Looks to match the characters the constitute the token LTE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mLTE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = LTE;
++       
++    
++    // RSP.g:105:5: ( '<=' )
++    // RSP.g:105:7: '<='
++    {
++        MATCHS(lit_7); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleLTEEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleLTEEx; /* Prevent compiler warnings */
++    ruleLTEEx: ;
++
++}
++// $ANTLR end LTE
++
++//   Comes from: 108:8: ( 'before' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start BEFORE
++ *
++ * Looks to match the characters the constitute the token BEFORE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mBEFORE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = BEFORE;
++       
++    
++    // RSP.g:108:8: ( 'before' )
++    // RSP.g:108:10: 'before'
++    {
++        MATCHS(lit_8); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleBEFOREEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleBEFOREEx; /* Prevent compiler warnings */
++    ruleBEFOREEx: ;
++
++}
++// $ANTLR end BEFORE
++
++//   Comes from: 109:7: ( 'after' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start AFTER
++ *
++ * Looks to match the characters the constitute the token AFTER
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mAFTER(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = AFTER;
++       
++    
++    // RSP.g:109:7: ( 'after' )
++    // RSP.g:109:9: 'after'
++    {
++        MATCHS(lit_9); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleAFTEREx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleAFTEREx; /* Prevent compiler warnings */
++    ruleAFTEREx: ;
++
++}
++// $ANTLR end AFTER
++
++//   Comes from: 110:5: ( 'day' | 'days' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start DAY
++ *
++ * Looks to match the characters the constitute the token DAY
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mDAY(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = DAY;
++       
++    
++    {
++        //  RSP.g:110:5: ( 'day' | 'days' )
++        
++        ANTLR3_UINT32 alt1;
++
++        alt1=2;
++
++        switch ( LA(1) ) 
++        {
++        case 'd':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'a':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'y':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 's':
++                                                              {
++                                                                      alt1=2;
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt1=1;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 1;
++                                          EXCEPTION->state        = 2;
++
++
++                                          goto ruleDAYEx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 1;
++                          EXCEPTION->state        = 1;
++
++
++                          goto ruleDAYEx;
++                      }
++
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 1;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleDAYEx;
++        }
++
++        switch (alt1) 
++        {
++      case 1:
++          // RSP.g:110:7: 'day'
++          {
++              MATCHS(lit_10); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleDAYEx;
++              }
++
++
++
++          }
++          break;
++      case 2:
++          // RSP.g:110:15: 'days'
++          {
++              MATCHS(lit_11); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleDAYEx;
++              }
++
++
++
++          }
++          break;
++
++        }
++    }
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleDAYEx; /* Prevent compiler warnings */
++    ruleDAYEx: ;
++
++}
++// $ANTLR end DAY
++
++//   Comes from: 111:6: ( 'week' | 'weeks' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start WEEK
++ *
++ * Looks to match the characters the constitute the token WEEK
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mWEEK(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = WEEK;
++       
++    
++    {
++        //  RSP.g:111:6: ( 'week' | 'weeks' )
++        
++        ANTLR3_UINT32 alt2;
++
++        alt2=2;
++
++        switch ( LA(1) ) 
++        {
++        case 'w':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'e':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'e':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'k':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 's':
++                                                                              {
++                                                                                      alt2=2;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt2=1;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 2;
++                                                          EXCEPTION->state        = 3;
++
++
++                                                          goto ruleWEEKEx;
++                                                      }
++
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 2;
++                                          EXCEPTION->state        = 2;
++
++
++                                          goto ruleWEEKEx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 2;
++                          EXCEPTION->state        = 1;
++
++
++                          goto ruleWEEKEx;
++                      }
++
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 2;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleWEEKEx;
++        }
++
++        switch (alt2) 
++        {
++      case 1:
++          // RSP.g:111:8: 'week'
++          {
++              MATCHS(lit_12); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleWEEKEx;
++              }
++
++
++
++          }
++          break;
++      case 2:
++          // RSP.g:111:17: 'weeks'
++          {
++              MATCHS(lit_13); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleWEEKEx;
++              }
++
++
++
++          }
++          break;
++
++        }
++    }
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleWEEKEx; /* Prevent compiler warnings */
++    ruleWEEKEx: ;
++
++}
++// $ANTLR end WEEK
++
++//   Comes from: 112:7: ( 'month' | 'months' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start MONTH
++ *
++ * Looks to match the characters the constitute the token MONTH
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mMONTH(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = MONTH;
++       
++    
++    {
++        //  RSP.g:112:7: ( 'month' | 'months' )
++        
++        ANTLR3_UINT32 alt3;
++
++        alt3=2;
++
++        switch ( LA(1) ) 
++        {
++        case 'm':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'o':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'n':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 't':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'h':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 's':
++                                                                                              {
++                                                                                                      alt3=2;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt3=1;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          CONSTRUCTEX();
++                                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                                          EXCEPTION->message      = (void *)"";
++                                                                          EXCEPTION->decisionNum  = 3;
++                                                                          EXCEPTION->state        = 4;
++
++
++                                                                          goto ruleMONTHEx;
++                                                                      }
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 3;
++                                                          EXCEPTION->state        = 3;
++
++
++                                                          goto ruleMONTHEx;
++                                                      }
++
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 3;
++                                          EXCEPTION->state        = 2;
++
++
++                                          goto ruleMONTHEx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 3;
++                          EXCEPTION->state        = 1;
++
++
++                          goto ruleMONTHEx;
++                      }
++
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 3;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleMONTHEx;
++        }
++
++        switch (alt3) 
++        {
++      case 1:
++          // RSP.g:112:9: 'month'
++          {
++              MATCHS(lit_14); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleMONTHEx;
++              }
++
++
++
++          }
++          break;
++      case 2:
++          // RSP.g:112:19: 'months'
++          {
++              MATCHS(lit_15); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleMONTHEx;
++              }
++
++
++
++          }
++          break;
++
++        }
++    }
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleMONTHEx; /* Prevent compiler warnings */
++    ruleMONTHEx: ;
++
++}
++// $ANTLR end MONTH
++
++//   Comes from: 113:6: ( 'year' | 'years' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start YEAR
++ *
++ * Looks to match the characters the constitute the token YEAR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mYEAR(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = YEAR;
++       
++    
++    {
++        //  RSP.g:113:6: ( 'year' | 'years' )
++        
++        ANTLR3_UINT32 alt4;
++
++        alt4=2;
++
++        switch ( LA(1) ) 
++        {
++        case 'y':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'e':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'a':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'r':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 's':
++                                                                              {
++                                                                                      alt4=2;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt4=1;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 4;
++                                                          EXCEPTION->state        = 3;
++
++
++                                                          goto ruleYEAREx;
++                                                      }
++
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 4;
++                                          EXCEPTION->state        = 2;
++
++
++                                          goto ruleYEAREx;
++                                      }
++
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 4;
++                          EXCEPTION->state        = 1;
++
++
++                          goto ruleYEAREx;
++                      }
++
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 4;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleYEAREx;
++        }
++
++        switch (alt4) 
++        {
++      case 1:
++          // RSP.g:113:8: 'year'
++          {
++              MATCHS(lit_16); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleYEAREx;
++              }
++
++
++
++          }
++          break;
++      case 2:
++          // RSP.g:113:17: 'years'
++          {
++              MATCHS(lit_17); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleYEAREx;
++              }
++
++
++
++          }
++          break;
++
++        }
++    }
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleYEAREx; /* Prevent compiler warnings */
++    ruleYEAREx: ;
++
++}
++// $ANTLR end YEAR
++
++//   Comes from: 114:7: ( 'today' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start TODAY
++ *
++ * Looks to match the characters the constitute the token TODAY
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mTODAY(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = TODAY;
++       
++    
++    // RSP.g:114:7: ( 'today' )
++    // RSP.g:114:9: 'today'
++    {
++        MATCHS(lit_18); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleTODAYEx;
++        }
++
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleTODAYEx; /* Prevent compiler warnings */
++    ruleTODAYEx: ;
++
++}
++// $ANTLR end TODAY
++
++//   Comes from: 116:9: ( ( '\\r' )? '\\n' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start NEWLINE
++ *
++ * Looks to match the characters the constitute the token NEWLINE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mNEWLINE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = NEWLINE;
++       
++    
++    // RSP.g:116:9: ( ( '\\r' )? '\\n' )
++    // RSP.g:116:11: ( '\\r' )? '\\n'
++    {
++
++        // RSP.g:116:11: ( '\\r' )?
++        {
++            int alt5=2;
++            switch ( LA(1) ) 
++            {
++                case '\r':
++                      {
++                              alt5=1;
++                      }
++                    break;
++            }
++
++            switch (alt5) 
++            {
++              case 1:
++                  // RSP.g:116:11: '\\r'
++                  {
++                      MATCHC('\r'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleNEWLINEEx;
++                      }
++
++
++                  }
++                  break;
++
++            }
++        }
++        MATCHC('\n'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleNEWLINEEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleNEWLINEEx; /* Prevent compiler warnings */
++    ruleNEWLINEEx: ;
++
++}
++// $ANTLR end NEWLINE
++
++//   Comes from: 118:4: ( ( ' ' | '\\t' ) )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start WS
++ *
++ * Looks to match the characters the constitute the token WS
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mWS(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = WS;
++       
++    
++    // RSP.g:118:4: ( ( ' ' | '\\t' ) )
++    // RSP.g:118:6: ( ' ' | '\\t' )
++    {
++        if ( LA(1) == '\t' || LA(1) == ' ' )
++        {
++            CONSUME();
++
++        }
++        else 
++        {
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++            EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++
++            LRECOVER();    goto ruleWSEx;
++        }
++
++        {
++             LEXSTATE->channel = HIDDEN; 
++        }
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleWSEx; /* Prevent compiler warnings */
++    ruleWSEx: ;
++
++}
++// $ANTLR end WS
++
++//   Comes from: 120:7: ( 'a' .. 'z' ( 'a' .. 'z' | '_' )* 'a' .. 'z' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start FIELD
++ *
++ * Looks to match the characters the constitute the token FIELD
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mFIELD(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = FIELD;
++       
++    
++    // RSP.g:120:7: ( 'a' .. 'z' ( 'a' .. 'z' | '_' )* 'a' .. 'z' )
++    // RSP.g:120:9: 'a' .. 'z' ( 'a' .. 'z' | '_' )* 'a' .. 'z'
++    {
++        MATCHRANGE('a', 'z'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleFIELDEx;
++        }
++
++
++        // RSP.g:120:18: ( 'a' .. 'z' | '_' )*
++
++        for (;;)
++        {
++            int alt6=2;
++            switch ( LA(1) ) 
++            {
++            case 'a':
++            case 'b':
++            case 'c':
++            case 'd':
++            case 'e':
++            case 'f':
++            case 'g':
++            case 'h':
++            case 'i':
++            case 'j':
++            case 'k':
++            case 'l':
++            case 'm':
++            case 'n':
++            case 'o':
++            case 'p':
++            case 'q':
++            case 'r':
++            case 's':
++            case 't':
++            case 'u':
++            case 'v':
++            case 'w':
++            case 'x':
++            case 'y':
++            case 'z':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt6=1;
++                              }
++                          break;
++
++                      }
++
++              }
++                break;
++            case '_':
++              {
++                      alt6=1;
++              }
++                break;
++
++            }
++
++            switch (alt6) 
++            {
++              case 1:
++                  // RSP.g:
++                  {
++                      if ( LA(1) == '_' || ((LA(1) >= 'a') && (LA(1) <= 'z')) )
++                      {
++                          CONSUME();
++
++                      }
++                      else 
++                      {
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                          EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++
++                          LRECOVER();    goto ruleFIELDEx;
++                      }
++
++
++                  }
++                  break;
++
++              default:
++                  goto loop6; /* break out of the loop */
++                  break;
++            }
++        }
++        loop6: ; /* Jump out to here if this rule does not match */
++
++        MATCHRANGE('a', 'z'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleFIELDEx;
++        }
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleFIELDEx; /* Prevent compiler warnings */
++    ruleFIELDEx: ;
++
++}
++// $ANTLR end FIELD
++
++//   Comes from: 122:5: ( DIGIT19 ( DIGIT09 )* )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start INT
++ *
++ * Looks to match the characters the constitute the token INT
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mINT(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = INT;
++       
++    
++    // RSP.g:122:5: ( DIGIT19 ( DIGIT09 )* )
++    // RSP.g:122:7: DIGIT19 ( DIGIT09 )*
++    {
++        /* 122:7: DIGIT19 ( DIGIT09 )* */
++        mDIGIT19(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleINTEx;
++        }
++
++
++        // RSP.g:122:15: ( DIGIT09 )*
++
++        for (;;)
++        {
++            int alt7=2;
++            switch ( LA(1) ) 
++            {
++            case '0':
++            case '1':
++            case '2':
++            case '3':
++            case '4':
++            case '5':
++            case '6':
++            case '7':
++            case '8':
++            case '9':
++              {
++                      alt7=1;
++              }
++                break;
++
++            }
++
++            switch (alt7) 
++            {
++              case 1:
++                  // RSP.g:122:15: DIGIT09
++                  {
++                      /* 122:15: DIGIT09 */
++                      mDIGIT09(ctx ); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleINTEx;
++                      }
++
++
++                  }
++                  break;
++
++              default:
++                  goto loop7; /* break out of the loop */
++                  break;
++            }
++        }
++        loop7: ; /* Jump out to here if this rule does not match */
++
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleINTEx; /* Prevent compiler warnings */
++    ruleINTEx: ;
++
++}
++// $ANTLR end INT
++
++//   Comes from: 125:6: ( DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start DATE
++ *
++ * Looks to match the characters the constitute the token DATE
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mDATE(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++    _type         = DATE;
++       
++    
++    // RSP.g:125:6: ( DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) )
++    // RSP.g:125:8: DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' )
++    {
++        /* 125:8: DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) */
++        mDIGIT19(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++        /* 125:8: DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) */
++        mDIGIT09(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++        /* 125:8: DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) */
++        mDIGIT09(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++        /* 125:8: DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ( '0' DIGIT19 | '1' '0' .. '2' ) '-' ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' ) */
++        mDIGIT09(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++        MATCHC('-'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++
++        // RSP.g:125:44: ( '0' DIGIT19 | '1' '0' .. '2' )
++        {
++            int alt8=2;
++            switch ( LA(1) ) 
++            {
++            case '0':
++              {
++                      alt8=1;
++              }
++                break;
++            case '1':
++              {
++                      alt8=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 8;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleDATEEx;
++            }
++
++            switch (alt8) 
++            {
++              case 1:
++                  // RSP.g:125:45: '0' DIGIT19
++                  {
++                      MATCHC('0'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++                      /* 125:45: '0' DIGIT19 */
++                      mDIGIT19(ctx ); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++
++                  }
++                  break;
++              case 2:
++                  // RSP.g:125:59: '1' '0' .. '2'
++                  {
++                      MATCHC('1'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++                      MATCHRANGE('0', '2'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++
++                  }
++                  break;
++
++            }
++        }
++        MATCHC('-'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDATEEx;
++        }
++
++
++        // RSP.g:125:77: ( '0' DIGIT19 | '1' .. '2' DIGIT09 | '3' '0' .. '1' )
++        {
++            int alt9=3;
++            switch ( LA(1) ) 
++            {
++            case '0':
++              {
++                      alt9=1;
++              }
++                break;
++            case '1':
++            case '2':
++              {
++                      alt9=2;
++              }
++                break;
++            case '3':
++              {
++                      alt9=3;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 9;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleDATEEx;
++            }
++
++            switch (alt9) 
++            {
++              case 1:
++                  // RSP.g:125:78: '0' DIGIT19
++                  {
++                      MATCHC('0'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++                      /* 125:78: '0' DIGIT19 */
++                      mDIGIT19(ctx ); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++
++                  }
++                  break;
++              case 2:
++                  // RSP.g:125:92: '1' .. '2' DIGIT09
++                  {
++                      MATCHRANGE('1', '2'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++                      /* 125:92: '1' .. '2' DIGIT09 */
++                      mDIGIT09(ctx ); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++
++                  }
++                  break;
++              case 3:
++                  // RSP.g:125:111: '3' '0' .. '1'
++                  {
++                      MATCHC('3'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++                      MATCHRANGE('0', '1'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleDATEEx;
++                      }
++
++
++                  }
++                  break;
++
++            }
++        }
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleDATEEx; /* Prevent compiler warnings */
++    ruleDATEEx: ;
++
++}
++// $ANTLR end DATE
++
++//   Comes from: 133:2: ( QUOTE (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+ QUOTE )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start STR
++ *
++ * Looks to match the characters the constitute the token STR
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mSTR(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++    pANTLR3_COMMON_TOKEN esc;
++    ANTLR3_UINT32 reg;
++
++
++    esc = NULL;
++
++    _type         = STR;
++       
++     pANTLR3_STRING unesc = GETTEXT()->factory->newRaw(GETTEXT()->factory); 
++    
++    // RSP.g:133:2: ( QUOTE (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+ QUOTE )
++    // RSP.g:133:4: QUOTE (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+ QUOTE
++    {
++        /* 133:4: QUOTE (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+ QUOTE */
++        mQUOTE(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleSTREx;
++        }
++
++        // RSP.g:133:10: (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+
++        {
++            int cnt10=0;
++
++            for (;;)
++            {
++                int alt10=3;
++              {
++                 /* dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)
++                  */
++                  int LA10_0 = LA(1);
++                  if ( (((LA10_0 >= 0x0000) && (LA10_0 <= '!')) || ((LA10_0 >= '#') && (LA10_0 <= '[')) || ((LA10_0 >= ']') && (LA10_0 <= 0xFFFF))) ) 
++                  {
++                      alt10=1;
++                  }
++                  else if ( (LA10_0 == '\\') ) 
++                  {
++                      alt10=2;
++                  }
++
++              }
++              switch (alt10) 
++              {
++                  case 1:
++                      // RSP.g:133:12: reg=~ ( '\\\\' | '\"' )
++                      {
++                          reg= LA(1);
++                          if ( ((LA(1) >= 0x0000) && (LA(1) <= '!')) || ((LA(1) >= '#') && (LA(1) <= '[')) || ((LA(1) >= ']') && (LA(1) <= 0xFFFF)) )
++                          {
++                              CONSUME();
++
++                          }
++                          else 
++                          {
++                              CONSTRUCTEX();
++                              EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                              EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++
++                              LRECOVER();    goto ruleSTREx;
++                          }
++
++                          {
++                               unesc->addc(unesc, reg); 
++                          }
++
++                      }
++                      break;
++                  case 2:
++                      // RSP.g:134:6: esc= ESCAPED
++                      {
++                          /* 134:6: esc= ESCAPED */
++                          {
++                              ANTLR3_MARKER escStart381 = GETCHARINDEX();
++                          mESCAPED(ctx ); 
++                              if  (HASEXCEPTION())
++                              {
++                                  goto ruleSTREx;
++                              }
++
++                              esc = LEXSTATE->tokFactory->newToken(LEXSTATE->tokFactory);
++                              esc->setType(esc, ANTLR3_TOKEN_INVALID);
++                              esc->setStartIndex(esc, escStart381);
++                              esc->setStopIndex(esc, GETCHARINDEX()-1);
++                              esc->input = INPUT;
++                          }
++                          {
++                               unesc->appendS(unesc, GETTEXT()); 
++                          }
++
++                      }
++                      break;
++
++                  default:
++                  
++                      if ( cnt10 >= 1 )
++                      {
++                          goto loop10;
++                      }
++                      /* mismatchedSetEx()
++                       */
++                      CONSTRUCTEX();
++                      EXCEPTION->type = ANTLR3_EARLY_EXIT_EXCEPTION;
++                      EXCEPTION->name = (void *)ANTLR3_EARLY_EXIT_NAME;
++
++
++                      goto ruleSTREx;
++              }
++              cnt10++;
++            }
++            loop10: ; /* Jump to here if this rule does not match */
++        }
++        /* 133:4: QUOTE (reg=~ ( '\\\\' | '\"' ) | esc= ESCAPED )+ QUOTE */
++        mQUOTE(ctx ); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleSTREx;
++        }
++
++        {
++             SETTEXT(unesc); 
++        }
++
++    }
++
++      LEXSTATE->type = _type;
++
++    // This is where rules clean up and exit
++    //
++    goto ruleSTREx; /* Prevent compiler warnings */
++    ruleSTREx: ;
++
++    esc = NULL;
++
++}
++// $ANTLR end STR
++
++//   Comes from: 138:9: ( '\\\\' ( '\\\\' | '\"' ) )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start ESCAPED
++ *
++ * Looks to match the characters the constitute the token ESCAPED
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mESCAPED(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++        
++    // RSP.g:138:9: ( '\\\\' ( '\\\\' | '\"' ) )
++    // RSP.g:138:11: '\\\\' ( '\\\\' | '\"' )
++    {
++        MATCHC('\\'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleESCAPEDEx;
++        }
++
++
++        // RSP.g:139:3: ( '\\\\' | '\"' )
++        {
++            int alt11=2;
++            switch ( LA(1) ) 
++            {
++            case '\\':
++              {
++                      alt11=1;
++              }
++                break;
++            case '"':
++              {
++                      alt11=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 11;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleESCAPEDEx;
++            }
++
++            switch (alt11) 
++            {
++              case 1:
++                  // RSP.g:139:5: '\\\\'
++                  {
++                      MATCHC('\\'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleESCAPEDEx;
++                      }
++
++                      {
++                           SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\\")); 
++                      }
++
++                  }
++                  break;
++              case 2:
++                  // RSP.g:140:5: '\"'
++                  {
++                      MATCHC('"'); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleESCAPEDEx;
++                      }
++
++                      {
++                           SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\"")); 
++                      }
++
++                  }
++                  break;
++
++            }
++        }
++
++    }
++
++
++
++    // This is where rules clean up and exit
++    //
++    goto ruleESCAPEDEx; /* Prevent compiler warnings */
++    ruleESCAPEDEx: ;
++
++}
++// $ANTLR end ESCAPED
++
++//   Comes from: 145:9: ( '0' .. '9' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start DIGIT09
++ *
++ * Looks to match the characters the constitute the token DIGIT09
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mDIGIT09(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++        
++    // RSP.g:145:9: ( '0' .. '9' )
++    // RSP.g:145:11: '0' .. '9'
++    {
++        MATCHRANGE('0', '9'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDIGIT09Ex;
++        }
++
++
++    }
++
++
++
++    // This is where rules clean up and exit
++    //
++    goto ruleDIGIT09Ex; /* Prevent compiler warnings */
++    ruleDIGIT09Ex: ;
++
++}
++// $ANTLR end DIGIT09
++
++//   Comes from: 148:9: ( '1' .. '9' )
++/** \brief Lexer rule generated by ANTLR3
++ *
++ * $ANTLR start DIGIT19
++ *
++ * Looks to match the characters the constitute the token DIGIT19
++ * from the attached input stream.
++ *
++ *
++ * \remark
++ *  - lexer->error == ANTLR3_TRUE if an exception was thrown.
++ */
++static ANTLR3_INLINE
++void mDIGIT19(pRSPLexer ctx)
++{
++      ANTLR3_UINT32   _type;
++
++        
++    // RSP.g:148:9: ( '1' .. '9' )
++    // RSP.g:148:11: '1' .. '9'
++    {
++        MATCHRANGE('1', '9'); 
++        if  (HASEXCEPTION())
++        {
++            goto ruleDIGIT19Ex;
++        }
++
++
++    }
++
++
++
++    // This is where rules clean up and exit
++    //
++    goto ruleDIGIT19Ex; /* Prevent compiler warnings */
++    ruleDIGIT19Ex: ;
++
++}
++// $ANTLR end DIGIT19
++
++/** This is the entry point in to the lexer from an object that
++ *  wants to generate the next token, such as a pCOMMON_TOKEN_STREAM
++ */
++static void 
++mTokens(pRSPLexer ctx)
++{
++    {
++        //  RSP.g:1:8: ( QUOTE | LPAR | RPAR | AND | OR | NOT | EQUAL | INCLUDES | STARTSW | ENDSW | GREATER | LESS | GTE | LTE | BEFORE | AFTER | DAY | WEEK | MONTH | YEAR | TODAY | NEWLINE | WS | FIELD | INT | DATE | STR )
++        
++        ANTLR3_UINT32 alt12;
++
++        alt12=27;
++
++        switch ( LA(1) ) 
++        {
++        case '"':
++              {
++
++                      {
++                          int LA12_1 = LA(2);
++                          if ( (((LA12_1 >= 0x0000) && (LA12_1 <= '!')) || ((LA12_1 >= '#') && (LA12_1 <= 0xFFFF))) ) 
++                          {
++                              alt12=27;
++                          }
++                          else 
++                          {
++                              alt12=1;    }
++                      }
++              }
++            break;
++        case '(':
++              {
++                      alt12=2;
++              }
++            break;
++        case ')':
++              {
++                      alt12=3;
++              }
++            break;
++        case 'a':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'n':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'd':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case '_':
++                                                      case 'a':
++                                                      case 'b':
++                                                      case 'c':
++                                                      case 'd':
++                                                      case 'e':
++                                                      case 'f':
++                                                      case 'g':
++                                                      case 'h':
++                                                      case 'i':
++                                                      case 'j':
++                                                      case 'k':
++                                                      case 'l':
++                                                      case 'm':
++                                                      case 'n':
++                                                      case 'o':
++                                                      case 'p':
++                                                      case 'q':
++                                                      case 'r':
++                                                      case 's':
++                                                      case 't':
++                                                      case 'u':
++                                                      case 'v':
++                                                      case 'w':
++                                                      case 'x':
++                                                      case 'y':
++                                                      case 'z':
++                                                              {
++                                                                      alt12=24;
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=4;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case 'f':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 't':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'e':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'r':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case '_':
++                                                                                      case 'a':
++                                                                                      case 'b':
++                                                                                      case 'c':
++                                                                                      case 'd':
++                                                                                      case 'e':
++                                                                                      case 'f':
++                                                                                      case 'g':
++                                                                                      case 'h':
++                                                                                      case 'i':
++                                                                                      case 'j':
++                                                                                      case 'k':
++                                                                                      case 'l':
++                                                                                      case 'm':
++                                                                                      case 'n':
++                                                                                      case 'o':
++                                                                                      case 'p':
++                                                                                      case 'q':
++                                                                                      case 'r':
++                                                                                      case 's':
++                                                                                      case 't':
++                                                                                      case 'u':
++                                                                                      case 'v':
++                                                                                      case 'w':
++                                                                                      case 'x':
++                                                                                      case 'y':
++                                                                                      case 'z':
++                                                                                              {
++                                                                                                      alt12=24;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=16;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 4;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'o':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'r':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case '_':
++                                      case 'a':
++                                      case 'b':
++                                      case 'c':
++                                      case 'd':
++                                      case 'e':
++                                      case 'f':
++                                      case 'g':
++                                      case 'h':
++                                      case 'i':
++                                      case 'j':
++                                      case 'k':
++                                      case 'l':
++                                      case 'm':
++                                      case 'n':
++                                      case 'o':
++                                      case 'p':
++                                      case 'q':
++                                      case 'r':
++                                      case 's':
++                                      case 't':
++                                      case 'u':
++                                      case 'v':
++                                      case 'w':
++                                      case 'x':
++                                      case 'y':
++                                      case 'z':
++                                              {
++                                                      alt12=24;
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=5;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 5;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case '!':
++              {
++                      alt12=6;
++              }
++            break;
++        case '=':
++              {
++                      alt12=7;
++              }
++            break;
++        case 'i':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'n':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'c':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'l':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'u':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 'd':
++                                                                                              {
++                                                                                                      switch ( LA(7) ) 
++                                                                                                      {
++                                                                                                      case 'e':
++                                                                                                              {
++                                                                                                                      switch ( LA(8) ) 
++                                                                                                                      {
++                                                                                                                      case 's':
++                                                                                                                              {
++                                                                                                                                      switch ( LA(9) ) 
++                                                                                                                                      {
++                                                                                                                                      case '_':
++                                                                                                                                      case 'a':
++                                                                                                                                      case 'b':
++                                                                                                                                      case 'c':
++                                                                                                                                      case 'd':
++                                                                                                                                      case 'e':
++                                                                                                                                      case 'f':
++                                                                                                                                      case 'g':
++                                                                                                                                      case 'h':
++                                                                                                                                      case 'i':
++                                                                                                                                      case 'j':
++                                                                                                                                      case 'k':
++                                                                                                                                      case 'l':
++                                                                                                                                      case 'm':
++                                                                                                                                      case 'n':
++                                                                                                                                      case 'o':
++                                                                                                                                      case 'p':
++                                                                                                                                      case 'q':
++                                                                                                                                      case 'r':
++                                                                                                                                      case 's':
++                                                                                                                                      case 't':
++                                                                                                                                      case 'u':
++                                                                                                                                      case 'v':
++                                                                                                                                      case 'w':
++                                                                                                                                      case 'x':
++                                                                                                                                      case 'y':
++                                                                                                                                      case 'z':
++                                                                                                                                              {
++                                                                                                                                                      alt12=24;
++                                                                                                                                              }
++                                                                                                                                          break;
++
++                                                                                                                                      default:
++                                                                                                                                          alt12=8;}
++
++                                                                                                                              }
++                                                                                                                          break;
++
++                                                                                                                      default:
++                                                                                                                          alt12=24;}
++
++                                                                                                              }
++                                                                                                          break;
++
++                                                                                                      default:
++                                                                                                          alt12=24;}
++
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=24;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 8;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 's':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 't':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'a':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'r':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 't':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 's':
++                                                                                              {
++                                                                                                      switch ( LA(7) ) 
++                                                                                                      {
++                                                                                                      case 'w':
++                                                                                                              {
++                                                                                                                      switch ( LA(8) ) 
++                                                                                                                      {
++                                                                                                                      case 'i':
++                                                                                                                              {
++                                                                                                                                      switch ( LA(9) ) 
++                                                                                                                                      {
++                                                                                                                                      case 't':
++                                                                                                                                              {
++                                                                                                                                                      switch ( LA(10) ) 
++                                                                                                                                                      {
++                                                                                                                                                      case 'h':
++                                                                                                                                                              {
++                                                                                                                                                                      switch ( LA(11) ) 
++                                                                                                                                                                      {
++                                                                                                                                                                      case '_':
++                                                                                                                                                                      case 'a':
++                                                                                                                                                                      case 'b':
++                                                                                                                                                                      case 'c':
++                                                                                                                                                                      case 'd':
++                                                                                                                                                                      case 'e':
++                                                                                                                                                                      case 'f':
++                                                                                                                                                                      case 'g':
++                                                                                                                                                                      case 'h':
++                                                                                                                                                                      case 'i':
++                                                                                                                                                                      case 'j':
++                                                                                                                                                                      case 'k':
++                                                                                                                                                                      case 'l':
++                                                                                                                                                                      case 'm':
++                                                                                                                                                                      case 'n':
++                                                                                                                                                                      case 'o':
++                                                                                                                                                                      case 'p':
++                                                                                                                                                                      case 'q':
++                                                                                                                                                                      case 'r':
++                                                                                                                                                                      case 's':
++                                                                                                                                                                      case 't':
++                                                                                                                                                                      case 'u':
++                                                                                                                                                                      case 'v':
++                                                                                                                                                                      case 'w':
++                                                                                                                                                                      case 'x':
++                                                                                                                                                                      case 'y':
++                                                                                                                                                                      case 'z':
++                                                                                                                                                                              {
++                                                                                                                                                                                      alt12=24;
++                                                                                                                                                                              }
++                                                                                                                                                                          break;
++
++                                                                                                                                                                      default:
++                                                                                                                                                                          alt12=9;}
++
++                                                                                                                                                              }
++                                                                                                                                                          break;
++
++                                                                                                                                                      default:
++                                                                                                                                                          alt12=24;}
++
++                                                                                                                                              }
++                                                                                                                                          break;
++
++                                                                                                                                      default:
++                                                                                                                                          alt12=24;}
++
++                                                                                                                              }
++                                                                                                                          break;
++
++                                                                                                                      default:
++                                                                                                                          alt12=24;}
++
++                                                                                                              }
++                                                                                                          break;
++
++                                                                                                      default:
++                                                                                                          alt12=24;}
++
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=24;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 9;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'e':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'n':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'd':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 's':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'w':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 'i':
++                                                                                              {
++                                                                                                      switch ( LA(7) ) 
++                                                                                                      {
++                                                                                                      case 't':
++                                                                                                              {
++                                                                                                                      switch ( LA(8) ) 
++                                                                                                                      {
++                                                                                                                      case 'h':
++                                                                                                                              {
++                                                                                                                                      switch ( LA(9) ) 
++                                                                                                                                      {
++                                                                                                                                      case '_':
++                                                                                                                                      case 'a':
++                                                                                                                                      case 'b':
++                                                                                                                                      case 'c':
++                                                                                                                                      case 'd':
++                                                                                                                                      case 'e':
++                                                                                                                                      case 'f':
++                                                                                                                                      case 'g':
++                                                                                                                                      case 'h':
++                                                                                                                                      case 'i':
++                                                                                                                                      case 'j':
++                                                                                                                                      case 'k':
++                                                                                                                                      case 'l':
++                                                                                                                                      case 'm':
++                                                                                                                                      case 'n':
++                                                                                                                                      case 'o':
++                                                                                                                                      case 'p':
++                                                                                                                                      case 'q':
++                                                                                                                                      case 'r':
++                                                                                                                                      case 's':
++                                                                                                                                      case 't':
++                                                                                                                                      case 'u':
++                                                                                                                                      case 'v':
++                                                                                                                                      case 'w':
++                                                                                                                                      case 'x':
++                                                                                                                                      case 'y':
++                                                                                                                                      case 'z':
++                                                                                                                                              {
++                                                                                                                                                      alt12=24;
++                                                                                                                                              }
++                                                                                                                                          break;
++
++                                                                                                                                      default:
++                                                                                                                                          alt12=10;}
++
++                                                                                                                              }
++                                                                                                                          break;
++
++                                                                                                                      default:
++                                                                                                                          alt12=24;}
++
++                                                                                                              }
++                                                                                                          break;
++
++                                                                                                      default:
++                                                                                                          alt12=24;}
++
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=24;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 10;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case '>':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case '=':
++                              {
++                                      alt12=13;
++                              }
++                          break;
++
++                      default:
++                          alt12=11;}
++
++              }
++            break;
++        case '<':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case '=':
++                              {
++                                      alt12=14;
++                              }
++                          break;
++
++                      default:
++                          alt12=12;}
++
++              }
++            break;
++        case 'b':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'e':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'f':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'o':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'r':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 'e':
++                                                                                              {
++                                                                                                      switch ( LA(7) ) 
++                                                                                                      {
++                                                                                                      case '_':
++                                                                                                      case 'a':
++                                                                                                      case 'b':
++                                                                                                      case 'c':
++                                                                                                      case 'd':
++                                                                                                      case 'e':
++                                                                                                      case 'f':
++                                                                                                      case 'g':
++                                                                                                      case 'h':
++                                                                                                      case 'i':
++                                                                                                      case 'j':
++                                                                                                      case 'k':
++                                                                                                      case 'l':
++                                                                                                      case 'm':
++                                                                                                      case 'n':
++                                                                                                      case 'o':
++                                                                                                      case 'p':
++                                                                                                      case 'q':
++                                                                                                      case 'r':
++                                                                                                      case 's':
++                                                                                                      case 't':
++                                                                                                      case 'u':
++                                                                                                      case 'v':
++                                                                                                      case 'w':
++                                                                                                      case 'x':
++                                                                                                      case 'y':
++                                                                                                      case 'z':
++                                                                                                              {
++                                                                                                                      alt12=24;
++                                                                                                              }
++                                                                                                          break;
++
++                                                                                                      default:
++                                                                                                          alt12=15;}
++
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=24;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 13;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'd':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'a':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'y':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 's':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case '_':
++                                                                      case 'a':
++                                                                      case 'b':
++                                                                      case 'c':
++                                                                      case 'd':
++                                                                      case 'e':
++                                                                      case 'f':
++                                                                      case 'g':
++                                                                      case 'h':
++                                                                      case 'i':
++                                                                      case 'j':
++                                                                      case 'k':
++                                                                      case 'l':
++                                                                      case 'm':
++                                                                      case 'n':
++                                                                      case 'o':
++                                                                      case 'p':
++                                                                      case 'q':
++                                                                      case 'r':
++                                                                      case 's':
++                                                                      case 't':
++                                                                      case 'u':
++                                                                      case 'v':
++                                                                      case 'w':
++                                                                      case 'x':
++                                                                      case 'y':
++                                                                      case 'z':
++                                                                              {
++                                                                                      alt12=24;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=17;}
++
++                                                              }
++                                                          break;
++                                                      case '_':
++                                                      case 'a':
++                                                      case 'b':
++                                                      case 'c':
++                                                      case 'd':
++                                                      case 'e':
++                                                      case 'f':
++                                                      case 'g':
++                                                      case 'h':
++                                                      case 'i':
++                                                      case 'j':
++                                                      case 'k':
++                                                      case 'l':
++                                                      case 'm':
++                                                      case 'n':
++                                                      case 'o':
++                                                      case 'p':
++                                                      case 'q':
++                                                      case 'r':
++                                                      case 't':
++                                                      case 'u':
++                                                      case 'v':
++                                                      case 'w':
++                                                      case 'x':
++                                                      case 'y':
++                                                      case 'z':
++                                                              {
++                                                                      alt12=24;
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=17;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 14;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'w':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'e':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'e':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'k':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 's':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case '_':
++                                                                                      case 'a':
++                                                                                      case 'b':
++                                                                                      case 'c':
++                                                                                      case 'd':
++                                                                                      case 'e':
++                                                                                      case 'f':
++                                                                                      case 'g':
++                                                                                      case 'h':
++                                                                                      case 'i':
++                                                                                      case 'j':
++                                                                                      case 'k':
++                                                                                      case 'l':
++                                                                                      case 'm':
++                                                                                      case 'n':
++                                                                                      case 'o':
++                                                                                      case 'p':
++                                                                                      case 'q':
++                                                                                      case 'r':
++                                                                                      case 's':
++                                                                                      case 't':
++                                                                                      case 'u':
++                                                                                      case 'v':
++                                                                                      case 'w':
++                                                                                      case 'x':
++                                                                                      case 'y':
++                                                                                      case 'z':
++                                                                                              {
++                                                                                                      alt12=24;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=18;}
++
++                                                                              }
++                                                                          break;
++                                                                      case '_':
++                                                                      case 'a':
++                                                                      case 'b':
++                                                                      case 'c':
++                                                                      case 'd':
++                                                                      case 'e':
++                                                                      case 'f':
++                                                                      case 'g':
++                                                                      case 'h':
++                                                                      case 'i':
++                                                                      case 'j':
++                                                                      case 'k':
++                                                                      case 'l':
++                                                                      case 'm':
++                                                                      case 'n':
++                                                                      case 'o':
++                                                                      case 'p':
++                                                                      case 'q':
++                                                                      case 'r':
++                                                                      case 't':
++                                                                      case 'u':
++                                                                      case 'v':
++                                                                      case 'w':
++                                                                      case 'x':
++                                                                      case 'y':
++                                                                      case 'z':
++                                                                              {
++                                                                                      alt12=24;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=18;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 15;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'm':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'o':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'n':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 't':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'h':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case 's':
++                                                                                              {
++                                                                                                      switch ( LA(7) ) 
++                                                                                                      {
++                                                                                                      case '_':
++                                                                                                      case 'a':
++                                                                                                      case 'b':
++                                                                                                      case 'c':
++                                                                                                      case 'd':
++                                                                                                      case 'e':
++                                                                                                      case 'f':
++                                                                                                      case 'g':
++                                                                                                      case 'h':
++                                                                                                      case 'i':
++                                                                                                      case 'j':
++                                                                                                      case 'k':
++                                                                                                      case 'l':
++                                                                                                      case 'm':
++                                                                                                      case 'n':
++                                                                                                      case 'o':
++                                                                                                      case 'p':
++                                                                                                      case 'q':
++                                                                                                      case 'r':
++                                                                                                      case 's':
++                                                                                                      case 't':
++                                                                                                      case 'u':
++                                                                                                      case 'v':
++                                                                                                      case 'w':
++                                                                                                      case 'x':
++                                                                                                      case 'y':
++                                                                                                      case 'z':
++                                                                                                              {
++                                                                                                                      alt12=24;
++                                                                                                              }
++                                                                                                          break;
++
++                                                                                                      default:
++                                                                                                          alt12=19;}
++
++                                                                                              }
++                                                                                          break;
++                                                                                      case '_':
++                                                                                      case 'a':
++                                                                                      case 'b':
++                                                                                      case 'c':
++                                                                                      case 'd':
++                                                                                      case 'e':
++                                                                                      case 'f':
++                                                                                      case 'g':
++                                                                                      case 'h':
++                                                                                      case 'i':
++                                                                                      case 'j':
++                                                                                      case 'k':
++                                                                                      case 'l':
++                                                                                      case 'm':
++                                                                                      case 'n':
++                                                                                      case 'o':
++                                                                                      case 'p':
++                                                                                      case 'q':
++                                                                                      case 'r':
++                                                                                      case 't':
++                                                                                      case 'u':
++                                                                                      case 'v':
++                                                                                      case 'w':
++                                                                                      case 'x':
++                                                                                      case 'y':
++                                                                                      case 'z':
++                                                                                              {
++                                                                                                      alt12=24;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=19;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 16;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 'y':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'e':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'a':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'r':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 's':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case '_':
++                                                                                      case 'a':
++                                                                                      case 'b':
++                                                                                      case 'c':
++                                                                                      case 'd':
++                                                                                      case 'e':
++                                                                                      case 'f':
++                                                                                      case 'g':
++                                                                                      case 'h':
++                                                                                      case 'i':
++                                                                                      case 'j':
++                                                                                      case 'k':
++                                                                                      case 'l':
++                                                                                      case 'm':
++                                                                                      case 'n':
++                                                                                      case 'o':
++                                                                                      case 'p':
++                                                                                      case 'q':
++                                                                                      case 'r':
++                                                                                      case 's':
++                                                                                      case 't':
++                                                                                      case 'u':
++                                                                                      case 'v':
++                                                                                      case 'w':
++                                                                                      case 'x':
++                                                                                      case 'y':
++                                                                                      case 'z':
++                                                                                              {
++                                                                                                      alt12=24;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=20;}
++
++                                                                              }
++                                                                          break;
++                                                                      case '_':
++                                                                      case 'a':
++                                                                      case 'b':
++                                                                      case 'c':
++                                                                      case 'd':
++                                                                      case 'e':
++                                                                      case 'f':
++                                                                      case 'g':
++                                                                      case 'h':
++                                                                      case 'i':
++                                                                      case 'j':
++                                                                      case 'k':
++                                                                      case 'l':
++                                                                      case 'm':
++                                                                      case 'n':
++                                                                      case 'o':
++                                                                      case 'p':
++                                                                      case 'q':
++                                                                      case 'r':
++                                                                      case 't':
++                                                                      case 'u':
++                                                                      case 'v':
++                                                                      case 'w':
++                                                                      case 'x':
++                                                                      case 'y':
++                                                                      case 'z':
++                                                                              {
++                                                                                      alt12=24;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=20;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'o':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 17;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case 't':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case 'o':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case 'd':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case 'a':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case 'y':
++                                                                              {
++                                                                                      switch ( LA(6) ) 
++                                                                                      {
++                                                                                      case '_':
++                                                                                      case 'a':
++                                                                                      case 'b':
++                                                                                      case 'c':
++                                                                                      case 'd':
++                                                                                      case 'e':
++                                                                                      case 'f':
++                                                                                      case 'g':
++                                                                                      case 'h':
++                                                                                      case 'i':
++                                                                                      case 'j':
++                                                                                      case 'k':
++                                                                                      case 'l':
++                                                                                      case 'm':
++                                                                                      case 'n':
++                                                                                      case 'o':
++                                                                                      case 'p':
++                                                                                      case 'q':
++                                                                                      case 'r':
++                                                                                      case 's':
++                                                                                      case 't':
++                                                                                      case 'u':
++                                                                                      case 'v':
++                                                                                      case 'w':
++                                                                                      case 'x':
++                                                                                      case 'y':
++                                                                                      case 'z':
++                                                                                              {
++                                                                                                      alt12=24;
++                                                                                              }
++                                                                                          break;
++
++                                                                                      default:
++                                                                                          alt12=21;}
++
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=24;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=24;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=24;}
++
++                              }
++                          break;
++                      case '_':
++                      case 'a':
++                      case 'b':
++                      case 'c':
++                      case 'd':
++                      case 'e':
++                      case 'f':
++                      case 'g':
++                      case 'h':
++                      case 'i':
++                      case 'j':
++                      case 'k':
++                      case 'l':
++                      case 'm':
++                      case 'n':
++                      case 'p':
++                      case 'q':
++                      case 'r':
++                      case 's':
++                      case 't':
++                      case 'u':
++                      case 'v':
++                      case 'w':
++                      case 'x':
++                      case 'y':
++                      case 'z':
++                              {
++                                      alt12=24;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 12;
++                          EXCEPTION->state        = 18;
++
++
++                          goto ruleTokensEx;
++                      }
++
++              }
++            break;
++        case '\n':
++        case '\r':
++              {
++                      alt12=22;
++              }
++            break;
++        case '\t':
++        case ' ':
++              {
++                      alt12=23;
++              }
++            break;
++        case 'c':
++        case 'f':
++        case 'g':
++        case 'h':
++        case 'j':
++        case 'k':
++        case 'l':
++        case 'n':
++        case 'p':
++        case 'q':
++        case 'r':
++        case 'u':
++        case 'v':
++        case 'x':
++        case 'z':
++              {
++                      alt12=24;
++              }
++            break;
++        case '1':
++        case '2':
++        case '3':
++        case '4':
++        case '5':
++        case '6':
++        case '7':
++        case '8':
++        case '9':
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case '0':
++                      case '1':
++                      case '2':
++                      case '3':
++                      case '4':
++                      case '5':
++                      case '6':
++                      case '7':
++                      case '8':
++                      case '9':
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case '0':
++                                      case '1':
++                                      case '2':
++                                      case '3':
++                                      case '4':
++                                      case '5':
++                                      case '6':
++                                      case '7':
++                                      case '8':
++                                      case '9':
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case '0':
++                                                      case '1':
++                                                      case '2':
++                                                      case '3':
++                                                      case '4':
++                                                      case '5':
++                                                      case '6':
++                                                      case '7':
++                                                      case '8':
++                                                      case '9':
++                                                              {
++                                                                      switch ( LA(5) ) 
++                                                                      {
++                                                                      case '-':
++                                                                              {
++                                                                                      alt12=26;
++                                                                              }
++                                                                          break;
++
++                                                                      default:
++                                                                          alt12=25;}
++
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          alt12=25;}
++
++                                              }
++                                          break;
++
++                                      default:
++                                          alt12=25;}
++
++                              }
++                          break;
++
++                      default:
++                          alt12=25;}
++
++              }
++            break;
++
++        default:
++            CONSTRUCTEX();
++            EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++            EXCEPTION->message      = (void *)"";
++            EXCEPTION->decisionNum  = 12;
++            EXCEPTION->state        = 0;
++
++
++            goto ruleTokensEx;
++        }
++
++        switch (alt12) 
++        {
++      case 1:
++          // RSP.g:1:10: QUOTE
++          {
++              /* 1:10: QUOTE */
++              mQUOTE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 2:
++          // RSP.g:1:16: LPAR
++          {
++              /* 1:16: LPAR */
++              mLPAR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 3:
++          // RSP.g:1:21: RPAR
++          {
++              /* 1:21: RPAR */
++              mRPAR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 4:
++          // RSP.g:1:26: AND
++          {
++              /* 1:26: AND */
++              mAND(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 5:
++          // RSP.g:1:30: OR
++          {
++              /* 1:30: OR */
++              mOR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 6:
++          // RSP.g:1:33: NOT
++          {
++              /* 1:33: NOT */
++              mNOT(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 7:
++          // RSP.g:1:37: EQUAL
++          {
++              /* 1:37: EQUAL */
++              mEQUAL(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 8:
++          // RSP.g:1:43: INCLUDES
++          {
++              /* 1:43: INCLUDES */
++              mINCLUDES(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 9:
++          // RSP.g:1:52: STARTSW
++          {
++              /* 1:52: STARTSW */
++              mSTARTSW(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 10:
++          // RSP.g:1:60: ENDSW
++          {
++              /* 1:60: ENDSW */
++              mENDSW(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 11:
++          // RSP.g:1:66: GREATER
++          {
++              /* 1:66: GREATER */
++              mGREATER(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 12:
++          // RSP.g:1:74: LESS
++          {
++              /* 1:74: LESS */
++              mLESS(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 13:
++          // RSP.g:1:79: GTE
++          {
++              /* 1:79: GTE */
++              mGTE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 14:
++          // RSP.g:1:83: LTE
++          {
++              /* 1:83: LTE */
++              mLTE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 15:
++          // RSP.g:1:87: BEFORE
++          {
++              /* 1:87: BEFORE */
++              mBEFORE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 16:
++          // RSP.g:1:94: AFTER
++          {
++              /* 1:94: AFTER */
++              mAFTER(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 17:
++          // RSP.g:1:100: DAY
++          {
++              /* 1:100: DAY */
++              mDAY(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 18:
++          // RSP.g:1:104: WEEK
++          {
++              /* 1:104: WEEK */
++              mWEEK(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 19:
++          // RSP.g:1:109: MONTH
++          {
++              /* 1:109: MONTH */
++              mMONTH(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 20:
++          // RSP.g:1:115: YEAR
++          {
++              /* 1:115: YEAR */
++              mYEAR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 21:
++          // RSP.g:1:120: TODAY
++          {
++              /* 1:120: TODAY */
++              mTODAY(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 22:
++          // RSP.g:1:126: NEWLINE
++          {
++              /* 1:126: NEWLINE */
++              mNEWLINE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 23:
++          // RSP.g:1:134: WS
++          {
++              /* 1:134: WS */
++              mWS(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 24:
++          // RSP.g:1:137: FIELD
++          {
++              /* 1:137: FIELD */
++              mFIELD(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 25:
++          // RSP.g:1:143: INT
++          {
++              /* 1:143: INT */
++              mINT(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 26:
++          // RSP.g:1:147: DATE
++          {
++              /* 1:147: DATE */
++              mDATE(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++      case 27:
++          // RSP.g:1:152: STR
++          {
++              /* 1:152: STR */
++              mSTR(ctx ); 
++              if  (HASEXCEPTION())
++              {
++                  goto ruleTokensEx;
++              }
++
++
++          }
++          break;
++
++        }
++    }
++
++    
++    goto ruleTokensEx; /* Prevent compiler warnings */
++ruleTokensEx: ;
++}
++
++/* =========================================================================
++ * Lexer matching rules end.
++ * =========================================================================
++ */
++/* End of Lexer code
++ * ================================================
++ * ================================================
++ */ 
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/RSPLexer.h b/src/pregen/RSPLexer.h
+new file mode 100644
+index 0000000..4f4d06b
+--- /dev/null
++++ b/src/pregen/RSPLexer.h
+@@ -0,0 +1,254 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP.g
++ *     -                            On : 2014-09-30 21:42:41
++ *     -                 for the lexer : RSPLexerLexer *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The lexer RSPLexer has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pRSPLexer, which is returned from a call to RSPLexerNew().
++ *
++ * As this is a generated lexer, it is unlikely you will call it 'manually'. However
++ * the methods are provided anyway.
++ * * The methods in pRSPLexer are  as follows:
++ *
++ *  -  void      pRSPLexer->QUOTE(pRSPLexer)
++ *  -  void      pRSPLexer->LPAR(pRSPLexer)
++ *  -  void      pRSPLexer->RPAR(pRSPLexer)
++ *  -  void      pRSPLexer->AND(pRSPLexer)
++ *  -  void      pRSPLexer->OR(pRSPLexer)
++ *  -  void      pRSPLexer->NOT(pRSPLexer)
++ *  -  void      pRSPLexer->EQUAL(pRSPLexer)
++ *  -  void      pRSPLexer->INCLUDES(pRSPLexer)
++ *  -  void      pRSPLexer->STARTSW(pRSPLexer)
++ *  -  void      pRSPLexer->ENDSW(pRSPLexer)
++ *  -  void      pRSPLexer->GREATER(pRSPLexer)
++ *  -  void      pRSPLexer->LESS(pRSPLexer)
++ *  -  void      pRSPLexer->GTE(pRSPLexer)
++ *  -  void      pRSPLexer->LTE(pRSPLexer)
++ *  -  void      pRSPLexer->BEFORE(pRSPLexer)
++ *  -  void      pRSPLexer->AFTER(pRSPLexer)
++ *  -  void      pRSPLexer->DAY(pRSPLexer)
++ *  -  void      pRSPLexer->WEEK(pRSPLexer)
++ *  -  void      pRSPLexer->MONTH(pRSPLexer)
++ *  -  void      pRSPLexer->YEAR(pRSPLexer)
++ *  -  void      pRSPLexer->TODAY(pRSPLexer)
++ *  -  void      pRSPLexer->NEWLINE(pRSPLexer)
++ *  -  void      pRSPLexer->WS(pRSPLexer)
++ *  -  void      pRSPLexer->FIELD(pRSPLexer)
++ *  -  void      pRSPLexer->INT(pRSPLexer)
++ *  -  void      pRSPLexer->DATE(pRSPLexer)
++ *  -  void      pRSPLexer->STR(pRSPLexer)
++ *  -  void      pRSPLexer->ESCAPED(pRSPLexer)
++ *  -  void      pRSPLexer->DIGIT09(pRSPLexer)
++ *  -  void      pRSPLexer->DIGIT19(pRSPLexer)
++ *  -  void      pRSPLexer->Tokens(pRSPLexer)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _RSPLexer_H
++#define _RSPLexer_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct RSPLexer_Ctx_struct RSPLexer, * pRSPLexer;
++
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++
++/** Context tracking structure for RSPLexer
++ */
++struct RSPLexer_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_LEXER    pLexer;
++
++
++     void (*mQUOTE)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mLPAR)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mRPAR)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mAND)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mOR)      (struct RSPLexer_Ctx_struct * ctx);
++     void (*mNOT)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mEQUAL)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mINCLUDES)        (struct RSPLexer_Ctx_struct * ctx);
++     void (*mSTARTSW) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mENDSW)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mGREATER) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mLESS)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mGTE)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mLTE)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mBEFORE)  (struct RSPLexer_Ctx_struct * ctx);
++     void (*mAFTER)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mDAY)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mWEEK)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mMONTH)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mYEAR)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mTODAY)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mNEWLINE) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mWS)      (struct RSPLexer_Ctx_struct * ctx);
++     void (*mFIELD)   (struct RSPLexer_Ctx_struct * ctx);
++     void (*mINT)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mDATE)    (struct RSPLexer_Ctx_struct * ctx);
++     void (*mSTR)     (struct RSPLexer_Ctx_struct * ctx);
++     void (*mESCAPED) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mDIGIT09) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mDIGIT19) (struct RSPLexer_Ctx_struct * ctx);
++     void (*mTokens)  (struct RSPLexer_Ctx_struct * ctx);    const char * (*getGrammarFileName)();
++    void          (*free)   (struct RSPLexer_Ctx_struct * ctx);
++        
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pRSPLexer RSPLexerNew         (pANTLR3_INPUT_STREAM instream);
++ANTLR3_API pRSPLexer RSPLexerNewSSD      (pANTLR3_INPUT_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the lexer will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STARTSW      14
++#define WEEK      26
++#define TODAY      24
++#define YEAR      28
++#define ENDSW      15
++#define GTE      20
++#define BEFORE      21
++#define DAY      25
++#define INT      16
++#define NOT      11
++#define AFTER      22
++#define AND      6
++#define EOF      -1
++#define LTE      19
++#define MONTH      27
++#define DIGIT19      31
++#define INCLUDES      13
++#define STR      10
++#define QUOTE      29
++#define GREATER      18
++#define WS      30
++#define LPAR      7
++#define NEWLINE      4
++#define EQUAL      12
++#define OR      5
++#define LESS      17
++#define FIELD      9
++#define RPAR      8
++#define ESCAPED      33
++#define DATE      23
++#define DIGIT09      32
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for RSPLexer
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
+diff --git a/src/pregen/RSPParser.c b/src/pregen/RSPParser.c
+new file mode 100644
+index 0000000..c538e49
+--- /dev/null
++++ b/src/pregen/RSPParser.c
+@@ -0,0 +1,2684 @@
++/** \file
++ *  This C source file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP.g
++ *     -                            On : 2014-09-30 21:42:40
++ *     -                for the parser : RSPParserParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++*/
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
++
++/* -----------------------------------------
++ * Include the ANTLR3 generated header file.
++ */
++#include    "RSPParser.h"
++/* ----------------------------------------- */
++
++
++
++
++
++/* MACROS that hide the C interface implementations from the
++ * generated code, which makes it a little more understandable to the human eye.
++ * I am very much against using C pre-processor macros for function calls and bits
++ * of code as you cannot see what is happening when single stepping in debuggers
++ * and so on. The exception (in my book at least) is for generated code, where you are
++ * not maintaining it, but may wish to read and understand it. If you single step it, you know that input()
++ * hides some indirect calls, but is always referring to the input stream. This is
++ * probably more readable than ctx->input->istream->input(snarfle0->blarg) and allows me to rejig
++ * the runtime interfaces without changing the generated code too often, without
++ * confusing the reader of the generated output, who may not wish to know the gory
++ * details of the interface inheritance.
++ */
++ 
++#define               CTX     ctx
++
++/* Aids in accessing scopes for grammar programmers
++ */
++#undef        SCOPE_TYPE
++#undef        SCOPE_STACK
++#undef        SCOPE_TOP
++#define       SCOPE_TYPE(scope)   pRSPParser_##scope##_SCOPE
++#define SCOPE_STACK(scope)  pRSPParser_##scope##Stack
++#define       SCOPE_TOP(scope)    ctx->pRSPParser_##scope##Top
++#define       SCOPE_SIZE(scope)               ctx->pRSPParser_##scope##Stack_limit
++#define SCOPE_INSTANCE(scope, i)      (ctx->SCOPE_STACK(scope)->get(ctx->SCOPE_STACK(scope),i))
++
++/* Macros for accessing things in the parser
++ */
++ 
++#undef            PARSER                  
++#undef            RECOGNIZER              
++#undef            HAVEPARSEDRULE
++#undef                MEMOIZE
++#undef            INPUT
++#undef            STRSTREAM
++#undef            HASEXCEPTION
++#undef            EXCEPTION
++#undef            MATCHT
++#undef            MATCHANYT
++#undef            FOLLOWSTACK
++#undef            FOLLOWPUSH
++#undef            FOLLOWPOP
++#undef            PRECOVER
++#undef            PREPORTERROR
++#undef            LA
++#undef            LT
++#undef            CONSTRUCTEX
++#undef            CONSUME
++#undef            MARK
++#undef            REWIND
++#undef            REWINDLAST
++#undef            PERRORRECOVERY
++#undef            HASFAILED
++#undef            FAILEDFLAG
++#undef            RECOVERFROMMISMATCHEDSET
++#undef            RECOVERFROMMISMATCHEDELEMENT
++#undef                INDEX
++#undef      ADAPTOR
++#undef                SEEK
++#undef            RULEMEMO                
++#undef                DBG
++
++#define           PARSER                                                      ctx->pParser  
++#define           RECOGNIZER                                          PARSER->rec
++#define               PSRSTATE                                                RECOGNIZER->state
++#define           HAVEPARSEDRULE(r)                           RECOGNIZER->alreadyParsedRule(RECOGNIZER, r)
++#define               MEMOIZE(ri,si)                                  RECOGNIZER->memoize(RECOGNIZER, ri, si)
++#define           INPUT                                                       PARSER->tstream
++#define           STRSTREAM                                           INPUT
++#define               ISTREAM                                                 INPUT->istream
++#define               INDEX()                                                 ISTREAM->index(INPUT->istream)
++#define           HASEXCEPTION()                                      (PSRSTATE->error == ANTLR3_TRUE)
++#define           EXCEPTION                                           PSRSTATE->exception
++#define           MATCHT(t, fs)                                       RECOGNIZER->match(RECOGNIZER, t, fs)
++#define           MATCHANYT()                                         RECOGNIZER->matchAny(RECOGNIZER)
++#define           FOLLOWSTACK                                     PSRSTATE->following
++#define           FOLLOWPUSH(x)                                       FOLLOWSTACK->push(FOLLOWSTACK, ((void *)(&(x))), NULL)
++#define           FOLLOWPOP()                                         FOLLOWSTACK->pop(FOLLOWSTACK)
++#define           PRECOVER()                                          RECOGNIZER->recover(RECOGNIZER)
++#define           PREPORTERROR()                                      RECOGNIZER->reportError(RECOGNIZER)
++#define           LA(n)                                                       INPUT->istream->_LA(ISTREAM, n)
++#define           LT(n)                                                       INPUT->_LT(INPUT, n)
++#define           CONSTRUCTEX()                                       RECOGNIZER->exConstruct(RECOGNIZER)
++#define           CONSUME()                                           ISTREAM->consume(ISTREAM)
++#define           MARK()                                                      ISTREAM->mark(ISTREAM)
++#define           REWIND(m)                                           ISTREAM->rewind(ISTREAM, m)
++#define           REWINDLAST()                                        ISTREAM->rewindLast(ISTREAM)
++#define               SEEK(n)                                                 ISTREAM->seek(ISTREAM, n)
++#define           PERRORRECOVERY                                      PSRSTATE->errorRecovery
++#define           FAILEDFLAG                                          PSRSTATE->failed
++#define           HASFAILED()                                         (FAILEDFLAG == ANTLR3_TRUE)
++#define           BACKTRACKING                                        PSRSTATE->backtracking
++#define           RECOVERFROMMISMATCHEDSET(s)         RECOGNIZER->recoverFromMismatchedSet(RECOGNIZER, s)
++#define           RECOVERFROMMISMATCHEDELEMENT(e)     RECOGNIZER->recoverFromMismatchedElement(RECOGNIZER, s)
++#define     ADAPTOR                         ctx->adaptor
++#define               RULEMEMO                                                PSRSTATE->ruleMemo
++#define               DBG                                                             RECOGNIZER->debugger
++
++#define               TOKTEXT(tok, txt)                               tok, (pANTLR3_UINT8)txt
++
++/* The 4 tokens defined below may well clash with your own #defines or token types. If so
++ * then for the present you must use different names for your defines as these are hard coded
++ * in the code generator. It would be better not to use such names internally, and maybe
++ * we can change this in a forthcoming release. I deliberately do not #undef these
++ * here as this will at least give you a redefined error somewhere if they clash.
++ */
++#define           UP      ANTLR3_TOKEN_UP
++#define           DOWN    ANTLR3_TOKEN_DOWN
++#define           EOR     ANTLR3_TOKEN_EOR
++#define           INVALID ANTLR3_TOKEN_INVALID
++
++
++/* =============================================================================
++ * Functions to create and destroy scopes. First come the rule scopes, followed
++ * by the global declared scopes.
++ */
++
++
++
++/* ============================================================================= */
++
++/* =============================================================================
++ * Start of recognizer
++ */
++
++
++
++/** \brief Table of all token names in symbolic order, mainly used for
++ *         error reporting.
++ */
++pANTLR3_UINT8   RSPParserTokenNames[30+4]
++     = {
++        (pANTLR3_UINT8) "<invalid>",       /* String to print to indicate an invalid token */
++        (pANTLR3_UINT8) "<EOR>",
++        (pANTLR3_UINT8) "<DOWN>", 
++        (pANTLR3_UINT8) "<UP>", 
++        (pANTLR3_UINT8) "NEWLINE",
++        (pANTLR3_UINT8) "OR",
++        (pANTLR3_UINT8) "AND",
++        (pANTLR3_UINT8) "LPAR",
++        (pANTLR3_UINT8) "RPAR",
++        (pANTLR3_UINT8) "FIELD",
++        (pANTLR3_UINT8) "STR",
++        (pANTLR3_UINT8) "NOT",
++        (pANTLR3_UINT8) "EQUAL",
++        (pANTLR3_UINT8) "INCLUDES",
++        (pANTLR3_UINT8) "STARTSW",
++        (pANTLR3_UINT8) "ENDSW",
++        (pANTLR3_UINT8) "INT",
++        (pANTLR3_UINT8) "LESS",
++        (pANTLR3_UINT8) "GREATER",
++        (pANTLR3_UINT8) "LTE",
++        (pANTLR3_UINT8) "GTE",
++        (pANTLR3_UINT8) "BEFORE",
++        (pANTLR3_UINT8) "AFTER",
++        (pANTLR3_UINT8) "DATE",
++        (pANTLR3_UINT8) "TODAY",
++        (pANTLR3_UINT8) "DAY",
++        (pANTLR3_UINT8) "WEEK",
++        (pANTLR3_UINT8) "MONTH",
++        (pANTLR3_UINT8) "YEAR",
++        (pANTLR3_UINT8) "QUOTE",
++        (pANTLR3_UINT8) "WS",
++        (pANTLR3_UINT8) "DIGIT19",
++        (pANTLR3_UINT8) "DIGIT09",
++        (pANTLR3_UINT8) "ESCAPED"
++       };
++
++        
++
++// Forward declare the locally static matching functions we have generated.
++//
++static RSPParser_query_return query    (pRSPParser ctx);
++static RSPParser_expr_return  expr    (pRSPParser ctx);
++static RSPParser_aexpr_return aexpr    (pRSPParser ctx);
++static RSPParser_crit_return  crit    (pRSPParser ctx);
++static RSPParser_strcrit_return       strcrit    (pRSPParser ctx);
++static RSPParser_strop_return strop    (pRSPParser ctx);
++static RSPParser_intcrit_return       intcrit    (pRSPParser ctx);
++static RSPParser_intop_return intop    (pRSPParser ctx);
++static RSPParser_datecrit_return      datecrit    (pRSPParser ctx);
++static RSPParser_dateop_return        dateop    (pRSPParser ctx);
++static RSPParser_datespec_return      datespec    (pRSPParser ctx);
++static RSPParser_dateref_return       dateref    (pRSPParser ctx);
++static RSPParser_dateintval_return    dateintval    (pRSPParser ctx);
++static void   RSPParserFree(pRSPParser ctx);
++/* For use in tree output where we are accumulating rule labels via label += ruleRef
++ * we need a function that knows how to free a return scope when the list is destroyed. 
++ * We cannot just use ANTLR3_FREE because in debug tracking mode, this is a macro.
++ */
++static        void ANTLR3_CDECL freeScope(void * scope)
++{
++    ANTLR3_FREE(scope);
++}
++
++/** \brief Name of the grammar file that generated this code
++ */
++static const char fileName[] = "RSP.g";
++
++/** \brief Return the name of the grammar file that generated this code.
++ */
++static const char * getGrammarFileName()
++{
++      return fileName;
++}
++/** \brief Create a new RSPParser parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pRSPParser
++RSPParserNew   (pANTLR3_COMMON_TOKEN_STREAM instream)
++{
++      // See if we can create a new parser with the standard constructor
++      //
++      return RSPParserNewSSD(instream, NULL);
++}
++
++/** \brief Create a new RSPParser parser and return a context for it.
++ *
++ * \param[in] instream Pointer to an input stream interface.
++ *
++ * \return Pointer to new parser context upon success.
++ */
++ANTLR3_API pRSPParser
++RSPParserNewSSD   (pANTLR3_COMMON_TOKEN_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state)
++{
++    pRSPParser ctx;       /* Context structure we will build and return   */
++    
++    ctx       = (pRSPParser) ANTLR3_CALLOC(1, sizeof(RSPParser));
++    
++    if        (ctx == NULL)
++    {
++              // Failed to allocate memory for parser context
++              //
++        return  NULL;
++    }
++    
++    /* -------------------------------------------------------------------
++     * Memory for basic structure is allocated, now to fill in
++     * the base ANTLR3 structures. We initialize the function pointers
++     * for the standard ANTLR3 parser function set, but upon return
++     * from here, the programmer may set the pointers to provide custom
++     * implementations of each function. 
++     *
++     * We don't use the macros defined in RSPParser.h here, in order that you can get a sense
++     * of what goes where.
++     */
++
++    /* Create a base parser/recognizer, using the supplied token stream
++     */
++    ctx->pParser          = antlr3ParserNewStream(ANTLR3_SIZE_HINT, instream->tstream, state);
++    /* Install the implementation of our RSPParser interface
++     */
++    ctx->query        = query;
++    ctx->expr = expr;
++    ctx->aexpr        = aexpr;
++    ctx->crit = crit;
++    ctx->strcrit      = strcrit;
++    ctx->strop        = strop;
++    ctx->intcrit      = intcrit;
++    ctx->intop        = intop;
++    ctx->datecrit     = datecrit;
++    ctx->dateop       = dateop;
++    ctx->datespec     = datespec;
++    ctx->dateref      = dateref;
++    ctx->dateintval   = dateintval;
++    ctx->free                 = RSPParserFree;
++    ctx->getGrammarFileName   = getGrammarFileName;
++    
++    /* Install the scope pushing methods.
++     */
++    ADAPTOR   = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);
++    ctx->vectors      = antlr3VectorFactoryNew(0);
++    
++
++      
++    /* Install the token table
++     */
++    PSRSTATE->tokenNames   = RSPParserTokenNames;
++    
++    
++    /* Return the newly built parser to the caller
++     */
++    return  ctx;
++}
++
++/** Free the parser resources
++ */
++ static void
++ RSPParserFree(pRSPParser ctx)
++ {
++    /* Free any scope memory
++     */
++    
++    ctx->vectors->close(ctx->vectors);
++    /* We created the adaptor so we must free it
++     */
++    ADAPTOR->free(ADAPTOR);
++      // Free this parser
++      //
++    ctx->pParser->free(ctx->pParser);
++    ANTLR3_FREE(ctx);
++
++    /* Everything is released, so we can return
++     */
++    return;
++ }
++ 
++/** Return token names used by this parser
++ *
++ * The returned pointer is used as an index into the token names table (using the token 
++ * number as the index).
++ * 
++ * \return Pointer to first char * in the table.
++ */
++static pANTLR3_UINT8    *getTokenNames() 
++{
++        return RSPParserTokenNames; 
++}
++
++    
++/* Declare the bitsets
++ */
++
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_query42  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_query42_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000010) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_query42     = { FOLLOW_expr_in_query42_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NEWLINE_in_query44  */
++static        ANTLR3_BITWORD FOLLOW_NEWLINE_in_query44_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000000) };
++static  ANTLR3_BITSET_LIST FOLLOW_NEWLINE_in_query44  = { FOLLOW_NEWLINE_in_query44_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_EOF_in_query47  */
++static        ANTLR3_BITWORD FOLLOW_EOF_in_query47_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_EOF_in_query47      = { FOLLOW_EOF_in_query47_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_aexpr_in_expr63  */
++static        ANTLR3_BITWORD FOLLOW_aexpr_in_expr63_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000022) };
++static  ANTLR3_BITSET_LIST FOLLOW_aexpr_in_expr63     = { FOLLOW_aexpr_in_expr63_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_OR_in_expr66  */
++static        ANTLR3_BITWORD FOLLOW_OR_in_expr66_bits[]       = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_OR_in_expr66        = { FOLLOW_OR_in_expr66_bits, 1 };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_aexpr_in_expr69  */
++static        ANTLR3_BITWORD FOLLOW_aexpr_in_expr69_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000022) };
++static  ANTLR3_BITSET_LIST FOLLOW_aexpr_in_expr69     = { FOLLOW_aexpr_in_expr69_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_crit_in_aexpr81  */
++static        ANTLR3_BITWORD FOLLOW_crit_in_aexpr81_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000042) };
++static  ANTLR3_BITSET_LIST FOLLOW_crit_in_aexpr81     = { FOLLOW_crit_in_aexpr81_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_AND_in_aexpr84  */
++static        ANTLR3_BITWORD FOLLOW_AND_in_aexpr84_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_AND_in_aexpr84      = { FOLLOW_AND_in_aexpr84_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_crit_in_aexpr87  */
++static        ANTLR3_BITWORD FOLLOW_crit_in_aexpr87_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000042) };
++static  ANTLR3_BITSET_LIST FOLLOW_crit_in_aexpr87     = { FOLLOW_crit_in_aexpr87_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_LPAR_in_crit99  */
++static        ANTLR3_BITWORD FOLLOW_LPAR_in_crit99_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000280) };
++static  ANTLR3_BITSET_LIST FOLLOW_LPAR_in_crit99      = { FOLLOW_LPAR_in_crit99_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_expr_in_crit101  */
++static        ANTLR3_BITWORD FOLLOW_expr_in_crit101_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000100) };
++static  ANTLR3_BITSET_LIST FOLLOW_expr_in_crit101     = { FOLLOW_expr_in_crit101_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_RPAR_in_crit103  */
++static        ANTLR3_BITWORD FOLLOW_RPAR_in_crit103_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_RPAR_in_crit103     = { FOLLOW_RPAR_in_crit103_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strcrit_in_crit114  */
++static        ANTLR3_BITWORD FOLLOW_strcrit_in_crit114_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_strcrit_in_crit114  = { FOLLOW_strcrit_in_crit114_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intcrit_in_crit119  */
++static        ANTLR3_BITWORD FOLLOW_intcrit_in_crit119_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_intcrit_in_crit119  = { FOLLOW_intcrit_in_crit119_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_datecrit_in_crit124  */
++static        ANTLR3_BITWORD FOLLOW_datecrit_in_crit124_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_datecrit_in_crit124 = { FOLLOW_datecrit_in_crit124_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_strcrit134  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_strcrit134_bits[]        = { ANTLR3_UINT64_LIT(0x000000000000F000) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_strcrit134 = { FOLLOW_FIELD_in_strcrit134_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strop_in_strcrit136  */
++static        ANTLR3_BITWORD FOLLOW_strop_in_strcrit136_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000400) };
++static  ANTLR3_BITSET_LIST FOLLOW_strop_in_strcrit136 = { FOLLOW_strop_in_strcrit136_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STR_in_strcrit138  */
++static        ANTLR3_BITWORD FOLLOW_STR_in_strcrit138_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_STR_in_strcrit138   = { FOLLOW_STR_in_strcrit138_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_strcrit155  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_strcrit155_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000800) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_strcrit155 = { FOLLOW_FIELD_in_strcrit155_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NOT_in_strcrit157  */
++static        ANTLR3_BITWORD FOLLOW_NOT_in_strcrit157_bits[]  = { ANTLR3_UINT64_LIT(0x000000000000F000) };
++static  ANTLR3_BITSET_LIST FOLLOW_NOT_in_strcrit157   = { FOLLOW_NOT_in_strcrit157_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_strop_in_strcrit159  */
++static        ANTLR3_BITWORD FOLLOW_strop_in_strcrit159_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000400) };
++static  ANTLR3_BITSET_LIST FOLLOW_strop_in_strcrit159 = { FOLLOW_strop_in_strcrit159_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_STR_in_strcrit161  */
++static        ANTLR3_BITWORD FOLLOW_STR_in_strcrit161_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_STR_in_strcrit161   = { FOLLOW_STR_in_strcrit161_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_set_in_strop0  */
++static        ANTLR3_BITWORD FOLLOW_set_in_strop0_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_set_in_strop0       = { FOLLOW_set_in_strop0_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_intcrit211  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_intcrit211_bits[]        = { ANTLR3_UINT64_LIT(0x00000000001E1000) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_intcrit211 = { FOLLOW_FIELD_in_intcrit211_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intop_in_intcrit213  */
++static        ANTLR3_BITWORD FOLLOW_intop_in_intcrit213_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000010000) };
++static  ANTLR3_BITSET_LIST FOLLOW_intop_in_intcrit213 = { FOLLOW_intop_in_intcrit213_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INT_in_intcrit215  */
++static        ANTLR3_BITWORD FOLLOW_INT_in_intcrit215_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_INT_in_intcrit215   = { FOLLOW_INT_in_intcrit215_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_intcrit232  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_intcrit232_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000000800) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_intcrit232 = { FOLLOW_FIELD_in_intcrit232_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_NOT_in_intcrit234  */
++static        ANTLR3_BITWORD FOLLOW_NOT_in_intcrit234_bits[]  = { ANTLR3_UINT64_LIT(0x00000000001E1000) };
++static  ANTLR3_BITSET_LIST FOLLOW_NOT_in_intcrit234   = { FOLLOW_NOT_in_intcrit234_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_intop_in_intcrit236  */
++static        ANTLR3_BITWORD FOLLOW_intop_in_intcrit236_bits[]        = { ANTLR3_UINT64_LIT(0x0000000000010000) };
++static  ANTLR3_BITSET_LIST FOLLOW_intop_in_intcrit236 = { FOLLOW_intop_in_intcrit236_bits, 1  };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INT_in_intcrit238  */
++static        ANTLR3_BITWORD FOLLOW_INT_in_intcrit238_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_INT_in_intcrit238   = { FOLLOW_INT_in_intcrit238_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_set_in_intop0  */
++static        ANTLR3_BITWORD FOLLOW_set_in_intop0_bits[]      = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_set_in_intop0       = { FOLLOW_set_in_intop0_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_FIELD_in_datecrit292  */
++static        ANTLR3_BITWORD FOLLOW_FIELD_in_datecrit292_bits[]       = { ANTLR3_UINT64_LIT(0x0000000000600000) };
++static  ANTLR3_BITSET_LIST FOLLOW_FIELD_in_datecrit292        = { FOLLOW_FIELD_in_datecrit292_bits, 1 };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateop_in_datecrit294  */
++static        ANTLR3_BITWORD FOLLOW_dateop_in_datecrit294_bits[]      = { ANTLR3_UINT64_LIT(0x0000000001810000) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateop_in_datecrit294       = { FOLLOW_dateop_in_datecrit294_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_datespec_in_datecrit296  */
++static        ANTLR3_BITWORD FOLLOW_datespec_in_datecrit296_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_datespec_in_datecrit296     = { FOLLOW_datespec_in_datecrit296_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_set_in_dateop0  */
++static        ANTLR3_BITWORD FOLLOW_set_in_dateop0_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_set_in_dateop0      = { FOLLOW_set_in_dateop0_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateref_in_datespec331  */
++static        ANTLR3_BITWORD FOLLOW_dateref_in_datespec331_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateref_in_datespec331      = { FOLLOW_dateref_in_datespec331_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_INT_in_datespec336  */
++static        ANTLR3_BITWORD FOLLOW_INT_in_datespec336_bits[] = { ANTLR3_UINT64_LIT(0x000000001E000000) };
++static  ANTLR3_BITSET_LIST FOLLOW_INT_in_datespec336  = { FOLLOW_INT_in_datespec336_bits, 1   };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateintval_in_datespec338  */
++static        ANTLR3_BITWORD FOLLOW_dateintval_in_datespec338_bits[]  = { ANTLR3_UINT64_LIT(0x0000000000600000) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateintval_in_datespec338   = { FOLLOW_dateintval_in_datespec338_bits, 1    };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateop_in_datespec340  */
++static        ANTLR3_BITWORD FOLLOW_dateop_in_datespec340_bits[]      = { ANTLR3_UINT64_LIT(0x0000000001800000) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateop_in_datespec340       = { FOLLOW_dateop_in_datespec340_bits, 1        };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_dateref_in_datespec342  */
++static        ANTLR3_BITWORD FOLLOW_dateref_in_datespec342_bits[]     = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_dateref_in_datespec342      = { FOLLOW_dateref_in_datespec342_bits, 1       };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_set_in_dateref0  */
++static        ANTLR3_BITWORD FOLLOW_set_in_dateref0_bits[]    = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_set_in_dateref0     = { FOLLOW_set_in_dateref0_bits, 1      };
++/** Bitset defining follow set for error recovery in rule state: FOLLOW_set_in_dateintval0  */
++static        ANTLR3_BITWORD FOLLOW_set_in_dateintval0_bits[] = { ANTLR3_UINT64_LIT(0x0000000000000002) };
++static  ANTLR3_BITSET_LIST FOLLOW_set_in_dateintval0  = { FOLLOW_set_in_dateintval0_bits, 1   };
++     
++
++ 
++ 
++/* ==============================================
++ * Parsing rules
++ */
++/** 
++ * $ANTLR start query
++ * RSP.g:27:1: query : expr ( NEWLINE )? EOF -> expr ;
++ */
++static RSPParser_query_return
++query(pRSPParser ctx)
++{   
++    RSPParser_query_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    NEWLINE2;
++    pANTLR3_COMMON_TOKEN    EOF3;
++    RSPParser_expr_return expr1;
++    #undef    RETURN_TYPE_expr1
++    #define   RETURN_TYPE_expr1 RSPParser_expr_return
++
++    pANTLR3_BASE_TREE NEWLINE2_tree;
++    pANTLR3_BASE_TREE EOF3_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_NEWLINE;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_EOF;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_expr;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    NEWLINE2       = NULL;
++    EOF3       = NULL;
++    expr1.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    NEWLINE2_tree   = NULL;
++    EOF3_tree   = NULL;
++
++    stream_NEWLINE   = NULL;
++    #define CREATE_stream_NEWLINE  if (stream_NEWLINE == NULL) {stream_NEWLINE = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token NEWLINE"); } 
++    stream_EOF   = NULL;
++    #define CREATE_stream_EOF  if (stream_EOF == NULL) {stream_EOF = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token EOF"); } 
++    stream_expr   = NULL;
++    #define CREATE_stream_expr  if (stream_expr == NULL) {stream_expr = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule expr"); }
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:27:7: ( expr ( NEWLINE )? EOF -> expr )
++        // RSP.g:27:9: expr ( NEWLINE )? EOF
++        {
++            FOLLOWPUSH(FOLLOW_expr_in_query42);
++            expr1=expr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++
++            CREATE_stream_expr; stream_expr->add(stream_expr, expr1.tree, NULL);
++
++            // RSP.g:27:14: ( NEWLINE )?
++            {
++                int alt1=2;
++                switch ( LA(1) ) 
++                {
++                    case NEWLINE:
++                      {
++                              alt1=1;
++                      }
++                        break;
++                }
++
++                switch (alt1) 
++                {
++              case 1:
++                  // RSP.g:27:14: NEWLINE
++                  {
++                      NEWLINE2 = (pANTLR3_COMMON_TOKEN) MATCHT(NEWLINE, &FOLLOW_NEWLINE_in_query44); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulequeryEx;
++                      }
++                       
++                      CREATE_stream_NEWLINE; stream_NEWLINE->add(stream_NEWLINE, NEWLINE2, NULL);
++
++
++                  }
++                  break;
++
++                }
++            }
++            EOF3 = (pANTLR3_COMMON_TOKEN) MATCHT(EOF, &FOLLOW_EOF_in_query47); 
++            if  (HASEXCEPTION())
++            {
++                goto rulequeryEx;
++            }
++             
++            CREATE_stream_EOF; stream_EOF->add(stream_EOF, EOF3, NULL);
++
++
++             
++            /* AST REWRITE
++             * elements          : expr
++             * token labels      : 
++             * rule labels       : retval
++             * token list labels : 
++             * rule list labels  : 
++             */
++            {
++              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++              retval.tree    = root_0;
++              // 27:28: -> expr
++              {
++                  ADAPTOR->addChild(ADAPTOR, root_0, stream_expr == NULL ? NULL : stream_expr->nextTree(stream_expr));
++
++              }
++
++              retval.tree = root_0; // set result root
++              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++            }
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulequeryEx; /* Prevent compiler warnings */
++    rulequeryEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_NEWLINE != NULL) stream_NEWLINE->free(stream_NEWLINE);
++        if (stream_EOF != NULL) stream_EOF->free(stream_EOF);
++        if (stream_expr != NULL) stream_expr->free(stream_expr);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end query */
++
++/** 
++ * $ANTLR start expr
++ * RSP.g:30:1: expr : aexpr ( OR aexpr )* ;
++ */
++static RSPParser_expr_return
++expr(pRSPParser ctx)
++{   
++    RSPParser_expr_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    OR5;
++    RSPParser_aexpr_return aexpr4;
++    #undef    RETURN_TYPE_aexpr4
++    #define   RETURN_TYPE_aexpr4 RSPParser_aexpr_return
++
++    RSPParser_aexpr_return aexpr6;
++    #undef    RETURN_TYPE_aexpr6
++    #define   RETURN_TYPE_aexpr6 RSPParser_aexpr_return
++
++    pANTLR3_BASE_TREE OR5_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    OR5       = NULL;
++    aexpr4.tree = NULL;
++
++    aexpr6.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    OR5_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:30:6: ( aexpr ( OR aexpr )* )
++        // RSP.g:30:8: aexpr ( OR aexpr )*
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            FOLLOWPUSH(FOLLOW_aexpr_in_expr63);
++            aexpr4=aexpr(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruleexprEx;
++            }
++
++            ADAPTOR->addChild(ADAPTOR, root_0, aexpr4.tree);
++
++            // RSP.g:30:14: ( OR aexpr )*
++
++            for (;;)
++            {
++                int alt2=2;
++                switch ( LA(1) ) 
++                {
++                case OR:
++                      {
++                              alt2=1;
++                      }
++                    break;
++
++                }
++
++                switch (alt2) 
++                {
++              case 1:
++                  // RSP.g:30:15: OR aexpr
++                  {
++                      OR5 = (pANTLR3_COMMON_TOKEN) MATCHT(OR, &FOLLOW_OR_in_expr66); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      OR5_tree = (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, OR5));
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, OR5_tree, root_0));
++
++                      FOLLOWPUSH(FOLLOW_aexpr_in_expr69);
++                      aexpr6=aexpr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleexprEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, aexpr6.tree);
++
++                  }
++                  break;
++
++              default:
++                  goto loop2; /* break out of the loop */
++                  break;
++                }
++            }
++            loop2: ; /* Jump out to here if this rule does not match */
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleexprEx; /* Prevent compiler warnings */
++    ruleexprEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end expr */
++
++/** 
++ * $ANTLR start aexpr
++ * RSP.g:33:1: aexpr : crit ( AND crit )* ;
++ */
++static RSPParser_aexpr_return
++aexpr(pRSPParser ctx)
++{   
++    RSPParser_aexpr_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    AND8;
++    RSPParser_crit_return crit7;
++    #undef    RETURN_TYPE_crit7
++    #define   RETURN_TYPE_crit7 RSPParser_crit_return
++
++    RSPParser_crit_return crit9;
++    #undef    RETURN_TYPE_crit9
++    #define   RETURN_TYPE_crit9 RSPParser_crit_return
++
++    pANTLR3_BASE_TREE AND8_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    AND8       = NULL;
++    crit7.tree = NULL;
++
++    crit9.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    AND8_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:33:7: ( crit ( AND crit )* )
++        // RSP.g:33:9: crit ( AND crit )*
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            FOLLOWPUSH(FOLLOW_crit_in_aexpr81);
++            crit7=crit(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruleaexprEx;
++            }
++
++            ADAPTOR->addChild(ADAPTOR, root_0, crit7.tree);
++
++            // RSP.g:33:14: ( AND crit )*
++
++            for (;;)
++            {
++                int alt3=2;
++                switch ( LA(1) ) 
++                {
++                case AND:
++                      {
++                              alt3=1;
++                      }
++                    break;
++
++                }
++
++                switch (alt3) 
++                {
++              case 1:
++                  // RSP.g:33:15: AND crit
++                  {
++                      AND8 = (pANTLR3_COMMON_TOKEN) MATCHT(AND, &FOLLOW_AND_in_aexpr84); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleaexprEx;
++                      }
++
++                      AND8_tree = (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, AND8));
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, AND8_tree, root_0));
++
++                      FOLLOWPUSH(FOLLOW_crit_in_aexpr87);
++                      crit9=crit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleaexprEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, crit9.tree);
++
++                  }
++                  break;
++
++              default:
++                  goto loop3; /* break out of the loop */
++                  break;
++                }
++            }
++            loop3: ; /* Jump out to here if this rule does not match */
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleaexprEx; /* Prevent compiler warnings */
++    ruleaexprEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end aexpr */
++
++/** 
++ * $ANTLR start crit
++ * RSP.g:36:1: crit : ( LPAR expr RPAR -> expr | strcrit | intcrit | datecrit );
++ */
++static RSPParser_crit_return
++crit(pRSPParser ctx)
++{   
++    RSPParser_crit_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    LPAR10;
++    pANTLR3_COMMON_TOKEN    RPAR12;
++    RSPParser_expr_return expr11;
++    #undef    RETURN_TYPE_expr11
++    #define   RETURN_TYPE_expr11 RSPParser_expr_return
++
++    RSPParser_strcrit_return strcrit13;
++    #undef    RETURN_TYPE_strcrit13
++    #define   RETURN_TYPE_strcrit13 RSPParser_strcrit_return
++
++    RSPParser_intcrit_return intcrit14;
++    #undef    RETURN_TYPE_intcrit14
++    #define   RETURN_TYPE_intcrit14 RSPParser_intcrit_return
++
++    RSPParser_datecrit_return datecrit15;
++    #undef    RETURN_TYPE_datecrit15
++    #define   RETURN_TYPE_datecrit15 RSPParser_datecrit_return
++
++    pANTLR3_BASE_TREE LPAR10_tree;
++    pANTLR3_BASE_TREE RPAR12_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_RPAR;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_LPAR;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_expr;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    LPAR10       = NULL;
++    RPAR12       = NULL;
++    expr11.tree = NULL;
++
++    strcrit13.tree = NULL;
++
++    intcrit14.tree = NULL;
++
++    datecrit15.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    LPAR10_tree   = NULL;
++    RPAR12_tree   = NULL;
++
++    stream_RPAR   = NULL;
++    #define CREATE_stream_RPAR  if (stream_RPAR == NULL) {stream_RPAR = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token RPAR"); } 
++    stream_LPAR   = NULL;
++    #define CREATE_stream_LPAR  if (stream_LPAR == NULL) {stream_LPAR = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token LPAR"); } 
++    stream_expr   = NULL;
++    #define CREATE_stream_expr  if (stream_expr == NULL) {stream_expr = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule expr"); }
++
++    retval.tree  = NULL;
++    {
++        {
++            //  RSP.g:36:6: ( LPAR expr RPAR -> expr | strcrit | intcrit | datecrit )
++            
++            ANTLR3_UINT32 alt4;
++
++            alt4=4;
++
++            switch ( LA(1) ) 
++            {
++            case LPAR:
++              {
++                      alt4=1;
++              }
++                break;
++            case FIELD:
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case NOT:
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case EQUAL:
++                                              {
++                                                      switch ( LA(4) ) 
++                                                      {
++                                                      case STR:
++                                                              {
++                                                                      alt4=2;
++                                                              }
++                                                          break;
++                                                      case INT:
++                                                              {
++                                                                      alt4=3;
++                                                              }
++                                                          break;
++
++                                                      default:
++                                                          CONSTRUCTEX();
++                                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                                          EXCEPTION->message      = (void *)"";
++                                                          EXCEPTION->decisionNum  = 4;
++                                                          EXCEPTION->state        = 8;
++
++
++                                                          goto rulecritEx;
++                                                      }
++
++                                              }
++                                          break;
++                                      case INCLUDES:
++                                      case STARTSW:
++                                      case ENDSW:
++                                              {
++                                                      alt4=2;
++                                              }
++                                          break;
++                                      case LESS:
++                                      case GREATER:
++                                      case LTE:
++                                      case GTE:
++                                              {
++                                                      alt4=3;
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 4;
++                                          EXCEPTION->state        = 3;
++
++
++                                          goto rulecritEx;
++                                      }
++
++                              }
++                          break;
++                      case EQUAL:
++                              {
++                                      switch ( LA(3) ) 
++                                      {
++                                      case INT:
++                                              {
++                                                      alt4=3;
++                                              }
++                                          break;
++                                      case STR:
++                                              {
++                                                      alt4=2;
++                                              }
++                                          break;
++
++                                      default:
++                                          CONSTRUCTEX();
++                                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                                          EXCEPTION->message      = (void *)"";
++                                          EXCEPTION->decisionNum  = 4;
++                                          EXCEPTION->state        = 4;
++
++
++                                          goto rulecritEx;
++                                      }
++
++                              }
++                          break;
++                      case BEFORE:
++                      case AFTER:
++                              {
++                                      alt4=4;
++                              }
++                          break;
++                      case LESS:
++                      case GREATER:
++                      case LTE:
++                      case GTE:
++                              {
++                                      alt4=3;
++                              }
++                          break;
++                      case INCLUDES:
++                      case STARTSW:
++                      case ENDSW:
++                              {
++                                      alt4=2;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 4;
++                          EXCEPTION->state        = 2;
++
++
++                          goto rulecritEx;
++                      }
++
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 4;
++                EXCEPTION->state        = 0;
++
++
++                goto rulecritEx;
++            }
++
++            switch (alt4) 
++            {
++              case 1:
++                  // RSP.g:36:8: LPAR expr RPAR
++                  {
++                      LPAR10 = (pANTLR3_COMMON_TOKEN) MATCHT(LPAR, &FOLLOW_LPAR_in_crit99); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++                       
++                      CREATE_stream_LPAR; stream_LPAR->add(stream_LPAR, LPAR10, NULL);
++
++                      FOLLOWPUSH(FOLLOW_expr_in_crit101);
++                      expr11=expr(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      CREATE_stream_expr; stream_expr->add(stream_expr, expr11.tree, NULL);
++                      RPAR12 = (pANTLR3_COMMON_TOKEN) MATCHT(RPAR, &FOLLOW_RPAR_in_crit103); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++                       
++                      CREATE_stream_RPAR; stream_RPAR->add(stream_RPAR, RPAR12, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : expr
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 36:25: -> expr
++                              {
++                                  ADAPTOR->addChild(ADAPTOR, root_0, stream_expr == NULL ? NULL : stream_expr->nextTree(stream_expr));
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++              case 2:
++                  // RSP.g:37:4: strcrit
++                  {
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++                      FOLLOWPUSH(FOLLOW_strcrit_in_crit114);
++                      strcrit13=strcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, strcrit13.tree);
++
++                  }
++                  break;
++              case 3:
++                  // RSP.g:38:4: intcrit
++                  {
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++                      FOLLOWPUSH(FOLLOW_intcrit_in_crit119);
++                      intcrit14=intcrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, intcrit14.tree);
++
++                  }
++                  break;
++              case 4:
++                  // RSP.g:39:4: datecrit
++                  {
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++                      FOLLOWPUSH(FOLLOW_datecrit_in_crit124);
++                      datecrit15=datecrit(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulecritEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, datecrit15.tree);
++
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulecritEx; /* Prevent compiler warnings */
++    rulecritEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_RPAR != NULL) stream_RPAR->free(stream_RPAR);
++        if (stream_LPAR != NULL) stream_LPAR->free(stream_LPAR);
++        if (stream_expr != NULL) stream_expr->free(stream_expr);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end crit */
++
++/** 
++ * $ANTLR start strcrit
++ * RSP.g:42:1: strcrit : ( FIELD strop STR -> ^( strop FIELD STR ) | FIELD NOT strop STR -> ^( NOT ^( strop FIELD STR ) ) );
++ */
++static RSPParser_strcrit_return
++strcrit(pRSPParser ctx)
++{   
++    RSPParser_strcrit_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    FIELD16;
++    pANTLR3_COMMON_TOKEN    STR18;
++    pANTLR3_COMMON_TOKEN    FIELD19;
++    pANTLR3_COMMON_TOKEN    NOT20;
++    pANTLR3_COMMON_TOKEN    STR22;
++    RSPParser_strop_return strop17;
++    #undef    RETURN_TYPE_strop17
++    #define   RETURN_TYPE_strop17 RSPParser_strop_return
++
++    RSPParser_strop_return strop21;
++    #undef    RETURN_TYPE_strop21
++    #define   RETURN_TYPE_strop21 RSPParser_strop_return
++
++    pANTLR3_BASE_TREE FIELD16_tree;
++    pANTLR3_BASE_TREE STR18_tree;
++    pANTLR3_BASE_TREE FIELD19_tree;
++    pANTLR3_BASE_TREE NOT20_tree;
++    pANTLR3_BASE_TREE STR22_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_STR;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_FIELD;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_NOT;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_strop;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    FIELD16       = NULL;
++    STR18       = NULL;
++    FIELD19       = NULL;
++    NOT20       = NULL;
++    STR22       = NULL;
++    strop17.tree = NULL;
++
++    strop21.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    FIELD16_tree   = NULL;
++    STR18_tree   = NULL;
++    FIELD19_tree   = NULL;
++    NOT20_tree   = NULL;
++    STR22_tree   = NULL;
++
++    stream_STR   = NULL;
++    #define CREATE_stream_STR  if (stream_STR == NULL) {stream_STR = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token STR"); } 
++    stream_FIELD   = NULL;
++    #define CREATE_stream_FIELD  if (stream_FIELD == NULL) {stream_FIELD = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token FIELD"); } 
++    stream_NOT   = NULL;
++    #define CREATE_stream_NOT  if (stream_NOT == NULL) {stream_NOT = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token NOT"); } 
++    stream_strop   = NULL;
++    #define CREATE_stream_strop  if (stream_strop == NULL) {stream_strop = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule strop"); }
++
++    retval.tree  = NULL;
++    {
++        {
++            //  RSP.g:42:9: ( FIELD strop STR -> ^( strop FIELD STR ) | FIELD NOT strop STR -> ^( NOT ^( strop FIELD STR ) ) )
++            
++            ANTLR3_UINT32 alt5;
++
++            alt5=2;
++
++            switch ( LA(1) ) 
++            {
++            case FIELD:
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case NOT:
++                              {
++                                      alt5=2;
++                              }
++                          break;
++                      case EQUAL:
++                      case INCLUDES:
++                      case STARTSW:
++                      case ENDSW:
++                              {
++                                      alt5=1;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 5;
++                          EXCEPTION->state        = 1;
++
++
++                          goto rulestrcritEx;
++                      }
++
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 5;
++                EXCEPTION->state        = 0;
++
++
++                goto rulestrcritEx;
++            }
++
++            switch (alt5) 
++            {
++              case 1:
++                  // RSP.g:42:11: FIELD strop STR
++                  {
++                      FIELD16 = (pANTLR3_COMMON_TOKEN) MATCHT(FIELD, &FOLLOW_FIELD_in_strcrit134); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++                       
++                      CREATE_stream_FIELD; stream_FIELD->add(stream_FIELD, FIELD16, NULL);
++
++                      FOLLOWPUSH(FOLLOW_strop_in_strcrit136);
++                      strop17=strop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++
++                      CREATE_stream_strop; stream_strop->add(stream_strop, strop17.tree, NULL);
++                      STR18 = (pANTLR3_COMMON_TOKEN) MATCHT(STR, &FOLLOW_STR_in_strcrit138); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++                       
++                      CREATE_stream_STR; stream_STR->add(stream_STR, STR18, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : strop, STR, FIELD
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 42:29: -> ^( strop FIELD STR )
++                              {
++                                  // RSP.g:42:32: ^( strop FIELD STR )
++                                  {
++                                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_strop == NULL ? NULL : stream_strop->nextNode(stream_strop), root_1));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_FIELD == NULL ? NULL : stream_FIELD->nextNode(stream_FIELD));
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_STR == NULL ? NULL : stream_STR->nextNode(stream_STR));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                                  }
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++              case 2:
++                  // RSP.g:43:4: FIELD NOT strop STR
++                  {
++                      FIELD19 = (pANTLR3_COMMON_TOKEN) MATCHT(FIELD, &FOLLOW_FIELD_in_strcrit155); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++                       
++                      CREATE_stream_FIELD; stream_FIELD->add(stream_FIELD, FIELD19, NULL);
++
++                      NOT20 = (pANTLR3_COMMON_TOKEN) MATCHT(NOT, &FOLLOW_NOT_in_strcrit157); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++                       
++                      CREATE_stream_NOT; stream_NOT->add(stream_NOT, NOT20, NULL);
++
++                      FOLLOWPUSH(FOLLOW_strop_in_strcrit159);
++                      strop21=strop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++
++                      CREATE_stream_strop; stream_strop->add(stream_strop, strop21.tree, NULL);
++                      STR22 = (pANTLR3_COMMON_TOKEN) MATCHT(STR, &FOLLOW_STR_in_strcrit161); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto rulestrcritEx;
++                      }
++                       
++                      CREATE_stream_STR; stream_STR->add(stream_STR, STR22, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : NOT, FIELD, strop, STR
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 43:25: -> ^( NOT ^( strop FIELD STR ) )
++                              {
++                                  // RSP.g:43:28: ^( NOT ^( strop FIELD STR ) )
++                                  {
++                                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_NOT == NULL ? NULL : stream_NOT->nextNode(stream_NOT), root_1));
++
++                                      // RSP.g:43:34: ^( strop FIELD STR )
++                                      {
++                                          pANTLR3_BASE_TREE root_2 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                          root_2 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_strop == NULL ? NULL : stream_strop->nextNode(stream_strop), root_2));
++
++                                          ADAPTOR->addChild(ADAPTOR, root_2, stream_FIELD == NULL ? NULL : stream_FIELD->nextNode(stream_FIELD));
++                                          ADAPTOR->addChild(ADAPTOR, root_2, stream_STR == NULL ? NULL : stream_STR->nextNode(stream_STR));
++
++                                          ADAPTOR->addChild(ADAPTOR, root_1, root_2);
++                                      }
++
++                                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                                  }
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulestrcritEx; /* Prevent compiler warnings */
++    rulestrcritEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_STR != NULL) stream_STR->free(stream_STR);
++        if (stream_FIELD != NULL) stream_FIELD->free(stream_FIELD);
++        if (stream_NOT != NULL) stream_NOT->free(stream_NOT);
++        if (stream_strop != NULL) stream_strop->free(stream_strop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end strcrit */
++
++/** 
++ * $ANTLR start strop
++ * RSP.g:46:1: strop : ( EQUAL | INCLUDES | STARTSW | ENDSW );
++ */
++static RSPParser_strop_return
++strop(pRSPParser ctx)
++{   
++    RSPParser_strop_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    set23;
++
++    pANTLR3_BASE_TREE set23_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    set23       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    set23_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:46:7: ( EQUAL | INCLUDES | STARTSW | ENDSW )
++        // RSP.g:
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            set23=(pANTLR3_COMMON_TOKEN)LT(1);
++            if ( ((LA(1) >= EQUAL) && (LA(1) <= ENDSW)) )
++            {
++                CONSUME();
++                ADAPTOR->addChild(ADAPTOR, root_0, (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, set23)));
++                PERRORRECOVERY=ANTLR3_FALSE;
++            }
++            else 
++            {
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++                EXCEPTION->expectingSet = &FOLLOW_set_in_strop0;
++                RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_strop0);    goto rulestropEx;
++            }
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto rulestropEx; /* Prevent compiler warnings */
++    rulestropEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end strop */
++
++/** 
++ * $ANTLR start intcrit
++ * RSP.g:52:1: intcrit : ( FIELD intop INT -> ^( intop FIELD INT ) | FIELD NOT intop INT -> ^( NOT ^( intop FIELD INT ) ) );
++ */
++static RSPParser_intcrit_return
++intcrit(pRSPParser ctx)
++{   
++    RSPParser_intcrit_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    FIELD24;
++    pANTLR3_COMMON_TOKEN    INT26;
++    pANTLR3_COMMON_TOKEN    FIELD27;
++    pANTLR3_COMMON_TOKEN    NOT28;
++    pANTLR3_COMMON_TOKEN    INT30;
++    RSPParser_intop_return intop25;
++    #undef    RETURN_TYPE_intop25
++    #define   RETURN_TYPE_intop25 RSPParser_intop_return
++
++    RSPParser_intop_return intop29;
++    #undef    RETURN_TYPE_intop29
++    #define   RETURN_TYPE_intop29 RSPParser_intop_return
++
++    pANTLR3_BASE_TREE FIELD24_tree;
++    pANTLR3_BASE_TREE INT26_tree;
++    pANTLR3_BASE_TREE FIELD27_tree;
++    pANTLR3_BASE_TREE NOT28_tree;
++    pANTLR3_BASE_TREE INT30_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_FIELD;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_INT;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_NOT;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_intop;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    FIELD24       = NULL;
++    INT26       = NULL;
++    FIELD27       = NULL;
++    NOT28       = NULL;
++    INT30       = NULL;
++    intop25.tree = NULL;
++
++    intop29.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    FIELD24_tree   = NULL;
++    INT26_tree   = NULL;
++    FIELD27_tree   = NULL;
++    NOT28_tree   = NULL;
++    INT30_tree   = NULL;
++
++    stream_FIELD   = NULL;
++    #define CREATE_stream_FIELD  if (stream_FIELD == NULL) {stream_FIELD = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token FIELD"); } 
++    stream_INT   = NULL;
++    #define CREATE_stream_INT  if (stream_INT == NULL) {stream_INT = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token INT"); } 
++    stream_NOT   = NULL;
++    #define CREATE_stream_NOT  if (stream_NOT == NULL) {stream_NOT = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token NOT"); } 
++    stream_intop   = NULL;
++    #define CREATE_stream_intop  if (stream_intop == NULL) {stream_intop = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule intop"); }
++
++    retval.tree  = NULL;
++    {
++        {
++            //  RSP.g:52:9: ( FIELD intop INT -> ^( intop FIELD INT ) | FIELD NOT intop INT -> ^( NOT ^( intop FIELD INT ) ) )
++            
++            ANTLR3_UINT32 alt6;
++
++            alt6=2;
++
++            switch ( LA(1) ) 
++            {
++            case FIELD:
++              {
++                      switch ( LA(2) ) 
++                      {
++                      case NOT:
++                              {
++                                      alt6=2;
++                              }
++                          break;
++                      case EQUAL:
++                      case LESS:
++                      case GREATER:
++                      case LTE:
++                      case GTE:
++                              {
++                                      alt6=1;
++                              }
++                          break;
++
++                      default:
++                          CONSTRUCTEX();
++                          EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                          EXCEPTION->message      = (void *)"";
++                          EXCEPTION->decisionNum  = 6;
++                          EXCEPTION->state        = 1;
++
++
++                          goto ruleintcritEx;
++                      }
++
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 6;
++                EXCEPTION->state        = 0;
++
++
++                goto ruleintcritEx;
++            }
++
++            switch (alt6) 
++            {
++              case 1:
++                  // RSP.g:52:11: FIELD intop INT
++                  {
++                      FIELD24 = (pANTLR3_COMMON_TOKEN) MATCHT(FIELD, &FOLLOW_FIELD_in_intcrit211); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++                       
++                      CREATE_stream_FIELD; stream_FIELD->add(stream_FIELD, FIELD24, NULL);
++
++                      FOLLOWPUSH(FOLLOW_intop_in_intcrit213);
++                      intop25=intop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++
++                      CREATE_stream_intop; stream_intop->add(stream_intop, intop25.tree, NULL);
++                      INT26 = (pANTLR3_COMMON_TOKEN) MATCHT(INT, &FOLLOW_INT_in_intcrit215); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++                       
++                      CREATE_stream_INT; stream_INT->add(stream_INT, INT26, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : FIELD, intop, INT
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 52:29: -> ^( intop FIELD INT )
++                              {
++                                  // RSP.g:52:32: ^( intop FIELD INT )
++                                  {
++                                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_intop == NULL ? NULL : stream_intop->nextNode(stream_intop), root_1));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_FIELD == NULL ? NULL : stream_FIELD->nextNode(stream_FIELD));
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_INT == NULL ? NULL : stream_INT->nextNode(stream_INT));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                                  }
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++              case 2:
++                  // RSP.g:53:4: FIELD NOT intop INT
++                  {
++                      FIELD27 = (pANTLR3_COMMON_TOKEN) MATCHT(FIELD, &FOLLOW_FIELD_in_intcrit232); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++                       
++                      CREATE_stream_FIELD; stream_FIELD->add(stream_FIELD, FIELD27, NULL);
++
++                      NOT28 = (pANTLR3_COMMON_TOKEN) MATCHT(NOT, &FOLLOW_NOT_in_intcrit234); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++                       
++                      CREATE_stream_NOT; stream_NOT->add(stream_NOT, NOT28, NULL);
++
++                      FOLLOWPUSH(FOLLOW_intop_in_intcrit236);
++                      intop29=intop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++
++                      CREATE_stream_intop; stream_intop->add(stream_intop, intop29.tree, NULL);
++                      INT30 = (pANTLR3_COMMON_TOKEN) MATCHT(INT, &FOLLOW_INT_in_intcrit238); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruleintcritEx;
++                      }
++                       
++                      CREATE_stream_INT; stream_INT->add(stream_INT, INT30, NULL);
++
++
++                       
++                      /* AST REWRITE
++                       * elements          : NOT, INT, FIELD, intop
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 53:25: -> ^( NOT ^( intop FIELD INT ) )
++                              {
++                                  // RSP.g:53:28: ^( NOT ^( intop FIELD INT ) )
++                                  {
++                                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_NOT == NULL ? NULL : stream_NOT->nextNode(stream_NOT), root_1));
++
++                                      // RSP.g:53:34: ^( intop FIELD INT )
++                                      {
++                                          pANTLR3_BASE_TREE root_2 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                          root_2 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_intop == NULL ? NULL : stream_intop->nextNode(stream_intop), root_2));
++
++                                          ADAPTOR->addChild(ADAPTOR, root_2, stream_FIELD == NULL ? NULL : stream_FIELD->nextNode(stream_FIELD));
++                                          ADAPTOR->addChild(ADAPTOR, root_2, stream_INT == NULL ? NULL : stream_INT->nextNode(stream_INT));
++
++                                          ADAPTOR->addChild(ADAPTOR, root_1, root_2);
++                                      }
++
++                                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                                  }
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleintcritEx; /* Prevent compiler warnings */
++    ruleintcritEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_FIELD != NULL) stream_FIELD->free(stream_FIELD);
++        if (stream_INT != NULL) stream_INT->free(stream_INT);
++        if (stream_NOT != NULL) stream_NOT->free(stream_NOT);
++        if (stream_intop != NULL) stream_intop->free(stream_intop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end intcrit */
++
++/** 
++ * $ANTLR start intop
++ * RSP.g:56:1: intop : ( EQUAL | LESS | GREATER | LTE | GTE );
++ */
++static RSPParser_intop_return
++intop(pRSPParser ctx)
++{   
++    RSPParser_intop_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    set31;
++
++    pANTLR3_BASE_TREE set31_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    set31       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    set31_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:56:7: ( EQUAL | LESS | GREATER | LTE | GTE )
++        // RSP.g:
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            set31=(pANTLR3_COMMON_TOKEN)LT(1);
++            if ( LA(1) == EQUAL || ((LA(1) >= LESS) && (LA(1) <= GTE)) )
++            {
++                CONSUME();
++                ADAPTOR->addChild(ADAPTOR, root_0, (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, set31)));
++                PERRORRECOVERY=ANTLR3_FALSE;
++            }
++            else 
++            {
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++                EXCEPTION->expectingSet = &FOLLOW_set_in_intop0;
++                RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_intop0);    goto ruleintopEx;
++            }
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruleintopEx; /* Prevent compiler warnings */
++    ruleintopEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end intop */
++
++/** 
++ * $ANTLR start datecrit
++ * RSP.g:63:1: datecrit : FIELD dateop datespec -> ^( dateop FIELD datespec ) ;
++ */
++static RSPParser_datecrit_return
++datecrit(pRSPParser ctx)
++{   
++    RSPParser_datecrit_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    FIELD32;
++    RSPParser_dateop_return dateop33;
++    #undef    RETURN_TYPE_dateop33
++    #define   RETURN_TYPE_dateop33 RSPParser_dateop_return
++
++    RSPParser_datespec_return datespec34;
++    #undef    RETURN_TYPE_datespec34
++    #define   RETURN_TYPE_datespec34 RSPParser_datespec_return
++
++    pANTLR3_BASE_TREE FIELD32_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_FIELD;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_datespec;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_dateop;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    FIELD32       = NULL;
++    dateop33.tree = NULL;
++
++    datespec34.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    FIELD32_tree   = NULL;
++
++    stream_FIELD   = NULL;
++    #define CREATE_stream_FIELD  if (stream_FIELD == NULL) {stream_FIELD = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token FIELD"); } 
++    stream_datespec   = NULL;
++    #define CREATE_stream_datespec  if (stream_datespec == NULL) {stream_datespec = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule datespec"); }
++    stream_dateop   = NULL;
++    #define CREATE_stream_dateop  if (stream_dateop == NULL) {stream_dateop = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule dateop"); }
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:63:9: ( FIELD dateop datespec -> ^( dateop FIELD datespec ) )
++        // RSP.g:63:11: FIELD dateop datespec
++        {
++            FIELD32 = (pANTLR3_COMMON_TOKEN) MATCHT(FIELD, &FOLLOW_FIELD_in_datecrit292); 
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++             
++            CREATE_stream_FIELD; stream_FIELD->add(stream_FIELD, FIELD32, NULL);
++
++            FOLLOWPUSH(FOLLOW_dateop_in_datecrit294);
++            dateop33=dateop(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++            CREATE_stream_dateop; stream_dateop->add(stream_dateop, dateop33.tree, NULL);
++            FOLLOWPUSH(FOLLOW_datespec_in_datecrit296);
++            datespec34=datespec(ctx);
++
++            FOLLOWPOP();
++            if  (HASEXCEPTION())
++            {
++                goto ruledatecritEx;
++            }
++
++            CREATE_stream_datespec; stream_datespec->add(stream_datespec, datespec34.tree, NULL);
++
++             
++            /* AST REWRITE
++             * elements          : FIELD, datespec, dateop
++             * token labels      : 
++             * rule labels       : retval
++             * token list labels : 
++             * rule list labels  : 
++             */
++            {
++              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++              retval.tree    = root_0;
++              // 63:34: -> ^( dateop FIELD datespec )
++              {
++                  // RSP.g:63:37: ^( dateop FIELD datespec )
++                  {
++                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_dateop == NULL ? NULL : stream_dateop->nextNode(stream_dateop), root_1));
++
++                      ADAPTOR->addChild(ADAPTOR, root_1, stream_FIELD == NULL ? NULL : stream_FIELD->nextNode(stream_FIELD));
++                      ADAPTOR->addChild(ADAPTOR, root_1, stream_datespec == NULL ? NULL : stream_datespec->nextTree(stream_datespec));
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                  }
++
++              }
++
++              retval.tree = root_0; // set result root
++              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++            }
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledatecritEx; /* Prevent compiler warnings */
++    ruledatecritEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_FIELD != NULL) stream_FIELD->free(stream_FIELD);
++        if (stream_datespec != NULL) stream_datespec->free(stream_datespec);
++        if (stream_dateop != NULL) stream_dateop->free(stream_dateop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end datecrit */
++
++/** 
++ * $ANTLR start dateop
++ * RSP.g:66:1: dateop : ( BEFORE | AFTER );
++ */
++static RSPParser_dateop_return
++dateop(pRSPParser ctx)
++{   
++    RSPParser_dateop_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    set35;
++
++    pANTLR3_BASE_TREE set35_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    set35       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    set35_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:66:8: ( BEFORE | AFTER )
++        // RSP.g:
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            set35=(pANTLR3_COMMON_TOKEN)LT(1);
++            if ( ((LA(1) >= BEFORE) && (LA(1) <= AFTER)) )
++            {
++                CONSUME();
++                ADAPTOR->addChild(ADAPTOR, root_0, (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, set35)));
++                PERRORRECOVERY=ANTLR3_FALSE;
++            }
++            else 
++            {
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++                EXCEPTION->expectingSet = &FOLLOW_set_in_dateop0;
++                RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_dateop0);    goto ruledateopEx;
++            }
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledateopEx; /* Prevent compiler warnings */
++    ruledateopEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end dateop */
++
++/** 
++ * $ANTLR start datespec
++ * RSP.g:70:1: datespec : ( dateref | INT dateintval dateop dateref -> ^( dateop dateref INT dateintval ) );
++ */
++static RSPParser_datespec_return
++datespec(pRSPParser ctx)
++{   
++    RSPParser_datespec_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    INT37;
++    RSPParser_dateref_return dateref36;
++    #undef    RETURN_TYPE_dateref36
++    #define   RETURN_TYPE_dateref36 RSPParser_dateref_return
++
++    RSPParser_dateintval_return dateintval38;
++    #undef    RETURN_TYPE_dateintval38
++    #define   RETURN_TYPE_dateintval38 RSPParser_dateintval_return
++
++    RSPParser_dateop_return dateop39;
++    #undef    RETURN_TYPE_dateop39
++    #define   RETURN_TYPE_dateop39 RSPParser_dateop_return
++
++    RSPParser_dateref_return dateref40;
++    #undef    RETURN_TYPE_dateref40
++    #define   RETURN_TYPE_dateref40 RSPParser_dateref_return
++
++    pANTLR3_BASE_TREE INT37_tree;
++    pANTLR3_REWRITE_RULE_TOKEN_STREAM stream_INT;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_dateintval;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_dateref;
++    pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_dateop;
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    INT37       = NULL;
++    dateref36.tree = NULL;
++
++    dateintval38.tree = NULL;
++
++    dateop39.tree = NULL;
++
++    dateref40.tree = NULL;
++
++    retval.start = LT(1); retval.stop = retval.start;
++
++    INT37_tree   = NULL;
++
++    stream_INT   = NULL;
++    #define CREATE_stream_INT  if (stream_INT == NULL) {stream_INT = antlr3RewriteRuleTOKENStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token INT"); } 
++    stream_dateintval   = NULL;
++    #define CREATE_stream_dateintval  if (stream_dateintval == NULL) {stream_dateintval = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule dateintval"); }
++    stream_dateref   = NULL;
++    #define CREATE_stream_dateref  if (stream_dateref == NULL) {stream_dateref = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule dateref"); }
++    stream_dateop   = NULL;
++    #define CREATE_stream_dateop  if (stream_dateop == NULL) {stream_dateop = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule dateop"); }
++
++    retval.tree  = NULL;
++    {
++        {
++            //  RSP.g:70:9: ( dateref | INT dateintval dateop dateref -> ^( dateop dateref INT dateintval ) )
++            
++            ANTLR3_UINT32 alt7;
++
++            alt7=2;
++
++            switch ( LA(1) ) 
++            {
++            case DATE:
++            case TODAY:
++              {
++                      alt7=1;
++              }
++                break;
++            case INT:
++              {
++                      alt7=2;
++              }
++                break;
++
++            default:
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_NO_VIABLE_ALT_EXCEPTION;
++                EXCEPTION->message      = (void *)"";
++                EXCEPTION->decisionNum  = 7;
++                EXCEPTION->state        = 0;
++
++
++                goto ruledatespecEx;
++            }
++
++            switch (alt7) 
++            {
++              case 1:
++                  // RSP.g:70:11: dateref
++                  {
++                      root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++                      FOLLOWPUSH(FOLLOW_dateref_in_datespec331);
++                      dateref36=dateref(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      ADAPTOR->addChild(ADAPTOR, root_0, dateref36.tree);
++
++                  }
++                  break;
++              case 2:
++                  // RSP.g:71:4: INT dateintval dateop dateref
++                  {
++                      INT37 = (pANTLR3_COMMON_TOKEN) MATCHT(INT, &FOLLOW_INT_in_datespec336); 
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++                       
++                      CREATE_stream_INT; stream_INT->add(stream_INT, INT37, NULL);
++
++                      FOLLOWPUSH(FOLLOW_dateintval_in_datespec338);
++                      dateintval38=dateintval(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      CREATE_stream_dateintval; stream_dateintval->add(stream_dateintval, dateintval38.tree, NULL);
++                      FOLLOWPUSH(FOLLOW_dateop_in_datespec340);
++                      dateop39=dateop(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      CREATE_stream_dateop; stream_dateop->add(stream_dateop, dateop39.tree, NULL);
++                      FOLLOWPUSH(FOLLOW_dateref_in_datespec342);
++                      dateref40=dateref(ctx);
++
++                      FOLLOWPOP();
++                      if  (HASEXCEPTION())
++                      {
++                          goto ruledatespecEx;
++                      }
++
++                      CREATE_stream_dateref; stream_dateref->add(stream_dateref, dateref40.tree, NULL);
++
++                       
++                      /* AST REWRITE
++                       * elements          : dateintval, INT, dateref, dateop
++                       * token labels      : 
++                       * rule labels       : retval
++                       * token list labels : 
++                       * rule list labels  : 
++                       */
++                      {
++                              pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_retval;
++
++                              stream_retval=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token retval", retval.tree != NULL ? retval.tree : NULL);
++
++                              root_0                      = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                              retval.tree    = root_0;
++                              // 71:34: -> ^( dateop dateref INT dateintval )
++                              {
++                                  // RSP.g:71:37: ^( dateop dateref INT dateintval )
++                                  {
++                                      pANTLR3_BASE_TREE root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++                                      root_1 = (pANTLR3_BASE_TREE)(ADAPTOR->becomeRoot(ADAPTOR, stream_dateop == NULL ? NULL : stream_dateop->nextNode(stream_dateop), root_1));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_dateref == NULL ? NULL : stream_dateref->nextTree(stream_dateref));
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_INT == NULL ? NULL : stream_INT->nextNode(stream_INT));
++                                      ADAPTOR->addChild(ADAPTOR, root_1, stream_dateintval == NULL ? NULL : stream_dateintval->nextTree(stream_dateintval));
++
++                                      ADAPTOR->addChild(ADAPTOR, root_0, root_1);
++                                  }
++
++                              }
++
++                              retval.tree = root_0; // set result root
++                              if (stream_retval != NULL) stream_retval->free(stream_retval);
++
++
++                      }
++                  }
++                  break;
++
++            }
++        }
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledatespecEx; /* Prevent compiler warnings */
++    ruledatespecEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++        if (stream_INT != NULL) stream_INT->free(stream_INT);
++        if (stream_dateintval != NULL) stream_dateintval->free(stream_dateintval);
++        if (stream_dateref != NULL) stream_dateref->free(stream_dateref);
++        if (stream_dateop != NULL) stream_dateop->free(stream_dateop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end datespec */
++
++/** 
++ * $ANTLR start dateref
++ * RSP.g:74:1: dateref : ( DATE | TODAY );
++ */
++static RSPParser_dateref_return
++dateref(pRSPParser ctx)
++{   
++    RSPParser_dateref_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    set41;
++
++    pANTLR3_BASE_TREE set41_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    set41       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    set41_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:74:9: ( DATE | TODAY )
++        // RSP.g:
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            set41=(pANTLR3_COMMON_TOKEN)LT(1);
++            if ( ((LA(1) >= DATE) && (LA(1) <= TODAY)) )
++            {
++                CONSUME();
++                ADAPTOR->addChild(ADAPTOR, root_0, (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, set41)));
++                PERRORRECOVERY=ANTLR3_FALSE;
++            }
++            else 
++            {
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++                EXCEPTION->expectingSet = &FOLLOW_set_in_dateref0;
++                RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_dateref0);    goto ruledaterefEx;
++            }
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledaterefEx; /* Prevent compiler warnings */
++    ruledaterefEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end dateref */
++
++/** 
++ * $ANTLR start dateintval
++ * RSP.g:78:1: dateintval : ( DAY | WEEK | MONTH | YEAR );
++ */
++static RSPParser_dateintval_return
++dateintval(pRSPParser ctx)
++{   
++    RSPParser_dateintval_return retval;
++
++    pANTLR3_BASE_TREE root_0;
++
++    pANTLR3_COMMON_TOKEN    set42;
++
++    pANTLR3_BASE_TREE set42_tree;
++
++    /* Initialize rule variables
++     */
++
++
++    root_0 = NULL;
++
++    set42       = NULL;
++    retval.start = LT(1); retval.stop = retval.start;
++
++    set42_tree   = NULL;
++
++
++    retval.tree  = NULL;
++    {
++        // RSP.g:79:2: ( DAY | WEEK | MONTH | YEAR )
++        // RSP.g:
++        {
++            root_0 = (pANTLR3_BASE_TREE)(ADAPTOR->nilNode(ADAPTOR));
++
++            set42=(pANTLR3_COMMON_TOKEN)LT(1);
++            if ( ((LA(1) >= DAY) && (LA(1) <= YEAR)) )
++            {
++                CONSUME();
++                ADAPTOR->addChild(ADAPTOR, root_0, (pANTLR3_BASE_TREE)(ADAPTOR->create(ADAPTOR, set42)));
++                PERRORRECOVERY=ANTLR3_FALSE;
++            }
++            else 
++            {
++                CONSTRUCTEX();
++                EXCEPTION->type         = ANTLR3_MISMATCHED_SET_EXCEPTION;
++                EXCEPTION->name         = (void *)ANTLR3_MISMATCHED_SET_NAME;
++                EXCEPTION->expectingSet = &FOLLOW_set_in_dateintval0;
++                RECOVERFROMMISMATCHEDSET(&FOLLOW_set_in_dateintval0);    goto ruledateintvalEx;
++            }
++
++
++        }
++
++    }
++    
++
++    // This is where rules clean up and exit
++    //
++    goto ruledateintvalEx; /* Prevent compiler warnings */
++    ruledateintvalEx: ;
++    retval.stop = LT(-1);
++
++      retval.stop = LT(-1);
++      retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
++      ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
++
++            if (HASEXCEPTION())
++            {
++                PREPORTERROR();
++                PRECOVER();
++                retval.tree = (pANTLR3_BASE_TREE)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
++            }
++
++
++    return retval;
++}
++/* $ANTLR end dateintval */
++/* End of parsing rules
++ * ==============================================
++ */
++
++/* ==============================================
++ * Syntactic predicates
++ */
++/* End of syntactic predicates
++ * ==============================================
++ */
++
++ 
++ 
++
++
++
++/* End of code
++ * =============================================================================
++ */
+diff --git a/src/pregen/RSPParser.h b/src/pregen/RSPParser.h
+new file mode 100644
+index 0000000..d0744a2
+--- /dev/null
++++ b/src/pregen/RSPParser.h
+@@ -0,0 +1,365 @@
++/** \file
++ *  This C header file was generated by $ANTLR version 3.2 debian-7ubuntu3
++ *
++ *     -  From the grammar source file : RSP.g
++ *     -                            On : 2014-09-30 21:42:40
++ *     -                for the parser : RSPParserParser *
++ * Editing it, at least manually, is not wise. 
++ *
++ * C language generator and runtime by Jim Idle, jimi|hereisanat|idle|dotgoeshere|ws.
++ *
++ *
++ * The parser RSPParser has the callable functions (rules) shown below,
++ * which will invoke the code for the associated rule in the source grammar
++ * assuming that the input stream is pointing to a token/text stream that could begin
++ * this rule.
++ * 
++ * For instance if you call the first (topmost) rule in a parser grammar, you will
++ * get the results of a full parse, but calling a rule half way through the grammar will
++ * allow you to pass part of a full token stream to the parser, such as for syntax checking
++ * in editors and so on.
++ *
++ * The parser entry points are called indirectly (by function pointer to function) via
++ * a parser context typedef pRSPParser, which is returned from a call to RSPParserNew().
++ *
++ * The methods in pRSPParser are  as follows:
++ *
++ *  - RSPParser_query_return      pRSPParser->query(pRSPParser)
++ *  - RSPParser_expr_return      pRSPParser->expr(pRSPParser)
++ *  - RSPParser_aexpr_return      pRSPParser->aexpr(pRSPParser)
++ *  - RSPParser_crit_return      pRSPParser->crit(pRSPParser)
++ *  - RSPParser_strcrit_return      pRSPParser->strcrit(pRSPParser)
++ *  - RSPParser_strop_return      pRSPParser->strop(pRSPParser)
++ *  - RSPParser_intcrit_return      pRSPParser->intcrit(pRSPParser)
++ *  - RSPParser_intop_return      pRSPParser->intop(pRSPParser)
++ *  - RSPParser_datecrit_return      pRSPParser->datecrit(pRSPParser)
++ *  - RSPParser_dateop_return      pRSPParser->dateop(pRSPParser)
++ *  - RSPParser_datespec_return      pRSPParser->datespec(pRSPParser)
++ *  - RSPParser_dateref_return      pRSPParser->dateref(pRSPParser)
++ *  - RSPParser_dateintval_return      pRSPParser->dateintval(pRSPParser)
++ *
++ * The return type for any particular rule is of course determined by the source
++ * grammar file.
++ */
++// [The "BSD licence"]
++// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
++// http://www.temporal-wave.com
++// http://www.linkedin.com/in/jimidle
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions
++// are met:
++// 1. Redistributions of source code must retain the above copyright
++//    notice, this list of conditions and the following disclaimer.
++// 2. 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.
++// 3. The name of the author may not be used to endorse or promote products
++//    derived from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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       _RSPParser_H
++#define _RSPParser_H
++/* =============================================================================
++ * Standard antlr3 C runtime definitions
++ */
++#include    <antlr3.h>
++
++/* End of standard antlr 3 runtime definitions
++ * =============================================================================
++ */
++ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++// Forward declare the context typedef so that we can use it before it is
++// properly defined. Delegators and delegates (from import statements) are
++// interdependent and their context structures contain pointers to each other
++// C only allows such things to be declared if you pre-declare the typedef.
++//
++typedef struct RSPParser_Ctx_struct RSPParser, * pRSPParser;
++
++
++
++#ifdef        ANTLR3_WINDOWS
++// Disable: Unreferenced parameter,                                                   - Rules with parameters that are not used
++//          constant conditional,                                                     - ANTLR realizes that a prediction is always true (synpred usually)
++//          initialized but unused variable                                   - tree rewrite variables declared but not needed
++//          Unreferenced local variable                                               - lexer rule declares but does not always use _type
++//          potentially unitialized variable used                     - retval always returned from a rule 
++//                    unreferenced local function has been removed    - susually getTokenNames or freeScope, they can go without warnigns
++//
++// These are only really displayed at warning level /W4 but that is the code ideal I am aiming at
++// and the codegen must generate some of these warnings by necessity, apart from 4100, which is
++// usually generated when a parser rule is given a parameter that it does not use. Mostly though
++// this is a matter of orthogonality hence I disable that one.
++//
++#pragma warning( disable : 4100 )
++#pragma warning( disable : 4101 )
++#pragma warning( disable : 4127 )
++#pragma warning( disable : 4189 )
++#pragma warning( disable : 4505 )
++#pragma warning( disable : 4701 )
++#endif
++typedef struct RSPParser_query_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_query_return;
++
++typedef struct RSPParser_expr_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_expr_return;
++
++typedef struct RSPParser_aexpr_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_aexpr_return;
++
++typedef struct RSPParser_crit_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_crit_return;
++
++typedef struct RSPParser_strcrit_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_strcrit_return;
++
++typedef struct RSPParser_strop_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_strop_return;
++
++typedef struct RSPParser_intcrit_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_intcrit_return;
++
++typedef struct RSPParser_intop_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_intop_return;
++
++typedef struct RSPParser_datecrit_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_datecrit_return;
++
++typedef struct RSPParser_dateop_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_dateop_return;
++
++typedef struct RSPParser_datespec_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_datespec_return;
++
++typedef struct RSPParser_dateref_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_dateref_return;
++
++typedef struct RSPParser_dateintval_return_struct
++{
++    /** Generic return elements for ANTLR3 rules that are not in tree parsers or returning trees
++     */
++    pANTLR3_COMMON_TOKEN    start;
++    pANTLR3_COMMON_TOKEN    stop;
++    pANTLR3_BASE_TREE tree;
++   
++}
++    RSPParser_dateintval_return;
++
++
++
++/** Context tracking structure for RSPParser
++ */
++struct RSPParser_Ctx_struct
++{
++    /** Built in ANTLR3 context tracker contains all the generic elements
++     *  required for context tracking.
++     */
++    pANTLR3_PARSER   pParser;
++
++
++     RSPParser_query_return (*query)  (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_expr_return (*expr)    (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_aexpr_return (*aexpr)  (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_crit_return (*crit)    (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_strcrit_return (*strcrit)      (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_strop_return (*strop)  (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_intcrit_return (*intcrit)      (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_intop_return (*intop)  (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_datecrit_return (*datecrit)    (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_dateop_return (*dateop)        (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_datespec_return (*datespec)    (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_dateref_return (*dateref)      (struct RSPParser_Ctx_struct * ctx);
++     RSPParser_dateintval_return (*dateintval)        (struct RSPParser_Ctx_struct * ctx);
++    // Delegated rules
++    const char * (*getGrammarFileName)();
++    void          (*free)   (struct RSPParser_Ctx_struct * ctx);
++    /* @headerFile.members() */
++    pANTLR3_BASE_TREE_ADAPTOR adaptor;
++    pANTLR3_VECTOR_FACTORY            vectors;
++    /* End @headerFile.members() */
++};
++
++// Function protoypes for the constructor functions that external translation units
++// such as delegators and delegates may wish to call.
++//
++ANTLR3_API pRSPParser RSPParserNew         (pANTLR3_COMMON_TOKEN_STREAM instream);
++ANTLR3_API pRSPParser RSPParserNewSSD      (pANTLR3_COMMON_TOKEN_STREAM instream, pANTLR3_RECOGNIZER_SHARED_STATE state);
++
++/** Symbolic definitions of all the tokens that the parser will work with.
++ * \{
++ *
++ * Antlr will define EOF, but we can't use that as it it is too common in
++ * in C header files and that would be confusing. There is no way to filter this out at the moment
++ * so we just undef it here for now. That isn't the value we get back from C recognizers
++ * anyway. We are looking for ANTLR3_TOKEN_EOF.
++ */
++#ifdef        EOF
++#undef        EOF
++#endif
++#ifdef        Tokens
++#undef        Tokens
++#endif 
++#define STARTSW      14
++#define WEEK      26
++#define TODAY      24
++#define YEAR      28
++#define ENDSW      15
++#define GTE      20
++#define BEFORE      21
++#define DAY      25
++#define INT      16
++#define NOT      11
++#define AFTER      22
++#define AND      6
++#define EOF      -1
++#define LTE      19
++#define MONTH      27
++#define DIGIT19      31
++#define INCLUDES      13
++#define STR      10
++#define QUOTE      29
++#define WS      30
++#define GREATER      18
++#define NEWLINE      4
++#define LPAR      7
++#define EQUAL      12
++#define OR      5
++#define LESS      17
++#define RPAR      8
++#define FIELD      9
++#define ESCAPED      33
++#define DATE      23
++#define DIGIT09      32
++#ifdef        EOF
++#undef        EOF
++#define       EOF     ANTLR3_TOKEN_EOF
++#endif
++
++#ifndef TOKENSOURCE
++#define TOKENSOURCE(lxr) lxr->pLexer->rec->state->tokSource
++#endif
++
++/* End of token definitions for RSPParser
++ * =============================================================================
++ */
++/** \} */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
++
++/* END - Note:Keep extra line feed to satisfy UNIX systems */
diff --git a/sound/madplay/Makefile b/sound/madplay/Makefile
new file mode 100644 (file)
index 0000000..f23e93d
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=madplay
+PKG_VERSION:=0.15.2b
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/mad \
+       ftp://ftp.mars.org/pub/mpeg/
+PKG_MD5SUM:=6814b47ceaa99880c754c5195aa1aac1
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Simon Peter <probono@puredarwin.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/madplay
+  SECTION:=sound
+  CATEGORY:=Sound
+  DEPENDS:=+libid3tag +libmad
+  TITLE:=MPEG audio player in fixed point
+  URL:=http://sourceforge.net/projects/mad
+endef
+
+define Package/madplay/description
+       MAD is an MPEG audio decoder. It currently only supports the MPEG 1
+       standard, but fully implements all three audio layers (Layer I, Layer II,
+       and Layer III, the latter often colloquially known as MP3.). There is also
+       full support for ID3 tags.
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default, \
+               --enable-shared \
+               --disable-static \
+               --disable-debugging \
+               --disable-profiling \
+               --disable-experimental \
+               --without-libiconv-prefix \
+               --without-libintl-prefix \
+               --without-alsa \
+               --without-esd \
+               , \
+               LIBS="-lz" \
+       )
+endef
+
+define Package/madplay/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/madplay $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,madplay))
index 0bdd231fa80e35d4f7ffab9a7a92b2248b2aa26a..5552ec96251913efe0cc014c0274da3cfb7f013b 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2011-2014 OpenWrt.org
+# Copyright (C) 2011-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=moc
-PKG_VERSION:=2.5.0-beta2
+PKG_VERSION:=2.5.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=http://ftp.daper.net/pub/soft/moc/unstable/
-PKG_MD5SUM:=da87b90b57934234589b63e347921458
+PKG_SOURCE_URL:=http://ftp.daper.net/pub/soft/moc/stable/
+PKG_MD5SUM:=18e3a979b67091bfee4b62217908c473
 
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
index 1d2ce22dca538db8e6bad21aaf667357574c575f..1b1e8686e67b80ad8079ecd4e832d779d4691677 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2014 OpenWrt.org
+# Copyright (C) 2007-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mpd
-PKG_VERSION:=0.18.16
+PKG_VERSION:=0.18.21
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://www.musicpd.org/download/mpd/0.18/
-PKG_MD5SUM:=900657ff55726f4cc09a27eb7df57015
+PKG_MD5SUM:=945879f55acc256d30a5f69787338ceb
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_BUILD_PARALLEL:=1
@@ -63,7 +63,6 @@ $(call Package/mpd/Default/description)
 endef
 
 define Package/mpd-full/conffiles
-/etc/avahi/services/mpd.service
 /etc/mpd.conf
 endef
 
@@ -85,6 +84,23 @@ define Package/mpd-mini/conffiles
 /etc/mpd.conf
 endef
 
+define Package/mpd-avahi-service
+$(call Package/mpd/Default)
+  TITLE+= (Avahi service)
+  DEPENDS+=+avahi-daemon
+endef
+
+define Package/mpd-avahi-service/description
+$(call Package/mpd/Default/description)
+ .
+ This package contains the service definition for announcing the
+ Music Player Daemon service via mDNS/DNS-SD.
+endef
+
+define Package/mpd-avahi-service/conffiles
+/etc/avahi/services/mpd.service
+endef
+
 CONFIGURE_ARGS += \
        $(call autoconf_bool,CONFIG_IPV6,ipv6) \
        --disable-debug \
@@ -189,22 +205,26 @@ endif
 
 define Package/mpd/install
        $(INSTALL_DIR) $(1)/usr/bin
-       $(CP) $(PKG_INSTALL_DIR)/usr/bin/mpd $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mpd $(1)/usr/bin/
        $(INSTALL_DIR) $(1)/etc
-       $(CP) $(PKG_BUILD_DIR)/doc/mpdconf.example $(1)/etc/mpd.conf
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/mpdconf.example $(1)/etc/mpd.conf
        $(INSTALL_DIR) $(1)/etc/init.d
        $(INSTALL_BIN) ./files/mpd.init $(1)/etc/init.d/mpd
 endef
 
 define Package/mpd-full/install
 $(call Package/mpd/install,$1)
-       $(INSTALL_DIR) $(1)/etc/avahi/services
-       $(INSTALL_DATA) ./files/mpd.service $(1)/etc/avahi/services/
 endef
 
 define Package/mpd-mini/install
 $(call Package/mpd/install,$1)
 endef
 
+define Package/mpd-avahi-service/install
+       $(INSTALL_DIR) $(1)/etc/avahi/services
+       $(INSTALL_DATA) ./files/mpd.service $(1)/etc/avahi/services/
+endef
+
 $(eval $(call BuildPackage,mpd-full))
 $(eval $(call BuildPackage,mpd-mini))
+$(eval $(call BuildPackage,mpd-avahi-service))
index 086a2bb3fc53ebe2d9e203652ab7f3d672e64578..a545f240f37f7a412720928ed662cdeb0e110086 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" standalone='no'?><!--*-nxml-*-->
 <!DOCTYPE service-group SYSTEM "avahi-service.dtd">
 <service-group>
- <name replace-wildcards="yes">Music Player Daemon on %h</name>
+ <name replace-wildcards="yes">%h</name>
   <service>
    <type>_mpd._tcp</type>
    <port>6600</port>
diff --git a/sound/portaudio/Makefile b/sound/portaudio/Makefile
new file mode 100644 (file)
index 0000000..ffa5cfb
--- /dev/null
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=portaudio
+PKG_VERSION:=19_20140130
+PKG_RELEASE:=1
+
+PKG_SOURCE:=pa_stable_v$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=http://www.portaudio.com/archives/
+PKG_MD5SUM:=7f220406902af9dca009668e198cbd23
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/portaudio
+  SECTION:=sound
+  CATEGORY:=Sound
+  DEPENDS:=+alsa-lib +libpthread +librt
+  TITLE:=Portable cross-platform audio I/O
+  URL:=http://www.portaudio.com/
+endef
+
+define Package/portaudio/description
+ PortAudio is a free, cross-platform, open-source, audio I/O library.  It lets
+ you write simple audio programs in 'C' or C++ that will compile and run on many
+ platforms including Windows, Macintosh OS X, and Unix (OSS/ALSA). It is
+ intended to promote the exchange of audio software between developers on
+ different platforms. Many applications use PortAudio for Audio I/O.
+endef
+
+CONFIGURE_ARGS+= \
+       --with-alsa \
+       --without-asihpi \
+       --without-jack \
+       --with-oss \
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/include/portaudio.h \
+               $(PKG_INSTALL_DIR)/usr/include/pa_linux_alsa.h \
+               $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/libportaudio.{a,so*} \
+               $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/portaudio-*.pc \
+               $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/portaudio/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libportaudio.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,portaudio))
index cfcb61c23b6029c11c1449bdb006c56c5b64711a..e1d97e7c86302821c0994e5d6e92f878769112f3 100644 (file)
@@ -38,6 +38,7 @@ define Package/pulseaudio/Default
   MAINTAINER:=Peter Wagner <tripolar@gmx.at>
   URL:=http://www.pulseaudio.org
   PROVIDES:=pulseaudio
+  USERID:=pulse=51:pulse=51
 endef
 
 define Package/pulseaudio-daemon
index 336f3716abcbf5b1eb309c0f3d678b6c2ccb3dc4..1262b941e62f29cc8cc49d2d90a283e9e491f6cf 100644 (file)
@@ -8,8 +8,6 @@ USE_PROCD=1
 PROG=/usr/bin/pulseaudio
 
 start_service() {
-       user_exists pulse 51 || user_add pulse 51
-       group_exists pulse 51 || group_add pulse 51
        [ -d /var/run/pulse ] || {
                mkdir -m 0755 -p /var/run/pulse
                chmod 0750 /var/run/pulse
diff --git a/sound/shairport-sync/Makefile b/sound/shairport-sync/Makefile
new file mode 100644 (file)
index 0000000..cd60f97
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# updated to work with latest source from abrasive
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=shairport-sync
+PKG_VERSION:=2.1.15
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/mikebrady/shairport-sync.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING LICENSES shairport.c
+
+PKG_BUILD_PARALLEL:=1
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_ARGS+= \
+       --with-alsa \
+       --with-avahi \
+       --with-soxr \
+       --with-ssl=openssl
+
+
+define Package/shairport-sync
+  SECTION:=sound
+  CATEGORY:=Sound
+  TITLE:=iPhone/iTunes compatible audio player
+  DEPENDS:= +libpthread +libopenssl +libavahi-client +alsa-lib +libdaemon +libsoxr +libpopt
+  MAINTAINER:=Mike Brady <mikebrady@eircom.net>
+endef
+
+define Package/shairport-sync/description
+  Shairport Sync is server software that implements the Apple-originated RAOP protocol for
+  playback of audio from a compatible remote client such as the iPhone, iTunes, Apple TV, Quicktime Player or forked-daapd.
+  Shairport Sync implements audio synchronisation, supporting multi-room use.
+  Shairport Sync supports audio only.
+endef
+
+define Package/shairport-sync/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/shairport-sync $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/shairport-sync.init $(1)/etc/init.d/shairport-sync
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/shairport-sync.config $(1)/etc/config/shairport-sync
+endef
+
+$(eval $(call BuildPackage,shairport-sync))
diff --git a/sound/shairport-sync/files/shairport-sync.config b/sound/shairport-sync/files/shairport-sync.config
new file mode 100644 (file)
index 0000000..f72c785
--- /dev/null
@@ -0,0 +1,35 @@
+# Uncomment the stanza you want, and make sure to comment out the others, especially duplicate options.
+
+#Arguments and defaults are as follows
+config shairport-sync main
+#       option name 'Shairport Sync'           #default name, "Shairport Sync on %d"
+#       option device default                  #default soundcard, volume control by software
+                                               #(Troubleshooting hint: make sure the soundcard's volume is turned up fully -- use alsamixer or amixer)
+#       option airplaylatency 88200
+#       option ituneslatency 99400
+#       option port 5000
+#       option stuffing basic                  #options are 'basic' or 'soxr' if shairport-sync was compiled with soxr support
+#       option awaitactioncompletion false     #[don't] wait until beforeaction or afteraction completes
+#       option beforeaction <action>           #action must be a fully qualified program with no arguments. Default no action.
+#       option afteraction <action>            #action must be a fully qualified program with no arguments. Default no action.
+#       option devicetype <devicetype>
+#       option volumecontrolname <name>
+
+#Here are some sample stanzas:
+
+#For Raspberry Pi using the built-in soundcard for the headphone jack
+#       option device 'hw:0'
+#       option devicetype hardware
+#       option volumecontrolname Master
+
+#For Raspberry Pi with the "3D Sound" USB Soundcard
+#        option name 'Pi'
+#        option device 'hw:1'
+#        option devicetype hardware
+#        option volumecontrolname Speaker
+
+#For Raspberry Pi with the first generation iMic or the Topping TP30 Class T Digital Mini Amplifier
+#        option name 'Kitchen'
+#        option device 'hw:1'
+#        option devicetype hardware
+#        option volumecontrolname PCM
diff --git a/sound/shairport-sync/files/shairport-sync.init b/sound/shairport-sync/files/shairport-sync.init
new file mode 100755 (executable)
index 0000000..f49e1e3
--- /dev/null
@@ -0,0 +1,77 @@
+#!/bin/sh /etc/rc.common
+
+NAME='shairport-sync'
+START=99
+
+USE_PROCD=1
+
+append_arg() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get val "$cfg" "$var"
+       [ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}"
+}
+
+append_bool() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get_bool val "$cfg" "$var" "$def"
+       [ "$val" = 1 ] && procd_append_param command "$opt"
+}
+
+start_shairport_service() {
+       local cfg=$1
+       local stuffing
+        local device
+
+       procd_open_instance
+
+       procd_set_param command /usr/bin/$NAME
+
+       append_arg "$cfg" name "-a"
+       append_arg "$cfg" port "-p"
+       append_arg "$cfg" airplaylatency "-A"
+       append_arg "$cfg" ituneslatency "-i"
+
+        config_get stuffing "$cfg" stuffing ""
+
+       if [ -n "$stuffing" ] ; then
+                case "x$stuffing" in
+                        ( "xbasic" ) procd_append_param command -S basic ;;
+                        ( "xsoxr" ) procd_append_param command -S soxr ;;
+                        ( * ) logger "bad argument for -S option -- should be \"basic\" or \"soxr\"" ;;
+                esac
+        fi
+
+       append_arg "$cfg" beforeaction "-B"
+       append_arg "$cfg" afteraction "-E"
+       append_bool "$cfg" awaitactioncompletion "-w"
+
+        config_get device "$cfg" device ""
+       if [ -n "$device" ] ; then
+               procd_append_param command "--"
+               append_arg "$cfg" device "-d"
+               append_arg "$cfg" devicetype "-t"
+               append_arg "$cfg" volumecontrolname "-c"
+       fi
+
+       procd_close_instance
+}
+
+service_triggers() { 
+        procd_add_reload_trigger $NAME
+} 
+
+start_service() {
+        config_load $NAME
+       # Just a single instance
+        start_shairport_service "main"
+}
index 8fa571325773145de12215ff0be3b175e584d747..eda080fa8b928cb106d6667b2b87ff3608a4e22f 100644 (file)
@@ -10,15 +10,17 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sox
 PKG_VERSION:=14.4.1
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=@SF/sox
 PKG_MD5SUM:=ff9ca6aca972549de0e80e8e30ed379c
 
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 PKG_LICENSE:=LGPL-2.1 GPL-2.0
 PKG_LICENSE_FILES:=COPYING LICENSE.LGPL LICENSE.GPL
 
+
 PKG_INSTALL:=1
 
 include $(INCLUDE_DIR)/package.mk
@@ -34,7 +36,6 @@ define Package/sox
                +libmagic +libpng +libffmpeg
   TITLE:=Sox is a general purpose sound converter/player/recorder
   URL:=http://sox.sourceforge.net/
-  MAINTAINER:=Hamish Guthrie <hcg@openwrt.org>
 endef
 
 define Package/sox/description
index 5770145649d526ca6fdfc696e024ab70d9b2d1fb..44e7ebbe984f1588b3d1397a3da167e4d4783dba 100644 (file)
      return -1;
    if (enc->codec_type != AVMEDIA_TYPE_AUDIO) {
      lsx_fail("ffmpeg CODEC %x is not an audio CODEC", enc->codec_type);
-@@ -267,7 +271,11 @@ static int stopread(sox_format_t * ft)
+@@ -178,7 +182,7 @@ static int startread(sox_format_t * ft)
+   }
+   /* Get CODEC parameters */
+-  if ((ret = av_find_stream_info(ffmpeg->ctxt)) < 0) {
++  if ((ret = avformat_find_stream_info(ffmpeg->ctxt, NULL)) < 0) {
+     lsx_fail("ffmpeg could not find CODEC parameters for %s", ft->filename);
+     return SOX_EOF;
+   }
+@@ -256,7 +260,7 @@ static int stopread(sox_format_t * ft)
+   if (ffmpeg->audio_stream >= 0)
+     stream_component_close(ffmpeg, ffmpeg->audio_stream);
+   if (ffmpeg->ctxt) {
+-    av_close_input_file(ffmpeg->ctxt);
++    avformat_close_input(&ffmpeg->ctxt);
+     ffmpeg->ctxt = NULL; /* safety */
+   }
+@@ -267,16 +271,21 @@ static int stopread(sox_format_t * ft)
  /*
   * add an audio output stream
   */
  {
    AVCodecContext *c;
    AVStream *st;
-@@ -306,7 +314,7 @@ static int open_audio(priv_t * ffmpeg, A
+-  st = av_new_stream(oc, 1);
++  st = avformat_new_stream(oc, NULL);
+   if (!st) {
+     lsx_fail("ffmpeg could not alloc stream");
+     return NULL;
+   }
++  st->id = 1;
+   c = st->codec;
+   c->codec_id = codec_id;
+@@ -306,7 +315,7 @@ static int open_audio(priv_t * ffmpeg, A
    }
  
    /* open it */
diff --git a/sound/svox/Makefile b/sound/svox/Makefile
new file mode 100644 (file)
index 0000000..159f1e3
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=svox
+PKG_VERSION:=1.0+git20130326
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
+PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/non-free/s/svox
+PKG_MD5SUM:=df4bf610ff4273b420e80ff64af93130
+
+PKG_MAINTAINER:=Alessandro Di Marco <dmr@ethzero.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/svox
+  TITLE:=SVOX PicoTTS text-to-speech engine
+  SECTION:=sound
+  CATEGORY:=Sound
+  URL:=https://android.googlesource.com/platform/external/svox/
+  DEPENDS:=+libpopt
+endef
+
+define Package/svox/description
+  SVOX is an embedded speech technology company founded in 2000 and
+  headquartered in Zurich, Switzerland. SVOX was acquired by Nuance
+  Communications in 2011. Company's products included Automated Speech
+  Recognition (ASR), Text-to-Speech (TTS) and Speech Dialog systems,
+  with customers mostly being manufacturers and system integrators in
+  automotive and mobile device industries.
+  SVOX TTS technology is characterized by natural and clear sound as well
+  as unique polyglot capability - the same voice can speak multiple
+  languages like a native speaker.
+endef
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       mv $(PKG_BUILD_DIR)/pico/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+       $(call Build/Configure/Default)
+endef
+
+define Package/svox/install
+       $(call Build/Install/Default)
+endef
+
+$(eval $(call BuildPackage,svox))
diff --git a/sound/svox/patches/0001-autoconf-building-of-library-using-libtool.patch b/sound/svox/patches/0001-autoconf-building-of-library-using-libtool.patch
new file mode 100644 (file)
index 0000000..73c76bb
--- /dev/null
@@ -0,0 +1,113 @@
+From 9fe1aa475b2667446b081623abc5c6f6083a76e6 Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Sat, 24 Oct 2009 17:03:37 +0200
+Subject: [PATCH 1/7] autoconf building of library (using libtool)
+
+---
+ pico/Makefile.am  |   36 ++++++++++++++++++++++++++++++++++++
+ pico/autogen.sh   |   36 ++++++++++++++++++++++++++++++++++++
+ pico/configure.in |   16 ++++++++++++++++
+ 3 files changed, 88 insertions(+), 0 deletions(-)
+ create mode 100644 pico/Makefile.am
+ create mode 100755 pico/autogen.sh
+ create mode 100644 pico/configure.in
+
+--- /dev/null
++++ b/pico/Makefile.am
+@@ -0,0 +1,36 @@
++## Makefile.am -- Process this file with automake to produce Makefile.in
++
++ACLOCAL_AMFLAGS = -I m4
++
++lib_LTLIBRARIES = libttspico.la
++libttspico_la_SOURCES = \
++      lib/picoacph.c \
++      lib/picoapi.c \
++      lib/picobase.c \
++      lib/picocep.c \
++      lib/picoctrl.c \
++      lib/picodata.c \
++      lib/picodbg.c \
++      lib/picoextapi.c \
++      lib/picofftsg.c \
++      lib/picokdbg.c \
++      lib/picokdt.c \
++      lib/picokfst.c \
++      lib/picoklex.c \
++      lib/picoknow.c \
++      lib/picokpdf.c \
++      lib/picokpr.c \
++      lib/picoktab.c \
++      lib/picoos.c \
++      lib/picopal.c \
++      lib/picopam.c \
++      lib/picopr.c \
++      lib/picorsrc.c \
++      lib/picosa.c \
++      lib/picosig.c \
++      lib/picosig2.c \
++      lib/picospho.c \
++      lib/picotok.c \
++      lib/picotrns.c \
++      lib/picowa.c
++
+--- /dev/null
++++ b/pico/autogen.sh
+@@ -0,0 +1,38 @@
++#!/bin/sh
++
++#created by aclocal
++rm -rf autom4te.cache
++rm -f aclocal.m4
++
++#created by libtoolize
++rm -rf m4
++mkdir m4
++rm -f ltmain.sh
++
++#created by autoconf
++rm -f configure
++
++#created by automake
++rm -f install-sh missing depcomp Makefile.in config.guess config.sub
++rm -f INSTALL COPYING compile
++
++#created by ./configure
++rm -rf .deps
++rm -f Makefile config.log config.status libtool
++
++if [ "$1" = "clean" ]; then
++    exit
++fi
++
++IPATHS="-I lib"
++
++libtoolize
++aclocal $IPATHS
++automake --add-missing
++autoconf $IPATHS
++
++rm -rf autom4te.cache
++
++echo "Now run ./configure and then make."
++exit 0
++
+--- /dev/null
++++ b/pico/configure.in
+@@ -0,0 +1,16 @@
++dnl Process this file with autoconf to produce a configure script.
++
++AC_PREREQ(2.59)
++
++AC_INIT([svox], [1.0], [math.parent@gmail.com])
++
++AM_INIT_AUTOMAKE([1.9 foreign])
++
++AC_PROG_CC
++LT_INIT
++AC_PROG_LIBTOOL
++
++AC_CONFIG_FILES([Makefile])
++AC_OUTPUT
++
++AC_CONFIG_MACRO_DIR([m4])
diff --git a/sound/svox/patches/0002-gitignore-for-autotools-files.patch b/sound/svox/patches/0002-gitignore-for-autotools-files.patch
new file mode 100644 (file)
index 0000000..df57df7
--- /dev/null
@@ -0,0 +1,51 @@
+From b56b0a4bdf3e11271caab744f532cb055c517b51 Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Sat, 24 Oct 2009 17:12:42 +0200
+Subject: [PATCH 2/7] gitignore for autotools files
+
+---
+ pico/.gitignore |   32 ++++++++++++++++++++++++++++++++
+ 1 files changed, 32 insertions(+), 0 deletions(-)
+ create mode 100644 pico/.gitignore
+
+diff --git a/pico/.gitignore b/pico/.gitignore
+new file mode 100644
+index 0000000..4235569
+--- /dev/null
++++ b/pico/.gitignore
+@@ -0,0 +1,32 @@
++#created by aclocal
++autom4te.cache
++aclocal.m4
++
++#created by libtoolize
++m4
++ltmain.sh
++
++#created by autoconf
++configure
++
++#created by automake
++install-sh
++missing
++depcomp
++Makefile.in
++config.guess
++config.sub
++
++#created by ./configure
++.deps
++Makefile
++config.log
++config.status
++libtool
++
++#created by make
++*.o
++*.lo
++.libs
++libttspico.la
++
+-- 
+1.7.1
+
diff --git a/sound/svox/patches/0003-pico2wave-Convert-text-to-.wav-using-svox-text-to-sp.patch b/sound/svox/patches/0003-pico2wave-Convert-text-to-.wav-using-svox-text-to-sp.patch
new file mode 100644 (file)
index 0000000..8ef4757
--- /dev/null
@@ -0,0 +1,399 @@
+From 8bec80dccc9f4fe147a500486813f4e89a0d56d8 Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Sun, 25 Oct 2009 15:19:01 +0100
+Subject: [PATCH 3/7] pico2wave: Convert text to .wav using svox text-to-speech system.
+
+---
+ pico/.gitignore      |    1 +
+ pico/Makefile.am     |    7 +
+ pico/bin/pico2wave.c |  341 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ pico/configure.in    |    3 +
+ 4 files changed, 352 insertions(+), 0 deletions(-)
+ create mode 100644 pico/bin/pico2wave.c
+
+diff --git a/pico/.gitignore b/pico/.gitignore
+index 4235569..a110298 100644
+--- a/pico/.gitignore
++++ b/pico/.gitignore
+@@ -29,4 +29,5 @@ libtool
+ *.lo
+ .libs
+ libttspico.la
++pico2wave
+diff --git a/pico/Makefile.am b/pico/Makefile.am
+index 6d8a10c..0d9472d 100644
+--- a/pico/Makefile.am
++++ b/pico/Makefile.am
+@@ -34,3 +34,10 @@ libttspico_la_SOURCES = \
+       lib/picotrns.c \
+       lib/picowa.c
++bin_PROGRAMS = pico2wave
++pico2wave_SOURCES = \
++      bin/pico2wave.c
++pico2wave_LDADD = \
++      libttspico.la -lm -lpopt
++pico2wave_CFLAGS = -Wall -I lib
++
+diff --git a/pico/bin/pico2wave.c b/pico/bin/pico2wave.c
+new file mode 100644
+index 0000000..0c035a7
+--- /dev/null
++++ b/pico/bin/pico2wave.c
+@@ -0,0 +1,341 @@
++/* pico2wave.c
++
++ * Copyright (C) 2009 Mathieu Parent <math.parent@gmail.com>
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ *     http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ *
++ *   Convert text to .wav using svox text-to-speech system.
++ *
++ */
++
++
++#include <popt.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <picoapi.h>
++#include <picoapid.h>
++#include <picoos.h>
++
++
++/* adaptation layer defines */
++#define PICO_MEM_SIZE       2500000
++#define DummyLen 100000000
++
++/* string constants */
++#define MAX_OUTBUF_SIZE     128
++const char * PICO_LINGWARE_PATH             = "./lang/";
++const char * PICO_VOICE_NAME                = "PicoVoice";
++
++/* supported voices
++   Pico does not seperately specify the voice and locale.   */
++const char * picoSupportedLangIso3[]        = { "eng",              "eng",              "deu",              "spa",              "fra",              "ita" };
++const char * picoSupportedCountryIso3[]     = { "USA",              "GBR",              "DEU",              "ESP",              "FRA",              "ITA" };
++const char * picoSupportedLang[]            = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
++const char * picoInternalLang[]             = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
++const char * picoInternalTaLingware[]       = { "en-US_ta.bin",     "en-GB_ta.bin",     "de-DE_ta.bin",     "es-ES_ta.bin",     "fr-FR_ta.bin",     "it-IT_ta.bin" };
++const char * picoInternalSgLingware[]       = { "en-US_lh0_sg.bin", "en-GB_kh0_sg.bin", "de-DE_gl0_sg.bin", "es-ES_zl0_sg.bin", "fr-FR_nk0_sg.bin", "it-IT_cm0_sg.bin" };
++const char * picoInternalUtppLingware[]     = { "en-US_utpp.bin",   "en-GB_utpp.bin",   "de-DE_utpp.bin",   "es-ES_utpp.bin",   "fr-FR_utpp.bin",   "it-IT_utpp.bin" };
++const int picoNumSupportedVocs              = 6;
++
++/* adapation layer global variables */
++void *          picoMemArea         = NULL;
++pico_System     picoSystem          = NULL;
++pico_Resource   picoTaResource      = NULL;
++pico_Resource   picoSgResource      = NULL;
++pico_Resource   picoUtppResource    = NULL;
++pico_Engine     picoEngine          = NULL;
++pico_Char *     picoTaFileName      = NULL;
++pico_Char *     picoSgFileName      = NULL;
++pico_Char *     picoUtppFileName    = NULL;
++pico_Char *     picoTaResourceName  = NULL;
++pico_Char *     picoSgResourceName  = NULL;
++pico_Char *     picoUtppResourceName = NULL;
++int     picoSynthAbort = 0;
++
++
++int main(int argc, const char *argv[]) {
++    char * wavefile = NULL;
++    char * lang = "en-US";
++    int langIndex = -1, langIndexTmp = -1;
++    char * text;
++    int8_t * buffer;
++    size_t bufferSize = 256;
++    
++    /* Parsing options */
++      poptContext optCon; /* context for parsing command-line options */
++      int opt; /* used for argument parsing */
++
++      struct poptOption optionsTable[] = {
++              { "wave", 'w', POPT_ARG_STRING, &wavefile, 0,
++                "Write output to this WAV file (extension SHOULD be .wav)", "filename.wav" },
++              { "lang", 'l', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &lang, 0,
++                "Language", "lang" },
++              POPT_AUTOHELP
++              POPT_TABLEEND
++      };
++      optCon = poptGetContext(NULL, argc, argv, optionsTable, POPT_CONTEXT_POSIXMEHARDER);
++    poptSetOtherOptionHelp(optCon, "<words>");
++
++    /* Reporting about invalid extra options */
++      while ((opt = poptGetNextOpt(optCon)) != -1) {
++              switch (opt) {
++              default:
++                      fprintf(stderr, "Invalid option %s: %s\n", 
++                              poptBadOption(optCon, 0), poptStrerror(opt));
++                      poptPrintHelp(optCon, stderr, 0);
++                      exit(1);
++              }
++      }
++
++    /* Mandatory option: --wave */
++      if(!wavefile) {
++              fprintf(stderr, "Mandatory option: %s\n\n", 
++                      "--wave=filename.wav");
++              poptPrintHelp(optCon, stderr, 0);
++              exit(1);
++      }
++      /* option: --lang */
++      for(langIndexTmp =0; langIndexTmp<picoNumSupportedVocs; langIndexTmp++) {
++          if(!strcmp(picoSupportedLang[langIndexTmp], lang)) {
++              langIndex = langIndexTmp;
++              break;
++          }
++      }
++      if(langIndex == -1) {
++              fprintf(stderr, "Unknown language: %s\nValid languages:\n", 
++                      lang);
++          for(langIndexTmp =0; langIndexTmp<picoNumSupportedVocs; langIndexTmp++) {
++              fprintf(stderr, "%s\n", picoSupportedLang[langIndexTmp]);
++          }
++          lang = "en-US";
++              fprintf(stderr, "\n");
++              poptPrintHelp(optCon, stderr, 0);
++              exit(1);
++      }
++
++      /* Remaining argument is <words> */
++      const char **extra_argv;
++      extra_argv = poptGetArgs(optCon);
++    if(extra_argv) {
++              text = (char *) &(*extra_argv)[0];
++    } else {
++        //TODO: stdin not supported yet.
++              fprintf(stderr, "Missing argument: %s\n\n", 
++                      "<words>");
++              poptPrintHelp(optCon, stderr, 0);
++              exit(1);
++    }
++
++    poptFreeContext(optCon);
++    
++    buffer = malloc( bufferSize );
++    
++    int ret, getstatus;
++    pico_Char * inp = NULL;
++    pico_Char * local_text = NULL;
++    short       outbuf[MAX_OUTBUF_SIZE/2];
++    pico_Int16  bytes_sent, bytes_recv, text_remaining, out_data_type;
++    pico_Retstring outMessage;
++    
++    picoSynthAbort = 0;
++
++    picoMemArea = malloc( PICO_MEM_SIZE );
++    if((ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot initialize pico (%i): %s\n", ret, outMessage);
++        goto terminate;
++    }
++    
++    /* Load the text analysis Lingware resource file.   */
++    picoTaFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
++    strcpy((char *) picoTaFileName,   PICO_LINGWARE_PATH);
++    strcat((char *) picoTaFileName,   (const char *) picoInternalTaLingware[langIndex]);
++    if((ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot load text analysis resource file (%i): %s\n", ret, outMessage);
++        goto unloadTaResource;
++    }
++    
++    /* Load the signal generation Lingware resource file.   */
++    picoSgFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
++    strcpy((char *) picoSgFileName,   PICO_LINGWARE_PATH);
++    strcat((char *) picoSgFileName,   (const char *) picoInternalSgLingware[langIndex]);
++    if((ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot load signal generation Lingware resource file (%i): %s\n", ret, outMessage);
++        goto unloadSgResource;
++    }
++ 
++    /* Load the utpp Lingware resource file if exists - NOTE: this file is optional
++       and is currently not used. Loading is only attempted for future compatibility.
++       If this file is not present the loading will still succeed.                      //
++    picoUtppFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
++    strcpy((char *) picoUtppFileName,   PICO_LINGWARE_PATH);
++    strcat((char *) picoUtppFileName,   (const char *) picoInternalUtppLingware[langIndex]);
++    ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource );
++    pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++    printf("pico_loadResource: %i: %s\n", ret, outMessage);
++    */
++    
++    /* Get the text analysis resource name.     */
++    picoTaResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
++    if((ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot get the text analysis resource name (%i): %s\n", ret, outMessage);
++        goto unloadUtppResource;
++    }
++
++    /* Get the signal generation resource name. */
++    picoSgResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
++    if((ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot get the signal generation resource name (%i): %s\n", ret, outMessage);
++        goto unloadUtppResource;
++    }
++
++
++    /* Create a voice definition.   */
++    if((ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot create voice definition (%i): %s\n", ret, outMessage);
++        goto unloadUtppResource;
++    }
++
++    /* Add the text analysis resource to the voice. */
++    if((ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot add the text analysis resource to the voice (%i): %s\n", ret, outMessage);
++        goto unloadUtppResource;
++    }
++    
++    /* Add the signal generation resource to the voice. */
++    if((ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot add the signal generation resource to the voice (%i): %s\n", ret, outMessage);
++        goto unloadUtppResource;
++    }
++
++    /* Create a new Pico engine. */
++    if((ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine ))) {
++        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++        fprintf(stderr, "Cannot create a new pico engine (%i): %s\n", ret, outMessage);
++        goto disposeEngine;
++    }
++    
++    local_text = (pico_Char *) text ;
++    text_remaining = strlen((const char *) local_text) + 1;
++
++    inp = (pico_Char *) local_text;
++    
++    size_t bufused = 0;
++    
++    picoos_Common common = (picoos_Common) pico_sysGetCommon(picoSystem);
++
++    picoos_SDFile sdOutFile = NULL;
++
++    picoos_bool done = TRUE;
++    if(TRUE != (done = picoos_sdfOpenOut(common, &sdOutFile,
++        (picoos_char *) wavefile, SAMPLE_FREQ_16KHZ, PICOOS_ENC_LIN)))
++    {
++        fprintf(stderr, "Cannot open output wave file\n");
++        ret = 1;
++        goto disposeEngine;
++    }
++    
++    /* synthesis loop   */
++    while (text_remaining) {
++        /* Feed the text into the engine.   */
++        if((ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent ))) {
++            pico_getSystemStatusMessage(picoSystem, ret, outMessage);
++            fprintf(stderr, "Cannot put Text (%i): %s\n", ret, outMessage);
++            goto disposeEngine;
++        }
++    
++        text_remaining -= bytes_sent;
++        inp += bytes_sent;
++
++        do {
++            if (picoSynthAbort) {
++                goto disposeEngine;
++            }
++            /* Retrieve the samples and add them to the buffer. */
++            getstatus = pico_getData( picoEngine, (void *) outbuf,
++                      MAX_OUTBUF_SIZE, &bytes_recv, &out_data_type );
++            if((getstatus !=PICO_STEP_BUSY) && (getstatus !=PICO_STEP_IDLE)){
++                pico_getSystemStatusMessage(picoSystem, getstatus, outMessage);
++                fprintf(stderr, "Cannot get Data (%i): %s\n", getstatus, outMessage);
++                goto disposeEngine;
++            }
++            if (bytes_recv) {
++                if ((bufused + bytes_recv) <= bufferSize) {
++                    memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv);
++                    bufused += bytes_recv;
++                } else {
++                    done = picoos_sdfPutSamples(
++                                        sdOutFile,
++                                        bufused / 2,
++                                        (picoos_int16*) (buffer));
++                    bufused = 0;
++                    memcpy(buffer, (int8_t *) outbuf, bytes_recv);
++                    bufused += bytes_recv;
++                }
++            }
++        } while (PICO_STEP_BUSY == getstatus);
++        /* This chunk of synthesis is finished; pass the remaining samples. */
++        if (!picoSynthAbort) {
++                    done = picoos_sdfPutSamples(
++                                        sdOutFile,
++                                        bufused / 2,
++                                        (picoos_int16*) (buffer));
++        }
++        picoSynthAbort = 0;
++    }
++    
++    if(TRUE != (done = picoos_sdfCloseOut(common, &sdOutFile)))
++    {
++        fprintf(stderr, "Cannot close output wave file\n");
++        ret = 1;
++        goto disposeEngine;
++    }
++
++disposeEngine:
++    if (picoEngine) {
++        pico_disposeEngine( picoSystem, &picoEngine );
++        pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME );
++        picoEngine = NULL;
++    }
++unloadUtppResource:
++    if (picoUtppResource) {
++        pico_unloadResource( picoSystem, &picoUtppResource );
++        picoUtppResource = NULL;
++    }
++unloadSgResource:
++    if (picoSgResource) {
++        pico_unloadResource( picoSystem, &picoSgResource );
++        picoSgResource = NULL;
++    }
++unloadTaResource:
++    if (picoTaResource) {
++        pico_unloadResource( picoSystem, &picoTaResource );
++        picoTaResource = NULL;
++    }
++terminate:
++    if (picoSystem) {
++        pico_terminate(&picoSystem);
++        picoSystem = NULL;
++    }
++    exit(ret);
++}
++
+diff --git a/pico/configure.in b/pico/configure.in
+index 0afb56d..349eb1d 100644
+--- a/pico/configure.in
++++ b/pico/configure.in
+@@ -14,3 +14,6 @@ AC_CONFIG_FILES([Makefile])
+ AC_OUTPUT
+ AC_CONFIG_MACRO_DIR([m4])
++
++AC_CHECK_LIB(popt, poptGetContext)
++
+-- 
+1.7.1
+
diff --git a/sound/svox/patches/0004-add-header-files.patch b/sound/svox/patches/0004-add-header-files.patch
new file mode 100644 (file)
index 0000000..f057308
--- /dev/null
@@ -0,0 +1,59 @@
+From 0866cb3f7cfe4b8bae1edc8d0dbf18c85e9ca74f Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Tue, 27 Oct 2009 18:29:45 +0100
+Subject: [PATCH 4/7] add header files
+
+---
+ pico/Makefile.am |   36 ++++++++++++++++++++++++++++++++++++
+ 1 files changed, 36 insertions(+), 0 deletions(-)
+
+diff --git a/pico/Makefile.am b/pico/Makefile.am
+index 0d9472d..9151042 100644
+--- a/pico/Makefile.am
++++ b/pico/Makefile.am
+@@ -34,6 +34,42 @@ libttspico_la_SOURCES = \
+       lib/picotrns.c \
+       lib/picowa.c
++libttspico_ladir = $(includedir)
++libttspico_la_HEADERS = \
++    lib/picoacph.h \
++    lib/picoapid.h \
++    lib/picoapi.h \
++    lib/picobase.h \
++    lib/picocep.h \
++    lib/picoctrl.h \
++    lib/picodata.h \
++    lib/picodbg.h \
++    lib/picodefs.h \
++    lib/picodsp.h \
++    lib/picoextapi.h \
++    lib/picofftsg.h \
++    lib/picokdbg.h \
++    lib/picokdt.h \
++    lib/picokfst.h \
++    lib/picoklex.h \
++    lib/picoknow.h \
++    lib/picokpdf.h \
++    lib/picokpr.h \
++    lib/picoktab.h \
++    lib/picoos.h \
++    lib/picopal.h \
++    lib/picopam.h \
++    lib/picopltf.h \
++    lib/picopr.h \
++    lib/picorsrc.h \
++    lib/picosa.h \
++    lib/picosig2.h \
++    lib/picosig.h \
++    lib/picospho.h \
++    lib/picotok.h \
++    lib/picotrns.h \
++    lib/picowa.h
++
+ bin_PROGRAMS = pico2wave
+ pico2wave_SOURCES = \
+       bin/pico2wave.c
+-- 
+1.7.1
+
diff --git a/sound/svox/patches/0005-Install-lang-files.patch b/sound/svox/patches/0005-Install-lang-files.patch
new file mode 100644 (file)
index 0000000..95344e3
--- /dev/null
@@ -0,0 +1,32 @@
+From 486b9f924bdf38f5f213feed2631060b44024c11 Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Tue, 27 Oct 2009 23:06:46 +0100
+Subject: [PATCH 5/7] Install lang files
+
+---
+ pico/Makefile.am |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/pico/Makefile.am b/pico/Makefile.am
+index 9151042..8898050 100644
+--- a/pico/Makefile.am
++++ b/pico/Makefile.am
+@@ -70,6 +70,15 @@ libttspico_la_HEADERS = \
+     lib/picotrns.h \
+     lib/picowa.h
++picolangdir = $(datadir)/pico/lang
++picolang_DATA = \
++    lang/de-DE*.bin \
++    lang/en-GB*.bin \
++    lang/en-US*.bin \
++    lang/es-ES*.bin \
++    lang/fr-FR*.bin \
++    lang/it-IT*.bin
++
+ bin_PROGRAMS = pico2wave
+ pico2wave_SOURCES = \
+       bin/pico2wave.c
+-- 
+1.7.1
+
diff --git a/sound/svox/patches/0006-Set-picolangdir.patch b/sound/svox/patches/0006-Set-picolangdir.patch
new file mode 100644 (file)
index 0000000..1ec646d
--- /dev/null
@@ -0,0 +1,40 @@
+From 0102d423b79de7af982c8d4619d816f95a9b9278 Mon Sep 17 00:00:00 2001
+From: Mathieu Parent <math.parent@gmail.com>
+Date: Thu, 29 Oct 2009 23:55:19 +0100
+Subject: [PATCH 6/7] Set picolangdir
+
+---
+ pico/Makefile.am     |    2 +-
+ pico/bin/pico2wave.c |    4 ++++
+ 2 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/pico/Makefile.am b/pico/Makefile.am
+index 8898050..a19c42a 100644
+--- a/pico/Makefile.am
++++ b/pico/Makefile.am
+@@ -84,5 +84,5 @@ pico2wave_SOURCES = \
+       bin/pico2wave.c
+ pico2wave_LDADD = \
+       libttspico.la -lm -lpopt
+-pico2wave_CFLAGS = -Wall -I lib
++pico2wave_CFLAGS = -Wall -Dpicolangdir=\"$(picolangdir)\" -I lib
+diff --git a/pico/bin/pico2wave.c b/pico/bin/pico2wave.c
+index 0c035a7..ec7ab79 100644
+--- a/pico/bin/pico2wave.c
++++ b/pico/bin/pico2wave.c
+@@ -35,7 +35,11 @@
+ /* string constants */
+ #define MAX_OUTBUF_SIZE     128
++#ifdef picolangdir
++const char * PICO_LINGWARE_PATH             = picolangdir "/";
++#else
+ const char * PICO_LINGWARE_PATH             = "./lang/";
++#endif
+ const char * PICO_VOICE_NAME                = "PicoVoice";
+ /* supported voices
+-- 
+1.7.1
+
diff --git a/sound/svox/patches/0008-64bits.patch b/sound/svox/patches/0008-64bits.patch
new file mode 100644 (file)
index 0000000..883a42e
--- /dev/null
@@ -0,0 +1,26 @@
+Description: fix execution on 64bit archs
+Bug: http://code.google.com/p/android/issues/detail?id=12224
+Author: Samuel Thibault <sthibault@debian.org>
+
+--- svox/pico/lib/picoapi.c.original   2010-10-25 19:06:57.000000000 +0200
++++ svox/pico/lib/picoapi.c    2010-10-25 19:07:18.000000000 +0200
+@@ -90,7 +90,7 @@
+         status = PICO_ERR_NULLPTR_ACCESS;
+     } else {
+         byte_ptr_t rest_mem;
+-        picoos_uint32 rest_mem_size;
++        picoos_objsize_t rest_mem_size;
+         pico_System sys;
+         picoos_MemoryManager sysMM;
+         picoos_ExceptionManager sysEM;
+--- svox/pico/lib/picosig2.c.original  2010-10-26 00:17:18.000000000 +0200
++++ svox/pico/lib/picosig2.c   2010-10-26 00:17:19.000000000 +0200
+@@ -568,7 +568,7 @@
+     for (nI = 1; nI < m1; nI++) {
+         XXr[nI] = c1[nI] << shift;
+     }
+-    i = sizeof(picoos_int32) * (PICODSP_FFTSIZE + 1 - m1);
++    i = sizeof(picoos_int32) * (PICODSP_FFTSIZE - m1);
+     picoos_mem_set(XXr + m1, 0, i);
+     dfct_nmf(m4, XXr); /* DFCT directly in fixed point */
diff --git a/sound/svox/patches/0009-Fix-link-order.patch b/sound/svox/patches/0009-Fix-link-order.patch
new file mode 100644 (file)
index 0000000..bcf3870
--- /dev/null
@@ -0,0 +1,21 @@
+Index: svox-1.0+git20130326/pico/Makefile.am
+===================================================================
+--- svox-1.0+git20130326.orig/pico/Makefile.am 2013-11-12 12:37:05.939979854 -0500
++++ svox-1.0+git20130326/pico/Makefile.am      2013-11-12 13:00:52.336945041 -0500
+@@ -70,6 +70,8 @@
+     lib/picotrns.h \
+     lib/picowa.h
++libttspico_la_LIBADD = -lm
++
+ picolangdir = $(datadir)/pico/lang
+ picolang_DATA = \
+     lang/de-DE*.bin \
+@@ -83,6 +85,6 @@
+ pico2wave_SOURCES = \
+       bin/pico2wave.c
+ pico2wave_LDADD = \
+-      libttspico.la -lm -lpopt
++      libttspico.la -lpopt
+ pico2wave_CFLAGS = -Wall -Dpicolangdir=\"$(picolangdir)\" -I lib
diff --git a/sound/svox/patches/0010-platform.patch b/sound/svox/patches/0010-platform.patch
new file mode 100644 (file)
index 0000000..ff76f75
--- /dev/null
@@ -0,0 +1,30 @@
+--- a/pico/lib/picopltf.h
++++ b/pico/lib/picopltf.h
+@@ -39,6 +39,8 @@
+ #define PICO_MacOSX     5   /* Macintosh OS X */
+ #define PICO_Linux      7   /* Linux */
++#define PICO_GENERIC    99  /* Generic */
++
+ /* * definition of current platform ***/
+ #if !defined(PICO_PLATFORM)
+ #if defined(_WIN32)
+@@ -48,7 +50,7 @@
+ #elif defined(linux) || defined(__linux__) || defined(__linux)
+ #define PICO_PLATFORM    PICO_Linux
+ #else
+-#error PICO_PLATFORM not defined
++#define PICO_PLATFORM    PICO_GENERIC
+ #endif
+ #endif /* !defined(PICO_PLATFORM) */
+@@ -64,7 +66,8 @@
+ #define PICO_PLATFORM_STRING "UnknownPlatform"
+ #endif
+-#if (PICO_PLATFORM == PICO_MacOSX)
++#include <endian.h>
++#if __BYTE_ORDER == __BIG_ENDIAN
+ #define PICO_ENDIANNESS ENDIANNESS_BIG
+ #else
+ #define PICO_ENDIANNESS ENDIANNESS_LITTLE
diff --git a/sound/svox/patches/0011-subdir.patch b/sound/svox/patches/0011-subdir.patch
new file mode 100644 (file)
index 0000000..fa9e91f
--- /dev/null
@@ -0,0 +1,12 @@
+diff -urN a/pico/configure.in b/pico/configure.in
+--- a/pico/configure.in        2015-01-21 18:59:39.604452795 +0100
++++ b/pico/configure.in        2015-01-21 19:00:53.288777298 +0100
+@@ -4,7 +4,7 @@
+ AC_INIT([svox], [1.0], [math.parent@gmail.com])
+-AM_INIT_AUTOMAKE([1.9 foreign])
++AM_INIT_AUTOMAKE([1.9 foreign subdir-objects])
+ AC_PROG_CC
+ LT_INIT
diff --git a/sound/svox/patches/0012-no-headers.patch b/sound/svox/patches/0012-no-headers.patch
new file mode 100644 (file)
index 0000000..edf4d04
--- /dev/null
@@ -0,0 +1,46 @@
+diff -urN a/pico/Makefile.am b/pico/Makefile.am
+--- a/pico/Makefile.am 2015-01-22 01:33:21.470895431 +0100
++++ b/pico/Makefile.am 2015-01-22 01:36:03.042228475 +0100
+@@ -34,42 +34,6 @@
+       lib/picotrns.c \
+       lib/picowa.c
+-libttspico_ladir = $(includedir)
+-libttspico_la_HEADERS = \
+-    lib/picoacph.h \
+-    lib/picoapid.h \
+-    lib/picoapi.h \
+-    lib/picobase.h \
+-    lib/picocep.h \
+-    lib/picoctrl.h \
+-    lib/picodata.h \
+-    lib/picodbg.h \
+-    lib/picodefs.h \
+-    lib/picodsp.h \
+-    lib/picoextapi.h \
+-    lib/picofftsg.h \
+-    lib/picokdbg.h \
+-    lib/picokdt.h \
+-    lib/picokfst.h \
+-    lib/picoklex.h \
+-    lib/picoknow.h \
+-    lib/picokpdf.h \
+-    lib/picokpr.h \
+-    lib/picoktab.h \
+-    lib/picoos.h \
+-    lib/picopal.h \
+-    lib/picopam.h \
+-    lib/picopltf.h \
+-    lib/picopr.h \
+-    lib/picorsrc.h \
+-    lib/picosa.h \
+-    lib/picosig2.h \
+-    lib/picosig.h \
+-    lib/picospho.h \
+-    lib/picotok.h \
+-    lib/picotrns.h \
+-    lib/picowa.h
+-
+ libttspico_la_LIBADD = -lm
+ picolangdir = $(datadir)/pico/lang
index d4da42461508304c40318f1f31237047a73b49b9..e7d719a957c114e55c0e819ff6d99f4a902aae14 100644 (file)
@@ -8,8 +8,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=acl
-PKG_REV:=f2a5f57a20ffa007abc1fa24df1f76e18b74a425
-PKG_VERSION:=20140610
+PKG_REV:=62ce6354ef5a8eb5644908748f79c8cd18474d4c
+PKG_VERSION:=20140812
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
@@ -21,6 +21,7 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_INSTALL:=1
 PKG_LICENSE:=LGPL-2.1 GPL-2.0
+PKG_LICENSE_FILES:=doc/COPYING doc/COPYING.LGPL
 
 include $(INCLUDE_DIR)/package.mk
 
index 43d90177f9d8c0a2f6ceb09fa39b57884b820083..1d3bde28262bcfaf65f4f0ca4bd96289823601c2 100644 (file)
@@ -8,8 +8,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=attr
-PKG_REV:=50fc862d69984089ce09138b3350ee7762290403
-PKG_VERSION:=20140610
+PKG_REV:=c4a7fdbcc109d6e8b465a427c714926fcb85c750
+PKG_VERSION:=20141020
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
@@ -21,6 +21,7 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_INSTALL:=1
 PKG_LICENSE:=LGPL-2.1 GPL-2.0
+PKG_LICENSE_FILES:=doc/COPYING doc/COPYING.LGPL
 
 include $(INCLUDE_DIR)/package.mk
 
index b85ded75679a41eb4a53c6a2a1a941aa173c40de..ca0911f903147734b23fe4c4affd5f94abd517b8 100644 (file)
@@ -22,6 +22,7 @@ PKG_LICENSE:=GPL-3.0+
 PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
 
+PKG_CHECK_FORMAT_SECURITY:=0
 include $(INCLUDE_DIR)/package.mk
 
 define Package/bash
diff --git a/utils/bluelog/Makefile b/utils/bluelog/Makefile
new file mode 100644 (file)
index 0000000..2fe10d8
--- /dev/null
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2012-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bluelog
+PKG_VERSION:=1.1.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=ftp://ftp.digifail.com/software/bluelog
+PKG_MD5SUM:=614d0fe65bae68acff1d33d9f86e4805
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bluelog/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Bluetooth scanner and logger
+  URL:=http://www.digifail.com/software/bluelog.shtml
+  DEPENDS:=+bluez-libs +kmod-bluetooth
+endef
+
+define Package/bluelog/Default/description
+  Bluelog is a simple Bluetooth scanner designed to tell you how many
+  discoverable devices there are in an area as quickly as possible. It is
+  intended to be used as a site survey tool, identifying the number of possible
+  Bluetooth targets there are in the surrounding environment.
+endef
+
+define Package/bluelog
+  $(call Package/bluelog/Default)
+endef
+
+define Package/bluelog/description
+  $(call Package/bluelog/Default/description)
+endef
+
+define Package/bluelog-live
+  $(call Package/bluelog/Default)
+  TITLE+= (live output)
+  DEPENDS+= bluelog
+endef
+
+define Package/bluelog-live/description
+  $(call Package/bluelog/Default/description)
+  This package contains the files for "Bluelog Live", an optional mode of
+  Bluelog which creates a real-time webpage of discovered Bluetooth devices.
+endef
+
+TARGET_CFLAGS += -DOPENWRT
+
+MAKE_FLAGS += \
+        LIBS="$(TARGET_LDFLAGS) -lbluetooth -lm"
+
+define Package/bluelog/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/bluelog $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/bluelog.init $(1)/etc/init.d/bluelog
+endef
+
+define Package/bluelog-live/install
+       $(INSTALL_DIR) $(1)/www/bluelog
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/bluelog/*.html $(1)/www/bluelog/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/openwrt.css \
+               $(1)/www/bluelog/style.css
+       $(INSTALL_DIR) $(1)/www/bluelog/images
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/images/digifail_logo.png \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/images/email.png \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/images/favicon.png \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/images/openwrt_logo.png \
+               $(PKG_INSTALL_DIR)/usr/share/bluelog/images/qrcontact.png \
+               $(1)/www/bluelog/images/
+       $(INSTALL_DIR) $(1)/www/cgi-bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/bluelog/cgi-bin/* $(1)/www/cgi-bin/
+endef
+
+$(eval $(call BuildPackage,bluelog))
+$(eval $(call BuildPackage,bluelog-live))
diff --git a/utils/bluelog/files/bluelog.init b/utils/bluelog/files/bluelog.init
new file mode 100644 (file)
index 0000000..efae288
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh /etc/rc.common
+
+START=65
+
+SERVICE_DAEMONIZE=1
+
+start() {
+       service_start /usr/bin/bluelog
+}
+
+stop() {
+       service_stop /usr/bin/bluelog
+}
diff --git a/utils/bluez/Makefile b/utils/bluez/Makefile
new file mode 100644 (file)
index 0000000..72dcaea
--- /dev/null
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bluez
+PKG_VERSION:=5.27
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://www.kernel.org/pub/linux/bluetooth/
+PKG_MD5SUM:=a8fc508690e497e88c2c0b373cd653a8
+
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/bluez/Default
+  TITLE:=Bluetooth
+  URL:=http://www.bluez.org/
+endef
+
+define Package/bluez-libs
+$(call Package/bluez/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  DEPENDS:=+libpthread
+endef
+
+define Package/bluez-utils
+$(call Package/bluez/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= utilities
+  DEPENDS:=+bluez-libs +libpthread +dbus +glib2 +libical +libncurses +libreadline $(INTL_DEPENDS) $(ICONV_DEPENDS)
+endef
+
+define Package/bluez-utils/conffiles
+/etc/bluetooth/hcid.conf
+/etc/bluetooth/rfcomm.conf
+/etc/config/bluetooth
+endef
+
+CONFIGURE_ARGS += \
+       --enable-static \
+       --enable-shared \
+       --enable-client \
+       --enable-datafiles \
+       --enable-experimental \
+       --enable-library \
+       --enable-monitor \
+       --enable-obex \
+       --enable-threads \
+       --enable-tools \
+       --disable-android \
+       --disable-cups \
+       --disable-manpages \
+       --disable-sixaxis \
+       --disable-systemd \
+       --disable-test \
+       --disable-udev \
+
+TARGET_CPPFLAGS += \
+       -D_GNU_SOURCE
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/bluetooth $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libbluetooth.{a,so*} $(1)/usr/lib/
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/bluez.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/bluez-libs/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libbluetooth.so.* $(1)/usr/lib/
+endef
+
+define Package/bluez-utils/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/bluetooth.config $(1)/etc/config/bluetooth
+       $(INSTALL_DIR) $(1)/etc/dbus-1/system.d/
+       $(INSTALL_DATA) ./files/bluetooth.dbus $(1)/etc/dbus-1/system.d/bluetooth.conf
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/bluez-utils.init $(1)/etc/init.d/bluez-utils
+endef
+
+$(eval $(call BuildPackage,bluez-libs))
+$(eval $(call BuildPackage,bluez-utils))
diff --git a/utils/bluez/files/bluetooth.config b/utils/bluez/files/bluetooth.config
new file mode 100644 (file)
index 0000000..42f390c
--- /dev/null
@@ -0,0 +1,32 @@
+config hcid
+#      option config   /etc/bluetooth/hcid.conf
+       option enabled  1
+
+config hciattach
+       option initspeed        115200
+       option tty      ttyS1
+       option type     csr
+       option speed    115200
+       option flow     noflow
+       option enabled  0
+
+config rfcomm
+#      option config   /etc/bluetooth/rfcomm.conf
+       option enabled  0
+
+config dund
+       option listen   true
+       option persist  true
+       option msdun    true
+       option interface dund
+       option unit     1
+       option pppdopts "ktune proxyarp 192.168.1.1:192.168.1.2 ms-dns 192.168.1.1"
+       option enabled  0
+
+config pand
+       option listen   true
+       option autozap  true
+       option role     "NAP"
+       option master   true
+       option persist  true
+       option enabled  0
diff --git a/utils/bluez/files/bluetooth.dbus b/utils/bluez/files/bluetooth.dbus
new file mode 100644 (file)
index 0000000..88545fa
--- /dev/null
@@ -0,0 +1,37 @@
+<!-- This configuration file specifies the required security policies
+     for Bluetooth core daemon to work. -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+  <!-- ../system.conf have denied everything, so we just punch some holes -->
+
+  <policy user="root">
+    <allow own="org.bluez"/>
+  </policy>
+
+  <policy at_console="true">
+    <allow send_path="/"/>
+    <allow send_path="/org/bluez"/>
+
+    <allow send_destination="org.bluez.Manager"/>
+    <allow receive_sender="org.bluez.Manager"/>
+
+    <allow send_destination="org.bluez.Adapter"/>
+    <allow receive_sender="org.bluez.Adapter"/>
+
+    <allow send_destination="org.bluez.Device"/>
+    <allow receive_sender="org.bluez.Device"/>
+
+    <allow send_destination="org.bluez.Service"/>
+    <allow receive_sender="org.bluez.Service"/>
+
+    <allow send_destination="org.bluez.Database"/>
+    <allow receive_sender="org.bluez.Database"/>
+
+    <allow send_destination="org.bluez.Security"/>
+    <allow receive_sender="org.bluez.Security"/>
+  </policy>
+
+</busconfig>
diff --git a/utils/bluez/files/bluez-utils.init b/utils/bluez/files/bluez-utils.init
new file mode 100644 (file)
index 0000000..e9320ae
--- /dev/null
@@ -0,0 +1,131 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2007 OpenWrt.org
+
+#start after dbus (60)
+START=62
+
+append_bool() {
+       local section="$1"
+       local option="$2"
+       local value="$3"
+       local _val
+       config_get_bool _val "$section" "$option" '0'
+       [ $_val -gt 0 ] && append args "$3"
+}
+
+append_string() {
+       local section="$1"
+       local option="$2"
+       local value="$3"
+       local default="$4"
+       local _val
+       config_get _val "$section" "$option" "$default"
+       [ -n "$_val" ] && append args "$3 $_val"
+}
+
+hcid_config() {
+       local cfg="$1"
+       config_get_bool enabled "$cfg" "enabled" '1'
+       [ $enabled -gt 0 ] || return 1
+       args=""
+       append_bool "$cfg" nodaemon "-n"
+       append_string "$cfg" config "-f"
+       service_start /usr/sbin/hcid $args
+}
+
+hciattach_config() {
+       local cfg="$1"
+       config_get_bool enabled "$cfg" "enabled" '1'
+       [ $enabled -gt 0 ] || return 1
+       args=""
+       append_string "$cfg" initspeed "-s" "115200"
+       append_string "$cfg" tty " " "ttyS1"
+       append_string "$cfg" type " " "csr"
+       append_string "$cfg" speed " " "115200"
+       append_string "$cfg" flow " " "noflow"
+       service_start /usr/sbin/hciattach $args
+}
+
+rfcomm_config() {
+       local cfg="$1"
+       config_get_bool enabled "$cfg" "enabled" '1'
+       [ $enabled -gt 0 ] || return 1
+       args=""
+       append_string "$cfg" config "-f"
+       /usr/bin/rfcomm $args bind all
+}
+
+dund_config() {
+       local cfg="$1"
+       config_get_bool enabled "$cfg" "enabled" '1'
+       [ $enabled -gt 0 ] || return 1
+       args=""
+       append_bool "$cfg" listen "--listen"
+       append_string "$cfg" connect "--connect"
+       append_string "$cfg" mrouter "--mrouter"
+       append_bool "$cfg" search "--search"
+       append_string "$cfg" channel "--channel"
+       append_string "$cfg" device "--device"
+       append_bool "$cfg" nosdp "--nosdp"
+       append_bool "$cfg" auth "--auth"
+       append_bool "$cfg" encrypt "--encrypt"
+       append_bool "$cfg" secure "--secure"
+       append_bool "$cfg" master "--master"
+       append_bool "$cfg" nodetach "--nodetach"
+       append_bool "$cfg" persist "--persist"
+       append_string "$cfg" pppd "--pppd"
+       append_bool "$cfg" msdun "--msdun"
+       append_bool "$cfg" activesync "--activesync"
+       append_bool "$cfg" cache "--cache"
+
+       append_string "$cfg" pppdopts ""
+       config_get ifn "$cfg" interface
+       if [ -n "$ifn" ]; then
+               config_get unit "$cfg" unit
+               [ -z "$unit" ] || append args "unit $unit ipparam $ifn linkname $ifn"
+       fi
+
+       service_start /usr/bin/dund $args
+}
+
+pand_config() {
+       local cfg="$1"
+       config_get_bool enabled "$cfg" "enabled" '1'
+       [ $enabled -gt 0 ] || return 1
+       args=""
+       append_bool "$cfg" listen "--listen"
+       append_string "$cfg" connect "--connect"
+       append_bool "$cfg" autozap "--autozap"
+       append_bool "$cfg" search "--search"
+       append_string "$cfg" role "--role"
+       append_string "$cfg" service "--service"
+       append_string "$cfg" ethernet "--ethernet"
+       append_string "$cfg" device "--device"
+       append_bool "$cfg" nosdp "-D"
+       append_bool "$cfg" auth "-A"
+       append_bool "$cfg" encrypt "-E"
+       append_bool "$cfg" secure "-S"
+       append_bool "$cfg" master "-M"
+       append_bool "$cfg" nodetach "-n"
+       append_bool "$cfg" persist "--persist"
+       append_bool "$cfg" cache "--cache"
+       append_string "$cfg" pidfile "--pidfile"
+       service_start /usr/bin/pand $args
+}
+
+start() {
+       config_load bluetooth
+       config_foreach hcid_config hcid
+       config_foreach hciattach_config hciattach
+       config_foreach rfcomm_config rfcomm
+       config_foreach dund_config dund
+       config_foreach pand_config pand
+}
+
+stop() {
+       service_stop /usr/bin/dund
+       service_stop /usr/bin/pand
+       /usr/bin/rfcomm release all
+       service_stop /usr/sbin/hciattach
+       service_stop /usr/sbin/hcid
+}
diff --git a/utils/bluez/files/givepin b/utils/bluez/files/givepin
new file mode 100644 (file)
index 0000000..e52a338
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Write bluetooth PIN number here:
+pin=
+
+if [ -z "$pin" ]; then
+       msg="Set bluetooth PIN in file $0"
+       logger -p user.err "$msg"
+       for i in /dev/pts/* ; do
+               [ -w $i ] && echo "$msg" > $i
+       done
+else
+       echo "PIN:$pin"
+fi
diff --git a/utils/bluez/patches/200-uart-speed.patch b/utils/bluez/patches/200-uart-speed.patch
new file mode 100644 (file)
index 0000000..ebe0153
--- /dev/null
@@ -0,0 +1,40 @@
+--- a/tools/hciattach.c
++++ b/tools/hciattach.c
+@@ -101,20 +101,37 @@ int uart_speed(int s)
+               return B230400;
+       case 460800:
+               return B460800;
++/* FIX: Not all platform support this high serial speed
++   claudyus84 @gamil.com
++*/
++#ifdef B500000
+       case 500000:
+               return B500000;
++#endif
++#ifdef B576000
+       case 576000:
+               return B576000;
++#endif
++#ifdef B921600
+       case 921600:
+               return B921600;
++#endif
++#ifdef B1000000
+       case 1000000:
+               return B1000000;
++#endif
++#ifdef B1152000
+       case 1152000:
+               return B1152000;
++#endif
++#ifdef B1500000
+       case 1500000:
+               return B1500000;
++#endif
++#ifdef B2000000
+       case 2000000:
+               return B2000000;
++#endif
+ #ifdef B2500000
+       case 2500000:
+               return B2500000;
diff --git a/utils/bluez/patches/201-readline.patch b/utils/bluez/patches/201-readline.patch
new file mode 100644 (file)
index 0000000..9d5bec0
--- /dev/null
@@ -0,0 +1,43 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -2038,7 +2038,7 @@ unit_tests = $(am__append_32) unit/test-
+ @CLIENT_TRUE@                                 monitor/uuid.h monitor/uuid.c
+ @CLIENT_TRUE@client_bluetoothctl_LDADD = gdbus/libgdbus-internal.la @GLIB_LIBS@ @DBUS_LIBS@ \
+-@CLIENT_TRUE@                         -lreadline
++@CLIENT_TRUE@                         -lreadline -lncurses
+ @MONITOR_TRUE@monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
+ @MONITOR_TRUE@                                monitor/display.h monitor/display.c \
+@@ -2245,13 +2245,13 @@ unit_tests = $(am__append_32) unit/test-
+ @READLINE_TRUE@                               client/display.h
+ @READLINE_TRUE@attrib_gatttool_LDADD = lib/libbluetooth-internal.la \
+-@READLINE_TRUE@                       src/libshared-glib.la @GLIB_LIBS@ -lreadline
++@READLINE_TRUE@                       src/libshared-glib.la @GLIB_LIBS@ -lreadline -lncurses
+ @READLINE_TRUE@tools_obex_client_tool_SOURCES = $(gobex_sources) $(btio_sources) \
+ @READLINE_TRUE@                                               tools/obex-client-tool.c
+ @READLINE_TRUE@tools_obex_client_tool_LDADD = lib/libbluetooth-internal.la \
+-@READLINE_TRUE@                                               @GLIB_LIBS@ -lreadline
++@READLINE_TRUE@                                               @GLIB_LIBS@ -lreadline -lncurses
+ @READLINE_TRUE@tools_obex_server_tool_SOURCES = $(gobex_sources) $(btio_sources) \
+ @READLINE_TRUE@                                               tools/obex-server-tool.c
+@@ -2261,13 +2261,13 @@ unit_tests = $(am__append_32) unit/test-
+ @READLINE_TRUE@                               client/display.h client/display.c
+ @READLINE_TRUE@tools_bluetooth_player_LDADD = gdbus/libgdbus-internal.la \
+-@READLINE_TRUE@                               @GLIB_LIBS@ @DBUS_LIBS@ -lreadline
++@READLINE_TRUE@                               @GLIB_LIBS@ @DBUS_LIBS@ -lreadline -lncurses
+ @READLINE_TRUE@tools_obexctl_SOURCES = tools/obexctl.c \
+ @READLINE_TRUE@                               client/display.h client/display.c
+ @READLINE_TRUE@tools_obexctl_LDADD = gdbus/libgdbus-internal.la \
+-@READLINE_TRUE@                               @GLIB_LIBS@ @DBUS_LIBS@ -lreadline
++@READLINE_TRUE@                               @GLIB_LIBS@ @DBUS_LIBS@ -lreadline -lncurses
+ @EXPERIMENTAL_TRUE@tools_gatt_service_SOURCES = tools/gatt-service.c
+ @EXPERIMENTAL_TRUE@tools_gatt_service_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ gdbus/libgdbus-internal.la
diff --git a/utils/btrfs-progs/Makefile b/utils/btrfs-progs/Makefile
new file mode 100644 (file)
index 0000000..ea486b9
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2009-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=btrfs-progs
+PKG_VERSION:=3.17.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/people/kdave/btrfs-progs/
+PKG_MD5SUM:=6716b4b109dd909af63ab3becbad67a6
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-v$(PKG_VERSION)
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=libacl
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/btrfs-progs
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Filesystem
+  DEPENDS:=+libattr +libuuid +zlib +libext2fs +libblkid +liblzo +libpthread
+  TITLE:=Btrfs filesystems utilities
+  URL:=http://btrfs.wiki.kernel.org/
+endef
+
+define Package/btrfs-progs/description
+ Btrfs is a new copy on write filesystem for Linux aimed at implementing
+ advanced features while focusing on fault tolerance, repair and easy
+ administration. Initially developed by Oracle, Btrfs is licensed under the
+ GPL and open for contribution from anyone.
+endef
+
+progs = btrfs btrfsck btrfs-convert btrfs-debug-tree btrfs-find-root \
+       btrfs-image btrfs-map-logical btrfs-show-super btrfstune \
+       btrfs-zero-log fsck.btrfs mkfs.btrfs
+
+
+MAKE_FLAGS+=\
+       CC="$(TARGET_CC)" \
+       CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+       LDFLAGS="$(TARGET_LDFLAGS)" \
+       prefix=/usr \
+       DESTDIR=$(PKG_INSTALL_DIR) \
+       DISABLE_BACKTRACE=1 \
+       DISABLE_DOCUMENTATION=1
+
+define Package/btrfs-progs/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libbtrfs.so* $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(addprefix $(PKG_INSTALL_DIR)/usr/bin/, $(progs)) $(1)/usr/bin/
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/btrfs-scan.init $(1)/etc/init.d/btrfs-scan
+endef
+
+$(eval $(call BuildPackage,btrfs-progs))
diff --git a/utils/btrfs-progs/files/btrfs-scan.init b/utils/btrfs-progs/files/btrfs-scan.init
new file mode 100644 (file)
index 0000000..762e0b8
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=19
+
+start() {
+       grep -q btrfs /proc/filesystems && /usr/bin/btrfs device scan
+}
+
diff --git a/utils/btrfs-progs/patches/001-fix-xattr-h-include-location.patch b/utils/btrfs-progs/patches/001-fix-xattr-h-include-location.patch
new file mode 100644 (file)
index 0000000..0e32169
--- /dev/null
@@ -0,0 +1,55 @@
+--- a/mkfs.c
++++ b/mkfs.c
+@@ -34,7 +34,7 @@
+ #include <getopt.h>
+ #include <uuid/uuid.h>
+ #include <ctype.h>
+-#include <sys/xattr.h>
++#include <attr/xattr.h>
+ #include <blkid/blkid.h>
+ #include <ftw.h>
+ #include "ctree.h"
+--- a/props.c
++++ b/props.c
+@@ -17,7 +17,7 @@
+ #include <sys/stat.h>
+ #include <sys/ioctl.h>
+ #include <sys/types.h>
+-#include <sys/xattr.h>
++#include <attr/xattr.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+--- a/cmds-receive.c
++++ b/cmds-receive.c
+@@ -39,7 +39,7 @@
+ #include <sys/ioctl.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+-#include <sys/xattr.h>
++#include <attr/xattr.h>
+ #include <uuid/uuid.h>
+ #include "ctree.h"
+--- a/cmds-restore.c
++++ b/cmds-restore.c
+@@ -34,7 +34,7 @@
+ #include <regex.h>
+ #include <getopt.h>
+ #include <sys/types.h>
+-#include <sys/xattr.h>
++#include <attr/xattr.h>
+ #include "ctree.h"
+ #include "disk-io.h"
+--- a/Makefile
++++ b/Makefile
+@@ -26,7 +26,7 @@ TESTS = fsck-tests.sh convert-tests.sh
+ INSTALL = install
+ prefix ?= /usr/local
+ bindir = $(prefix)/bin
+-lib_LIBS = -luuid -lblkid -lm -lz -llzo2 -L.
++lib_LIBS = -lattr -luuid -lblkid -lm -lz -llzo2 -L.
+ libdir ?= $(prefix)/lib
+ incdir = $(prefix)/include/btrfs
+ LIBS = $(lib_LIBS) $(libs_static)
index 1d8c1739a45d7ba3de70b647cf0cdbfe78dd6d9a..ce059cbb4d1cd627c477c12eee41edaeedeecd1e 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ccid
-PKG_VERSION:=1.4.17
+PKG_VERSION:=1.4.18
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=https://alioth.debian.org/frs/download.php/file/4091
-PKG_MD5SUM:=a227a20a0dd034cd4bb7400806a0a2d0
+PKG_SOURCE_URL:=https://alioth.debian.org/frs/download.php/file/4111
+PKG_MD5SUM:=8d57342bda53aaee706ef2d02409c4f4
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=LGPL-2.1+
 PKG_LICENSE_FILES:=COPYING
index a85c12417672377cc013556d2f2a449e6a1d6395..5b9f52d1c25f6b90ef5b7544677474609aa6aff5 100644 (file)
@@ -17,7 +17,7 @@ PKG_MD5SUM:=6633b2354b7f23f9cd8e2bfb6e735965
 
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 PKG_LICENSE:=MIT
-PKG_LICENSE_FILE:=doc/COPYING
+PKG_LICENSE_FILES:=doc/COPYING
 
 include $(INCLUDE_DIR)/package.mk
 
index d191615113e0e02a7fd8245a5ad0f301a4d995fb..33af152a79937fc15b6158ac55186b67d97b408f 100644 (file)
@@ -313,7 +313,7 @@ $(eval $(call BuildPlugin,powerdns,PowerDNS server status input,powerdns,))
 $(eval $(call BuildPlugin,processes,process status input,processes,))
 $(eval $(call BuildPlugin,protocols,network protocols input,protocols,))
 $(eval $(call BuildPlugin,rrdtool,RRDtool output,rrdtool,+PACKAGE_collectd-mod-rrdtool:librrd1))
-$(eval $(call BuildPlugin,sensors,lm_sensors input,sensors,+PACKAGE_collectd-mod-sensors:libsensors @BROKEN))
+$(eval $(call BuildPlugin,sensors,lm_sensors input,sensors,+PACKAGE_collectd-mod-sensors:libsensors))
 $(eval $(call BuildPlugin,snmp,SNMP input,snmp,+PACKAGE_collectd-mod-snmp:libnetsnmp))
 $(eval $(call BuildPlugin,syslog,syslog output,syslog,))
 $(eval $(call BuildPlugin,tail,tail input,tail,))
index 4500e88e478e0078007cf7119cc7e36664067d1d..3b9f17d37f7ff30dc5eab054ffb14ab9f384474b 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=coreutils
-PKG_VERSION:=8.16
+PKG_VERSION:=8.23
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@GNU/coreutils
-PKG_MD5SUM:=89b06f91634208dceba7b36ad1f9e8b9
+PKG_MD5SUM:=abed135279f87ad6762ce57ff6d89c41
 PKG_BUILD_DEPENDS:=libpthread
 PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
 
@@ -36,6 +36,12 @@ DEPENDS_sort = +libpthread
 DEPENDS_timeout = +librt
 DEPENDS_expr = +libgmp
 DEPENDS_factor = +libgmp
+DEPENDS_cp = +libacl
+DEPENDS_dir = +libacl
+DEPENDS_install = +libacl
+DEPENDS_ls = +libacl
+DEPENDS_mv = +libacl
+DEPENDS_vdir = +libacl
 
 define Package/coreutils/Default
   SECTION:=utils
@@ -89,7 +95,7 @@ define Build/Compile
        $(MAKE) -C $(PKG_BUILD_DIR) \
                DESTDIR="$(PKG_INSTALL_DIR)" \
                SHELL="/bin/bash" \
-               all install install-root
+               all install
 endef
 
 define Package/coreutils/install
index 2c04117509f5124ec9ea1d0a8da4a75374f6c48d..60f2df2b8061975dac81453d7c6058a7d859515b 100644 (file)
@@ -4,19 +4,86 @@
  
  ALL_RECURSIVE_TARGETS =
  
--SUBDIRS = lib src doc man po tests gnulib-tests
-+SUBDIRS = lib src po
+-SUBDIRS = po . gnulib-tests
++SUBDIRS = po
  
  changelog_etc =                               \
    ChangeLog-2005                      \
+@@ -213,6 +213,4 @@ AM_CPPFLAGS = -Ilib -I$(top_srcdir)/lib
+ include $(top_srcdir)/lib/local.mk
+ include $(top_srcdir)/src/local.mk
+-include $(top_srcdir)/doc/local.mk
+-include $(top_srcdir)/man/local.mk
+-include $(top_srcdir)/tests/local.mk
++
 --- a/Makefile.in
 +++ b/Makefile.in
-@@ -1639,7 +1639,7 @@ top_srcdir = @top_srcdir@
- # Some tests always need root privileges, others need them only sometimes.
- ALL_RECURSIVE_TARGETS = install-root check-root distcheck-hook
--SUBDIRS = lib src doc man po tests gnulib-tests
-+SUBDIRS = lib src po
+@@ -159,8 +159,7 @@ build_triplet = @build@
+ host_triplet = @host@
+ DIST_COMMON = $(top_srcdir)/lib/local.mk $(srcdir)/lib/gnulib.mk \
+       $(top_srcdir)/src/local.mk $(srcdir)/src/cu-progs.mk \
+-      $(top_srcdir)/src/single-binary.mk $(top_srcdir)/doc/local.mk \
+-      $(top_srcdir)/man/local.mk $(top_srcdir)/tests/local.mk \
++      $(top_srcdir)/src/single-binary.mk \
+       INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \
+       $(srcdir)/Makefile.am $(top_srcdir)/configure \
+       $(am__configure_deps) $(top_srcdir)/lib/config.hin ABOUT-NLS \
+@@ -2276,11 +2275,7 @@ RECURSIVE_TARGETS = all-recursive check-
+       install-ps-recursive install-recursive installcheck-recursive \
+       installdirs-recursive pdf-recursive ps-recursive \
+       tags-recursive uninstall-recursive
+-am__can_run_installinfo = \
+-  case $$AM_UPDATE_INFO_DIR in \
+-    n|no|NO) false;; \
+-    *) (install-info --version) >/dev/null 2>&1;; \
+-  esac
++am__can_run_installinfo = false
+ am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+ am__vpath_adj = case $$p in \
+     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+@@ -2606,7 +2601,7 @@ EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+ EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ ERRNO_H = @ERRNO_H@
+ EXEEXT = @EXEEXT@
+-EXTRA_MANS = @EXTRA_MANS@
++EXTRA_MANS = 
+ FLOAT_H = @FLOAT_H@
+ FNMATCH_H = @FNMATCH_H@
+ GETADDRINFO_LIB = @GETADDRINFO_LIB@
+@@ -3820,7 +3815,7 @@ libexecdir = @libexecdir@
+ lispdir = @lispdir@
+ localedir = @localedir@
+ localstatedir = @localstatedir@
+-man1_MANS = @man1_MANS@
++man1_MANS = 
+ mandir = @mandir@
+ mkdir_p = @mkdir_p@
+ oldincludedir = @oldincludedir@
+@@ -3843,7 +3838,7 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ ALL_RECURSIVE_TARGETS = distcheck-hook check-root
+-SUBDIRS = po . gnulib-tests
++SUBDIRS = po
  changelog_etc = \
    ChangeLog-2005                      \
    ChangeLog-2006                      \
+@@ -5767,7 +5762,7 @@ all: $(BUILT_SOURCES)
+ .SUFFIXES: .1 .c .dvi .log .o .obj .pl .pl$(EXEEXT) .ps .sed .sh .sh$(EXEEXT) .sin .trs .x .xpl .xpl$(EXEEXT) .y
+ am--refresh: Makefile
+       @:
+-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/lib/local.mk $(srcdir)/lib/gnulib.mk $(top_srcdir)/src/local.mk $(srcdir)/src/cu-progs.mk $(top_srcdir)/src/single-binary.mk $(top_srcdir)/doc/local.mk $(top_srcdir)/man/local.mk $(top_srcdir)/tests/local.mk $(am__configure_deps)
++$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/lib/local.mk $(srcdir)/lib/gnulib.mk $(top_srcdir)/src/local.mk $(srcdir)/src/cu-progs.mk $(top_srcdir)/src/single-binary.mk $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+@@ -5790,7 +5785,7 @@ Makefile: $(srcdir)/Makefile.in $(top_bu
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+       esac;
+-$(top_srcdir)/lib/local.mk $(srcdir)/lib/gnulib.mk $(top_srcdir)/src/local.mk $(srcdir)/src/cu-progs.mk $(top_srcdir)/src/single-binary.mk $(top_srcdir)/doc/local.mk $(top_srcdir)/man/local.mk $(top_srcdir)/tests/local.mk:
++$(top_srcdir)/lib/local.mk $(srcdir)/lib/gnulib.mk $(top_srcdir)/src/local.mk $(srcdir)/src/cu-progs.mk $(top_srcdir)/src/single-binary.mk:
+ $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
index bee8a5656a7ecaec423f789ddb5689e5b71c20df..94187e4b6a30eb1db38a46933d397bb2a0d1a598 100644 (file)
@@ -1,6 +1,6 @@
 --- a/lib/pthread.in.h
 +++ b/lib/pthread.in.h
-@@ -232,6 +232,9 @@ pthread_mutex_unlock (pthread_mutex_t *m
+@@ -252,6 +252,9 @@ pthread_mutex_unlock (pthread_mutex_t *m
  
  /* Approximate spinlocks with mutexes.  */
  
@@ -9,4 +9,4 @@
 +#endif
  typedef pthread_mutex_t pthread_spinlock_t;
  
static inline int
_GL_PTHREAD_INLINE int
diff --git a/utils/coreutils/patches/010-fix-gets-removal.patch b/utils/coreutils/patches/010-fix-gets-removal.patch
deleted file mode 100644 (file)
index 2be5fc4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/lib/stdio.in.h b/lib/stdio.in.h
-index 9dc7c4a..9fdac77 100644
---- a/lib/stdio.in.h
-+++ b/lib/stdio.in.h
-@@ -711,10 +711,6 @@ _GL_CXXALIAS_SYS (gets, char *, (char *s));
- #  undef gets
- # endif
- _GL_CXXALIASWARN (gets);
--/* It is very rare that the developer ever has full control of stdin,
--   so any use of gets warrants an unconditional warning.  Assume it is
--   always declared, since it is required by C89.  */
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
- #endif
diff --git a/utils/cryptsetup/Makefile b/utils/cryptsetup/Makefile
new file mode 100644 (file)
index 0000000..330c4ec
--- /dev/null
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cryptsetup
+PKG_VERSION:=1.6.6
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0+ LGPL-2.1+
+PKG_LICENSE_FILES:=COPYING COPYING.LGPL
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/utils/cryptsetup/v1.6
+PKG_MD5SUM:=179c0781de59838a4e39f61b2df5ea48
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_LDFLAGS+=-Wl,-rpath-link=$(STAGING_DIR)/usr/lib
+
+define Package/cryptsetup/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Cryptsetup
+  DEPENDS:=+libblkid +libuuid +libpopt +lvm2 +libdevmapper +@KERNEL_DIRECT_IO
+  URL:=http://code.google.com/p/cryptsetup/
+endef
+
+define Package/cryptsetup
+$(call Package/cryptsetup/Default)
+  DEPENDS+=+libgcrypt
+  VARIANT:=gcrypt
+endef
+
+define Package/cryptsetup-openssl
+$(call Package/cryptsetup/Default)
+  TITLE+= (with openssl support)
+  DEPENDS+=+libopenssl
+  VARIANT:=openssl
+endef
+
+define Package/cryptsetup/Default/description
+       Cryptsetup-luks
+endef
+
+define Package/cryptsetup/description
+$(call Package/cryptsetup/Default/description)
+linked against libgcrypt
+endef
+
+
+define Package/cryptsetup-openssl/description
+$(call Package/cryptsetup/Default/description)
+linked against openssl
+endef
+
+ifeq ($(BUILD_VARIANT),openssl)
+CONFIGURE_ARGS+= \
+        --with-crypto_backend=openssl
+endif
+
+define Package/cryptsetup/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(CP) $(PKG_BUILD_DIR)/src/.libs/cryptsetup $(1)/usr/sbin
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_BUILD_DIR)/lib/.libs/libcryptsetup.so* $(1)/usr/lib
+endef
+
+Package/cryptsetup-openssl/install = $(Package/cryptsetup/install)
+
+$(eval $(call BuildPackage,cryptsetup))
+$(eval $(call BuildPackage,cryptsetup-openssl))
index 240e100e76bce3dfaa287b874615393db7e69f82..d5609323f50fd55c1052b6b6fcc870c8099f1388 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2014 OpenWrt.org
+# Copyright (C) 2007-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,18 +9,19 @@ include $(TOPDIR)/rules.mk
 
 # Make sure to also update the dbus-x package
 PKG_NAME:=dbus
-PKG_VERSION:=1.8.8
+PKG_VERSION:=1.9.6
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://dbus.freedesktop.org/releases/dbus/
-PKG_MD5SUM:=b9f4a18ee3faa1e07c04aa1d83239c43
+PKG_MD5SUM:=5c64a166c72c50765d9c9cfbc696fac9
 PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
 PKG_LICENSE:=AFL-2.1
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
 
+include $(INCLUDE_DIR)/host-build.mk
 include $(INCLUDE_DIR)/package.mk
 
 TARGET_LDFLAGS+= \
@@ -46,7 +47,7 @@ define Package/libdbus
 $(call Package/dbus/Default)
   CATEGORY:=Libraries
   TITLE+= (library)
-  DEPENDS:= +librt
+  DEPENDS:= +libpthread
 endef
 
 define Package/libdbus/Description
@@ -107,6 +108,29 @@ CONFIGURE_VARS+= \
        ac_cv_have_abstract_sockets="yes" \
        ac_cv_lib_expat_XML_ParserCreate_MM="yes" \
 
+HOST_CONFIGURE_ARGS+= \
+       --enable-shared \
+       --enable-static \
+       --disable-abstract-sockets \
+       --disable-ansi \
+       --disable-asserts \
+       --disable-console-owner-file \
+       --disable-docygen-docs \
+       --disable-compiler_coverage \
+       --disable-selinux \
+       --disable-tests \
+       --disable-verbose-mode \
+       --disable-xml-docs \
+       --with-dbus-user=root \
+       --with-dbus-daemondir="$(STAGIND_DIR_HOST)/bin" \
+       --with-system-socket="$(STAGING_DIR_HOST)/var/run/dbus/system_bus_socket" \
+       --with-system-pid-file="$(STAGING_DIR_HOST)/var/run/dbus.pid" \
+       --without-x \
+       --libexecdir="$(STAGING_DIR_HOST)/lib/dbus-1"
+
+HOST_CONFIGURE_VARS+= \
+       ac_cv_have_abstract_sockets="yes" \
+       ac_cv_lib_expat_XML_ParserCreate_MM="yes" \
 
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include
@@ -184,6 +208,7 @@ define Package/dbus-utils/install
                $(1)/usr/bin/
 endef
 
+$(eval $(call HostBuild))
 $(eval $(call BuildPackage,libdbus))
 $(eval $(call BuildPackage,dbus))
 $(eval $(call BuildPackage,dbus-utils))
diff --git a/utils/dbus/patches/100-fix-poll-select.patch b/utils/dbus/patches/100-fix-poll-select.patch
new file mode 100644 (file)
index 0000000..64f6525
--- /dev/null
@@ -0,0 +1,13 @@
+Index: dbus-1.9.4/tools/tool-common.c
+===================================================================
+--- dbus-1.9.4.orig/tools/tool-common.c
++++ dbus-1.9.4/tools/tool-common.c
+@@ -29,6 +29,8 @@
+ #include <string.h>
+ #include <time.h>
++#include <sys/select.h>
++
+ #ifdef DBUS_WIN
+ #include <windows.h>
+ #endif
index 12978ed4099c77f18694277563b94fb183b4fa2b..82ce06a67ada4831b584a4f711eba7e5b931e6f9 100644 (file)
@@ -8,18 +8,23 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=dump1090
-PKG_VERSION:=2014-08-22
+PKG_VERSION:=2014-11-09
 PKG_RELEASE:=$(PKG_SOURCE_VERSION)
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=git://github.com/MalcolmRobb/dump1090.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=a82df07c0c0a750d58610bf3c3ece77482f3a58c
+PKG_SOURCE_VERSION:=bff92c4ad772a0a8d433f788d39dae97e00e4dbe
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 
 PKG_LICENSE:=BSD-3c
 
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_DUMP1090_DUMP \
+       CONFIG_DUMP1090_WWW \
+       CONFIG_DUMP1090_VIEW
+
 include $(INCLUDE_DIR)/package.mk
 
 define Package/dump1090
@@ -47,14 +52,18 @@ define Package/dump1090/install
        $(INSTALL_DIR) $(1)/usr/bin
 
 ifneq ($(CONFIG_DUMP1090_DUMP),)
-       $(CP) $(PKG_BUILD_DIR)/dump1090 $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) files/dump1090.init $(1)/etc/init.d/dump1090
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) files/dump1090.config $(1)/etc/config/dump1090
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/dump1090 $(1)/usr/bin
 ifneq ($(CONFIG_DUMP1090_WWW),)
        $(INSTALL_DIR) $(1)/usr/share/dump1090
        $(CP) $(PKG_BUILD_DIR)/public_html/* $(1)/usr/share/dump1090
 endif
 endif
 ifneq ($(CONFIG_DUMP1090_VIEW),)
-       $(CP) $(PKG_BUILD_DIR)/view1090 $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/view1090 $(1)/usr/bin
 endif
 endef
 
diff --git a/utils/dump1090/files/dump1090.config b/utils/dump1090/files/dump1090.config
new file mode 100644 (file)
index 0000000..53d40ef
--- /dev/null
@@ -0,0 +1,39 @@
+config dump1090 main
+       option disabled '1'
+       option respawn '1'
+       option device_index ''
+       option gain ''
+       option enable_agc '0'
+       option freq ''
+       option ifile ''
+       option raw '0'
+       option net '1'
+       option modeac '0'
+       option net_beast '0'
+       option net_only '0'
+       option net_bind_address ''
+       option net_http_port '8080'
+       option net_ri_port ''
+       option net_ro_port ''
+       option net_sbs_port ''
+       option net_bi_port ''
+       option net_bo_port ''
+       option net_ro_size ''
+       option net_ro_rate ''
+       option net_heartbeat ''
+       option net_buffer ''
+       option lat ''
+       option lon ''
+       option fix '0'
+       option no_fix '0'
+       option no_crc_check '0'
+       option phase_enhance '0'
+       option agressive '0'
+       option mlat '0'
+       option stats '0'
+       option stats_every ''
+       option onlyaddr '0'
+       option metric '0'
+       option snip ''
+       option debug ''
+       option ppm ''
diff --git a/utils/dump1090/files/dump1090.init b/utils/dump1090/files/dump1090.init
new file mode 100644 (file)
index 0000000..bc0755f
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+
+START=90
+STOP=10
+USE_PROCD=1
+
+append_arg() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get val "$cfg" "$var"
+       [ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}"
+}
+
+append_bool() {
+       local cfg="$1"
+       local var="$2"
+       local opt="$3"
+       local def="$4"
+       local val
+
+       config_get_bool val "$cfg" "$var" "$def"
+       [ "$val" = 1 ] && procd_append_param command "$opt"
+}
+
+start_instance() {
+       local cfg="$1"
+       local aux
+
+       config_get_bool aux "$cfg" 'disabled' '0'
+       [ "$aux" = 1 ] && return 1
+
+       procd_open_instance
+
+       procd_set_param command /usr/bin/dump1090
+       procd_append_param command "--quiet"
+
+       append_arg "$cfg" device_index "--device-index"
+       append_arg "$cfg" gain "--gain"
+       append_bool "$cfg" enable_agc "--enable-agc"
+       append_arg "$cfg" freq "--freq"
+       append_arg "$cfg" ifile "--ifile"
+       append_bool "$cfg" raw "--raw"
+       append_bool "$cfg" net "--net"
+       append_bool "$cfg" modeac "--modeac"
+       append_bool "$cfg" net_beast "--net-beast"
+       append_bool "$cfg" net_only "--net-only"
+       append_arg "$cfg" net_bind_address "--net-bind-address"
+       append_arg "$cfg" net_http_port "--net-http-port"
+       append_arg "$cfg" net_ri_port "--net-ri-port"
+       append_arg "$cfg" net_ro_port "--net-ro-port"
+       append_arg "$cfg" net_sbs_port "--net-sbs-port"
+       append_arg "$cfg" net_bi_port "--net-bi-port"
+       append_arg "$cfg" net_bo_port "--net-bo-port"
+       append_arg "$cfg" net_ro_size "--net-ro-size"
+       append_arg "$cfg" net_ro_rate "--net-ro-rate"
+       append_arg "$cfg" net_heartbeat "--net-heartbeat"
+       append_arg "$cfg" net_buffer "--net-buffer"
+       append_arg "$cfg" lat "--lat"
+       append_arg "$cfg" lon "--lon"
+       append_bool "$cfg" fix "--fix"
+       append_bool "$cfg" no_fix "--no-fix"
+       append_bool "$cfg" no_crc_check "--no-crc-check"
+       append_bool "$cfg" phase_enhance "--phase-enhance"
+       append_bool "$cfg" agressive "--agressive"
+       append_bool "$cfg" mlat "--mlat"
+       append_bool "$cfg" stats "--stats"
+       append_arg "$cfg" stats_every "--stats-every"
+       append_bool "$cfg" onlyaddr "--onlyaddr"
+       append_bool "$cfg" metric "--metric"
+       append_arg "$cfg" snip "--snip"
+       append_arg "$cfg" debug "--debug"
+       append_arg "$cfg" ppm "--ppm"
+
+       config_get_bool aux "$cfg" 'respawn' '0'
+       [ "$aux" = 1 ] && procd_set_param respawn
+
+       procd_close_instance
+}
+
+service_triggers() { 
+       procd_add_reload_trigger "dump1090" 
+} 
+
+start_service() {
+       config_load dump1090
+       config_foreach start_instance dump1090
+}
diff --git a/utils/f2fs-tools/Config.in b/utils/f2fs-tools/Config.in
new file mode 100644 (file)
index 0000000..0c7ecab
--- /dev/null
@@ -0,0 +1,25 @@
+menu "Configuration"
+        depends on PACKAGE_f2fs-tools
+
+config F2FS_UTILS_f2fstat
+       bool "Install f2fstat utility"
+       default y
+
+config F2FS_UTILS_fibmap_f2fs
+       bool "Install fibmap.f2fs utility"
+       default y
+
+config F2FS_UTILS_fsck_f2fs
+       bool "Install fsck.f2fs utility"
+       default y
+
+config F2FS_UTILS_dump_f2fs
+       bool "Install dump.f2fs utility"
+       select F2FS_UTILS_fsck_f2fs
+       default y
+
+config F2FS_UTILS_mkfs_f2fs
+       bool "Install mkfs.f2fs utility"
+       default y
+
+endmenu
diff --git a/utils/f2fs-tools/Makefile b/utils/f2fs-tools/Makefile
new file mode 100644 (file)
index 0000000..62d5155
--- /dev/null
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=f2fs-tools
+PKG_VERSION:=1.4.0
+PKG_RELEASE:=1
+
+PKG_LICENSE:=GPLv2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git/snapshot/
+PKG_MD5SUM:=be9bfdddf3e5fd5e701a88d0b388dc26
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/f2fs-tools
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Filesystem
+  TITLE:=Tools for Flash-Friendly File System (F2FS)
+  DEPENDS:=+libuuid +libf2fs
+  URL:=http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs-tools.git
+  MENU:=1
+endef
+
+define Package/libf2fs
+  $(call Package/lxc/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for Flash-Friendly File System (F2FS) tools
+  DEPENDS:=
+endef
+
+define Package/f2fs-tools/config
+  source "$(SOURCE)/Config.in"
+endef
+
+define Package/libf2fs/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libf2fs.so* $(1)/usr/lib/
+endef
+
+define Package/f2fs-tools/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+
+ifeq ($(CONFIG_F2FS_UTILS_f2fstat),y)
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/f2fstat $(1)/usr/sbin
+endif
+
+ifeq ($(CONFIG_F2FS_UTILS_fibmap_f2fs),y)
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/fibmap.f2fs $(1)/usr/sbin
+endif
+
+ifeq ($(CONFIG_F2FS_UTILS_fsck_f2fs),y)
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/fsck.f2fs $(1)/usr/sbin
+endif
+
+ifeq ($(CONFIG_F2FS_UTILS_dump_f2fs),y)
+       ln -s /usr/sbin/fsck.f2fs $(1)/usr/sbin/dump.f2fs
+endif
+
+ifeq ($(CONFIG_F2FS_UTILS_mkfs_f2fs),y)
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/mkfs.f2fs $(1)/usr/sbin
+endif
+
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_BUILD_DIR)/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libf2fs.so* $(1)/usr/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libf2fs.a $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libf2fs))
+$(eval $(call BuildPackage,f2fs-tools))
diff --git a/utils/f2fs-tools/patches/001-compile.patch b/utils/f2fs-tools/patches/001-compile.patch
new file mode 100644 (file)
index 0000000..2ff6ee8
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -20,14 +20,9 @@ AC_DEFINE([F2FS_MINOR_VERSION], m4_bpats
+                               [\([0-9]*\).\([0-9]*\)\(\w\|\W\)*], [\2]),
+                               [Minor version for f2fs-tools])
+-AC_CHECK_FILE(.git,
+-      AC_DEFINE([F2FS_TOOLS_DATE],
+-              "m4_bpatsubst(f2fs_tools_gitdate,
+-              [\([0-9-]*\)\(\w\|\W\)*], [\1])",
+-              [f2fs-tools date based on Git commits]),
+-      AC_DEFINE([F2FS_TOOLS_DATE],
++AC_DEFINE([F2FS_TOOLS_DATE],
+               "f2fs_tools_date",
+-              [f2fs-tools date based on Source releases]))
++              [f2fs-tools date based on Source releases])
+ AC_CONFIG_SRCDIR([config.h.in])
+ AC_CONFIG_HEADER([config.h])
diff --git a/utils/gammu/Makefile b/utils/gammu/Makefile
new file mode 100644 (file)
index 0000000..2186e37
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gammu
+PKG_VERSION:=1.34.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=http://dl.cihar.com/gammu/releases/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_MD5SUM:=5bc2508389d9b291ca0b8d4f210d0012
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_MAINTAINER:=Vitaly Protsko <villy@sft.ru>
+PKG_LICENCE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/gammu
+       SECTION:=utils
+       CATEGORY:=Utilities
+       TITLE:=Cell phone/modem SMS and control tool
+       URL:=http://dl.cihar.com/gammu/releases/
+       DEPENDS:=@BUILD_NLS +libpthread +libcurl +glib2 $(ICONV_DEPENDS) $(INTL_DEPENDS)
+       DEPENDS+=+PACKAGE_python:python +PACKAGE_bluez-libs:bluez-libs
+       DEPENDS+=+PACKAGE_libmysqlclient:libmysqlclient +PACKAGE_unixodbc:unixodbc
+       DEPENDS+=+PACKAGE_libusb-1.0:libusb-1.0
+endef
+
+CONFIGURE_ARGS:= \
+       --prefix=/usr \
+       --cross-root="$(STAGING_DIR) $(TOOLCHAIN_DIR)" \
+       --enable-shared
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               $(TARGET_CONFIGURE_OPTS) \
+               LDSHARED="$(TARGET_CROSS)ld -shared" \
+               CFLAGS="$(TARGET_CFLAGS) $(FPIC)"
+endef
+
+define Build/Install
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               install
+endef
+
+define Build/InstallDev
+       mkdir -p $(1)/usr/include
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/include/gammu $(1)/usr/include/
+       mkdir -p $(1)/usr/lib
+       $(CP)    $(PKG_INSTALL_DIR)/usr/lib/lib{Gammu*,gsmsd*} $(1)/usr/lib/
+endef
+
+define Package/gammu/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gammu $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gammu-{smsd,smsd-inject,smsd-monitor} $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/lib{Gammu*,gsmsd*} $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_CONF) ./files/gammurc $(1)/etc/gammurc
+endef
+
+define Package/gammu/conffiles
+/etc/gammurc
+endef
+
+$(eval $(call BuildPackage,gammu))
diff --git a/utils/gammu/files/gammurc b/utils/gammu/files/gammurc
new file mode 100644 (file)
index 0000000..d547c04
--- /dev/null
@@ -0,0 +1,37 @@
+# Port         : "/dev/ttyS%" or "/dev/ircomm%" ("irda" connection), "/dev/ttyUSB%"
+#                (instead of "%" please put "0", "1", "2", etc.)
+# Model                : use only, when Gammu doesn't recognize your phone model.
+#                Put it here. Example values: "6110", "6150", "6210", "8210"
+# Connection   : type of connection. Use "fbus" or "mbus" or "dlr3" or
+#                "irda" (Infrared over sockets) or "infrared" (DirectIR)
+#                or "at19200" (AT commands on 19200, 8 bits, None parity,
+#                1 stop bit, no flow control) or "at115200" (AT commands on
+#                115200, 8 bits, None parity, 1 stop bit, no flow control)
+#                or "atblue" (AT over BlueTooth) or "dlr3blue" (FBUS
+#                over BlueTooth)
+# SynchronizeTime: If you want to set time from computer to phone during
+#                starting connection. Do not rather use this option when want
+#                to reset phone during connection (in some phones need to
+#                set time again after restart)
+# Logfile      : Use, when want to have logfile from communication.
+# Logformat    : What debug info and format should be used:
+#                "nothing" - no debug level, "text" - transmission dump in
+#                text format, "textall" - all possible info in text format,
+#                "errors"  - errors in text format, "binary" - transmission
+#                dump in binary format
+# Use_Locking  : under Unix/Linux use "yes", if want to lock used device
+#                to prevent using it by other applications
+# GammuLoc     : name of localisation file
+
+[gammu]
+
+port = /dev/ttyUSB0
+#model =
+connection = at
+#synchronizetime = yes
+#logfile =
+#logformat = errors
+use_locking = yes
+#gammuloc =
+
+# EOF /etc/gammurc
diff --git a/utils/gammu/patches/001-iconv-disabling-option.patch b/utils/gammu/patches/001-iconv-disabling-option.patch
new file mode 100644 (file)
index 0000000..91abfe7
--- /dev/null
@@ -0,0 +1,51 @@
+--- a/cmake/FindIconv.cmake
++++ b/cmake/FindIconv.cmake
+@@ -34,9 +34,9 @@ string(REGEX REPLACE "(.*)/include/?" "\
+ FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c HINTS "${ICONV_INCLUDE_BASE_DIR}/lib" PATHS /opt/local/lib)
+  
+-IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
++IF(NOT DISABLE_ICONV AND ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+    SET(ICONV_FOUND TRUE) 
+-ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
++ENDIF(NOT DISABLE_ICONV AND ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+ set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+--- a/configure
++++ b/configure
+@@ -31,6 +31,7 @@ Usage: ./configure [options]
+ --enable-backup     enable backup support
+ --enable-win32      enable mingw crosscomilation
+ --enable-protection enable compile time protections
++--disable-iconv     disable iconv support
+ --with-python=<path> path to Python interpreter
+ --without-gnapplet  disable installation of gnapplet
+ --without-completion disable installation of bash completion script
+@@ -57,6 +58,7 @@ CMAKE_PROTECTION=
+ CMAKE_PYTHON=
+ CMAKE_GNAP=
+ CMAKE_COMPLETE=
++CMAKE_ICONV=
+ # process command line
+ while [ "$#" -gt 0 ] ; do
+@@ -94,6 +96,12 @@ while [ "$#" -gt 0 ] ; do
+         --disable-protection)
+             CMAKE_PROTECTION="-DENABLE_PROTECTION=OFF"
+             ;;
++        --enable-iconv)
++            CMAKE_ICONV="-DDISABLE_ICONV=OFF"
++            ;;
++        --disable-iconv)
++            CMAKE_ICONV="-DDISABLE_ICONV=ON"
++            ;;
+         --enable-debug)
+             CMAKE_DEBUG="-DCMAKE_BUILD_TYPE=Debug"
+             ;;
+@@ -142,4 +150,4 @@ fi
+ cd "$BUILD_DIR"
+ # invoke cmake to do configuration
+-cmake $SOURCE_DIR $CMAKE_PREFIX $CMAKE_SHARED $CMAKE_DEBUG $CMAKE_BACKUP $CMAKE_CROSS $CMAKE_PROTECTION $CMAKE_PYTHON $CMAKE_GNAP $CMAKE_COMPLETE
++cmake $SOURCE_DIR $CMAKE_PREFIX $CMAKE_SHARED $CMAKE_DEBUG $CMAKE_BACKUP $CMAKE_CROSS $CMAKE_PROTECTION $CMAKE_PYTHON $CMAKE_GNAP $CMAKE_COMPLETE $CMAKE_ICONV
diff --git a/utils/gammu/patches/002-no-fstack-protector.patch b/utils/gammu/patches/002-no-fstack-protector.patch
new file mode 100644 (file)
index 0000000..ec0badf
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -537,8 +537,6 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMP
+         #    MACRO_TUNE_LINKER("-pie")
+         # These do not work on Windows right now
+         if (NOT WIN32)
+-            # Stack protector
+-            MACRO_TUNE_COMPILER("-fstack-protector")
+             # Mark code read only
+             MACRO_TUNE_LINKER("-Wl,-zrelro")
+         endif (NOT WIN32)
diff --git a/utils/gammu/patches/003-cmake-cross-toolchain.patch b/utils/gammu/patches/003-cmake-cross-toolchain.patch
new file mode 100644 (file)
index 0000000..cfacf11
--- /dev/null
@@ -0,0 +1,43 @@
+--- /dev/null
++++ b/cmake/Toolchain-cross.cmake
+@@ -0,0 +1,5 @@
++# search for programs in the build host directories
++SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
++# for libraries and headers in the target directories
++SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
++SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+--- a/configure
++++ b/configure
+@@ -25,6 +25,7 @@ Usage: ./configure [options]
+ --help|-h           shows this help
+ --prefix=<path>     installation prefix
++--cross-root=<path> cross-compilation prefix
+ --enable-shared     enables shared build
+ --enable-debug      enables debug build
+ --enable-tiger      enables Mac OS X 10.4 (Tiger) build
+@@ -50,6 +51,7 @@ SOURCE_DIR=`pwd`
+ # cmake parameters
+ CMAKE_PREFIX=
++CMAKE_ROOT=
+ CMAKE_SHARED=
+ CMAKE_DEBUG=
+ CMAKE_BACKUP=
+@@ -69,6 +71,10 @@ while [ "$#" -gt 0 ] ; do
+         --prefix=*)
+             CMAKE_PREFIX="-DCMAKE_INSTALL_PREFIX=${1##--prefix=}"
+             ;;
++        --cross-root=*)
++            CMAKE_ROOT="-DCMAKE_TOOLCHAIN_FILE=$SOURCE_DIR/cmake/Toolchain-cross.cmake"
++            echo "SET(CMAKE_FIND_ROOT_PATH ${1##--cross-root=})" >> $SOURCE_DIR/cmake/Toolchain-cross.cmake
++            ;;
+         --with-python=*)
+             CMAKE_PYTHON="-DBUILD_PYTHON=${1##--with-python=}"
+             ;;
+@@ -150,4 +156,4 @@ fi
+ cd "$BUILD_DIR"
+ # invoke cmake to do configuration
+-cmake $SOURCE_DIR $CMAKE_PREFIX $CMAKE_SHARED $CMAKE_DEBUG $CMAKE_BACKUP $CMAKE_CROSS $CMAKE_PROTECTION $CMAKE_PYTHON $CMAKE_GNAP $CMAKE_COMPLETE $CMAKE_ICONV
++cmake $SOURCE_DIR $CMAKE_ROOT $CMAKE_PREFIX $CMAKE_SHARED $CMAKE_DEBUG $CMAKE_BACKUP $CMAKE_CROSS $CMAKE_PROTECTION $CMAKE_PYTHON $CMAKE_GNAP $CMAKE_COMPLETE $CMAKE_ICONV
diff --git a/utils/gammu/patches/010-utils-shell-fix.patch b/utils/gammu/patches/010-utils-shell-fix.patch
new file mode 100644 (file)
index 0000000..d1b3ec3
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/utils/gammu-config
++++ b/utils/gammu-config
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ # Gammu configuration generator
+ # Copyright (C) 2003 - 2009 Michal Cihar <michal@cihar.com>
+ # vim: expandtab sw=4 ts=4 sts=4:
+--- a/utils/jadmaker
++++ b/utils/jadmaker
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ # JAD file generator
+ # Copyright © 2008 - 2009 Michal Čihař <michal@cihar.com>
+ # vim: expandtab sw=4 ts=4 sts=4:
index f1e5f84f706a5e72f7ff1ab8b1ca2d6c58fd314b..0bec41d8b793131f7aa212ed18234220e8985386 100644 (file)
@@ -17,7 +17,7 @@ PKG_SOURCE_URL:=ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/gnupg
 PKG_MD5SUM:=54db1be9588b11afbbdd8b82d4ea883a
 
 PKG_LICENSE:=GPL-3.0
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_INSTALL:=1
index 5bf77e69a4810da20609cb11f00f551522260193..42a4ef64fea5419b785d2f871faee909a97d1964 100644 (file)
@@ -8,15 +8,24 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=grep
-PKG_VERSION:=2.20
+PKG_VERSION:=2.21
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@GNU/grep
-PKG_MD5SUM:=2cbea44a4f1548aee20b9ff2d3076908
+PKG_MD5SUM:=43c48064d6409862b8a850db83c8038a
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Julen Landa Alustiza <julen@zokormazo.info>
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
 
 include $(INCLUDE_DIR)/package.mk
 
+TARGET_CFLAGS+=--std=gnu99
+
 define Package/grep
   SECTION:=utils
   CATEGORY:=Utilities
index 5f6ca650f0c0e3657cf00a40dba5d692018dc71d..90bfd24fd36ad49e7bde124d3ea47c06436a4bfa 100644 (file)
@@ -16,6 +16,12 @@ PKG_SOURCE_URL:=@SF/haserl
 PKG_MD5SUM:=a9decddb508944d56f71dd2f821e2ec5
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_CONFIG_DEPENDS:= \
+       CONFIG_HASERL_with_lua \
+       CONFIG_HASERL_shell_luac \
+       CONFIG_HASERL_shell_lua \
 
 include $(INCLUDE_DIR)/package.mk
 
index cf1493ab568c946d04583656d094dd640478c42e..aa222846630b6d69c3c9ae344adbcd2eab980ac5 100644 (file)
@@ -13,7 +13,7 @@ PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Lim Guo Wei <limguowei@gmail.com>
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=
+PKG_LICENSE_FILES:=
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
 PKG_SOURCE_URL:=@SF/$(PKG_NAME)
diff --git a/utils/hdparm/Makefile b/utils/hdparm/Makefile
new file mode 100644 (file)
index 0000000..8841213
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hdparm
+PKG_VERSION:=9.45
+PKG_RELEASE:=1
+PKG_USE_MIPS16:=0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=1c75d0751a44928b6c4bc81fb16d7fe8
+PKG_MAINTAINER:=Richard Kunze <richard.kunze@web.de>
+PKG_LICENSE:=BSD-Style Open Source License
+
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_CFLAGS+=-D_GNU_SOURCE
+
+define Package/hdparm
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=disc
+  TITLE:=Hard disk drive configuration utilitity
+  URL:=http://sourceforge.net/projects/hdparm/
+endef
+
+define Package/hdparm/description
+ get/set SATA/IDE device parameters
+endef
+
+define Package/hdparm/install
+       $(INSTALL_DIR) $(1)/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,hdparm))
diff --git a/utils/hdparm/patches/001-fix-includes.patch b/utils/hdparm/patches/001-fix-includes.patch
new file mode 100644 (file)
index 0000000..44343fb
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/hdparm.h
++++ b/hdparm.h
+@@ -2,6 +2,7 @@
+ //#undef __KERNEL_STRICT_NAMES
+ #include <linux/types.h>
++#include <sys/types.h>
+ #if !defined(__GNUC__) && !defined(__attribute__)
+ #define __attribute__(x)
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -12,6 +12,7 @@
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <errno.h>
++#include <limits.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
+ #include <linux/types.h>
diff --git a/utils/hub-ctrl/Makefile b/utils/hub-ctrl/Makefile
new file mode 100644 (file)
index 0000000..48cca4d
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hub-ctrl
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/codazoda/hub-ctrl.c.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=3eef0240fac90067d081551e9f73dfa741d94a9e
+PKG_LICENSE:=GPL-2.0+
+
+PKG_MAINTAINER:=Simon Peter <probono@puredarwin.org>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/hub-ctrl
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Control USB power on a port by port basis 
+  URL:=https://github.com/codazoda/hub-ctrl.c
+  DEPENDS:=+libusb-compat
+endef
+
+define Package/hub-ctrl/description
+  Control USB power on a port by port basis on some USB hubs.
+  This only works on USB hubs that have the hardware necessary 
+  to allow software controlled power switching.
+  Most hubs DO NOT include the hardware.
+endef
+
+define Build/Compile
+       $(TARGET_CC) $(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include \
+               -L$(STAGING_DIR)/usr/lib -lusb \
+               -o $(PKG_BUILD_DIR)/hub-ctrl $(PKG_BUILD_DIR)/hub-ctrl.c
+endef
+
+define Package/hub-ctrl/install
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/hub-ctrl $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,hub-ctrl))
diff --git a/utils/joe/Makefile b/utils/joe/Makefile
new file mode 100644 (file)
index 0000000..3019d34
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# changes by David Kuehling <dvdkhlng TA gmx TOD de>:
+#
+#  - include support for all emulation modes jmacs jpico etc.
+#  - see patches/002-builtinrc.patch
+#
+# changes by Vitaly Prosko <villy TA sft TOD ru>:
+#
+#  - updated for new build system rules
+#  - added static joerc config - no more defaults for native mode
+#  - got maintenance role
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=joe
+PKG_VERSION:=3.7
+PKG_RELEASE:=3
+
+PKG_SOURCE_URL:=@SF/joe-editor
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_MD5SUM:=66de1b073e869ba12abbfcde3885c577
+PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_MAINTAINER:=Vitaly Protsko <villy@sft.ru>
+PKG_LICENCE:=GPL-1.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/joe
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Editors
+  TITLE:=JOE - Joes own editor
+  URL:=http://sourceforge.net/projects/joe-editor/
+  DEPENDS:=+libncurses
+endef
+
+define Package/joe/description
+Joe is world-famous Wordstar like text editor, that also features
+Emacs and Pico emulation
+endef
+
+define Package/joe/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/joe $(1)/usr/bin/
+       for i in jmacs jstar rjoe jpico; do \
+         ln -sf joe $(1)/usr/bin/$$$$i; \
+       done
+       $(INSTALL_DIR) $(1)/etc/joe
+       $(INSTALL_CONF) ./files/joerc $(1)/etc/joe/joerc
+endef
+
+define Package/joe/conffiles
+/etc/joe/joerc
+endef
+
+$(eval $(call BuildPackage,joe))
diff --git a/utils/joe/files/joerc b/utils/joe/files/joerc
new file mode 100644 (file)
index 0000000..24def75
--- /dev/null
@@ -0,0 +1,621 @@
+
+-asis
+-nobackups
+-nonotice
+-noxon
+-notite
+-assume_color
+-assume_256color
+-guess_non_utf8
+-guess_crlf
+-guess_indent
+-menu_above
+-transpose
+-joe_state
+-restore
+-mouse
+-joexterm
+-search_prompting
+-lmsg \i%k%T%W%I%X %n %m%y%R %M %x
+-rmsg  %S Row %r Col %c %t  Ctrl-K H for help
+-highlight
+-istep 2
+
+ :include ftyperc
+
+:defmenu root
+mode,"overwrite",rtn   T Overtype %Zoverwrite%
+mode,"hex",rtn % % Hex edit mode
+mode,"autoindent",rtn  I Autoindent %Zautoindent%
+mode,"wordwrap",rtn    W Word wrap %Zwordwrap%
+mode,"tab",rtn D Tab width %Ztab%
+mode,"lmargin",rtn     L Left margin %Zlmargin%
+mode,"rmargin",rtn     R Right margin %Zrmargin%
+mode,"square",rtn      X Rectangle mode %Zsquare%
+mode,"indentc",rtn     % % Indent char %Zindentc%
+mode,"istep",rtn       % % Indent step %Zistep%
+mode,"highlight",rtn   H Highlighting %Zhighlight%
+mode,"crlf",rtn        Z CR-LF (MS-DOS) %Zcrlf%
+mode,"linums",rtn      N Line numbers %Zlinums%
+mode,"beep",rtn        B Beep %Zbeep%
+mode,"rdonly",rtn      O Read only %Zrdonly%
+ mode,"syntax",rtn     Y Syntax
+mode,"encoding",rtn    E Encoding
+mode,"asis",rtn        % % Meta chars as-is
+mode,"language",rtn    V Language
+mode,"picture",rtn     P picture %Zpicture%
+menu,"more-options",rtn          % % More options...
+
+:defmenu more-options
+menu,"^G",rtn  % % ^G options
+menu,"search",rtn      % % search options
+menu,"paragraph",rtn   % % paragraph options
+menu,"file",rtn        % % file options
+menu,"menu",rtn        % % menu options
+menu,"global",rtn      % % global options
+menu,"cursor",rtn      % % cursor options
+menu,"marking",rtn     % % marking options
+menu,"tab",rtn % % tab/indent options
+
+:defmenu menu
+mode,"menu_explorer",rtn       % % Menu explorer %Zmenu_explorer%
+mode,"menu_above",rtn  % % Menu position %Zmenu_above%
+mode,"menu_jump",rtn   % % Jump into menu %Zmenu_jump%
+mode,"transpose",rtn   % % Transpose menus %Ztranspose%
+
+:defmenu ^G
+mode,"single_quoted",rtn       % % ^G ignores '...' %Zsingle_quoted%
+mode,"no_double_quoted",rtn    % % ^G no ignore "..." %Zno_double_quoted%
+mode,"c_comment",rtn   % % ^G ignores /*...*/ %Zc_comment%
+mode,"cpp_comment",rtn % % ^G ignores //... %Zcpp_comment%
+mode,"pound_comment",rtn       % % ^G ignores #... %Zpound_comment%
+mode,"vhdl_comment",rtn        % % ^G ignores --... %Zvhdl_comment%
+mode,"semi_comment",rtn        % % ^G ignores ;... %Zsemi_comment%
+mode,"tex_comment",rtn % % ^G ignores %... %Ztex_comment%
+mode,"text_delimiters",rtn % % Text delimiters %Ztext_delimiters%
+
+:defmenu search
+mode,"icase",rtn       % % Case insensitivity %Zicase%
+mode,"wrap",rtn        % % Search wraps %Zwrap%
+mode,"search_prompting",rtn    % % Search prompting %Zsearch_prompting%
+mode,"csmode",rtn      % % Continued search %Zcsmode%
+
+:defmenu paragraph
+mode,"french",rtn      % % French spacing %Zfrench%
+mode,"flowed",rtn      % % Flowed text %Zflowed%
+mode,"cpara",rtn       % % Paragraph indent chars %Zcpara%
+
+:defmenu file
+mode,"restore",rtn     % % Restore cursor %Zrestore%
+mode,"guess_crlf",rtn  % % Auto detect CR-LF %Zguess_crlf%
+mode,"guess_indent",rtn        % % Guess indent %Zguess_indent%
+mode,"guess_non_utf8",rtn      % % Guess non-UTF-8 %Zguess_non_utf8%
+mode,"guess_utf8",rtn  % % Guess UTF-8 %Zguess_utf8%
+mode,"force",rtn       % % Force last NL %Zforce%
+mode,"nobackup",rtn    % % No backup %Znobackup%
+
+:defmenu global
+mode,"nolocks",rtn     % % Disable locks %Znolocks%
+mode,"nobackups",rtn   % % Disable backups %Znobackups%
+mode,"nomodcheck",rtn  % % Disable mtime check %Znomodcheck%
+mode,"nocurdir",rtn    % % Disable current dir %Znocurdir%
+mode,"exask",rtn       % % Exit ask %Zexask%
+mode,"nosta",rtn       % % Disable status line %Znosta%
+mode,"keepup",rtn      % % Fast status line %Zkeepup%
+mode,"break_hardlinks",rtn     % % Break hard links %Zbreak_hardlinks%
+mode,"break_links",rtn % % Break links %Zbreak_links%
+mode,"joe_state",rtn   % % Joe_state file %Zjoe_state%
+mode,"undo_keep",rtn   % % No. undo records %Zundo_keep%
+mode,"backpath",rtn    % % Path to backup files %Zbackpath%
+
+:defmenu cursor
+mode,"pg",rtn  % % No. PgUp/PgDn lines %Zpg%
+mode,"mid",rtn C Center on scroll %Zmid%
+mode,"floatmouse",rtn  % % Click past end %Zfloatmouse%
+mode,"rtbutton",rtn    % % Right button %Zrtbutton%
+
+:defmenu marking
+mode,"autoswap",rtn    % % Autoswap mode %Zautoswap%
+mode,"marking",rtn     % % Marking %Zmarking%
+mode,"lightoff",rtn    % % Auto unmask %Zlightoff%
+
+:defmenu tab
+mode,"smarthome",rtn   % % Smart home key %Zsmarthome%
+mode,"smartbacks",rtn  % % Smart backspace %Zsmartbacks%
+mode,"indentfirst",rtn % % To indent first %Zindentfirst%
+mode,"purify",rtn      % % Clean up indents %Zpurify%
+mode,"spaces",rtn      % % No tabs %Zspaces%
+
+{Basic
+\i   Help Screen    \|turn off with ^KH    more help with ESC . (^[.)              \i
+\i \i\|\uCURSOR\u           \|\uGO TO\u            \|\uBLOCK\u      \|\uDELETE\u   \|\uMISC\u         \|\uEXIT\u      \|\i \i
+\i \i\|^B left ^F right \|^U  prev. screen \|^KB begin  \|^D char. \|^KJ reformat \|^KX save  \|\i \i
+\i \i\|^P up   ^N down  \|^V  next screen  \|^KK end    \|^Y line  \|^KA center   \|^C  abort \|\i \i
+\i \i\|^Z previous word \|^A  beg. of line \|^KM move   \|^W >word \|^T  options  \|^KZ shell \|\i \i
+\i \i\|^X next word     \|^E  end of line  \|^KC copy   \|^O word< \|^R  refresh  \|\uFILE\u      \|\i \i
+\i \i\|\uSEARCH\u           \|^KU top of file  \|^KW file   \|^J >line \|\uSPELL\u        \|^KE edit  \|\i \i
+\i \i\|^KF find text    \|^KV end of file  \|^KY delete \|^_ undo  \|^[N word     \|^KR insert\|\i \i
+\i \i\|^L  find next    \|^KL to line No.  \|^K/ filter \|^^ redo  \|^[L file     \|^KD save  \|\i \i
+}
+
+{Windows
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i\|^KO Split the window in half           \|^KE Load file into window             \|\i \i
+\i \i\|^KG Make current window bigger         \|^KT Make current window smaller       \|\i \i
+\i \i\|^KN Go to the window below             \|^KP Go to the window above            \|\i \i
+\i \i\|^[V Switch to next buffer              \|^[U Switch to previous buffer         \|\i \i
+\i \i\|^C  Eliminate the current window       \|^KI Show all windows / Show one window\|\i \i
+}
+
+{Advanced
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i\|\uMACROS\u         \|\uMISC\u            \|\uSCROLL\u    \|\uSHELL\u       \|\uGOTO\u       \|\uI-SEARCH\u     \|\i \i
+\i \i\|^K[ 0-9 Record \|^K SPACE status \|^[W Up    \|^K' Window  \|^[B To ^KB \|^[R Backwards\|\i \i
+\i \i\|^K]     Stop   \|^K\\ Repeat      \|^[Z Down  \|^[! Command \|^[K To ^KK \|^[S Forwards \|\i \i
+\i \i\|^K 0-9  Play   \|\uINSERT\u          \|^K< Left  \|\uQUOTE\u       \|\uDELETE\u     \|\uBOOKMARKS\u    \|\i \i
+\i \i\|^K?     Query  \|^] split line   \|^K> Right \|^[' Ctrl-   \|^[Y yank   \|^[ 0-9 Goto  \|\i \i
+\i \i\|^[D     Dump   \|^SPACE ins space\|          \|^\\ Meta-    \|^[O line<  \|^[^[   Set   \|\i \i
+}
+
+{Programs
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i\|\uGOTO\u                 \|\uINDENT\u   \|\uCOMPILING\u          \uQUICK\u                       \|\i \i
+\i \i\|^G  Matching ( [ {   \|^K, less \|^[C Compile & parse ^G  find word under cursor \|\i \i
+\i \i\|^K- Previous place   \|^K. more \|^[G Grep & parse    ^[ENTER complete word      \|\i \i
+\i \i\|^K= Next place       \|\uFILE\u     \|^[= To next error   ^[Y paste deleted text     \|\i \i
+\i \i\|^K; Tags file search \|^K `     \|^[- To prev. error  ^[^Y cycle through deleted \|\i \i
+\i \i\|                     \| revert  \|^[ SP Jump to error                            \|\i \i
+}
+
+{Search
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \iSpecial search sequences:                                                    \|\i \i
+\i \i    \\^  \\$  matches beg./end of line      \\?     match any single char       \|\i \i
+\i \i    \\<  \\>  matches beg./end of word      \\*     match 0 or more chars       \|\i \i
+\i \i    \\c      matches balanced C expression \\\\     matches a \\                 \|\i \i
+\i \i    \\[..]   matches one of a set          \\n     matches a newline           \|\i \i
+\i \i    \\+      matches 0 or more of the character which follows the \\+          \|\i \i
+\i \iSpecial replace sequences:                                                   \|\i \i
+\i \i    \\&      replaced with text which matched search string                   \|\i \i
+\i \i    \\0 - 9  replaced with text which matched Nth \\*, \\?, \\c, \\+, or \\[..]    \|\i \i
+\i \i    \\\\      replaced with \\               \\n     replaced with newline       \|\i \i
+}
+
+{SearchOptions
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \iSearch options:                                                              \|\i \i
+\i \i   r Replace                                                                 \|\i \i
+\i \i   k Restrict search to highlighted block, which can be rectangular          \|\i \i
+\i \i   b Search backward instead of forward                                      \|\i \i
+\i \i   i Ignore case                                                             \|\i \i
+\i \i   a Search across all loaded files                                          \|\i \i
+\i \i   e Search across all files in Grep or Compile error list                   \|\i \i
+\i \i   w Wrap to beginning of file for this search                               \|\i \i
+\i \i   n Do not wrap to beginning of file for this search                        \|\i \i
+\i \i   nnn Perform exaclty nnn replacements                                      \|\i \i
+}
+
+{Math
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i \uCOMMANDS\u (hit ESC m for math)  \uFUNCTIONS\u                                    \|\i \i
+\i \i     hex hex display mode       sin cos tab asin acos atan                   \|\i \i
+\i \i     dec decimal mode           sinh cosh tanh asinh acosh atanh             \|\i \i
+\i \i     ins type result into file  sqrt cbrt exp ln log                         \|\i \i
+\i \i    eval evaluate block         int floor ceil abs erg ergc                  \|\i \i
+\i \i    0xff enter number in hex    joe(..macro..) - runs an editor macro        \|\i \i
+\i \i    3e-4 floating point decimal \uBLOCK\u                                        \|\i \i
+\i \i    a=10 assign a variable      sum cnt  Sum, count                          \|\i \i
+\i \i 2+3:ins multiple commands      avg dev  Average, std. deviation             \|\i \i
+\i \i    e pi constants              \uOPERATORS\u                                    \|\i \i
+\i \i     ans previous result        ! ^  * / %  + -  < <= > >= == !=  &&  ||  ? :\|\i \i
+}
+
+{Names
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i Hit TAB at file name prompts to generate menu of file names                 \|\i \i
+\i \i Or use up/down keys to access history of previously entered names           \|\i \i
+\i \i Special file names:                                                         \|\i \i
+\i \i      !command                 Pipe in/out of a shell command                \|\i \i
+\i \i      >>filename               Append to a file                              \|\i \i
+\i \i      -                        Read/Write to/from standard I/O               \|\i \i
+\i \i      filename,START,SIZE      Read/Write a part of a file/device            \|\i \i
+\i \i          Give START/SIZE in decimal (255), octal (0377) or hex (0xFF)       \|\i \i
+}
+
+{Joe
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,    next screen ^[.     \i
+\i \i Send bug reports to: http://sourceforge.net/projects/joe-editor \|\i \i
+\i \i \|\i \i
+\i \i  default joerc file is here /etc/joe/joerc \|\i \i
+\i \i  default syntax and i18n files are here /usr/share/joe \|\i \i
+\i \i  additional documentation can be found here /usr/share/doc/joe \|\i \i
+}
+
+{CharTable
+\i   Help Screen    \|turn off with ^KH    prev. screen ^[,                        \i
+\i \i\| Dec  \u 0123 4567  8901 2345    0123 4567  8901 2345 \u  Dec \|\i \i
+\i \i\|     |                                              |     \|\i \i
+\i \i\|   0 | \u@ABC\u \uDEFG\u  \uHIJK\u \uLMNO\u    \i\u@ABC\u\i \i\uDEFG\u\i  \i\uHIJK\u\i \i\uLMNO\u\i | 128 \|\i \i
+\i \i\|  16 | \uPQRS\u \uTUVW\u  \uXYZ[\u \u\\]^_\u    \i\uPQRS\u\i \i\uTUVW\u\i  \i\uXYZ[\u\i \i\u\\]^_\u\i | 144 \|\i \i
+\i \i\|  32 |  !"# $%&'  ()*+ ,-./     ¡¢£ ¤¥¦§  ¨©ª« ¬­®¯ | 160 \|\i \i
+\i \i\|  48 | 0123 4567  89:; <=>?    °±²³ ´µ¶·  ¸¹º» ¼½¾¿ | 176 \|\i \i
+\i \i\|  64 | @ABC DEFG  HIJK LMNO    ÀÁÂàÄÅÆÇ  ÈÉÊË ÌÍÎÏ | 192 \|\i \i
+\i \i\|  80 | PQRS TUVW  XYZ[ \\]^_    ÐÑÒÓ ÔÕÖ×  ØÙÚÛ ÜÝÞß | 208 \|\i \i
+\i \i\|  96 | `abc defg  hijk lmno    àáâã äåæç  èéêë ìíîï | 224 \|\i \i
+\i \i\| 112 | pqrs tuvw  xyz{ |}~\7f    ðñòó ôõö÷  øùúû üýþÿ | 240 \|\i \i
+}
+
+:windows               Bindings common to all windows
+type           ^@ TO ÿ
+abort          ^C
+abort          ^K Q
+abort          ^K ^Q
+abort          ^K q
+arg            ^K \
+explode                ^K I
+explode                ^K ^I
+explode                ^K i
+help           ^K H
+help           ^K ^H
+help           ^K h
+hnext          ^[ .
+hprev          ^[ ,
+math           ^[ m
+math           ^[ M
+msg            ^[ h
+msg            ^[ H
+msg            ^[ ^H
+nextw          ^K N
+nextw          ^K ^N
+nextw          ^K n
+pgdn           .kN
+pgdn           ^V
+pgdn           ^[ [ 6 ~
+pgup           .kP
+pgup           ^U
+pgup           ^[ [ 5 ~
+play           ^K 0 TO 9
+prevw          ^K P
+prevw          ^K ^P
+prevw          ^K p
+query          ^K ?
+record         ^K [
+retype         ^R
+rtn            ^M
+shell          ^K Z
+shell          ^K ^Z
+shell          ^K z
+stop           ^K ]
+
+defmdown       MDOWN
+defmup         MUP
+defmdrag       MDRAG
+defm2down      M2DOWN
+defm2up                M2UP
+defm2drag      M2DRAG
+defm3down      M3DOWN
+defm3up                M3UP
+defm3drag      M3DRAG
+
+xtmouse                ^[ [ M
+
+if,"char==65",then,"it's an A",else,"it's not an a",endif      ^[ q
+
+:main                  Text editing window
+:inherit windows
+
+:def ispellfile filt,"cat >ispell.tmp;ispell ispell.tmp </dev/tty >/dev/tty;cat ispell.tmp;/bin/rm ispell.tmp",rtn,retype
+:def ispellword psh,nextword,markk,prevword,markb,filt,"cat >ispell.tmp;ispell ispell.tmp </dev/tty >/dev/tty;tr -d <ispell.tmp '\\012';/bin/rm ispell.tmp",rtn,retype,nextword
+
+:def aspellfile filt,"SPLTMP=ispell.tmp;cat >$SPLTMP;aspell --lang=",language,".",charset," -x -c $SPLTMP </dev/tty >/dev/tty;cat $SPLTMP;/bin/rm $SPLTMP",rtn,retype
+:def aspellword psh,nextword,markk,prevword,markb,filt,"SPLTMP=ispell.tmp;cat >$SPLTMP;aspell --lang=",language,".",charset," -x -c $SPLTMP </dev/tty >/dev/tty;tr -d <$SPLTMP '\\012';/bin/rm $SPLTMP",rtn,retype,nextword
+
+aspellfile     ^[ l
+aspellword     ^[ n
+
+:def compile mwind!,mfit!,querysave,query,scratch,"* Build Log *",rtn,bof,markb,eof," ",markk,blkdel,build
+
+:def grep_find mwind!,mfit!,scratch,"* Grep Log *",rtn,bof,markb,eof," ",markk,blkdel,grep
+
+:def man scratch,"* Man Page *",rtn,bof,markb,eof," ",markk,blkdel," ",ltarw,run,"man -P cat -S 2:3 "
+
+paste                  ^[ ] 5 2 ;
+
+insc                   ^[ [ 2 ~
+insc                   ^[ [ L
+
+delch                  ^[ [ 3 ~
+
+pgup                   ^[ [ I
+
+pgdn                   ^[ [ G
+
+home                   ^[ [ 1 ~
+home                   ^[ [ H
+home                   ^[ O H
+home                   ^[ [ 7 ~
+
+eol                    ^[ [ 4 ~
+eol                    ^[ [ F
+eol                    ^[ O F
+eol                    ^[ [ 8 ~
+
+rtarw,ltarw,begin_marking,rtarw,toggle_marking ^[ [ 1 ; 5 C
+rtarw,ltarw,begin_marking,rtarw,toggle_marking ^[ [ 5 C
+rtarw,ltarw,begin_marking,rtarw,toggle_marking ^[ O c
+
+ltarw,rtarw,begin_marking,ltarw,toggle_marking ^[ [ 1 ; 5 D
+ltarw,rtarw,begin_marking,ltarw,toggle_marking ^[ [ 5 D
+ltarw,rtarw,begin_marking,ltarw,toggle_marking ^[ O d
+
+uparw,dnarw,begin_marking,uparw,toggle_marking ^[ [ 1 ; 5 A
+uparw,dnarw,begin_marking,uparw,toggle_marking ^[ [ 5 A
+uparw,dnarw,begin_marking,uparw,toggle_marking ^[ O a
+
+dnarw,uparw,begin_marking,dnarw,toggle_marking ^[ [ 1 ; 5 B
+dnarw,uparw,begin_marking,dnarw,toggle_marking ^[ [ 5 B
+dnarw,uparw,begin_marking,dnarw,toggle_marking ^[ O b
+
+blkdel,nmark   ^[ [ 3 ; 5 -
+blkdel,nmark   ^[ [ 3 ; 5 ~
+
+yank           ^[ [ 2 ; 5 -
+yank           ^[ [ 2 ; 5 ~
+
+delbol         ^[ o
+delbol         ^[ ^O
+dnslide                ^[ z
+dnslide                ^[ Z
+dnslide                ^[ ^Z
+dnslide,dnslide,dnslide,dnslide                MWDOWN
+compile                ^[ c
+compile                ^[ C
+compile                ^[ ^C
+grep_find      ^[ g
+grep_find      ^[ G
+grep_find      ^[ ^G
+execmd         ^[ x
+execmd         ^[ X
+execmd         ^[ ^X
+finish         ^[ ^I
+finish         ^[ ^M
+mwind,mfit,jump,bol            ^[ SP
+isrch          ^[ s
+isrch          ^[ S
+isrch          ^[ ^S
+notmod         ^[ ~
+mwind,mfit,prevw,nxterr                ^[ =
+parserr                ^[ e
+parserr                ^[ E
+parserr                ^[ ^E
+mwind,mfit,prevw,prverr                ^[ -
+rsrch          ^[ r
+rsrch          ^[ R
+rsrch          ^[ ^R
+run            ^[ !
+tomarkb                ^[ b
+tomarkb                ^[ ^B
+tomarkk                ^[ k
+tomarkk                ^[ ^K
+tomarkk                ^[ K
+txt            ^[ i
+txt            ^[ I
+upslide                ^[ w
+upslide                ^[ ^W
+upslide                ^[ W
+upslide,upslide,upslide,upslide                MWUP
+yank           ^[ y
+yankpop                ^[ ^Y
+yank           ^[ Y
+
+insc           ^@
+
+nbuf           ^[ v
+nbuf           ^[ V
+nbuf           ^[ ^V
+pbuf           ^[ u
+pbuf           ^[ U
+pbuf           ^[ ^U
+
+quote8         ^\
+quote          ^[ '
+quote          ^Q
+
+backs          ^?
+backs          ^H
+backw          ^O
+bknd           ^K '
+blkcpy         ^K C
+blkcpy         ^K ^C
+blkcpy         ^K c
+blkdel         ^K Y
+blkdel         ^K ^Y
+blkdel         ^K y
+blkmove                ^K M
+blkmove                ^K ^M
+blkmove                ^K m
+blksave                ^K W
+blksave                ^K ^W
+blksave                ^K w
+bof            ^K U
+bof            ^K ^U
+bof            ^K u
+home           .kh
+home           ^A
+center         ^K A
+center         ^K ^A
+center         ^K a
+crawll         ^K <
+crawlr         ^K >
+delch          .kD
+delch          ^D
+deleol         ^J
+dellin         ^Y
+delw           ^W
+dnarw          .kd
+dnarw          ^N
+dnarw          ^[ O B
+dnarw          ^[ [ B
+edit           ^K E
+edit           ^K ^E
+edit           ^K e
+eof            ^K V
+eof            ^K ^V
+eof            ^K v
+eol            .kH
+eol            .@7
+eol            ^E
+exsave         ^K X
+exsave         ^K ^X
+exsave         ^K x
+ffirst         ^K F
+ffirst         ^K ^F
+ffirst         ^K f
+filt           ^K /
+fnext          ^L
+fmtblk         ^K J
+fmtblk         ^K ^J
+fmtblk         ^K j
+gomark         ^[ 0 TO 9
+groww          ^K G
+groww          ^K ^G
+groww          ^K g
+insc           .kI
+insf           ^K R
+insf           ^K ^R
+insf           ^K r
+lindent                ^K ,
+line           ^K L
+line           ^K ^L
+line           ^K l
+ltarw          .kl
+ltarw          ^B
+ltarw          ^[ O D
+ltarw          ^[ [ D
+macros         ^[ d
+macros         ^[ ^D
+markb          ^K B
+markb          ^K ^B
+markb          ^K b
+markk          ^K K
+markk          ^K ^K
+markk          ^K k
+menu,"root",rtn        ^T
+nextpos                ^K =
+nextword       ^X
+open           ^]
+prevpos                ^K -
+prevword       ^Z
+reload         ^K `
+redo           ^^
+rindent                ^K .
+rtarw          .kr
+rtarw          ^F
+rtarw          ^[ O C
+rtarw          ^[ [ C
+run            ^K !
+save           ^K D
+save           ^K S
+save           ^K ^D
+save           ^K ^S
+save           ^K d
+save           ^K s
+setmark                ^[ ^[
+shrinkw                ^K T
+shrinkw                ^K ^T
+shrinkw                ^K t
+splitw         ^K O
+splitw         ^K ^O
+splitw         ^K o
+stat           ^K SP
+tag            ^K ;
+tomatch                ^G
+undo           ^_
+uparw          .ku
+uparw          ^P
+uparw          ^[ O A
+uparw          ^[ [ A
+
+:prompt                        Prompt windows
+:inherit main
+if,"byte>size",then,complete,complete,else,delch,endif ^D
+complete       ^I
+dnarw,eol      .kd
+dnarw,eol      ^N
+dnarw,eol      ^[ O B
+dnarw,eol      ^[ [ B
+uparw,eol      .ku
+uparw,eol      ^P
+uparw,eol      ^[ O A
+uparw,eol      ^[ [ A
+
+:menu                  Selection menus
+:inherit windows
+
+pgupmenu       ^[ [ I
+
+pgdnmenu       ^[ [ G
+
+bolmenu                ^[ [ 1 ~
+bolmenu                ^[ [ H
+bolmenu                ^[ O H
+bolmenu                ^[ [ 7 ~
+
+eolmenu                ^[ [ 4 ~
+eolmenu                ^[ [ F
+eolmenu                ^[ O F
+eolmenu                ^[ [ 8 ~
+
+abort          ^[ ^[
+backsmenu      ^?
+backsmenu      ^H
+bofmenu                ^K U
+bofmenu                ^K ^U
+bofmenu                ^K u
+bolmenu                .kh
+bolmenu                ^A
+dnarwmenu      .kd
+dnarwmenu      ^N
+dnarwmenu      ^[ [ B
+dnarwmenu      ^[ O B
+dnarwmenu      MWDOWN
+eofmenu                ^K V
+eofmenu                ^K ^V
+eofmenu                ^K v
+eolmenu                .kH
+eolmenu                ^E
+ltarwmenu      .kl
+ltarwmenu      ^B
+ltarwmenu      ^[ [ D
+ltarwmenu      ^[ O D
+pgdnmenu       .kN
+pgdnmenu       ^V
+pgdnmenu       ^[ [ 6 ~
+pgupmenu       .kP
+pgupmenu       ^U
+pgupmenu       ^[ [ 5 ~
+rtarwmenu      .kr
+rtarwmenu      ^F
+rtarwmenu      ^[ [ C
+rtarwmenu      ^[ O C
+rtn            SP
+rtn            ^I
+rtn            ^K H
+rtn            ^K h
+rtn            ^K ^H
+tabmenu                ^I
+uparwmenu      .ku
+uparwmenu      ^P
+uparwmenu      ^[ [ A
+uparwmenu      ^[ O A
+uparwmenu      MWUP
+defm2down      M2DOWN
+
+:query                 Single-key query window
+:inherit windows
+
+:querya                        Single-key query window for quoting
+type           ^@ TO ÿ
+
+:querysr               Search & replace query window
+type           ^@ TO ÿ
diff --git a/utils/joe/patches/001-mathaway.patch b/utils/joe/patches/001-mathaway.patch
new file mode 100644 (file)
index 0000000..99fc930
--- /dev/null
@@ -0,0 +1,58 @@
+--- a/umath.c
++++ b/umath.c
+@@ -378,7 +378,6 @@ double m_cos(double n) { return cos(n); 
+ double m_tan(double n) { return tan(n); }
+ double m_exp(double n) { return exp(n); }
+ double m_sqrt(double n) { return sqrt(n); }
+-double m_cbrt(double n) { return cbrt(n); }
+ double m_log(double n) { return log(n); }
+ double m_log10(double n) { return log10(n); }
+ double m_asin(double n) { return asin(n); }
+@@ -387,19 +386,10 @@ double m_atan(double n) { return atan(n)
+ double m_sinh(double n) { return sinh(n); }
+ double m_cosh(double n) { return cosh(n); }
+ double m_tanh(double n) { return tanh(n); }
+-double m_asinh(double n) { return asinh(n); }
+-double m_acosh(double n) { return acosh(n); }
+-double m_atanh(double n) { return atanh(n); }
+ double m_int(double n) { return (int)(n); }
+ double m_floor(double n) { return floor(n); }
+ double m_ceil(double n) { return ceil(n); }
+ double m_fabs(double n) { return fabs(n); }
+-double m_erf(double n) { return erf(n); }
+-double m_erfc(double n) { return erfc(n); }
+-double m_j0(double n) { return j0(n); }
+-double m_j1(double n) { return j1(n); }
+-double m_y0(double n) { return y0(n); }
+-double m_y1(double n) { return y1(n); }
+ double calc(BW *bw, unsigned char *s)
+ {
+@@ -414,7 +404,6 @@ double calc(BW *bw, unsigned char *s)
+               v = get(USTR "tan"); v->func = m_tan;
+               v = get(USTR "exp"); v->func = m_exp;
+               v = get(USTR "sqrt"); v->func = m_sqrt;
+-              v = get(USTR "cbrt"); v->func = m_cbrt;
+               v = get(USTR "ln"); v->func = m_log;
+               v = get(USTR "log"); v->func = m_log10;
+               v = get(USTR "asin"); v->func = m_asin;
+@@ -425,19 +414,10 @@ double calc(BW *bw, unsigned char *s)
+               v = get(USTR "sinh"); v->func = m_sinh;
+               v = get(USTR "cosh"); v->func = m_cosh;
+               v = get(USTR "tanh"); v->func = m_tanh;
+-              v = get(USTR "asinh"); v->func = m_asinh;
+-              v = get(USTR "acosh"); v->func = m_acosh;
+-              v = get(USTR "atanh"); v->func = m_atanh;
+               v = get(USTR "int"); v->func = m_int;
+               v = get(USTR "floor"); v->func = m_floor;
+               v = get(USTR "ceil"); v->func = m_ceil;
+               v = get(USTR "abs"); v->func = m_fabs;
+-              v = get(USTR "erf"); v->func = m_erf;
+-              v = get(USTR "erfc"); v->func = m_erfc;
+-              v = get(USTR "j0"); v->func = m_j0;
+-              v = get(USTR "j1"); v->func = m_j1;
+-              v = get(USTR "y0"); v->func = m_y0;
+-              v = get(USTR "y1"); v->func = m_y1;
+       }
+       v = get(USTR "top");
diff --git a/utils/less/Makefile b/utils/less/Makefile
new file mode 100644 (file)
index 0000000..f3893e9
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2010-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=less
+PKG_VERSION:=458
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.greenwoodsoftware.com/less
+PKG_MD5SUM:=935b38aa2e73c888c210dedf8fd94f49
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Julen Landa Alustiza <julen@zokormazo.info>
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/less/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Pager program similar to more
+  URL:=http://www.greenwoodsoftware.com/less/
+endef
+
+define Package/less/Default/description
+  Full version of GNU less utility
+endef
+
+define Package/less
+  $(call Package/less/Default)
+  DEPENDS:=+libncurses
+  VARIANT:=narrow
+endef
+
+define Package/less/description
+  $(call Package/less/Default/description)
+endef
+
+define Package/less-wide
+  $(call Package/less/Default)
+  TITLE+= (Unicode)
+  DEPENDS:=+libncursesw
+  VARIANT:=wide
+endef
+
+define Package/less-wide/description
+  $(call Package/less/Default/description)
+  This package contains the Unicode enabled version of less.
+endef
+
+ifeq ($(BUILD_VARIANT),narrow)
+       CONFIGURE_VARS += \
+               ac_cv_lib_ncursesw_initscr=no           
+endif
+
+ifeq ($(BUILD_VARIANT),wide)
+       CONFIGURE_VARS += \
+               ac_cv_lib_ncursesw_initscr=yes
+endif
+
+define Package/less/install
+       $(INSTALL_DIR) $(1)/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/less $(1)/bin/less
+endef
+
+define Package/less/postinst
+#!/bin/sh
+[ -L "$${IPKG_INSTROOT}/usr/bin/less" ] && rm -f "$${IPKG_INSTROOT}/usr/bin/less"
+exit 0
+endef
+
+define Package/less/postrm
+#!/bin/sh
+/bin/busybox less -h 2>&1 | grep -q BusyBox && ln -sf ../../bin/busybox /usr/bin/less
+exit 0
+endef
+
+Package/less-wide/install = $(Package/less/install)
+Package/less-wide/postinst = $(Package/less/postinst)
+Package/less-wide/postrm = $(Package/less/postrm)
+
+$(eval $(call BuildPackage,less))
+$(eval $(call BuildPackage,less-wide))
index f609f64e79d9d19daa262ca435aedd0b5ed9526a..75b2c547945214ebbcf11d9700700fed663fb02c 100644 (file)
@@ -17,6 +17,8 @@ PKG_SOURCE_URL:=http://ftp2.de.debian.org/debian/pool/main/l/lsof
 PKG_MD5SUM:=23420509564a897b76055f9d84d19068
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)+dfsg.orig
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
+PKG_LICENSE:=Unique
+PKG_LICENSE_FILES:=00README
 
 include $(INCLUDE_DIR)/package.mk
 
diff --git a/utils/luci-app-lxc/Makefile b/utils/luci-app-lxc/Makefile
new file mode 100644 (file)
index 0000000..f08d81e
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=luci-app-lxc
+PKG_RELEASE:=20141012
+
+PKG_LICENSE:=Apache-2.0
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/luci-app-lxc
+  SECTION:=luci
+  CATEGORY:=LuCI
+  SUBMENU:=3. Applications
+  TITLE:=LXC management Web UI
+  DEPENDS:=+luci-mod-admin-full +lxc +lxc-create +liblxc +rpcd-mod-lxc
+  MAINTAINER:=Petar Koretic <petar.koretic@sartura.hr>
+endef
+
+define Package/luci-app-lxc/description
+ This package will install LXC management Web UI.
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/luci-app-lxc/install
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/
+       $(INSTALL_BIN) \
+               ./files/controller/lxc.lua \
+               $(1)/usr/lib/lua/luci/controller/
+
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/
+       $(INSTALL_DATA) \
+               ./files/view/lxc.htm \
+               $(1)/usr/lib/lua/luci/view/
+
+       $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/
+       $(INSTALL_BIN) \
+               ./files/model/cbi/lxc.lua \
+               $(1)/usr/lib/lua/luci/model/cbi/
+
+       $(INSTALL_DIR) $(1)/etc/config/
+       $(INSTALL_DATA) \
+               ./files/lxc.config \
+               $(1)/etc/config/lxc
+
+       $(INSTALL_DIR) $(1)/www
+       $(CP) -R \
+               ./files/www/* \
+               $(1)/www
+endef
+
+$(eval $(call BuildPackage,luci-app-lxc))
diff --git a/utils/luci-app-lxc/files/controller/lxc.lua b/utils/luci-app-lxc/files/controller/lxc.lua
new file mode 100644 (file)
index 0000000..f3f5d07
--- /dev/null
@@ -0,0 +1,125 @@
+--[[
+
+LuCI LXC module
+
+Copyright (C) 2014, Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Author: Petar Koretic <petar.koretic@sartura.hr>
+
+]]--
+
+module("luci.controller.lxc", package.seeall)
+
+require "ubus"
+local conn = ubus.connect()
+if not conn then
+    error("Failed to connect to ubus")
+end
+
+
+function fork_exec(command)
+       local pid = nixio.fork()
+       if pid > 0 then
+               return
+       elseif pid == 0 then
+               -- change to root dir
+               nixio.chdir("/")
+
+               -- patch stdin, out, err to /dev/null
+               local null = nixio.open("/dev/null", "w+")
+               if null then
+                       nixio.dup(null, nixio.stderr)
+                       nixio.dup(null, nixio.stdout)
+                       nixio.dup(null, nixio.stdin)
+                       if null:fileno() > 2 then
+                               null:close()
+                       end
+               end
+
+               -- replace with target command
+               nixio.exec("/bin/sh", "-c", command)
+       end
+end
+
+function index()
+       page = node("admin", "services", "lxc")
+       page.target = cbi("lxc")
+       page.title = _("LXC Containers")
+       page.order = 70
+
+       page = entry({"admin", "services", "lxc_create"}, call("lxc_create"), nil)
+       page.leaf = true
+
+       page = entry({"admin", "services", "lxc_action"}, call("lxc_action"), nil)
+       page.leaf = true
+
+       page = entry({"admin", "services", "lxc_configuration_get"}, call("lxc_configuration_get"), nil)
+       page.leaf = true
+
+       page = entry({"admin", "services", "lxc_configuration_set"}, call("lxc_configuration_set"), nil)
+       page.leaf = true
+
+end
+
+function lxc_create(lxc_name, lxc_template)
+       luci.http.prepare_content("text/plain")
+
+       local uci = require("uci").cursor()
+
+       local url = uci:get("lxc", "lxc", "url")
+
+       if not pcall(dofile, "/etc/openwrt_release") then
+               return luci.http.write("1")
+       end
+
+       local target = _G.DISTRIB_TARGET:match('([^/]+)')
+
+       local data = conn:call("lxc", "create", { name = lxc_name, template = "download", args = { "--server", url,  "--no-validate", "--dist", lxc_template, "--release", "bb", "--arch", target } } )
+
+       luci.http.write(data)
+end
+
+function lxc_action(lxc_action, lxc_name)
+       luci.http.prepare_content("application/json")
+
+       local data, ec = conn:call("lxc", lxc_action, lxc_name and { name = lxc_name} or {} )
+
+       luci.http.write_json(ec and {} or data)
+end
+
+function lxc_configuration_get(lxc_name)
+       luci.http.prepare_content("text/plain")
+
+       local f = io.open("/lxc/" .. lxc_name .. "/config", "r")
+       local content = f:read("*all")
+       f:close()
+
+       luci.http.write(content)
+end
+
+function lxc_configuration_set(lxc_name)
+       luci.http.prepare_content("text/plain")
+
+       local lxc_configuration = luci.http.formvalue("lxc_configuration")
+
+       if lxc_configuration == nil then
+               return luci.http.write("1")
+       end
+
+       local f, err = io.open("/lxc/" .. lxc_name .. "/config","w+")
+       if not f then
+               return luci.http.write("2")
+       end
+
+       f:write(lxc_configuration)
+       f:close()
+
+       luci.http.write("0")
+end
+
diff --git a/utils/luci-app-lxc/files/lxc.config b/utils/luci-app-lxc/files/lxc.config
new file mode 100644 (file)
index 0000000..5572c73
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# lxc uci configuration
+#
+
+config lxc 'lxc'
+       option url 'virtualwrt.org/containers/'
diff --git a/utils/luci-app-lxc/files/model/cbi/lxc.lua b/utils/luci-app-lxc/files/model/cbi/lxc.lua
new file mode 100644 (file)
index 0000000..ac0fdff
--- /dev/null
@@ -0,0 +1,31 @@
+--[[
+
+LuCI LXC module
+
+Copyright (C) 2014, Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Author: Petar Koretic <petar.koretic@sartura.hr>
+
+]]--
+
+local fs = require "nixio.fs"
+
+m = Map("lxc", translate("LXC Containers"))
+
+if fs.access("/etc/config/lxc") then
+       m:section(SimpleSection).template = "lxc"
+
+       s = m:section(TypedSection, "lxc", translate("Options"))
+       s.anonymous = true
+       s.addremove = false
+
+       s:option(Value, "url", translate("Containers URL"))
+end
+
+return m
diff --git a/utils/luci-app-lxc/files/view/lxc.htm b/utils/luci-app-lxc/files/view/lxc.htm
new file mode 100644 (file)
index 0000000..1376968
--- /dev/null
@@ -0,0 +1,441 @@
+<%#
+
+LuCI LXC module
+
+Copyright (C) 2014, Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+Author: Petar Koretic <petar.koretic@sartura.hr>
+
+-%>
+
+<fieldset class="cbi-section">
+       <legend><%:Available Containers%></legend>
+       <div class="cbi-section-node">
+               <table id="t_lxc_list" class="cbi-section-table">
+                       <tr class="cbi-section-table-titles">
+                               <th class="cbi-section-table-cell"><%:Name%></th>
+                               <th class="cbi-section-table-cell"><%:Status%></th>
+                               <th class="cbi-section-table-cell"><%:Actions%></th>
+                       </tr>
+               </table>
+       </div>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <span id="lxc-list-output"></span>
+</fieldset>
+
+<hr/>
+<fieldset class="cbi-section">
+       <legend><%:Create New Container%></legend>
+       <div class="cbi-section-node">
+               <table id="t_lxc_create" class="cbi-section-table">
+                       <tr class="cbi-section-table-titles">
+                               <th class="cbi-section-table-cell"><%:Name%></th>
+                               <th class="cbi-section-table-cell"><%:Template%></th>
+                               <th class="cbi-section-table-cell"><%:Actions%></th>
+                       </tr>
+                       <tr id="tr_holder">
+                               <td>
+                                       <input type="text" id="tx_name" placeholder="<%:Enter new name%>" value='' />
+                               </td>
+                               <td>
+                                       <select id="s_template" class="cbi-input-select cbi-button">
+                                               <option value="openwrt">OpenWrt</option>
+                                       </select>
+                               </td>
+                               <td>
+                                       <input type="button" id="bt_create" value="<%:Create%>" onclick="lxc_create(tr_holder)" class="cbi-button cbi-button-add" />
+                                       <span id="lxc-add-loader" style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>
+                               </td>
+                       </tr>
+               </table>
+       </div>
+</fieldset>
+
+<fieldset class="cbi-section">
+       <span id="lxc-add-output"></span>
+</fieldset>
+
+<hr/>
+
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript">//<![CDATA[
+
+       window.img = { "red" : "<%=resource%>/cbi/red.gif", "green" : "<%=resource%>/cbi/green.gif", "purple" : "<%=resource%>/cbi/purple.gif" }
+       window.states = {  "STOPPED" : "red", "RUNNING" : "green", "FROZEN" : "purple"}
+
+       var t_lxc_list = document.getElementById('t_lxc_list');
+       var loader_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" /> ';
+       var timeout_msg = 0
+       var output_list = document.getElementById("lxc-list-output")
+       var output_add = document.getElementById("lxc-add-output")
+       var loader_add = document.getElementById("lxc-add-loader")
+
+       function lxc_create(tr)
+       {
+               var lxc_name = tr.querySelector("#tx_name").value.trim()
+               var lxc_template = tr.querySelector("#s_template").value
+               var bt_create = tr.querySelector("#bt_create")
+
+               if (t_lxc_list.querySelector("[data-id='" + lxc_name + "']") != null)
+                       return info_message(output_add, "Container with that name already exists!", 4000)
+
+               bt_create.disabled = true
+               output_add.innerHTML = ''
+
+               if (!lxc_name || !lxc_name.length)
+               {
+                       bt_create.disabled = false
+                       return info_message(output_add, "Name cannot be empty!", 4000)
+               }
+
+               loading(loader_add)
+
+               new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_create/' + '%h/%h'.format(lxc_name, lxc_template) , null,
+               function(x)
+               {
+                       bt_create.disabled = false
+                       loading(loader_add, 0)
+
+                       if (!x)
+                               info_message(output_add, "Container creation failed!")
+               })
+       }
+
+       function lxc_create_template(lxc_name, lxc_state)
+       {
+               var info_row = t_lxc_list.querySelector("#empty")
+               if (info_row)
+                       t_lxc_list.deleteRow(1)
+
+               var actions = ''
+               actions += '<input type="button" onclick="action_handler(this)" data-action="start" value="<%:Start%>" class="cbi-button cbi-button-apply" />'
+               actions+= '<input type="button" onclick="action_handler(this)" data-action="stop" value="<%:Stop%>" class="cbi-button cbi-button-reset" />'
+               actions+= '<input type="button" onclick="action_handler(this)" data-action="destroy" value="<%:Delete%>" class="cbi-button cbi-button-remove" />'
+               actions+= ' <select class="cbi-input-select cbi-button" onchange="action_more_handler(this)">\
+                                               <option selected disabled>more</option>\
+                                               <option>configure</option>\
+                                               <option>freeze</option>\
+                                               <option>unfreeze</option>\
+                                               <option>reboot</option>\
+                                       </select>'
+               actions+= '<span data-loader style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>'
+
+               var row = t_lxc_list.insertRow(-1)
+               var cell = row.insertCell(-1)
+               cell.innerHTML = '%q%h%q'.format("<strong>", lxc_name, "</strong>")
+               cell.width = "30%"
+               cell.setAttribute("data-id", lxc_name)
+
+               cell = row.insertCell(-1)
+               cell.width = "20%"
+               cell.innerHTML = "<img src='"+window.img[lxc_state]+"'/>"
+
+               cell = row.insertCell(-1)
+               cell.width = "50%"
+               cell.innerHTML = actions
+       }
+
+       function action_handler(self)
+       {
+               var action = self.getAttribute("data-action");
+
+               var bt_action = self
+               var lxc_name = self.parentNode.parentNode.children[0].getAttribute('data-id')
+               var status_img = self.parentNode.parentNode.querySelector('img')
+               var loader = self.parentNode.querySelector('[data-loader]')
+
+               bt_action.disabled = true
+
+               if (action == "stop")
+               {
+                       loading(loader)
+
+                       new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
+                       function(x, ec)
+                       {
+                               loading(loader, 0)
+                               bt_action.disabled = false
+
+                               if (!x || ec)
+                                       return info_message(output_list,"Action failed!")
+
+                               set_status(status_img, "red")
+
+                       });
+               }
+
+               else if (action == "start")
+               {
+                       loading(loader)
+
+                       new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
+                       function(x, data)
+                       {
+                               loading(loader, 0)
+                               bt_action.disabled = false
+
+                               //FIXME: uncomment after fixing 'lxc-start'
+                               if (!x /*|| ec */)
+                                       return info_message(output_list,"Action failed!")
+
+                               //FIXME: uncomment after fixing 'lxc-start'
+                               //set_status(status_img, "green")
+                       });
+               }
+
+               else if (action == "destroy")
+               {
+                       if (!confirm("This will completely remove LXC container from the disk. Are you sure? (container will be stopped if running)"))
+                               return
+
+                       loading(loader)
+
+                       new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(action, lxc_name), null,
+                       function(x, ec)
+                       {
+                               loading(loader, 0)
+                               bt_action.disabled = false
+
+                               if (!x || ec)
+                                       return info_message(output_list,"Action failed!")
+
+                               var row = self.parentNode.parentNode
+                               row.parentNode.removeChild(row)
+
+                       });
+               }
+       }
+
+       function lxc_configure_handler(self)
+       {
+               var td = self.parentNode
+               var textarea = td.querySelector('[data-id]')
+               var lxc_name = textarea.getAttribute('data-id')
+               var lxc_configuration = textarea.value
+
+               new XHR().post('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_configuration_set/' + lxc_name, "lxc_configuration=" + encodeURIComponent(lxc_configuration) ,
+               function(x)
+               {
+                       if (!x || x.responseText != "0")
+                               return info_message(output_list,"Action failed!")
+
+                       info_message(output_list,"LXC configuration updated")
+                       var row = td.parentNode
+                       row.parentNode.removeChild(row)
+               })
+       }
+
+       function lxc_rename_template(lxc_name)
+       {
+               var h = '\
+                       <input data-id="'+ lxc_name + '" type="text" placeholder="Enter new name" /> \
+                       <input data-id="bt_confirm" onclick="lxc_rename_handler(this)" type="button" class="cbi-button" value="Confirm" />'
+
+               return h
+       }
+
+       function lxc_configure_template(lxc_name, lxc_configuration)
+       {
+               var h = '\
+                       <textarea data-id="'+ lxc_name + '" rows="20" style="width:100%">'+ lxc_configuration +'</textarea> \
+                       <input data-id="bt_confirm" onclick="lxc_configure_handler(this)" type="button" class="cbi-button" value="Confirm" />'
+
+               return h
+       }
+
+       function action_more_handler(self)
+       {
+               var lxc_name = self.parentNode.parentNode.querySelector('[data-id]').getAttribute('data-id')
+               var loader = self.parentNode.parentNode.querySelector('[data-loader]')
+
+               var option = self.options[self.selectedIndex].text
+
+               self.value = "more"
+
+               switch (option)
+               {
+                       case "configure":
+                               var tr = document.createElement('tr')
+                               var row = self.parentNode.parentNode
+                               var next_row = row.nextSibling
+                               if (next_row && next_row.getAttribute('data-action') !== null)
+                                       row.parentNode.removeChild(next_row)
+
+                               new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_configuration_get/' + lxc_name, null,
+                               function(x)
+                               {
+                                       tr.innerHTML="<td colspan='" + row.cells.length + "'>" + lxc_configure_template(lxc_name, x.responseText) + "</td>"
+                                       tr.setAttribute('data-action','')
+                                       row.parentNode.insertBefore(tr, row.nextSibling)
+                               })
+
+                       break
+
+                       case "freeze":
+                               var tr = self.parentNode.parentNode
+                               var img = tr.querySelector('img')
+                               if(img.getAttribute('src') != window.img["green"])
+                                       return info_message(output_list,"Container is not running!")
+
+                               loading(loader)
+                               new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
+                               function(x, ec)
+                               {
+                                       loading(loader, 0)
+                                       if (!x || ec)
+                                               return info_message(output_list,"Action failed!")
+
+                                       set_status(img, "purple")
+                               })
+
+                       break
+
+                       case "unfreeze":
+                               var tr = self.parentNode.parentNode
+                               var img = tr.querySelector('img')
+
+                               if(img.getAttribute('src') != window.img["purple"])
+                                       return info_message(output_list,"Container is not frozen!")
+
+                               loading(loader)
+                               new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
+                               function(x, ec)
+                               {
+                                       loading(loader, 0)
+                                       if (!x || ec)
+                                               return info_message(output_list,"Action failed!")
+
+                                       set_status(img, "green")
+                               })
+
+                       break
+
+                       case "reboot":
+                               var tr = self.parentNode.parentNode
+                               var img = tr.querySelector('img')
+                               if(img.getAttribute('src') != window.img["green"])
+                                       return info_message(output_list,"Container is not running!")
+
+                               if (!confirm("Are you sure?"))
+                                       return
+
+                               loading(loader)
+                               new XHR().get('<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/' + '%h/%h'.format(option, lxc_name), null,
+                               function(x, ec)
+                               {
+                                       loading(loader, 0)
+                                       if (!x || ec)
+                                               return info_message(output_list,"Action failed!")
+
+                                       info_message(output_list,"LXC rebooted")
+                               })
+                       break
+               }
+
+       }
+
+       function set_empty(t_lxc_list)
+       {
+               if (document.getElementById('empty') !== null)
+                       return
+
+               var row_count = t_lxc_list.rows.length;
+               while(--row_count) t_lxc_list.deleteRow(row_count);
+
+               var row = t_lxc_list.insertRow(-1);
+               row.id = 'empty'
+               var cell = row.insertCell(0);
+               cell.colSpan = 4;
+               cell.innerHTML = '<em><br />There are no containers available yet.</em>';
+       }
+
+       function lxc_list_update()
+       {
+               XHR.poll(4, '<%=luci.dispatcher.build_url("admin", "services")%>/lxc_action/list', null,
+               function(x, data)
+               {
+                       if (!x) return;
+
+                       var lxc_count = Object.keys(data).length
+                       if (!data || !lxc_count)
+                               return set_empty(t_lxc_list)
+
+                       if (document.getElementById('empty') !== null)
+                               t_lxc_list.deleteRow(1);
+
+                       var lxcs = t_lxc_list.querySelectorAll('td[data-id]')
+                       var lxc_name_table = {}
+                       for (var i = 0, len = lxcs.length; i < len; i++)
+                       {
+                               var lxc_name = lxcs[i].getAttribute('data-id')
+                               if (!(lxc_name in data))
+                               {
+                                       var row = t_lxc_list.querySelector("[data-id='" + lxc_name + "']").parentNode
+                                       row.parentNode.removeChild(row)
+                                       continue
+                               }
+
+                               lxc_name_table[lxc_name] = lxcs[i].parentNode.querySelector('img')
+                       }
+
+                       for(var key in data)
+                       {
+                               var lxc_name = key
+                               var state = window.states[data[key]]
+
+                               if (!(lxc_name in lxc_name_table))
+                                       lxc_create_template(lxc_name, state)
+
+                               else if (state != get_status(lxc_name_table[lxc_name]))
+                                       set_status(lxc_name_table[lxc_name], state)
+                       }
+
+               })
+       }
+
+       function loading(elem, state)
+       {
+               state = (typeof state === 'undefined') ? 1 : state
+
+               if (state === 1)
+                       elem.innerHTML = loader_html
+               else
+                       setTimeout(function() { elem.innerHTML = ''}, 1000)
+       }
+
+       function set_status(elem, state)
+       {
+               state = (typeof state === 'undefined') ? 1 : state
+
+               setTimeout(function() { elem.setAttribute('src', window.img[state])}, 300)
+       }
+
+       function get_status(elem)
+       {
+               var src = elem.getAttribute('src')
+
+               for (var i in img)
+               {
+                       if (img[i] == src)
+                               return i
+               }
+       }
+
+       function info_message(output, msg, timeout)
+       {
+               timeout = timeout || 3000
+               output.innerHTML = msg
+               clearTimeout(timeout_msg)
+               timeout_msg = setTimeout(function(){ output.innerHTML=""}, timeout);
+       }
+
+       lxc_list_update()
+//]]></script>
diff --git a/utils/luci-app-lxc/files/www/luci-static/resources/cbi/green.gif b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/green.gif
new file mode 100644 (file)
index 0000000..d09febf
Binary files /dev/null and b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/green.gif differ
diff --git a/utils/luci-app-lxc/files/www/luci-static/resources/cbi/purple.gif b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/purple.gif
new file mode 100644 (file)
index 0000000..f0d68cc
Binary files /dev/null and b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/purple.gif differ
diff --git a/utils/luci-app-lxc/files/www/luci-static/resources/cbi/red.gif b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/red.gif
new file mode 100644 (file)
index 0000000..c1b39bb
Binary files /dev/null and b/utils/luci-app-lxc/files/www/luci-static/resources/cbi/red.gif differ
diff --git a/utils/lvm2/Makefile b/utils/lvm2/Makefile
new file mode 100644 (file)
index 0000000..935f213
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2009-2010 Stefan Monnier
+# Copyright (C) 2011-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v3+.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=LVM2
+PKG_VERSION:=2.02.116
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0 LGPL-2.1
+
+PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=ftp://sources.redhat.com/pub/lvm2
+PKG_MD5SUM:=3a1104e3d1dc4d5e92a40228161cd660
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME).$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdevmapper
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The Linux Kernel Device Mapper userspace library
+  URL:=http://sourceware.org/dm/
+  DEPENDS:=+kmod-dm +libpthread
+endef
+
+define Package/libdevmapper/description
+ The device-mapper is a component of the 2.6 linux kernel that supports logical
+ volume management. It is required by LVM2 and EVMS.
+endef
+
+define Package/lvm2
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=disc
+  TITLE:=The Linux Logical Volume Manager
+  URL:=http://sourceware.org/lvm2/
+  DEPENDS:=+libdevmapper +libblkid +libreadline +libncurses
+endef
+
+define Package/lvm2/description
+ LVM2 refers to a new userspace toolset that provide logical volume management
+ facilities on linux. It is reasonably backwards-compatible with the original
+ LVM toolset.
+endef
+
+CONFIGURE_ARGS += --disable-o_direct
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(FPIC)" \
+               DESTDIR="$(PKG_INSTALL_DIR)" \
+               install
+endef
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/libdevmapper.h $(1)/usr/include
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdevmapper.so* $(1)/usr/lib
+       $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_BUILD_DIR)/libdm/libdevmapper.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libdevmapper/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libdevmapper.so.* $(1)/usr/lib
+endef
+
+define Package/lvm2/install
+       $(INSTALL_DIR) $(1)/sbin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/lvm $(1)/sbin
+       $(INSTALL_DIR) $(1)/etc/lvm
+       $(SED) '/^[[:space:]]*\(#\|$$$$\)/d' $(PKG_BUILD_DIR)/conf/example.conf
+       $(INSTALL_CONF) $(PKG_BUILD_DIR)/conf/example.conf $(1)/etc/lvm/lvm.conf
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/lvm2.init $(1)/etc/init.d/lvm2
+       $(FIND) $(PKG_INSTALL_DIR)/usr/sbin/ -type l -exec $(CP) -a {} $(1)/sbin/ \;
+endef
+
+define Package/lvm2/conffiles
+/etc/lvm/lvm.conf
+endef
+
+$(eval $(call BuildPackage,libdevmapper))
+$(eval $(call BuildPackage,lvm2))
diff --git a/utils/lvm2/files/lvm2.init b/utils/lvm2/files/lvm2.init
new file mode 100644 (file)
index 0000000..3b542d0
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2009 Stefan Monnier
+START=15
+
+start () {
+   /sbin/lvm vgscan --ignorelockingfailure --mknodes || :
+   /sbin/lvm vgchange -aly --ignorelockingfailure || return 2
+}
+
+stop () {
+    /sbin/lvm vgchange -aln --ignorelockingfailure || return 2
+}
diff --git a/utils/lvm2/patches/000-compile.patch b/utils/lvm2/patches/000-compile.patch
new file mode 100644 (file)
index 0000000..9fa1c1d
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/make.tmpl.in
++++ b/make.tmpl.in
+@@ -19,7 +19,7 @@ SHELL = /bin/sh
+ # Allow environment to override any built-in default value for CC.
+ # If there is a built-in default, CC is NOT set to @CC@ here.
+-CC ?= @CC@
++CC = @CC@
+ # If $(CC) holds the usual built-in default value of 'cc' then replace it with
+ # the configured value.
diff --git a/utils/lvm2/patches/001-include_fix.patch b/utils/lvm2/patches/001-include_fix.patch
new file mode 100644 (file)
index 0000000..dc159c5
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/lib/device/dev-type.c
++++ b/lib/device/dev-type.c
+@@ -22,7 +22,7 @@
+ #include <ctype.h>
+ #ifdef BLKID_WIPING_SUPPORT
+-#include <blkid.h>
++#include <blkid/blkid.h>
+ #endif
+ #include "device-types.h"
index c52ba532ed9a9b53f2e001c9a15f2a7c1dc0fa16..37286bfab4f30f54829c0208620bfb5d135c05c7 100644 (file)
@@ -12,4 +12,19 @@ config LXC_KERNEL_OPTIONS
          include cgroups, namespaces and other miscellaneous options. These
          options unfortunately can not be installed as a module.
 
+config LXC_BUSYBOX_OPTIONS
+       bool "Enable busybox support for lxc-create tool"
+       default n
+       select BUSYBOX_CUSTOM
+       select BUSYBOX_CONFIG_HAVE_DOT_CONFIG
+       select BUSYBOX_CONFIG_FEATURE_SEAMLESS_XZ
+       select BUSYBOX_CONFIG_FEATURE_TAR_LONG_OPTIONS
+       select BUSYBOX_CONFIG_UNXZ
+       select BUSYBOX_CONFIG_XZ
+       select BUSYBOX_CONFIG_GETOPT
+       select BUSYBOX_CONFIG_FEATURE_GETOPT_LONG
+       help
+         Select needed busybox options for lxc-create utility. This include XZ tar
+         compression, long option support for tar and built-in getopt support.
+
 endmenu
index 97d79835ead49967de3d0ebcee44a766e86edd00..3adfd5de952e6aea6caaf4a460fadfb31b202e4e 100644 (file)
@@ -8,12 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=lxc
-PKG_VERSION:=1.0.5
-PKG_RELEASE:=2
+PKG_VERSION:=1.0.6
+PKG_RELEASE:=1
+
+PKG_LICENSE:=LGPL-2.1+ BSD-2-Clause GPL-2.0
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://linuxcontainers.org/downloads/
-PKG_MD5SUM:=9d9af9e9e69a831cd50b58d91c786013
+PKG_MD5SUM:=4aad3aee84b42faa194e44091d723a3b
 
 PKG_BUILD_DEPENDS:=lua
 PKG_BUILD_PARALLEL:=1
@@ -33,6 +35,8 @@ LXC_SCRIPTS += \
 
 DEPENDS_APPLETS = +libpthread +libcap +liblxc
 
+DEPENDS_create = +lxc-configs +lxc-hooks +lxc-templates
+DEPENDS_ls = +lxc-config
 DEPENDS_top = +lxc-lua +luafilesystem @BROKEN
 
 
@@ -73,7 +77,13 @@ endef
 define Package/lxc-templates
   $(call Package/lxc/Default)
   TITLE:=LXC virtual machine templates
-  DEPENDS:= lxc @BROKEN
+  DEPENDS:= lxc
+endef
+
+define Package/lxc-configs
+  $(call Package/lxc/Default)
+  TITLE:=LXC virtual machine common config files
+  DEPENDS:= lxc
 endef
 
 define Package/liblxc
@@ -155,16 +165,20 @@ define Package/lxc-common/install
        $(INSTALL_DIR) $(1)/etc/lxc/
        $(CP) \
                $(PKG_INSTALL_DIR)/etc/lxc/default.conf \
-               $(1)/etc/lxc/
+               $(1)/etc/lxc/default.conf
+
+       $(INSTALL_DIR) $(1)/etc/lxc/
+       $(CP) \
+               ./files/lxc.conf \
+               $(1)/etc/lxc/lxc.conf
+
+       $(INSTALL_DIR) $(1)/lxc/
 endef
 
 define Package/lxc-hooks/install
        $(INSTALL_DIR) $(1)/usr/share/lxc/hooks
        $(CP) \
-               $(PKG_INSTALL_DIR)/usr/share/lxc/hooks/mountcgroups \
-               $(1)/usr/share/lxc/hooks/
-       $(CP) \
-               $(PKG_INSTALL_DIR)/usr/share/lxc/hooks/mountecryptfsroot \
+               $(PKG_INSTALL_DIR)/usr/share/lxc/hooks/* \
                $(1)/usr/share/lxc/hooks/
 endef
 
@@ -175,6 +189,13 @@ define Package/lxc-templates/install
                $(1)/usr/share/lxc/templates/
 endef
 
+define Package/lxc-configs/install
+       $(INSTALL_DIR) $(1)/usr/share/lxc/config/
+       $(CP) \
+               $(PKG_INSTALL_DIR)/usr/share/lxc/config/* \
+               $(1)/usr/share/lxc/config/
+endef
+
 define Package/liblxc/install
        $(INSTALL_DIR) $(1)/usr/lib/
        $(CP) \
@@ -221,9 +242,11 @@ endef
 $(eval $(call BuildPackage,lxc))
 $(eval $(call BuildPackage,lxc-common))
 $(eval $(call BuildPackage,lxc-hooks))
+$(eval $(call BuildPackage,lxc-configs))
 $(eval $(call BuildPackage,lxc-templates))
 $(eval $(call BuildPackage,liblxc))
 $(eval $(call BuildPackage,lxc-lua))
+$(eval $(call BuildPackage,lxc-init))
 $(foreach u,$(LXC_APPLETS_BIN),$(eval $(call GenPlugin,$(u),$(DEPENDS_APPLETS),"/usr/bin")))
 $(foreach u,$(LXC_APPLETS_LIB),$(eval $(call GenPlugin,$(u),$(DEPENDS_APPLETS),"/usr/lib/lxc")))
 $(foreach u,$(LXC_SCRIPTS),$(eval $(call GenPlugin,$(u),,"/usr/bin")))
diff --git a/utils/lxc/files/lxc.conf b/utils/lxc/files/lxc.conf
new file mode 100644 (file)
index 0000000..3b77baa
--- /dev/null
@@ -0,0 +1 @@
+lxc.lxcpath = /lxc
diff --git a/utils/lxc/patches/025-remove-unsupported-option.patch b/utils/lxc/patches/025-remove-unsupported-option.patch
new file mode 100644 (file)
index 0000000..f70d49d
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/templates/lxc-download.in
++++ b/templates/lxc-download.in
+@@ -479,15 +479,7 @@ fi
+ # Unpack the rootfs
+ echo "Unpacking the rootfs"
+-EXCLUDES=""
+-excludelist=$(relevant_file excludes)
+-if [ -f "${excludelist}" ]; then
+-    while read line; do
+-        EXCLUDES="$EXCLUDES --exclude=$line"
+-    done < $excludelist
+-fi
+-
+-tar  --anchored ${EXCLUDES} --numeric-owner -xpJf \
++tar --numeric-owner -xpJf \
+     ${LXC_CACHE_PATH}/rootfs.tar.xz -C ${LXC_ROOTFS}
+ mkdir -p ${LXC_ROOTFS}/dev/pts/
diff --git a/utils/lxc/patches/300-fix-lxc-destroy.patch b/utils/lxc/patches/300-fix-lxc-destroy.patch
new file mode 100644 (file)
index 0000000..2192c5f
--- /dev/null
@@ -0,0 +1,48 @@
+From bdeafb7bc4857e80dbca5192a751eedcf7b69abd Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Mon, 27 Oct 2014 21:49:46 +0100
+Subject: [PATCH] utils: remove unnecessary check of mystat.st_dev
+
+The check is not needed and it breaks lxc-destroy when container is installed
+on top of overlayfs. More information why this is a problem on overlayfs can be
+found here:
+
+https://kernel.googlesource.com/pub/scm/linux/kernel/git/mszeredi/vfs/+/overlayfs.current/Documentation/filesystems/overlayfs.txt
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+---
+ src/lxc/utils.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/src/lxc/utils.c
++++ b/src/lxc/utils.c
+@@ -46,7 +46,7 @@
+ lxc_log_define(lxc_utils, lxc);
+-static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
++static int _recursive_rmdir_onedev(char *dirname)
+ {
+       struct dirent dirent, *direntp;
+       DIR *dir;
+@@ -82,10 +82,8 @@ static int _recursive_rmdir_onedev(char
+                       failed=1;
+                       continue;
+               }
+-              if (mystat.st_dev != pdev)
+-                      continue;
+               if (S_ISDIR(mystat.st_mode)) {
+-                      if (_recursive_rmdir_onedev(pathname, pdev) < 0)
++                      if (_recursive_rmdir_onedev(pathname) < 0)
+                               failed=1;
+               } else {
+                       if (unlink(pathname) < 0) {
+@@ -119,7 +117,7 @@ extern int lxc_rmdir_onedev(char *path)
+               return -1;
+       }
+-      return _recursive_rmdir_onedev(path, mystat.st_dev);
++      return _recursive_rmdir_onedev(path);
+ }
+ static int mount_fs(const char *source, const char *target, const char *type)
diff --git a/utils/lxc/patches/301-add-openwrt-common-config.patch b/utils/lxc/patches/301-add-openwrt-common-config.patch
new file mode 100644 (file)
index 0000000..6736d9b
--- /dev/null
@@ -0,0 +1,78 @@
+--- /dev/null
++++ b/config/templates/openwrt.common.conf.in
+@@ -0,0 +1,56 @@
++# Default mount entries
++lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
++lxc.mount.entry = sysfs sys sysfs defaults 0 0
++
++# Default console settings
++lxc.devttydir = lxc
++lxc.tty = 4
++lxc.pts = 1024
++
++# Default capabilities
++lxc.cap.drop = mac_admin
++lxc.cap.drop = mac_override
++lxc.cap.drop = sys_admin
++lxc.cap.drop = sys_module
++lxc.cap.drop = sys_nice
++lxc.cap.drop = sys_pacct
++lxc.cap.drop = sys_ptrace
++lxc.cap.drop = sys_rawio
++lxc.cap.drop = sys_resource
++lxc.cap.drop = sys_time
++lxc.cap.drop = sys_tty_config
++lxc.cap.drop = syslog
++lxc.cap.drop = wake_alarm
++
++# Default cgroups - all denied except those whitelisted
++lxc.cgroup.devices.deny = a
++## /dev/null and zero
++lxc.cgroup.devices.allow = c 1:3 rwm
++lxc.cgroup.devices.allow = c 1:5 rwm
++## consoles
++lxc.cgroup.devices.allow = c 5:0 rwm
++lxc.cgroup.devices.allow = c 5:1 rwm
++## /dev/{,u}random
++lxc.cgroup.devices.allow = c 1:8 rwm
++lxc.cgroup.devices.allow = c 1:9 rwm
++## /dev/pts/*
++lxc.cgroup.devices.allow = c 5:2 rwm
++lxc.cgroup.devices.allow = c 136:* rwm
++## rtc
++lxc.cgroup.devices.allow = c 254:0 rm
++## fuse
++lxc.cgroup.devices.allow = c 10:229 rwm
++## tun
++lxc.cgroup.devices.allow = c 10:200 rwm
++## dev/tty0
++lxc.cgroup.devices.allow = c 4:0 rwm
++## dev/tty1
++lxc.cgroup.devices.allow = c 4:1 rwm
++
++## To use loop devices, copy the following line to the container's
++## configuration file (uncommented).
++#lxc.cgroup.devices.allow = b 7:* rwm
++
++# Blacklist some syscalls which are not safe in privileged
++# containers
++lxc.seccomp = /usr/share/lxc/config/common.seccomp
+--- a/configure.ac
++++ b/configure.ac
+@@ -579,6 +579,7 @@ AC_CONFIG_FILES([
+       config/templates/ubuntu.common.conf
+       config/templates/ubuntu.lucid.conf
+       config/templates/ubuntu.userns.conf
++      config/templates/openwrt.common.conf
+       config/yum/Makefile
+       doc/Makefile
+--- a/config/templates/Makefile.am
++++ b/config/templates/Makefile.am
+@@ -22,4 +22,5 @@ templatesconfig_DATA = \
+       ubuntu-cloud.userns.conf \
+       ubuntu.common.conf \
+       ubuntu.lucid.conf \
+-      ubuntu.userns.conf
++      ubuntu.userns.conf \
++      openwrt.common.conf
diff --git a/utils/mc/Config.in b/utils/mc/Config.in
new file mode 100644 (file)
index 0000000..1445aa1
--- /dev/null
@@ -0,0 +1,60 @@
+menu "Configuration"
+       depends on PACKAGE_mc
+
+config MC_DIFFVIEWER
+       bool "Enable internal diff viewer"
+       default n
+       help
+           This option enables the built-in diff viewer.
+           Disabled by default.
+
+config MC_EDITOR
+       bool "Enable internal editor"
+       default n
+       help
+           This option enables the built-in file editor.
+           Disabled by default.
+
+config MC_SUBSHELL
+       bool "Enable concurrent subshell"
+       default n
+       help
+           This option enables concurrent subshell support.
+           Disabled by default.
+
+config MC_LARGEFILE
+       bool "Enable largefile support"
+       default n
+       help
+           This option enables support for large files (> 2 GB).
+           Disabled by default.
+
+config MC_BACKGROUND
+       bool "Enable background operations"
+       default n
+       help
+           This option enables support for background operations which
+           allow to perform some tasks such as copying files in a
+           separate background process. Background code is known
+           to be less stable than the rest of the code.
+           Disabled by default.
+
+config MC_CHARSET
+       bool "Enable charset support"
+       default n
+       help
+           This option adds support for selecting character set of the text in
+           the internal viewer and editor and converting it on the fly.
+           The implementation is currently incomplete.
+           Disabled by default.
+
+config MC_VFS
+       bool "Enable virtual filesystem support"
+       default n
+       help
+           This option enables the Virtual File System switch code to get
+           transparent access to the following file systems:
+           cpio, tar, fish, sfs, ftp, sftp, extfs, smb.
+           Disabled by default.
+
+endmenu
diff --git a/utils/mc/Makefile b/utils/mc/Makefile
new file mode 100644 (file)
index 0000000..1fb7bec
--- /dev/null
@@ -0,0 +1,122 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mc
+PKG_VERSION:=4.8.13
+PKG_RELEASE:=1.2
+PKG_MAINTAINER:=Dirk Brenken <dibdot@gmail.com>
+PKG_LICENSE:=GPL-3.0+
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://ftp.midnight-commander.org/
+PKG_MD5SUM:=d967caa12765eb86e52a6a63ca202500
+
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+
+PKG_CONFIG_DEPENDS := \
+       CONFIG_PACKAGE_MC \
+       CONFIG_MC_DIFFVIEWER \
+       CONFIG_MC_EDITOR \
+       CONFIG_MC_SUBSHELL \
+       CONFIG_MC_LARGEFILE \
+       CONFIG_MC_BACKGROUND \
+       CONFIG_MC_CHARSET \
+       CONFIG_MC_VFS
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/mc
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+glib2 +libncurses +MC_VFS:libssh2 $(LIBRPC_DEPENDS) $(ICONV_DEPENDS)
+  TITLE:=Midnight Commander - a powerful visual file manager
+  URL:=http://www.midnight-commander.org/
+  MENU:=1
+endef
+
+define Package/mc/config
+       source "$(SOURCE)/Config.in"
+endef
+
+define Package/mc/description
+ GNU Midnight Commander is a visual file manager,
+ licensed under GNU General Public License and therefore qualifies as Free Software.
+ It's a feature rich full-screen text mode application that allows you to copy,
+ move and delete files and whole directory trees, search for files
+ and run commands in the subshell. Internal viewer and editor are included.
+endef
+
+CONFIGURE_ARGS += \
+       --disable-doxygen-doc \
+       --with-screen=ncurses \
+       --without-gpm-mouse \
+       --without-x \
+
+CONFIGURE_VARS += \
+       ac_cv_search_addwstr=no \
+
+ifeq ($(CONFIG_MC_DIFFVIEWER),)
+CONFIGURE_ARGS += \
+       --without-diff-viewer
+endif
+
+ifeq ($(CONFIG_MC_EDITOR),)
+CONFIGURE_ARGS += \
+       --without-internal-edit
+endif
+
+ifeq ($(CONFIG_MC_SUBSHELL),)
+CONFIGURE_ARGS += \
+       --without-subshell
+endif
+
+ifeq ($(CONFIG_MC_LARGEFILE),)
+CONFIGURE_ARGS += \
+       --disable-largefile
+endif
+
+ifeq ($(CONFIG_MC_BACKGROUND),)
+CONFIGURE_ARGS += \
+       --disable-background
+endif
+
+ifeq ($(CONFIG_MC_CHARSET),)
+CONFIGURE_ARGS += \
+       --disable-charset
+endif
+
+ifeq ($(CONFIG_MC_VFS),)
+CONFIGURE_ARGS += \
+       --disable-vfs
+endif
+
+define Package/mc/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mc $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/etc/mc
+ifeq ($(CONFIG_MC_DIFFVIEWER),y)
+       ln -sf mc $(1)/usr/bin/mcdiff
+endif
+ifeq ($(CONFIG_MC_EDITOR),y)
+       ln -sf mc $(1)/usr/bin/mcedit
+endif
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/mc.menu $(1)/etc/mc
+       $(INSTALL_DIR) $(1)/etc/mc/skins
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/skins/default.ini $(1)/etc/mc/skins
+       $(INSTALL_DIR) $(1)/root/.mc/cedit/Syntax
+endef
+
+define Package/mc/conffiles
+/etc/mc/mc.menu
+/etc/mc/skins/default.ini
+endef
+
+$(eval $(call BuildPackage,mc))
diff --git a/utils/mksh/Makefile b/utils/mksh/Makefile
new file mode 100644 (file)
index 0000000..89380a9
--- /dev/null
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2007-2011 OpenWrt.org
+# Copyright (c) 2009-2014 Thorsten Glaser <tg@mirbsd.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mksh
+PKG_VERSION:=50d
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Thorsten Glaser <tg@mirbsd.org>
+PKG_LICENSE:=MirOS
+
+PKG_SOURCE:=$(PKG_NAME)-R$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=http://www.mirbsd.org/MirOS/dist/mir/mksh
+PKG_MD5SUM:=1c3882c07a760b23df1ad94ad0b4ed2e
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mksh
+  SECTION:=shells
+  CATEGORY:=Base system
+  TITLE:=MirBSD Korn Shell
+  DEPENDS:=$(DEP)
+  URL:=http://mirbsd.de/mksh
+endef
+
+define Package/mksh/description
+mksh is the MirBSD enhanced version of the Public Domain Korn
+shell (pdksh), a Bourne-compatible shell which is largely si-
+milar to the original AT&T Korn shell; mksh is the only pdksh
+derivate currently being actively developed.  It includes bug
+fixes and feature improvements, in order to produce a modern,
+robust shell good for interactive and especially script use.
+mksh has UTF-8 support (in substring operations and the Emacs
+editing mode) and - while R50 corresponds to OpenBSD 5.5-cur-
+rent ksh (without GNU bash-like PS1 and fancy character clas-
+ses) - adheres to SUSv4 and is much more robust. The code has
+been cleaned up and simplified, bugs fixed, standards compli-
+ance added, and several enhancements (for extended compatibi-
+lity to other modern shells - as well as a couple of its own)
+are available. It has sensible defaults as usual with BSD.
+endef
+
+define Build/Compile
+       # -DMKSH_SMALL=1 ⇒ reduce functionality quite a lot
+       # -DMKSH_ASSUME_UTF8=0 ⇒ never automatically enable
+       #       UTF-8 mode, neither use setlocale/nl_langinfo
+       #       nor look at $LC_* and $LANG (not recommended)
+       # -DMKSH_BINSHPOSIX ⇒ enable POSIX mode if called as sh
+       #XXX maybe change to -DMKSH_ASSUME_UTF8=1 now (which
+       #XXX is always assume UTF-8 mode)
+       # HAVE_CAN_FSTACKPROTECTORALL=0 ⇒ nuke libssp dependency
+       # HAVE_CAN_FSTACKPROTECTORSTRONG=0 ⇒ same, for gcc 4.9+
+       cd $(PKG_BUILD_DIR); \
+               CC="$(TARGET_CC)" \
+               TARGET_OS="$(shell uname -s)" \
+               CFLAGS="$(TARGET_CFLAGS)" \
+               CPPFLAGS="-DMKSH_SMALL=1 -DMKSH_ASSUME_UTF8=0 -DMKSH_BINSHPOSIX" \
+               HAVE_CAN_FSTACKPROTECTORALL=0 \
+               HAVE_CAN_FSTACKPROTECTORSTRONG=0 \
+               LDFLAGS="$(TARGET_LDFLAGS)" \
+                       $(BASH) Build.sh -Q -r -c lto
+endef
+
+define Package/mksh/postinst
+#!/bin/sh
+grep mksh $${IPKG_INSTROOT}/etc/shells || \
+       echo "/bin/mksh" >> $${IPKG_INSTROOT}/etc/shells
+endef
+
+define Package/mksh/install
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) $(PKG_BUILD_DIR)/dot.mkshrc $(1)/etc/mkshrc
+       $(INSTALL_DIR) $(1)/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/mksh $(1)/bin/
+endef
+
+define Package/mksh/conffiles
+/etc/mkshrc
+endef
+
+$(eval $(call BuildPackage,mksh))
diff --git a/utils/mksh/patches/100-dot_mkshrc b/utils/mksh/patches/100-dot_mkshrc
new file mode 100644 (file)
index 0000000..a7bf840
--- /dev/null
@@ -0,0 +1,50 @@
+From 23712cea8e2a623fd952eb781df0011c501703d0 Mon Sep 17 00:00:00 2001
+From: Thorsten Glaser <tg@mirbsd.org>
+Date: Thu, 25 Jul 2013 22:07:33 +0200
+Subject: [PATCH] Make default mkshrc file suitable for OpenWrt environment:
+
+* Part of the FreeWRT patches:
+  - no hostname(1)
+  - ls(1) has no -o option
+* OpenWrt and FreeWRT-1.0 fix:
+  - since this is not ~/.mkshrc make sure subshells find it
+---
+ dot.mkshrc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/dot.mkshrc b/dot.mkshrc
+index 233a10c..caf482c 100644
+--- a/dot.mkshrc
++++ b/dot.mkshrc
+@@ -28,8 +28,8 @@ case $KSH_VERSION in
+ *) return 0 ;;
+ esac
+-PS1='#'; (( USER_ID )) && PS1='$'; [[ ${HOSTNAME:=$(ulimit -c 0; hostname -s \
+-    2>/dev/null)} = *([        ]|localhost) ]] && HOSTNAME=$(ulimit -c 0; hostname \
++PS1='#'; (( USER_ID )) && PS1='$'; [[ ${HOSTNAME:=$(</proc/sys/kernel/hostname
++    )} = *([   ]|localhost) ]] && HOSTNAME=$(ulimit -c 0; hostname \
+     2>/dev/null); : ${EDITOR:=/bin/ed} ${HOSTNAME:=nil} ${TERM:=vt100}
+ : ${MKSH:=$(whence -p mksh)}; PS4='[$EPOCHREALTIME] '; PS1=$'\001\r''${|
+       local e=$?
+@@ -50,7 +50,7 @@ unalias ls
+ alias l='ls -F'
+ alias la='l -a'
+ alias ll='l -l'
+-alias lo='l -alo'
++alias lo='l -al'
+ alias doch='sudo mksh -c "$(fc -ln -1)"'
+ whence -p rot13 >/dev/null || alias rot13='tr \
+     abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \
+@@ -402,4 +402,8 @@ alias cls='print -n \\033c'
+ unset p
++# we need this in OpenWrt for subshells that are not login shells
++: ${ENV=/etc/mkshrc}
++[[ -z $ENV ]] || export ENV
++
+ : place customisations above this line
+-- 
+2.1.1
+
diff --git a/utils/mpack/Makefile b/utils/mpack/Makefile
new file mode 100644 (file)
index 0000000..c2b77eb
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mpack
+PKG_VERSION:=1.6
+PKG_RELEASE:=1
+PKG_LICENSE:=NLPL
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://ftp.andrew.cmu.edu/pub/mpack/
+PKG_MD5SUM:=a70fa5afa76539a9afb70b9d81568fe8
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mpack
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=mpack/munpack MIME format mail messages
+  URL:=http://ftp.andrew.cmu.edu/pub/mpack/
+  MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
+endef
+
+define Package/mpack/description
+  Mpack and munpack are utilities for encoding and decoding
+  (respectively) binary files in MIME (Multipurpose Internet Mail
+  Extensions) format mail messages.  For compatibility with older forms
+  of transferring binary files, the munpack program can also decode
+  messages in split-uuencoded format.
+endef
+
+define Package/mpack/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,mpack))
+
diff --git a/utils/mysql/patches/120-bison-compat.patch b/utils/mysql/patches/120-bison-compat.patch
new file mode 100644 (file)
index 0000000..6c9ac94
--- /dev/null
@@ -0,0 +1,3290 @@
+--- a/sql/sql_lex.cc
++++ b/sql/sql_lex.cc
+@@ -775,14 +775,13 @@ bool consume_comment(Lex_input_stream *l
+                               (which can't be followed by a signed number)
+ */
+-int MYSQLlex(void *arg, void *yythd)
++int MYSQLlex(void *arg, THD *thd)
+ {
+   reg1        uchar c= 0;
+   bool comment_closed;
+   int tokval, result_state;
+   uint length;
+   enum my_lex_states state;
+-  THD *thd= (THD *)yythd;
+   Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+   LEX *lex= thd->lex;
+   YYSTYPE *yylval=(YYSTYPE*) arg;
+--- a/sql/sql_lex.h
++++ b/sql/sql_lex.h
+@@ -2072,7 +2072,7 @@ extern void lex_init(void);
+ extern void lex_free(void);
+ extern void lex_start(THD *thd);
+ extern void lex_end(LEX *lex);
+-extern int MYSQLlex(void *arg, void *yythd);
++extern int MYSQLlex(void *arg, THD *thd);
+ extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str);
+--- a/sql/sql_parse.cc
++++ b/sql/sql_parse.cc
+@@ -8012,7 +8012,7 @@ bool check_host_name(LEX_STRING *str)
+ }
+-extern int MYSQLparse(void *thd); // from sql_yacc.cc
++extern int MYSQLparse(THD *thd); // from sql_yacc.cc
+ /**
+--- a/sql/sql_yacc.yy
++++ b/sql/sql_yacc.yy
+@@ -25,17 +25,15 @@
+ %{
+ /* thd is passed as an argument to yyparse(), and subsequently to yylex().
+ ** The type will be void*, so it must be  cast to (THD*) when used.
+-** Use the YYTHD macro for this.
++** Use the thd macro for this.
+ */
+-#define YYPARSE_PARAM yythd
+-#define YYLEX_PARAM yythd
+-#define YYTHD ((THD *)yythd)
+-#define YYLIP (& YYTHD->m_parser_state->m_lip)
++#define YYLIP (& thd->m_parser_state->m_lip)
++#define YYPS (& thd->m_parser_state->m_yacc)
+ #define MYSQL_YACC
+ #define YYINITDEPTH 100
+ #define YYMAXDEPTH 3200                        /* Because of 64K stack */
+-#define Lex (YYTHD->lex)
++#define Lex (thd->lex)
+ #define Select Lex->current_select
+ #include "mysql_priv.h"
+ #include "slave.h"
+@@ -64,7 +62,7 @@ const LEX_STRING null_lex_str= {0,0};
+     ulong val= *(F);                          \
+     if (my_yyoverflow((B), (D), &val))        \
+     {                                         \
+-      yyerror((char*) (A));                   \
++      yyerror(current_thd, (char*) (A));      \
+       return 2;                               \
+     }                                         \
+     else                                      \
+@@ -76,7 +74,7 @@ const LEX_STRING null_lex_str= {0,0};
+ #define MYSQL_YYABORT                         \
+   do                                          \
+   {                                           \
+-    LEX::cleanup_lex_after_parse_error(YYTHD);\
++    LEX::cleanup_lex_after_parse_error(thd);  \
+     YYABORT;                                  \
+   } while (0)
+@@ -159,10 +157,8 @@ void my_parse_error(const char *s)
+   to abort from the parser.
+ */
+-void MYSQLerror(const char *s)
++void MYSQLerror(THD *thd, const char *s)
+ {
+-  THD *thd= current_thd;
+-
+   /*
+     Restore the original LEX if it was replaced when parsing
+     a stored procedure. We must ensure that a parsing error
+@@ -675,7 +671,10 @@ static bool add_create_index (LEX *lex,
+ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
+ %}
+-%pure_parser                                    /* We have threads */
++/* We have threads */
++%define api.pure
++%parse-param { THD *thd }
++%lex-param { THD *thd }
+ /*
+   Currently there are 169 shift/reduce conflicts.
+   We should not introduce new conflicts any more.
+@@ -1516,7 +1515,6 @@ rule: <-- starts at col 1
+ query:
+           END_OF_INPUT
+           {
+-            THD *thd= YYTHD;
+             if (!thd->bootstrap &&
+               (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
+             {
+@@ -1530,7 +1528,7 @@ query:
+           {
+             Lex_input_stream *lip = YYLIP;
+-            if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
++            if ((thd->client_capabilities & CLIENT_MULTI_QUERIES) &&
+                 ! lip->stmt_prepare_mode &&
+                 ! lip->eof())
+             {
+@@ -1626,7 +1624,6 @@ statement:
+ deallocate:
+           deallocate_or_drop PREPARE_SYM ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
+             lex->prepared_stmt_name= $3;
+@@ -1641,7 +1638,6 @@ deallocate_or_drop:
+ prepare:
+           PREPARE_SYM ident FROM prepare_src
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sql_command= SQLCOM_PREPARE;
+             lex->prepared_stmt_name= $2;
+@@ -1651,14 +1647,12 @@ prepare:
+ prepare_src:
+           TEXT_STRING_sys
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->prepared_stmt_code= $1;
+             lex->prepared_stmt_code_is_varref= FALSE;
+           }
+         | '@' ident_or_text
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->prepared_stmt_code= $2;
+             lex->prepared_stmt_code_is_varref= TRUE;
+@@ -1668,7 +1662,6 @@ prepare_src:
+ execute:
+           EXECUTE_SYM ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sql_command= SQLCOM_EXECUTE;
+             lex->prepared_stmt_name= $2;
+@@ -1826,7 +1819,6 @@ master_file_def:
+ create:
+           CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sql_command= SQLCOM_CREATE_TABLE;
+             if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
+@@ -1844,13 +1836,13 @@ create:
+           }
+           create2
+           {
+-            LEX *lex= YYTHD->lex;
++            LEX *lex= thd->lex;
+             lex->current_select= &lex->select_lex; 
+             if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
+                 !lex->create_info.db_type)
+             {
+-              lex->create_info.db_type= ha_default_handlerton(YYTHD);
+-              push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
++              lex->create_info.db_type= ha_default_handlerton(thd);
++              push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                                   ER_WARN_USING_OTHER_HANDLER,
+                                   ER(ER_WARN_USING_OTHER_HANDLER),
+                                   ha_resolve_storage_engine_name(lex->create_info.db_type),
+@@ -1979,7 +1971,6 @@ server_option:
+ event_tail:
+           remember_name EVENT_SYM opt_if_not_exists sp_name
+           {
+-            THD *thd= YYTHD;
+             LEX *lex=Lex;
+             lex->stmt_definition_begin= $1;
+@@ -2046,7 +2037,7 @@ opt_ev_status:
+ ev_starts:
+           /* empty */
+           {
+-            Item *item= new (YYTHD->mem_root) Item_func_now_local();
++            Item *item= new (thd->mem_root) Item_func_now_local();
+             if (item == NULL)
+               MYSQL_YYABORT;
+             Lex->event_parse_data->item_starts= item;
+@@ -2096,7 +2087,6 @@ opt_ev_comment:
+ ev_sql_stmt:
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+@@ -2139,7 +2129,6 @@ ev_sql_stmt:
+           }
+           ev_sql_stmt_inner
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             /* return back to the original memory root ASAP */
+@@ -2198,11 +2187,10 @@ sp_name:
+             $$= new sp_name($1, $3, true);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+-            $$->init_qname(YYTHD);
++            $$->init_qname(thd);
+           }
+         | ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             LEX_STRING db;
+             if (check_routine_name(&$1))
+@@ -2272,7 +2260,7 @@ call:
+             lex->sql_command= SQLCOM_CALL;
+             lex->spname= $2;
+             lex->value_list.empty();
+-            sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
++            sp_add_used_routine(lex, thd, $2, TYPE_ENUM_PROCEDURE);
+           }
+           opt_sp_cparam_list {}
+         ;
+@@ -2345,7 +2333,7 @@ sp_fdparam:
+                                                      (enum enum_field_types)$3,
+                                                      sp_param_in);
+-            if (lex->sphead->fill_field_definition(YYTHD, lex,
++            if (lex->sphead->fill_field_definition(thd, lex,
+                                                    (enum enum_field_types) $3,
+                                                    &spvar->field_def))
+             {
+@@ -2382,7 +2370,7 @@ sp_pdparam:
+                                                      (enum enum_field_types)$4,
+                                                      (sp_param_mode_t)$1);
+-            if (lex->sphead->fill_field_definition(YYTHD, lex,
++            if (lex->sphead->fill_field_definition(thd, lex,
+                                                    (enum enum_field_types) $4,
+                                                    &spvar->field_def))
+             {
+@@ -2445,13 +2433,12 @@ sp_decl:
+           {
+             LEX *lex= Lex;
+-            lex->sphead->reset_lex(YYTHD);
++            lex->sphead->reset_lex(thd);
+             lex->spcont->declare_var_boundary($2);
+           }
+           type
+           sp_opt_default
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= Lex;
+             sp_pcontext *pctx= lex->spcont;
+             uint num_vars= pctx->context_var_count();
+@@ -2477,7 +2464,7 @@ sp_decl:
+               spvar->type= var_type;
+               spvar->dflt= dflt_value_item;
+             
+-              if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
++              if (lex->sphead->fill_field_definition(thd, lex, var_type,
+                                                      &spvar->field_def))
+               {
+                 MYSQL_YYABORT;
+@@ -2501,7 +2488,7 @@ sp_decl:
+             }
+             pctx->declare_var_boundary(0);
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+             $$.vars= $2;
+             $$.conds= $$.hndlrs= $$.curs= 0;
+@@ -2516,7 +2503,7 @@ sp_decl:
+             my_error(ER_SP_DUP_COND, MYF(0), $2.str);
+             MYSQL_YYABORT;
+           }
+-          if(YYTHD->lex->spcont->push_cond(&$2, $5))
++          if(thd->lex->spcont->push_cond(&$2, $5))
+               MYSQL_YYABORT;
+             $$.vars= $$.hndlrs= $$.curs= 0;
+             $$.conds= 1;
+@@ -2602,7 +2589,7 @@ sp_decl:
+ sp_cursor_stmt:
+           {
+-            Lex->sphead->reset_lex(YYTHD);
++            Lex->sphead->reset_lex(thd);
+           }
+           select
+           {
+@@ -2618,7 +2605,7 @@ sp_cursor_stmt:
+             }
+             lex->sp_lex_in_use= TRUE;
+             $$= lex;
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+         ;
+@@ -2662,7 +2649,7 @@ sp_hcond_element:
+ sp_cond:
+           ulong_num
+           { /* mysql errno */
+-            $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
++            $$= (sp_cond_type_t *)thd->alloc(sizeof(sp_cond_type_t));
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->type= sp_cond_type_t::number;
+@@ -2675,7 +2662,7 @@ sp_cond:
+               my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str);
+               MYSQL_YYABORT;
+             }
+-            $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
++            $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->type= sp_cond_type_t::state;
+@@ -2705,21 +2692,21 @@ sp_hcond:
+           }
+         | SQLWARNING_SYM /* SQLSTATEs 01??? */
+           {
+-            $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
++            $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->type= sp_cond_type_t::warning;
+           }
+         | not FOUND_SYM /* SQLSTATEs 02??? */
+           {
+-            $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
++            $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->type= sp_cond_type_t::notfound;
+           }
+         | SQLEXCEPTION_SYM /* All other SQLSTATEs */
+           {
+-            $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
++            $$= (sp_cond_type_t *) thd->alloc(sizeof(sp_cond_type_t));
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->type= sp_cond_type_t::exception;
+@@ -2789,7 +2776,6 @@ sp_proc_stmt_if:
+         
+ sp_proc_stmt_statement:
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+@@ -2798,7 +2784,6 @@ sp_proc_stmt_statement:
+           }
+           statement
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+             sp_head *sp= lex->sphead;
+@@ -2845,7 +2830,7 @@ sp_proc_stmt_statement:
+ sp_proc_stmt_return:
+           RETURN_SYM 
+-          { Lex->sphead->reset_lex(YYTHD); }
++          { Lex->sphead->reset_lex(thd); }
+           expr
+           {
+             LEX *lex= Lex;
+@@ -2867,7 +2852,7 @@ sp_proc_stmt_return:
+                 MYSQL_YYABORT;
+               sp->m_flags|= sp_head::HAS_RETURN;
+             }
+-            if (sp->restore_lex(YYTHD))
++            if (sp->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+         ;
+@@ -3094,7 +3079,7 @@ sp_fetch_list:
+         ;
+ sp_if:
+-          { Lex->sphead->reset_lex(YYTHD); }
++          { Lex->sphead->reset_lex(thd); }
+           expr THEN_SYM
+           {
+             LEX *lex= Lex;
+@@ -3108,7 +3093,7 @@ sp_if:
+                 sp->add_cont_backpatch(i) ||
+                 sp->add_instr(i))
+               MYSQL_YYABORT;
+-            if (sp->restore_lex(YYTHD))
++            if (sp->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+           sp_proc_stmts1
+@@ -3147,7 +3132,7 @@ simple_case_stmt:
+           {
+             LEX *lex= Lex;
+             case_stmt_action_case(lex);
+-            lex->sphead->reset_lex(YYTHD); /* For expr $3 */
++            lex->sphead->reset_lex(thd); /* For expr $3 */
+           }
+           expr
+           {
+@@ -3156,7 +3141,7 @@ simple_case_stmt:
+               MYSQL_YYABORT;
+             /* For expr $3 */
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+           simple_when_clause_list
+@@ -3198,7 +3183,7 @@ searched_when_clause_list:
+ simple_when_clause:
+           WHEN_SYM
+           {
+-            Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
++            Lex->sphead->reset_lex(thd); /* For expr $3 */
+           }
+           expr
+           {
+@@ -3208,7 +3193,7 @@ simple_when_clause:
+             if (case_stmt_action_when(lex, $3, true))
+               MYSQL_YYABORT;
+             /* For expr $3 */
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+           THEN_SYM
+@@ -3223,7 +3208,7 @@ simple_when_clause:
+ searched_when_clause:
+           WHEN_SYM
+           {
+-            Lex->sphead->reset_lex(YYTHD); /* For expr $3 */
++            Lex->sphead->reset_lex(thd); /* For expr $3 */
+           }
+           expr
+           {
+@@ -3231,7 +3216,7 @@ searched_when_clause:
+             if (case_stmt_action_when(lex, $3, false))
+               MYSQL_YYABORT;
+             /* For expr $3 */
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+           THEN_SYM
+@@ -3395,7 +3380,7 @@ sp_unlabeled_control:
+               MYSQL_YYABORT;
+         }
+         | WHILE_SYM 
+-          { Lex->sphead->reset_lex(YYTHD); }
++          { Lex->sphead->reset_lex(thd); }
+           expr DO_SYM
+           {
+             LEX *lex= Lex;
+@@ -3409,7 +3394,7 @@ sp_unlabeled_control:
+                 sp->new_cont_backpatch(i) ||
+                 sp->add_instr(i))
+               MYSQL_YYABORT;
+-            if (sp->restore_lex(YYTHD))
++            if (sp->restore_lex(thd))
+               MYSQL_YYABORT;
+           }
+           sp_proc_stmts1 END WHILE_SYM
+@@ -3424,7 +3409,7 @@ sp_unlabeled_control:
+             lex->sphead->do_cont_backpatch();
+           }
+         | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM 
+-          { Lex->sphead->reset_lex(YYTHD); }
++          { Lex->sphead->reset_lex(thd); }
+           expr END REPEAT_SYM
+           {
+             LEX *lex= Lex;
+@@ -3436,7 +3421,7 @@ sp_unlabeled_control:
+             if (i == NULL ||
+                 lex->sphead->add_instr(i))
+               MYSQL_YYABORT;
+-            if (lex->sphead->restore_lex(YYTHD))
++            if (lex->sphead->restore_lex(thd))
+               MYSQL_YYABORT;
+             /* We can shortcut the cont_backpatch here */
+             i->m_cont_dest= ip+1;
+@@ -3859,7 +3844,6 @@ create2:
+           create3 {}
+         | LIKE table_ident
+           {
+-            THD *thd= YYTHD;
+             TABLE_LIST *src_table;
+             LEX *lex= thd->lex;
+@@ -3873,7 +3857,6 @@ create2:
+           }
+         | '(' LIKE table_ident ')'
+           {
+-            THD *thd= YYTHD;
+             TABLE_LIST *src_table;
+             LEX *lex= thd->lex;
+@@ -4342,7 +4325,6 @@ part_bit_expr:
+           bit_expr
+           {
+             Item *part_expr= $1;
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Name_resolution_context *context= &lex->current_select->context;
+             TABLE_LIST *save_list= context->table_list;
+@@ -4364,7 +4346,7 @@ part_bit_expr:
+               my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+               MYSQL_YYABORT;
+             }
+-            if (part_expr->fix_fields(YYTHD, (Item**)0) ||
++            if (part_expr->fix_fields(thd, (Item**)0) ||
+                 ((context->table_list= save_list), FALSE) ||
+                 (!part_expr->const_item()) ||
+                 (!lex->safe_to_cache_query))
+@@ -4629,7 +4611,7 @@ create_table_option:
+         | TYPE_SYM opt_equal storage_engines
+           {
+             Lex->create_info.db_type= $3;
+-            WARN_DEPRECATED(yythd, "6.0", "TYPE=storage_engine",
++            WARN_DEPRECATED(thd, "6.0", "TYPE=storage_engine",
+                             "'ENGINE=storage_engine'");
+             Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
+           }
+@@ -4791,19 +4773,19 @@ default_collation:
+ storage_engines:
+           ident_or_text
+           {
+-            plugin_ref plugin= ha_resolve_by_name(YYTHD, &$1);
++            plugin_ref plugin= ha_resolve_by_name(thd, &$1);
+             if (plugin)
+               $$= plugin_data(plugin, handlerton*);
+             else
+             {
+-              if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
++              if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
+               {
+                 my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
+                 MYSQL_YYABORT;
+               }
+               $$= 0;
+-              push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
++              push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                                   ER_UNKNOWN_STORAGE_ENGINE,
+                                   ER(ER_UNKNOWN_STORAGE_ENGINE),
+                                   $1.str);
+@@ -4815,7 +4797,7 @@ known_storage_engines:
+           ident_or_text
+           {
+             plugin_ref plugin;
+-            if ((plugin= ha_resolve_by_name(YYTHD, &$1)))
++            if ((plugin= ha_resolve_by_name(thd, &$1)))
+               $$= plugin_data(plugin, handlerton*);
+             else
+             {
+@@ -5043,7 +5025,7 @@ type:
+               {
+                 char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
+                 my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length);
+-                push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_NOTE,
++                push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                                     ER_WARN_DEPRECATED_SYNTAX,
+                                     ER(ER_WARN_DEPRECATED_SYNTAX),
+                                     buff, "YEAR(4)");
+@@ -5057,7 +5039,7 @@ type:
+           { $$=MYSQL_TYPE_TIME; }
+         | TIMESTAMP opt_field_length
+           {
+-            if (YYTHD->variables.sql_mode & MODE_MAXDB)
++            if (thd->variables.sql_mode & MODE_MAXDB)
+               $$=MYSQL_TYPE_DATETIME;
+             else
+             {
+@@ -5189,7 +5171,7 @@ int_type:
+ real_type:
+           REAL
+           {
+-            $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ?
++            $$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ?
+               MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
+           }
+         | DOUBLE_SYM
+@@ -5263,7 +5245,7 @@ attribute:
+         | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
+         | ON UPDATE_SYM NOW_SYM optional_braces
+           {
+-            Item *item= new (YYTHD->mem_root) Item_func_now_local();
++            Item *item= new (thd->mem_root) Item_func_now_local();
+             if (item == NULL)
+               MYSQL_YYABORT;
+             Lex->on_update_value= item;
+@@ -5312,7 +5294,7 @@ attribute:
+ now_or_signed_literal:
+           NOW_SYM optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_now_local();
++            $$= new (thd->mem_root) Item_func_now_local();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -5673,7 +5655,6 @@ string_list:
+ alter:
+           ALTER opt_ignore TABLE_SYM table_ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->name.str= 0;
+             lex->name.length= 0;
+@@ -5799,7 +5780,7 @@ alter:
+               Event_parse_data.
+             */
+-            if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
++            if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))
+               MYSQL_YYABORT;
+             Lex->event_parse_data->identifier= $4;
+@@ -6192,7 +6173,6 @@ alter_list_item:
+           {
+             if (!$4)
+             {
+-              THD *thd= YYTHD;
+               $4= thd->variables.collation_database;
+             }
+             $5= $5 ? $5 : $4;
+@@ -6556,7 +6536,7 @@ keycache_list:
+ assign_to_keycache:
+           table_ident cache_keys_spec
+           {
+-            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ, 
++            if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, 
+                                            Select->pop_index_hints()))
+               MYSQL_YYABORT;
+           }
+@@ -6585,7 +6565,7 @@ preload_list:
+ preload_keys:
+           table_ident cache_keys_spec opt_ignore_leaves
+           {
+-            if (!Select->add_table_to_list(YYTHD, $1, NULL, $3, TL_READ,
++            if (!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ,
+                                            Select->pop_index_hints()))
+               MYSQL_YYABORT;
+           }
+@@ -6593,7 +6573,7 @@ preload_keys:
+ cache_keys_spec:
+           {
+-            Lex->select_lex.alloc_index_hints(YYTHD);
++            Lex->select_lex.alloc_index_hints(thd);
+             Select->set_index_hint_type(INDEX_HINT_USE, 
+                                         global_system_variables.old_mode ? 
+                                         INDEX_HINT_MASK_JOIN : 
+@@ -6813,7 +6793,6 @@ select_item_list:
+         | select_item
+         | '*'
+           {
+-            THD *thd= YYTHD;
+             Item *item= new (thd->mem_root)
+                           Item_field(&thd->lex->current_select->context,
+                                      NULL, NULL, "*");
+@@ -6828,7 +6807,6 @@ select_item_list:
+ select_item:
+           remember_name select_item2 remember_end select_alias
+           {
+-            THD *thd= YYTHD;
+             DBUG_ASSERT($1 < $3);
+             if (add_item_to_list(thd, $2))
+@@ -6929,7 +6907,7 @@ expr:
+             else
+             {
+               /* X OR Y */
+-              $$ = new (YYTHD->mem_root) Item_cond_or($1, $3);
++              $$ = new (thd->mem_root) Item_cond_or($1, $3);
+               if ($$ == NULL)
+                 MYSQL_YYABORT;
+             }
+@@ -6937,7 +6915,7 @@ expr:
+         | expr XOR expr %prec XOR
+           {
+             /* XOR is a proprietary extension */
+-            $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3);
++            $$ = new (thd->mem_root) Item_cond_xor($1, $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -6979,50 +6957,50 @@ expr:
+             else
+             {
+               /* X AND Y */
+-              $$ = new (YYTHD->mem_root) Item_cond_and($1, $3);
++              $$ = new (thd->mem_root) Item_cond_and($1, $3);
+               if ($$ == NULL)
+                 MYSQL_YYABORT;
+             }
+           }
+         | NOT_SYM expr %prec NOT_SYM
+           {
+-            $$= negate_expression(YYTHD, $2);
++            $$= negate_expression(thd, $2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS TRUE_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_istrue($1);
++            $$= new (thd->mem_root) Item_func_istrue($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS not TRUE_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnottrue($1);
++            $$= new (thd->mem_root) Item_func_isnottrue($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS FALSE_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isfalse($1);
++            $$= new (thd->mem_root) Item_func_isfalse($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS not FALSE_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnotfalse($1);
++            $$= new (thd->mem_root) Item_func_isnotfalse($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS UNKNOWN_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnull($1);
++            $$= new (thd->mem_root) Item_func_isnull($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS not UNKNOWN_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
++            $$= new (thd->mem_root) Item_func_isnotnull($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7032,19 +7010,19 @@ expr:
+ bool_pri:
+           bool_pri IS NULL_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnull($1);
++            $$= new (thd->mem_root) Item_func_isnull($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri IS not NULL_SYM %prec IS
+           {
+-            $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
++            $$= new (thd->mem_root) Item_func_isnotnull($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_func_equal($1,$3);
++            $$= new (thd->mem_root) Item_func_equal($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7066,13 +7044,12 @@ bool_pri:
+ predicate:
+           bit_expr IN_SYM '(' subselect ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
++            $$= new (thd->mem_root) Item_in_subselect($1, $4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr not IN_SYM '(' subselect ')'
+           {
+-            THD *thd= YYTHD;
+             Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
+             if (item == NULL)
+               MYSQL_YYABORT;
+@@ -7082,7 +7059,7 @@ predicate:
+           }
+         | bit_expr IN_SYM '(' expr ')'
+           {
+-            $$= handle_sql2003_note184_exception(YYTHD, $1, true, $4);
++            $$= handle_sql2003_note184_exception(thd, $1, true, $4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7090,13 +7067,13 @@ predicate:
+           { 
+             $6->push_front($4);
+             $6->push_front($1);
+-            $$= new (YYTHD->mem_root) Item_func_in(*$6);
++            $$= new (thd->mem_root) Item_func_in(*$6);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr not IN_SYM '(' expr ')'
+           {
+-            $$= handle_sql2003_note184_exception(YYTHD, $1, false, $5);
++            $$= handle_sql2003_note184_exception(thd, $1, false, $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7104,7 +7081,7 @@ predicate:
+           {
+             $7->push_front($5);
+             $7->push_front($1);
+-            Item_func_in *item = new (YYTHD->mem_root) Item_func_in(*$7);
++            Item_func_in *item = new (thd->mem_root) Item_func_in(*$7);
+             if (item == NULL)
+               MYSQL_YYABORT;
+             item->negate();
+@@ -7112,14 +7089,14 @@ predicate:
+           }
+         | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
+           {
+-            $$= new (YYTHD->mem_root) Item_func_between($1,$3,$5);
++            $$= new (thd->mem_root) Item_func_between($1,$3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
+           {
+             Item_func_between *item;
+-            item= new (YYTHD->mem_root) Item_func_between($1,$4,$6);
++            item= new (thd->mem_root) Item_func_between($1,$4,$6);
+             if (item == NULL)
+               MYSQL_YYABORT;
+             item->negate();
+@@ -7127,42 +7104,42 @@ predicate:
+           }
+         | bit_expr SOUNDS_SYM LIKE bit_expr
+           {
+-            Item *item1= new (YYTHD->mem_root) Item_func_soundex($1);
+-            Item *item4= new (YYTHD->mem_root) Item_func_soundex($4);
++            Item *item1= new (thd->mem_root) Item_func_soundex($1);
++            Item *item4= new (thd->mem_root) Item_func_soundex($4);
+             if ((item1 == NULL) || (item4 == NULL))
+               MYSQL_YYABORT;
+-            $$= new (YYTHD->mem_root) Item_func_eq(item1, item4);
++            $$= new (thd->mem_root) Item_func_eq(item1, item4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr LIKE simple_expr opt_escape
+           {
+-            $$= new (YYTHD->mem_root) Item_func_like($1,$3,$4,Lex->escape_used);
++            $$= new (thd->mem_root) Item_func_like($1,$3,$4,Lex->escape_used);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr not LIKE simple_expr opt_escape
+           {
+-            Item *item= new (YYTHD->mem_root) Item_func_like($1,$4,$5,
++            Item *item= new (thd->mem_root) Item_func_like($1,$4,$5,
+                                                              Lex->escape_used);
+             if (item == NULL)
+               MYSQL_YYABORT;
+-            $$= new (YYTHD->mem_root) Item_func_not(item);
++            $$= new (thd->mem_root) Item_func_not(item);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr REGEXP bit_expr
+           {
+-            $$= new (YYTHD->mem_root) Item_func_regex($1,$3);
++            $$= new (thd->mem_root) Item_func_regex($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr not REGEXP bit_expr
+           {
+-            Item *item= new (YYTHD->mem_root) Item_func_regex($1,$4);
++            Item *item= new (thd->mem_root) Item_func_regex($1,$4);
+             if (item == NULL)
+               MYSQL_YYABORT;
+-            $$= negate_expression(YYTHD, item);
++            $$= negate_expression(thd, item);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7172,85 +7149,85 @@ predicate:
+ bit_expr:
+           bit_expr '|' bit_expr %prec '|'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_bit_or($1,$3);
++            $$= new (thd->mem_root) Item_func_bit_or($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '&' bit_expr %prec '&'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_bit_and($1,$3);
++            $$= new (thd->mem_root) Item_func_bit_and($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
+           {
+-            $$= new (YYTHD->mem_root) Item_func_shift_left($1,$3);
++            $$= new (thd->mem_root) Item_func_shift_left($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
+           {
+-            $$= new (YYTHD->mem_root) Item_func_shift_right($1,$3);
++            $$= new (thd->mem_root) Item_func_shift_right($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '+' bit_expr %prec '+'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_plus($1,$3);
++            $$= new (thd->mem_root) Item_func_plus($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '-' bit_expr %prec '-'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_minus($1,$3);
++            $$= new (thd->mem_root) Item_func_minus($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '+' INTERVAL_SYM expr interval %prec '+'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,0);
++            $$= new (thd->mem_root) Item_date_add_interval($1,$4,$5,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '-' INTERVAL_SYM expr interval %prec '-'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,1);
++            $$= new (thd->mem_root) Item_date_add_interval($1,$4,$5,1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '*' bit_expr %prec '*'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_mul($1,$3);
++            $$= new (thd->mem_root) Item_func_mul($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '/' bit_expr %prec '/'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_div($1,$3);
++            $$= new (thd->mem_root) Item_func_div($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '%' bit_expr %prec '%'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
++            $$= new (thd->mem_root) Item_func_mod($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr DIV_SYM bit_expr %prec DIV_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_func_int_div($1,$3);
++            $$= new (thd->mem_root) Item_func_int_div($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr MOD_SYM bit_expr %prec MOD_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
++            $$= new (thd->mem_root) Item_func_mod($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | bit_expr '^' bit_expr
+           {
+-            $$= new (YYTHD->mem_root) Item_func_bit_xor($1,$3);
++            $$= new (thd->mem_root) Item_func_bit_xor($1,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7299,7 +7276,6 @@ simple_expr:
+         | function_call_conflict
+         | simple_expr COLLATE_SYM ident_or_text %prec NEG
+           {
+-            THD *thd= YYTHD;
+             Item *i1= new (thd->mem_root) Item_string($3.str,
+                                                       $3.length,
+                                                       thd->charset());
+@@ -7315,7 +7291,7 @@ simple_expr:
+         | sum_expr
+         | simple_expr OR_OR_SYM simple_expr
+           {
+-            $$= new (YYTHD->mem_root) Item_func_concat($1, $3);
++            $$= new (thd->mem_root) Item_func_concat($1, $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7325,25 +7301,25 @@ simple_expr:
+           }
+         | '-' simple_expr %prec NEG
+           {
+-            $$= new (YYTHD->mem_root) Item_func_neg($2);
++            $$= new (thd->mem_root) Item_func_neg($2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | '~' simple_expr %prec NEG
+           {
+-            $$= new (YYTHD->mem_root) Item_func_bit_neg($2);
++            $$= new (thd->mem_root) Item_func_bit_neg($2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | not2 simple_expr %prec NEG
+           {
+-            $$= negate_expression(YYTHD, $2);
++            $$= negate_expression(thd, $2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | '(' subselect ')'
+           { 
+-            $$= new (YYTHD->mem_root) Item_singlerow_subselect($2);
++            $$= new (thd->mem_root) Item_singlerow_subselect($2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7352,20 +7328,20 @@ simple_expr:
+         | '(' expr ',' expr_list ')'
+           {
+             $4->push_front($2);
+-            $$= new (YYTHD->mem_root) Item_row(*$4);
++            $$= new (thd->mem_root) Item_row(*$4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | ROW_SYM '(' expr ',' expr_list ')'
+           {
+             $5->push_front($3);
+-            $$= new (YYTHD->mem_root) Item_row(*$5);
++            $$= new (thd->mem_root) Item_row(*$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | EXISTS '(' subselect ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_exists_subselect($3);
++            $$= new (thd->mem_root) Item_exists_subselect($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7374,7 +7350,7 @@ simple_expr:
+         | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
+           {
+             $2->push_front($5);
+-            Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6);
++            Item_func_match *i1= new (thd->mem_root) Item_func_match(*$2, $6);
+             if (i1 == NULL)
+               MYSQL_YYABORT;
+             Select->add_ftfunc_to_list(i1);
+@@ -7382,7 +7358,7 @@ simple_expr:
+           }
+         | BINARY simple_expr %prec NEG
+           {
+-            $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, NULL, NULL,
++            $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL,
+                                  &my_charset_bin);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+@@ -7390,27 +7366,27 @@ simple_expr:
+         | CAST_SYM '(' expr AS cast_type ')'
+           {
+             LEX *lex= Lex;
+-            $$= create_func_cast(YYTHD, $3, $5, lex->length, lex->dec,
++            $$= create_func_cast(thd, $3, $5, lex->length, lex->dec,
+                                  lex->charset);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CASE_SYM opt_expr when_list opt_else END
+           {
+-            $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 );
++            $$= new (thd->mem_root) Item_func_case(* $3, $2, $4 );
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CONVERT_SYM '(' expr ',' cast_type ')'
+           {
+-            $$= create_func_cast(YYTHD, $3, $5, Lex->length, Lex->dec,
++            $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec,
+                                  Lex->charset);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CONVERT_SYM '(' expr USING charset_name ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5);
++            $$= new (thd->mem_root) Item_func_conv_charset($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7423,14 +7399,14 @@ simple_expr:
+               my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
+               MYSQL_YYABORT;
+             }
+-            $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
++            $$= new (thd->mem_root) Item_default_value(Lex->current_context(),
+                                                          $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | VALUES '(' simple_ident_nospvar ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(),
++            $$= new (thd->mem_root) Item_insert_value(Lex->current_context(),
+                                                         $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+@@ -7438,7 +7414,7 @@ simple_expr:
+         | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM
+           /* we cannot put interval before - */
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($5,$2,$3,0);
++            $$= new (thd->mem_root) Item_date_add_interval($5,$2,$3,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7453,19 +7429,19 @@ simple_expr:
+ function_call_keyword:
+           CHAR_SYM '(' expr_list ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_char(*$3);
++            $$= new (thd->mem_root) Item_func_char(*$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CHAR_SYM '(' expr_list USING charset_name ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_char(*$3, $5);
++            $$= new (thd->mem_root) Item_func_char(*$3, $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CURRENT_USER optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
++            $$= new (thd->mem_root) Item_func_current_user(Lex->current_context());
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->set_stmt_unsafe();
+@@ -7473,31 +7449,30 @@ function_call_keyword:
+           }
+         | DATE_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_typecast($3);
++            $$= new (thd->mem_root) Item_date_typecast($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | DAY_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_dayofmonth($3);
++            $$= new (thd->mem_root) Item_func_dayofmonth($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | HOUR_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_hour($3);
++            $$= new (thd->mem_root) Item_func_hour($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | INSERT '(' expr ',' expr ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9);
++            $$= new (thd->mem_root) Item_func_insert($3,$5,$7,$9);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM
+           {
+-            THD *thd= YYTHD;
+             List<Item> *list= new (thd->mem_root) List<Item>;
+             if (list == NULL)
+               MYSQL_YYABORT;
+@@ -7512,7 +7487,6 @@ function_call_keyword:
+           }
+         | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM
+           {
+-            THD *thd= YYTHD;
+             $7->push_front($5);
+             $7->push_front($3);
+             Item_row *item= new (thd->mem_root) Item_row(*$7);
+@@ -7524,103 +7498,103 @@ function_call_keyword:
+           }
+         | LEFT '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_left($3,$5);
++            $$= new (thd->mem_root) Item_func_left($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MINUTE_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_minute($3);
++            $$= new (thd->mem_root) Item_func_minute($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MONTH_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_month($3);
++            $$= new (thd->mem_root) Item_func_month($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | RIGHT '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_right($3,$5);
++            $$= new (thd->mem_root) Item_func_right($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SECOND_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_second($3);
++            $$= new (thd->mem_root) Item_func_second($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TIME_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_time_typecast($3);
++            $$= new (thd->mem_root) Item_time_typecast($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TIMESTAMP '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_datetime_typecast($3);
++            $$= new (thd->mem_root) Item_datetime_typecast($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TIMESTAMP '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0);
++            $$= new (thd->mem_root) Item_func_add_time($3, $5, 1, 0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_trim($3);
++            $$= new (thd->mem_root) Item_func_trim($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' LEADING expr FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4);
++            $$= new (thd->mem_root) Item_func_ltrim($6,$4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' TRAILING expr FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4);
++            $$= new (thd->mem_root) Item_func_rtrim($6,$4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' BOTH expr FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_trim($6,$4);
++            $$= new (thd->mem_root) Item_func_trim($6,$4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' LEADING FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_ltrim($5);
++            $$= new (thd->mem_root) Item_func_ltrim($5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' TRAILING FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_rtrim($5);
++            $$= new (thd->mem_root) Item_func_rtrim($5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' BOTH FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_trim($5);
++            $$= new (thd->mem_root) Item_func_trim($5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRIM '(' expr FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_trim($5,$3);
++            $$= new (thd->mem_root) Item_func_trim($5,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | USER '(' ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_user();
++            $$= new (thd->mem_root) Item_func_user();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->set_stmt_unsafe();
+@@ -7628,7 +7602,7 @@ function_call_keyword:
+           }
+         | YEAR_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_year($3);
++            $$= new (thd->mem_root) Item_func_year($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7649,34 +7623,34 @@ function_call_keyword:
+ function_call_nonkeyword:
+           ADDDATE_SYM '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
++            $$= new (thd->mem_root) Item_date_add_interval($3, $5,
+                                                              INTERVAL_DAY, 0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0);
++            $$= new (thd->mem_root) Item_date_add_interval($3, $6, $7, 0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CURDATE optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_curdate_local();
++            $$= new (thd->mem_root) Item_func_curdate_local();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | CURTIME optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_curtime_local();
++            $$= new (thd->mem_root) Item_func_curtime_local();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | CURTIME '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_curtime_local($3);
++            $$= new (thd->mem_root) Item_func_curtime_local($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+@@ -7684,83 +7658,83 @@ function_call_nonkeyword:
+         | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
+           %prec INTERVAL_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,0);
++            $$= new (thd->mem_root) Item_date_add_interval($3,$6,$7,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
+           %prec INTERVAL_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,1);
++            $$= new (thd->mem_root) Item_date_add_interval($3,$6,$7,1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | EXTRACT_SYM '(' interval FROM expr ')'
+           {
+-            $$=new (YYTHD->mem_root) Item_extract( $3, $5);
++            $$=new (thd->mem_root) Item_extract( $3, $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | GET_FORMAT '(' date_time_type  ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_get_format($3, $5);
++            $$= new (thd->mem_root) Item_func_get_format($3, $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | NOW_SYM optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_now_local();
++            $$= new (thd->mem_root) Item_func_now_local();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | NOW_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_now_local($3);
++            $$= new (thd->mem_root) Item_func_now_local($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | POSITION_SYM '(' bit_expr IN_SYM expr ')'
+           {
+-            $$ = new (YYTHD->mem_root) Item_func_locate($5,$3);
++            $$ = new (thd->mem_root) Item_func_locate($5,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBDATE_SYM '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
++            $$= new (thd->mem_root) Item_date_add_interval($3, $5,
+                                                              INTERVAL_DAY, 1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1);
++            $$= new (thd->mem_root) Item_date_add_interval($3, $6, $7, 1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBSTRING '(' expr ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
++            $$= new (thd->mem_root) Item_func_substr($3,$5,$7);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBSTRING '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
++            $$= new (thd->mem_root) Item_func_substr($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
++            $$= new (thd->mem_root) Item_func_substr($3,$5,$7);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUBSTRING '(' expr FROM expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
++            $$= new (thd->mem_root) Item_func_substr($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7775,9 +7749,9 @@ function_call_nonkeyword:
+             */
+             Lex->set_stmt_unsafe();
+             if (global_system_variables.sysdate_is_now == 0)
+-              $$= new (YYTHD->mem_root) Item_func_sysdate_local();
++              $$= new (thd->mem_root) Item_func_sysdate_local();
+             else
+-              $$= new (YYTHD->mem_root) Item_func_now_local();
++              $$= new (thd->mem_root) Item_func_now_local();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+@@ -7785,42 +7759,42 @@ function_call_nonkeyword:
+         | SYSDATE '(' expr ')'
+           {
+             if (global_system_variables.sysdate_is_now == 0)
+-              $$= new (YYTHD->mem_root) Item_func_sysdate_local($3);
++              $$= new (thd->mem_root) Item_func_sysdate_local($3);
+             else
+-              $$= new (YYTHD->mem_root) Item_func_now_local($3);
++              $$= new (thd->mem_root) Item_func_now_local($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0);
++            $$= new (thd->mem_root) Item_date_add_interval($7,$5,$3,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3);
++            $$= new (thd->mem_root) Item_func_timestamp_diff($5,$7,$3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | UTC_DATE_SYM optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_curdate_utc();
++            $$= new (thd->mem_root) Item_func_curdate_utc();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | UTC_TIME_SYM optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_curtime_utc();
++            $$= new (thd->mem_root) Item_func_curtime_utc();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | UTC_TIMESTAMP_SYM optional_braces
+           {
+-            $$= new (YYTHD->mem_root) Item_func_now_utc();
++            $$= new (thd->mem_root) Item_func_now_utc();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+@@ -7835,62 +7809,61 @@ function_call_nonkeyword:
+ function_call_conflict:
+           ASCII_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_ascii($3);
++            $$= new (thd->mem_root) Item_func_ascii($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | CHARSET '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_charset($3);
++            $$= new (thd->mem_root) Item_func_charset($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | COALESCE '(' expr_list ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_coalesce(* $3);
++            $$= new (thd->mem_root) Item_func_coalesce(* $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | COLLATION_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_collation($3);
++            $$= new (thd->mem_root) Item_func_collation($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | DATABASE '(' ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_database();
++            $$= new (thd->mem_root) Item_func_database();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             Lex->safe_to_cache_query=0;
+           }
+         | IF '(' expr ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7);
++            $$= new (thd->mem_root) Item_func_if($3,$5,$7);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MICROSECOND_SYM '(' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_microsecond($3);
++            $$= new (thd->mem_root) Item_func_microsecond($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MOD_SYM '(' expr ',' expr ')'
+           {
+-            $$ = new (YYTHD->mem_root) Item_func_mod($3, $5);
++            $$ = new (thd->mem_root) Item_func_mod($3, $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | OLD_PASSWORD '(' expr ')'
+           {
+-            $$=  new (YYTHD->mem_root) Item_func_old_password($3);
++            $$=  new (thd->mem_root) Item_func_old_password($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | PASSWORD '(' expr ')'
+           {
+-            THD *thd= YYTHD;
+             Item* i1;
+             if (thd->variables.old_passwords)
+               i1= new (thd->mem_root) Item_func_old_password($3);
+@@ -7902,31 +7875,30 @@ function_call_conflict:
+           }
+         | QUARTER_SYM '(' expr ')'
+           {
+-            $$ = new (YYTHD->mem_root) Item_func_quarter($3);
++            $$ = new (thd->mem_root) Item_func_quarter($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | REPEAT_SYM '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_repeat($3,$5);
++            $$= new (thd->mem_root) Item_func_repeat($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | REPLACE '(' expr ',' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7);
++            $$= new (thd->mem_root) Item_func_replace($3,$5,$7);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRUNCATE_SYM '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_round($3,$5,1);
++            $$= new (thd->mem_root) Item_func_round($3,$5,1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | WEEK_SYM '(' expr ')'
+           {
+-            THD *thd= YYTHD;
+             Item *i1= new (thd->mem_root) Item_int((char*) "0",
+                                            thd->variables.default_week_format,
+                                                    1);
+@@ -7938,7 +7910,7 @@ function_call_conflict:
+           }
+         | WEEK_SYM '(' expr ',' expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_func_week($3,$5);
++            $$= new (thd->mem_root) Item_func_week($3,$5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -7960,52 +7932,52 @@ function_call_conflict:
+ geometry_function:
+           CONTAINS_SYM '(' expr ',' expr ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_rel($3, $5,
+                                                Item_func::SP_CONTAINS_FUNC));
+           }
+         | GEOMETRYCOLLECTION '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_geometrycollection,
+                            Geometry::wkb_point));
+           }
+         | LINESTRING '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_linestring,
+                            Geometry::wkb_point));
+           }
+         | MULTILINESTRING '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_multilinestring,
+                            Geometry::wkb_linestring));
+           }
+         | MULTIPOINT '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_multipoint,
+                            Geometry::wkb_point));
+           }
+         | MULTIPOLYGON '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_multipolygon,
+                            Geometry::wkb_polygon));
+           }
+         | POINT_SYM '(' expr ',' expr ')'
+           {
+-            $$= GEOM_NEW(YYTHD, Item_func_point($3,$5));
++            $$= GEOM_NEW(thd, Item_func_point($3,$5));
+           }
+         | POLYGON '(' expr_list ')'
+           {
+-            $$= GEOM_NEW(YYTHD,
++            $$= GEOM_NEW(thd,
+                          Item_func_spatial_collection(* $3,
+                            Geometry::wkb_polygon,
+                            Geometry::wkb_linestring));
+@@ -8043,7 +8015,6 @@ function_call_generic:
+           }
+           opt_udf_expr_list ')'
+           {
+-            THD *thd= YYTHD;
+             Create_func *builder;
+             Item *item= NULL;
+@@ -8097,7 +8068,6 @@ function_call_generic:
+           }
+         | ident '.' ident '(' opt_expr_list ')'
+           {
+-            THD *thd= YYTHD;
+             Create_qfunc *builder;
+             Item *item= NULL;
+@@ -8161,7 +8131,7 @@ opt_udf_expr_list:
+ udf_expr_list:
+           udf_expr
+           {
+-            $$= new (YYTHD->mem_root) List<Item>;
++            $$= new (thd->mem_root) List<Item>;
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->push_back($1);
+@@ -8194,7 +8164,7 @@ udf_expr:
+                remember_name we may get quoted or escaped names.
+             */
+             else if ($2->type() != Item::FIELD_ITEM)
+-              $2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
++              $2->set_name($1, (uint) ($3 - $1), thd->charset());
+             $$= $2;
+           }
+         ;
+@@ -8202,46 +8172,46 @@ udf_expr:
+ sum_expr:
+           AVG_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_avg($3);
++            $$= new (thd->mem_root) Item_sum_avg($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | AVG_SYM '(' DISTINCT in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_avg_distinct($4);
++            $$= new (thd->mem_root) Item_sum_avg_distinct($4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | BIT_AND  '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_and($3);
++            $$= new (thd->mem_root) Item_sum_and($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | BIT_OR  '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_or($3);
++            $$= new (thd->mem_root) Item_sum_or($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | BIT_XOR  '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_xor($3);
++            $$= new (thd->mem_root) Item_sum_xor($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | COUNT_SYM '(' opt_all '*' ')'
+           {
+-            Item *item= new (YYTHD->mem_root) Item_int((int32) 0L,1);
++            Item *item= new (thd->mem_root) Item_int((int32) 0L,1);
+             if (item == NULL)
+               MYSQL_YYABORT;
+-            $$= new (YYTHD->mem_root) Item_sum_count(item);
++            $$= new (thd->mem_root) Item_sum_count(item);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | COUNT_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_count($3);
++            $$= new (thd->mem_root) Item_sum_count($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -8251,13 +8221,13 @@ sum_expr:
+           { Select->in_sum_expr--; }
+           ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_count_distinct(* $5);
++            $$= new (thd->mem_root) Item_sum_count_distinct(* $5);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MIN_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_min($3);
++            $$= new (thd->mem_root) Item_sum_min($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -8268,55 +8238,55 @@ sum_expr:
+         */
+         | MIN_SYM '(' DISTINCT in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_min($4);
++            $$= new (thd->mem_root) Item_sum_min($4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MAX_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_max($3);
++            $$= new (thd->mem_root) Item_sum_max($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | MAX_SYM '(' DISTINCT in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_max($4);
++            $$= new (thd->mem_root) Item_sum_max($4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | STD_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_std($3, 0);
++            $$= new (thd->mem_root) Item_sum_std($3, 0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | VARIANCE_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_variance($3, 0);
++            $$= new (thd->mem_root) Item_sum_variance($3, 0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | STDDEV_SAMP_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_std($3, 1);
++            $$= new (thd->mem_root) Item_sum_std($3, 1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | VAR_SAMP_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_variance($3, 1);
++            $$= new (thd->mem_root) Item_sum_variance($3, 1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUM_SYM '(' in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_sum($3);
++            $$= new (thd->mem_root) Item_sum_sum($3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | SUM_SYM '(' DISTINCT in_sum_expr ')'
+           {
+-            $$= new (YYTHD->mem_root) Item_sum_sum_distinct($4);
++            $$= new (thd->mem_root) Item_sum_sum_distinct($4);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -8328,7 +8298,7 @@ sum_expr:
+           {
+             SELECT_LEX *sel= Select;
+             sel->in_sum_expr--;
+-            $$= new (YYTHD->mem_root)
++            $$= new (thd->mem_root)
+                   Item_func_group_concat(Lex->current_context(), $3, $5,
+                                          sel->gorder_list, $7);
+             if ($$ == NULL)
+@@ -8357,7 +8327,7 @@ variable_aux:
+           ident_or_text SET_VAR expr
+           {
+             Item_func_set_user_var *item;
+-            $$= item= new (YYTHD->mem_root) Item_func_set_user_var($1, $3);
++            $$= item= new (thd->mem_root) Item_func_set_user_var($1, $3);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             LEX *lex= Lex;
+@@ -8366,7 +8336,7 @@ variable_aux:
+           }
+         | ident_or_text
+           {
+-            $$= new (YYTHD->mem_root) Item_func_get_user_var($1);
++            $$= new (thd->mem_root) Item_func_get_user_var($1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             LEX *lex= Lex;
+@@ -8380,7 +8350,7 @@ variable_aux:
+               my_parse_error(ER(ER_SYNTAX_ERROR));
+               MYSQL_YYABORT;
+             }
+-            if (!($$= get_system_var(YYTHD, $2, $3, $4)))
++            if (!($$= get_system_var(thd, $2, $3, $4)))
+               MYSQL_YYABORT;
+             if (!((Item_func_get_system_var*) $$)->is_written_to_binlog())
+               Lex->set_stmt_unsafe();
+@@ -8395,7 +8365,7 @@ opt_distinct:
+ opt_gconcat_separator:
+           /* empty */
+           {
+-            $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1);
++            $$= new (thd->mem_root) String(",", 1, &my_charset_latin1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -8422,9 +8392,9 @@ opt_gorder_clause:
+ gorder_list:
+           gorder_list ',' order_ident order_dir
+-          { if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
++          { if (add_gorder_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
+         | order_ident order_dir
+-          { if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
++          { if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
+         ;
+ in_sum_expr:
+@@ -8477,7 +8447,7 @@ opt_expr_list:
+ expr_list:
+           expr
+           {
+-            $$= new (YYTHD->mem_root) List<Item>;
++            $$= new (thd->mem_root) List<Item>;
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->push_back($1);
+@@ -8497,7 +8467,7 @@ ident_list_arg:
+ ident_list:
+           simple_ident
+           {
+-            $$= new (YYTHD->mem_root) List<Item>;
++            $$= new (thd->mem_root) List<Item>;
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             $$->push_back($1);
+@@ -8595,7 +8565,7 @@ join_table:
+           {
+             MYSQL_YYABORT_UNLESS($1 && $3);
+             /* Change the current name resolution context to a local context. */
+-            if (push_new_name_resolution_context(YYTHD, $1, $3))
++            if (push_new_name_resolution_context(thd, $1, $3))
+               MYSQL_YYABORT;
+             Select->parsing_place= IN_ON;
+           }
+@@ -8610,7 +8580,7 @@ join_table:
+           {
+             MYSQL_YYABORT_UNLESS($1 && $3);
+             /* Change the current name resolution context to a local context. */
+-            if (push_new_name_resolution_context(YYTHD, $1, $3))
++            if (push_new_name_resolution_context(thd, $1, $3))
+               MYSQL_YYABORT;
+             Select->parsing_place= IN_ON;
+           }
+@@ -8640,7 +8610,7 @@ join_table:
+           {
+             MYSQL_YYABORT_UNLESS($1 && $5);
+             /* Change the current name resolution context to a local context. */
+-            if (push_new_name_resolution_context(YYTHD, $1, $5))
++            if (push_new_name_resolution_context(thd, $1, $5))
+               MYSQL_YYABORT;
+             Select->parsing_place= IN_ON;
+           }
+@@ -8676,7 +8646,7 @@ join_table:
+           {
+             MYSQL_YYABORT_UNLESS($1 && $5);
+             /* Change the current name resolution context to a local context. */
+-            if (push_new_name_resolution_context(YYTHD, $1, $5))
++            if (push_new_name_resolution_context(thd, $1, $5))
+               MYSQL_YYABORT;
+             Select->parsing_place= IN_ON;
+           }
+@@ -8724,7 +8694,7 @@ table_factor:
+           }
+           table_ident opt_table_alias opt_key_definition
+           {
+-            if (!($$= Select->add_table_to_list(YYTHD, $2, $3,
++            if (!($$= Select->add_table_to_list(thd, $2, $3,
+                                                 Select->get_table_join_options(),
+                                                 Lex->lock_option,
+                                                 Select->pop_index_hints())))
+@@ -8922,7 +8892,7 @@ index_hints_list:
+ opt_index_hints_list:
+           /* empty */
+-        | { Select->alloc_index_hints(YYTHD); } index_hints_list
++        | { Select->alloc_index_hints(thd); } index_hints_list
+         ;
+ opt_key_definition:
+@@ -8931,15 +8901,15 @@ opt_key_definition:
+         ;
+ opt_key_usage_list:
+-          /* empty */ { Select->add_index_hint(YYTHD, NULL, 0); }
++          /* empty */ { Select->add_index_hint(thd, NULL, 0); }
+         | key_usage_list {}
+         ;
+ key_usage_element:
+           ident
+-          { Select->add_index_hint(YYTHD, $1.str, $1.length); }
++          { Select->add_index_hint(thd, $1.str, $1.length); }
+         | PRIMARY_SYM
+-          { Select->add_index_hint(YYTHD, (char *)"PRIMARY", 7); }
++          { Select->add_index_hint(thd, (char *)"PRIMARY", 7); }
+         ;
+ key_usage_list:
+@@ -8952,7 +8922,7 @@ using_list:
+           {
+             if (!($$= new List<String>))
+               MYSQL_YYABORT;
+-            String *s= new (YYTHD->mem_root) String((const char *) $1.str,
++            String *s= new (thd->mem_root) String((const char *) $1.str,
+                                                     $1.length,
+                                                     system_charset_info);
+             if (s == NULL)
+@@ -8961,7 +8931,7 @@ using_list:
+           }
+         | using_list ',' ident
+           {
+-            String *s= new (YYTHD->mem_root) String((const char *) $3.str,
++            String *s= new (thd->mem_root) String((const char *) $3.str,
+                                                     $3.length,
+                                                     system_charset_info);
+             if (s == NULL)
+@@ -9002,7 +8972,7 @@ interval_time_stamp:
+                                     implementation without changing its
+                                     resolution.
+                                   */
+-                                  WARN_DEPRECATED(yythd, VER_CELOSIA, "FRAC_SECOND", "MICROSECOND");
++                                  WARN_DEPRECATED(thd, VER_CELOSIA, "FRAC_SECOND", "MICROSECOND");
+                                 }
+       ;
+@@ -9086,7 +9056,6 @@ opt_escape:
+           }
+         | /* empty */
+           {
+-            THD *thd= YYTHD;
+             Lex->escape_used= FALSE;
+             $$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ?
+                  new (thd->mem_root) Item_string("", 0, &my_charset_latin1) :
+@@ -9107,9 +9076,9 @@ group_clause:
+ group_list:
+           group_list ',' order_ident order_dir
+-          { if (add_group_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
++          { if (add_group_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
+         | order_ident order_dir
+-          { if (add_group_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
++          { if (add_group_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
+         ;
+ olap_opt:
+@@ -9156,7 +9125,6 @@ alter_order_list:
+ alter_order_item:
+           simple_ident_nospvar order_dir
+           {
+-            THD *thd= YYTHD;
+             bool ascending= ($2 == 1) ? true : false;
+             if (add_order_to_list(thd, $1, ascending))
+               MYSQL_YYABORT;
+@@ -9209,9 +9177,9 @@ order_clause:
+ order_list:
+           order_list ',' order_ident order_dir
+-          { if (add_order_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
++          { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
+         | order_ident order_dir
+-          { if (add_order_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
++          { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
+         ;
+ order_dir:
+@@ -9271,19 +9239,19 @@ limit_option:
+         }
+         | ULONGLONG_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
++            $$= new (thd->mem_root) Item_uint($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | LONG_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
++            $$= new (thd->mem_root) Item_uint($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
++            $$= new (thd->mem_root) Item_uint($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -9365,7 +9333,7 @@ procedure_clause:
+             lex->proc_list.elements=0;
+             lex->proc_list.first=0;
+             lex->proc_list.next= &lex->proc_list.first;
+-            Item_field *item= new (YYTHD->mem_root)
++            Item_field *item= new (thd->mem_root)
+                                 Item_field(&lex->current_select->context,
+                                            NULL, NULL, $2.str);
+             if (item == NULL)
+@@ -9390,8 +9358,6 @@ procedure_list2:
+ procedure_item:
+           remember_name expr remember_end
+           {
+-            THD *thd= YYTHD;
+-
+             if (add_proc_to_list(thd, $2))
+               MYSQL_YYABORT;
+             if (!$2->name)
+@@ -9560,7 +9526,6 @@ drop:
+           }
+         | DROP FUNCTION_SYM if_exists ident '.' ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             sp_name *spname;
+             if ($4.str && check_db_name(&$4))
+@@ -9583,7 +9548,6 @@ drop:
+           }
+         | DROP FUNCTION_SYM if_exists ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             LEX_STRING db= {0, 0};
+             sp_name *spname;
+@@ -9664,7 +9628,7 @@ table_list:
+ table_name:
+           table_ident
+           {
+-            if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING))
++            if (!Select->add_table_to_list(thd, $1, NULL, TL_OPTION_UPDATING))
+               MYSQL_YYABORT;
+           }
+         ;
+@@ -9677,7 +9641,7 @@ table_alias_ref_list:
+ table_alias_ref:
+           table_ident_opt_wild
+           {
+-            if (!Select->add_table_to_list(YYTHD, $1, NULL,
++            if (!Select->add_table_to_list(thd, $1, NULL,
+                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
+                                            Lex->lock_option ))
+               MYSQL_YYABORT;
+@@ -9868,7 +9832,7 @@ expr_or_default:
+           expr { $$= $1;}
+         | DEFAULT
+           {
+-            $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context());
++            $$= new (thd->mem_root) Item_default_value(Lex->current_context());
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -9922,7 +9886,7 @@ update_list:
+ update_elem:
+           simple_ident_nospvar equal expr_or_default
+           {
+-            if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
++            if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
+               MYSQL_YYABORT;
+           }
+         ;
+@@ -9965,7 +9929,7 @@ delete:
+ single_multi:
+           FROM table_ident
+           {
+-            if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
++            if (!Select->add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING,
+                                            Lex->lock_option))
+               MYSQL_YYABORT;
+           }
+@@ -9998,7 +9962,7 @@ table_wild_one:
+             Table_ident *ti= new Table_ident($1);
+             if (ti == NULL)
+               MYSQL_YYABORT;
+-            if (!Select->add_table_to_list(YYTHD,
++            if (!Select->add_table_to_list(thd,
+                                            ti,
+                                            $3,
+                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
+@@ -10007,10 +9971,10 @@ table_wild_one:
+           }
+         | ident '.' ident opt_wild opt_table_alias
+           {
+-            Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
++            Table_ident *ti= new Table_ident(thd, $1, $3, 0);
+             if (ti == NULL)
+               MYSQL_YYABORT;
+-            if (!Select->add_table_to_list(YYTHD,
++            if (!Select->add_table_to_list(thd,
+                                            ti,
+                                            $5, 
+                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
+@@ -10130,7 +10094,7 @@ show_param:
+            {
+              LEX *lex= Lex;
+              lex->sql_command= SQLCOM_SHOW_DATABASES;
+-             if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA))
++             if (prepare_schema_table(thd, lex, 0, SCH_SCHEMATA))
+                MYSQL_YYABORT;
+            }
+          | opt_full TABLES opt_db wild_and_where
+@@ -10138,7 +10102,7 @@ show_param:
+              LEX *lex= Lex;
+              lex->sql_command= SQLCOM_SHOW_TABLES;
+              lex->select_lex.db= $3;
+-             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
++             if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
+                MYSQL_YYABORT;
+            }
+          | opt_full TRIGGERS_SYM opt_db wild_and_where
+@@ -10146,7 +10110,7 @@ show_param:
+              LEX *lex= Lex;
+              lex->sql_command= SQLCOM_SHOW_TRIGGERS;
+              lex->select_lex.db= $3;
+-             if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS))
++             if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
+                MYSQL_YYABORT;
+            }
+          | EVENTS_SYM opt_db wild_and_where
+@@ -10154,7 +10118,7 @@ show_param:
+              LEX *lex= Lex;
+              lex->sql_command= SQLCOM_SHOW_EVENTS;
+              lex->select_lex.db= $2;
+-             if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS))
++             if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
+                MYSQL_YYABORT;
+            }
+          | TABLE_SYM STATUS_SYM opt_db wild_and_where
+@@ -10162,7 +10126,7 @@ show_param:
+              LEX *lex= Lex;
+              lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
+              lex->select_lex.db= $3;
+-             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
++             if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
+                MYSQL_YYABORT;
+            }
+         | OPEN_SYM TABLES opt_db wild_and_where
+@@ -10170,22 +10134,22 @@ show_param:
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
+             lex->select_lex.db= $3;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
++            if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
+               MYSQL_YYABORT;
+           }
+         | opt_full PLUGIN_SYM
+           {
+             LEX *lex= Lex;
+-            WARN_DEPRECATED(yythd, "6.0", "SHOW PLUGIN", "'SHOW PLUGINS'");
++            WARN_DEPRECATED(thd, "6.0", "SHOW PLUGIN", "'SHOW PLUGINS'");
+             lex->sql_command= SQLCOM_SHOW_PLUGINS;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
++            if (prepare_schema_table(thd, lex, 0, SCH_PLUGINS))
+               MYSQL_YYABORT;
+           }
+         | PLUGINS_SYM
+           {
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_PLUGINS;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
++            if (prepare_schema_table(thd, lex, 0, SCH_PLUGINS))
+               MYSQL_YYABORT;
+           }
+         | ENGINE_SYM known_storage_engines show_engine_param
+@@ -10198,7 +10162,7 @@ show_param:
+             lex->sql_command= SQLCOM_SHOW_FIELDS;
+             if ($5)
+               $4->change_db($5);
+-            if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS))
++            if (prepare_schema_table(thd, lex, $4, SCH_COLUMNS))
+               MYSQL_YYABORT;
+           }
+         | NEW_SYM MASTER_SYM FOR_SYM SLAVE
+@@ -10233,7 +10197,7 @@ show_param:
+             lex->sql_command= SQLCOM_SHOW_KEYS;
+             if ($4)
+               $3->change_db($4);
+-            if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS))
++            if (prepare_schema_table(thd, lex, $3, SCH_STATISTICS))
+               MYSQL_YYABORT;
+           }
+         | COLUMN_SYM TYPES_SYM
+@@ -10245,15 +10209,15 @@ show_param:
+           {
+             LEX *lex=Lex;
+             lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
+-            WARN_DEPRECATED(yythd, "6.0", "SHOW TABLE TYPES", "'SHOW [STORAGE] ENGINES'");
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
++            WARN_DEPRECATED(thd, "6.0", "SHOW TABLE TYPES", "'SHOW [STORAGE] ENGINES'");
++            if (prepare_schema_table(thd, lex, 0, SCH_ENGINES))
+               MYSQL_YYABORT;
+           }
+         | opt_storage ENGINES_SYM
+           {
+             LEX *lex=Lex;
+             lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
++            if (prepare_schema_table(thd, lex, 0, SCH_ENGINES))
+               MYSQL_YYABORT;
+           }
+         | AUTHORS_SYM
+@@ -10285,7 +10249,7 @@ show_param:
+           { 
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_PROFILE;
+-            if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
++            if (prepare_schema_table(thd, lex, NULL, SCH_PROFILES) != 0)
+               YYABORT;
+           }
+         | opt_var_type STATUS_SYM wild_and_where
+@@ -10293,7 +10257,7 @@ show_param:
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_STATUS;
+             lex->option_type= $1;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
++            if (prepare_schema_table(thd, lex, 0, SCH_STATUS))
+               MYSQL_YYABORT;
+           }
+         | INNOBASE_SYM STATUS_SYM
+@@ -10301,24 +10265,24 @@ show_param:
+             LEX *lex= Lex;
+             lex->sql_command = SQLCOM_SHOW_ENGINE_STATUS;
+             if (!(lex->create_info.db_type=
+-                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB)))
++                  ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)))
+             {
+               my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
+               MYSQL_YYABORT;
+             }
+-            WARN_DEPRECATED(yythd, "6.0", "SHOW INNODB STATUS", "'SHOW ENGINE INNODB STATUS'");
++            WARN_DEPRECATED(thd, "6.0", "SHOW INNODB STATUS", "'SHOW ENGINE INNODB STATUS'");
+           }
+         | MUTEX_SYM STATUS_SYM
+           {
+             LEX *lex= Lex;
+             lex->sql_command = SQLCOM_SHOW_ENGINE_MUTEX;
+             if (!(lex->create_info.db_type=
+-                  ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB)))
++                  ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)))
+             {
+               my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
+               MYSQL_YYABORT;
+             }
+-            WARN_DEPRECATED(yythd, "6.0", "SHOW MUTEX STATUS", "'SHOW ENGINE INNODB MUTEX'");
++            WARN_DEPRECATED(thd, "6.0", "SHOW MUTEX STATUS", "'SHOW ENGINE INNODB MUTEX'");
+           }
+         | opt_full PROCESSLIST_SYM
+           { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
+@@ -10327,21 +10291,21 @@ show_param:
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_VARIABLES;
+             lex->option_type= $1;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
++            if (prepare_schema_table(thd, lex, 0, SCH_VARIABLES))
+               MYSQL_YYABORT;
+           }
+         | charset wild_and_where
+           {
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_CHARSETS;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS))
++            if (prepare_schema_table(thd, lex, 0, SCH_CHARSETS))
+               MYSQL_YYABORT;
+           }
+         | COLLATION_SYM wild_and_where
+           {
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_COLLATIONS;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS))
++            if (prepare_schema_table(thd, lex, 0, SCH_COLLATIONS))
+               MYSQL_YYABORT;
+           }
+         | GRANTS
+@@ -10371,7 +10335,7 @@ show_param:
+           {
+             LEX *lex= Lex;
+             lex->sql_command = SQLCOM_SHOW_CREATE;
+-            if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0))
++            if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
+               MYSQL_YYABORT;
+             lex->only_view= 0;
+             lex->create_info.storage_media= HA_SM_DEFAULT;
+@@ -10380,7 +10344,7 @@ show_param:
+           {
+             LEX *lex= Lex;
+             lex->sql_command = SQLCOM_SHOW_CREATE;
+-            if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0))
++            if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+               MYSQL_YYABORT;
+             lex->only_view= 1;
+           }
+@@ -10416,14 +10380,14 @@ show_param:
+           {
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
++            if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))
+               MYSQL_YYABORT;
+           }
+         | FUNCTION_SYM STATUS_SYM wild_and_where
+           {
+             LEX *lex= Lex;
+             lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
+-            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
++            if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))
+               MYSQL_YYABORT;
+           }
+         | PROCEDURE CODE_SYM sp_name
+@@ -10501,7 +10465,7 @@ wild_and_where:
+           /* empty */
+         | LIKE TEXT_STRING_sys
+           {
+-            Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
++            Lex->wild= new (thd->mem_root) String($2.str, $2.length,
+                                                     system_charset_info);
+             if (Lex->wild == NULL)
+               MYSQL_YYABORT;
+@@ -10525,7 +10489,7 @@ describe:
+             lex->sql_command= SQLCOM_SHOW_FIELDS;
+             lex->select_lex.db= 0;
+             lex->verbose= 0;
+-            if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
++            if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
+               MYSQL_YYABORT;
+           }
+           opt_describe_column {}
+@@ -10554,7 +10518,7 @@ opt_describe_column:
+         | text_string { Lex->wild= $1; }
+         | ident
+           {
+-            Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,
++            Lex->wild= new (thd->mem_root) String((const char*) $1.str,
+                                                     $1.length,
+                                                     system_charset_info);
+             if (Lex->wild == NULL)
+@@ -10697,7 +10661,6 @@ use:
+ load:
+           LOAD DATA_SYM
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             if (lex->sphead)
+@@ -10711,7 +10674,7 @@ load:
+         | LOAD TABLE_SYM table_ident FROM MASTER_SYM
+           {
+             LEX *lex=Lex;
+-            WARN_DEPRECATED(yythd, "6.0", "LOAD TABLE FROM MASTER",
++            WARN_DEPRECATED(thd, "6.0", "LOAD TABLE FROM MASTER",
+                             "MySQL Administrator (mysqldump, mysql)");
+             if (lex->sphead)
+             {
+@@ -10719,7 +10682,7 @@ load:
+               MYSQL_YYABORT;
+             }
+             lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
+-            if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING))
++            if (!Select->add_table_to_list(thd, $3, NULL, TL_OPTION_UPDATING))
+               MYSQL_YYABORT;
+           }
+         ;
+@@ -10739,7 +10702,7 @@ load_data:
+           opt_duplicate INTO TABLE_SYM table_ident
+           {
+             LEX *lex=Lex;
+-            if (!Select->add_table_to_list(YYTHD, $9, NULL, TL_OPTION_UPDATING,
++            if (!Select->add_table_to_list(thd, $9, NULL, TL_OPTION_UPDATING,
+                                            lex->lock_option))
+               MYSQL_YYABORT;
+             lex->field_list.empty();
+@@ -10754,7 +10717,7 @@ load_data:
+         | FROM MASTER_SYM
+           {
+             Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
+-            WARN_DEPRECATED(yythd, "6.0", "LOAD DATA FROM MASTER",
++            WARN_DEPRECATED(thd, "6.0", "LOAD DATA FROM MASTER",
+                             "mysqldump or future "
+                             "BACKUP/RESTORE DATABASE facility");
+           }
+@@ -10872,7 +10835,7 @@ field_or_var:
+           simple_ident_nospvar {$$= $1;}
+         | '@' ident_or_text
+           {
+-            $$= new (YYTHD->mem_root) Item_user_var_as_out_param($2);
++            $$= new (thd->mem_root) Item_user_var_as_out_param($2);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -10889,7 +10852,6 @@ text_literal:
+           TEXT_STRING
+           {
+             LEX_STRING tmp;
+-            THD *thd= YYTHD;
+             CHARSET_INFO *cs_con= thd->variables.collation_connection;
+             CHARSET_INFO *cs_cli= thd->variables.character_set_client;
+             uint repertoire= thd->lex->text_string_is_7bit &&
+@@ -10915,7 +10877,7 @@ text_literal:
+             uint repertoire= Lex->text_string_is_7bit ?
+                              MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
+             DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
+-            $$= new (YYTHD->mem_root) Item_string($1.str, $1.length,
++            $$= new (thd->mem_root) Item_string($1.str, $1.length,
+                                                   national_charset_info,
+                                                   DERIVATION_COERCIBLE,
+                                                   repertoire);
+@@ -10924,7 +10886,7 @@ text_literal:
+           }
+         | UNDERSCORE_CHARSET TEXT_STRING
+           {
+-            Item_string *str= new (YYTHD->mem_root) Item_string($2.str,
++            Item_string *str= new (thd->mem_root) Item_string($2.str,
+                                                                 $2.length, $1);
+             if (str == NULL)
+               MYSQL_YYABORT;
+@@ -10943,7 +10905,7 @@ text_literal:
+                  If the string has been pure ASCII so far,
+                  check the new part.
+               */
+-              CHARSET_INFO *cs= YYTHD->variables.collation_connection;
++              CHARSET_INFO *cs= thd->variables.collation_connection;
+               item->collation.repertoire|= my_string_repertoire(cs,
+                                                                 $2.str,
+                                                                 $2.length);
+@@ -10954,15 +10916,15 @@ text_literal:
+ text_string:
+           TEXT_STRING_literal
+           {
+-            $$= new (YYTHD->mem_root) String($1.str,
++            $$= new (thd->mem_root) String($1.str,
+                                              $1.length,
+-                                             YYTHD->variables.collation_connection);
++                                             thd->variables.collation_connection);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | HEX_NUM
+           {
+-            Item *tmp= new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
++            Item *tmp= new (thd->mem_root) Item_hex_string($1.str, $1.length);
+             if (tmp == NULL)
+               MYSQL_YYABORT;
+             /*
+@@ -10974,7 +10936,7 @@ text_string:
+           }
+         | BIN_NUM
+           {
+-            Item *tmp= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
++            Item *tmp= new (thd->mem_root) Item_bin_string($1.str, $1.length);
+             if (tmp == NULL)
+               MYSQL_YYABORT;
+             /*
+@@ -10989,7 +10951,6 @@ text_string:
+ param_marker:
+           PARAM_MARKER
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+             Item_param *item;
+@@ -11022,38 +10983,38 @@ literal:
+         | NUM_literal { $$ = $1; }
+         | NULL_SYM
+           {
+-            $$ = new (YYTHD->mem_root) Item_null();
++            $$ = new (thd->mem_root) Item_null();
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+             YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
+           }
+         | FALSE_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_int((char*) "FALSE",0,1);
++            $$= new (thd->mem_root) Item_int((char*) "FALSE",0,1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | TRUE_SYM
+           {
+-            $$= new (YYTHD->mem_root) Item_int((char*) "TRUE",1,1);
++            $$= new (thd->mem_root) Item_int((char*) "TRUE",1,1);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | HEX_NUM
+           {
+-            $$ = new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
++            $$ = new (thd->mem_root) Item_hex_string($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | BIN_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
++            $$= new (thd->mem_root) Item_bin_string($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | UNDERSCORE_CHARSET HEX_NUM
+           {
+-            Item *tmp= new (YYTHD->mem_root) Item_hex_string($2.str, $2.length);
++            Item *tmp= new (thd->mem_root) Item_hex_string($2.str, $2.length);
+             if (tmp == NULL)
+               MYSQL_YYABORT;
+             /*
+@@ -11064,7 +11025,7 @@ literal:
+             String *str= tmp->val_str((String*) 0);
+             Item_string *item_str;
+-            item_str= new (YYTHD->mem_root)
++            item_str= new (thd->mem_root)
+                         Item_string(NULL, /* name will be set in select_item */
+                                     str ? str->ptr() : "",
+                                     str ? str->length() : 0,
+@@ -11082,7 +11043,7 @@ literal:
+           }
+         | UNDERSCORE_CHARSET BIN_NUM
+           {
+-            Item *tmp= new (YYTHD->mem_root) Item_bin_string($2.str, $2.length);
++            Item *tmp= new (thd->mem_root) Item_bin_string($2.str, $2.length);
+             if (tmp == NULL)
+               MYSQL_YYABORT;
+             /*
+@@ -11093,7 +11054,7 @@ literal:
+             String *str= tmp->val_str((String*) 0);
+             Item_string *item_str;
+-            item_str= new (YYTHD->mem_root)
++            item_str= new (thd->mem_root)
+                         Item_string(NULL, /* name will be set in select_item */
+                                     str ? str->ptr() : "",
+                                     str ? str->length() : 0,
+@@ -11117,7 +11078,7 @@ NUM_literal:
+           NUM
+           {
+             int error;
+-            $$= new (YYTHD->mem_root)
++            $$= new (thd->mem_root)
+                   Item_int($1.str,
+                            (longlong) my_strtoll10($1.str, NULL, &error),
+                            $1.length);
+@@ -11127,7 +11088,7 @@ NUM_literal:
+         | LONG_NUM
+           {
+             int error;
+-            $$= new (YYTHD->mem_root)
++            $$= new (thd->mem_root)
+                   Item_int($1.str,
+                            (longlong) my_strtoll10($1.str, NULL, &error),
+                            $1.length);
+@@ -11136,23 +11097,23 @@ NUM_literal:
+           }
+         | ULONGLONG_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
++            $$= new (thd->mem_root) Item_uint($1.str, $1.length);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | DECIMAL_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_decimal($1.str, $1.length,
+-                                                   YYTHD->charset());
+-            if (($$ == NULL) || (YYTHD->is_error()))
++            $$= new (thd->mem_root) Item_decimal($1.str, $1.length,
++                                                   thd->charset());
++            if (($$ == NULL) || (thd->is_error()))
+             {
+               MYSQL_YYABORT;
+             }
+           }
+         | FLOAT_NUM
+           {
+-            $$= new (YYTHD->mem_root) Item_float($1.str, $1.length);
+-            if (($$ == NULL) || (YYTHD->is_error()))
++            $$= new (thd->mem_root) Item_float($1.str, $1.length);
++            if (($$ == NULL) || (thd->is_error()))
+             {
+               MYSQL_YYABORT;
+             }
+@@ -11172,7 +11133,7 @@ table_wild:
+           ident '.' '*'
+           {
+             SELECT_LEX *sel= Select;
+-            $$= new (YYTHD->mem_root) Item_field(Lex->current_context(),
++            $$= new (thd->mem_root) Item_field(Lex->current_context(),
+                                                  NullS, $1.str, "*");
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+@@ -11180,7 +11141,6 @@ table_wild:
+           }
+         | ident '.' ident '.' '*'
+           {
+-            THD *thd= YYTHD;
+             SELECT_LEX *sel= Select;
+             const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ?
+                                   NullS : $1.str;
+@@ -11200,7 +11160,6 @@ order_ident:
+ simple_ident:
+           ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+             sp_variable_t *spv;
+@@ -11251,7 +11210,6 @@ simple_ident:
+ simple_ident_nospvar:
+           ident
+           {
+-            THD *thd= YYTHD;
+             SELECT_LEX *sel=Select;
+             if ((sel->parsing_place != IN_HAVING) ||
+                 (sel->get_in_sum_expr() > 0))
+@@ -11273,7 +11231,6 @@ simple_ident_nospvar:
+ simple_ident_q:
+           ident '.' ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             /*
+@@ -11352,7 +11309,6 @@ simple_ident_q:
+           }
+         | '.' ident '.' ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             SELECT_LEX *sel= lex->current_select;
+             if (sel->no_table_names_allowed)
+@@ -11377,7 +11333,6 @@ simple_ident_q:
+           }
+         | ident '.' ident '.' ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             SELECT_LEX *sel= lex->current_select;
+             const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
+@@ -11445,7 +11400,7 @@ table_ident:
+           }
+         | ident '.' ident
+           {
+-            $$= new Table_ident(YYTHD, $1,$3,0);
++            $$= new Table_ident(thd, $1,$3,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -11467,7 +11422,7 @@ table_ident_opt_wild:
+           }
+         | ident '.' ident opt_wild
+           {
+-            $$= new Table_ident(YYTHD, $1,$3,0);
++            $$= new Table_ident(thd, $1,$3,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -11477,7 +11432,7 @@ table_ident_nodb:
+           ident
+           {
+             LEX_STRING db={(char*) any_db,3};
+-            $$= new Table_ident(YYTHD, db,$1,0);
++            $$= new Table_ident(thd, db,$1,0);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -11487,8 +11442,6 @@ IDENT_sys:
+           IDENT { $$= $1; }
+         | IDENT_QUOTED
+           {
+-            THD *thd= YYTHD;
+-
+             if (thd->charset_is_system_charset)
+             {
+               CHARSET_INFO *cs= system_charset_info;
+@@ -11516,8 +11469,6 @@ IDENT_sys:
+ TEXT_STRING_sys:
+           TEXT_STRING
+           {
+-            THD *thd= YYTHD;
+-
+             if (thd->charset_is_system_charset)
+               $$= $1;
+             else
+@@ -11532,8 +11483,6 @@ TEXT_STRING_sys:
+ TEXT_STRING_literal:
+           TEXT_STRING
+           {
+-            THD *thd= YYTHD;
+-
+             if (thd->charset_is_collation_connection)
+               $$= $1;
+             else
+@@ -11548,8 +11497,6 @@ TEXT_STRING_literal:
+ TEXT_STRING_filesystem:
+           TEXT_STRING
+           {
+-            THD *thd= YYTHD;
+-
+             if (thd->charset_is_character_set_filesystem)
+               $$= $1;
+             else
+@@ -11566,7 +11513,6 @@ ident:
+           IDENT_sys    { $$=$1; }
+         | keyword
+           {
+-            THD *thd= YYTHD;
+             $$.str= thd->strmake($1.str, $1.length);
+             if ($$.str == NULL)
+               MYSQL_YYABORT;
+@@ -11578,7 +11524,6 @@ label_ident:
+           IDENT_sys    { $$=$1; }
+         | keyword_sp
+           {
+-            THD *thd= YYTHD;
+             $$.str= thd->strmake($1.str, $1.length);
+             if ($$.str == NULL)
+               MYSQL_YYABORT;
+@@ -11595,7 +11540,6 @@ ident_or_text:
+ user:
+           ident_or_text
+           {
+-            THD *thd= YYTHD;
+             if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+               MYSQL_YYABORT;
+             $$->user = $1;
+@@ -11609,7 +11553,6 @@ user:
+           }
+         | ident_or_text '@' ident_or_text
+           {
+-            THD *thd= YYTHD;
+             if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+               MYSQL_YYABORT;
+             $$->user = $1; $$->host=$3;
+@@ -11628,7 +11571,7 @@ user:
+           }
+         | CURRENT_USER optional_braces
+           {
+-            if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
++            if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
+               MYSQL_YYABORT;
+             /* 
+               empty LEX_USER means current_user and 
+@@ -11991,7 +11934,6 @@ option_value_list:
+ option_type_value:
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+@@ -12022,7 +11964,6 @@ option_type_value:
+           }
+           ext_option_value
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+@@ -12105,7 +12046,6 @@ ext_option_value:
+ sys_option_value:
+           option_type internal_variable_name equal set_expr_or_default
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= Lex;
+             LEX_STRING *name= &$2.base_name;
+@@ -12117,7 +12057,7 @@ sys_option_value:
+                 my_parse_error(ER(ER_SYNTAX_ERROR));
+                 MYSQL_YYABORT;
+               }
+-              if (set_trigger_new_row(YYTHD, name, $4))
++              if (set_trigger_new_row(thd, name, $4))
+                 MYSQL_YYABORT;
+             }
+             else if ($2.var)
+@@ -12147,7 +12087,6 @@ sys_option_value:
+           }
+         | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
+           {
+-            THD *thd= YYTHD;
+             LEX *lex=Lex;
+             lex->option_type= $1;
+             Item *item= new (thd->mem_root) Item_int((int32) $5);
+@@ -12167,7 +12106,7 @@ option_value:
+           '@' ident_or_text equal expr
+           {
+             Item_func_set_user_var *item;
+-            item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4);
++            item= new (thd->mem_root) Item_func_set_user_var($2, $4);
+             if (item == NULL)
+               MYSQL_YYABORT;
+             set_var_user *var= new set_var_user(item);
+@@ -12177,7 +12116,6 @@ option_value:
+           }
+         | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
+           {
+-            THD *thd= YYTHD;
+             struct sys_var_with_base tmp= $4;
+             /* Lookup if necessary: must be a system variable. */
+             if (tmp.var == NULL)
+@@ -12190,7 +12128,6 @@ option_value:
+           }
+         | charset old_or_new_charset_name_or_default
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             CHARSET_INFO *cs2;
+             cs2= $2 ? $2: global_system_variables.character_set_client;
+@@ -12238,7 +12175,6 @@ option_value:
+           }
+         | PASSWORD equal text_or_password
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             LEX_USER *user;
+             sp_pcontext *spc= lex->spcont;
+@@ -12278,7 +12214,6 @@ option_value:
+ internal_variable_name:
+           ident
+           {
+-            THD *thd= YYTHD;
+             sp_pcontext *spc= thd->lex->spcont;
+             sp_variable_t *spv;
+@@ -12337,7 +12272,7 @@ internal_variable_name:
+             }
+             else
+             {
+-              sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
++              sys_var *tmp=find_sys_var(thd, $3.str, $3.length);
+               if (!tmp)
+                 MYSQL_YYABORT;
+               if (!tmp->is_struct())
+@@ -12348,7 +12283,7 @@ internal_variable_name:
+           }
+         | DEFAULT '.' ident
+           {
+-            sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
++            sys_var *tmp=find_sys_var(thd, $3.str, $3.length);
+             if (!tmp)
+               MYSQL_YYABORT;
+             if (!tmp->is_struct())
+@@ -12370,16 +12305,16 @@ text_or_password:
+           TEXT_STRING { $$=$1.str;}
+         | PASSWORD '(' TEXT_STRING ')'
+           {
+-            $$= $3.length ? YYTHD->variables.old_passwords ?
+-              Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
+-              Item_func_password::alloc(YYTHD, $3.str, $3.length) :
++            $$= $3.length ? thd->variables.old_passwords ?
++              Item_func_old_password::alloc(thd, $3.str, $3.length) :
++              Item_func_password::alloc(thd, $3.str, $3.length) :
+               $3.str;
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | OLD_PASSWORD '(' TEXT_STRING ')'
+           {
+-            $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str,
++            $$= $3.length ? Item_func_old_password::alloc(thd, $3.str,
+                                                           $3.length) :
+               $3.str;
+             if ($$ == NULL)
+@@ -12393,19 +12328,19 @@ set_expr_or_default:
+         | DEFAULT { $$=0; }
+         | ON
+           {
+-            $$=new (YYTHD->mem_root) Item_string("ON",  2, system_charset_info);
++            $$=new (thd->mem_root) Item_string("ON",  2, system_charset_info);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | ALL
+           {
+-            $$=new (YYTHD->mem_root) Item_string("ALL", 3, system_charset_info);
++            $$=new (thd->mem_root) Item_string("ALL", 3, system_charset_info);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+         | BINARY
+           {
+-            $$=new (YYTHD->mem_root) Item_string("binary", 6, system_charset_info);
++            $$=new (thd->mem_root) Item_string("binary", 6, system_charset_info);
+             if ($$ == NULL)
+               MYSQL_YYABORT;
+           }
+@@ -12443,7 +12378,7 @@ table_lock:
+           table_ident opt_table_alias lock_option
+           {
+             thr_lock_type lock_type= (thr_lock_type) $3;
+-            if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type))
++            if (!Select->add_table_to_list(thd, $1, $2, 0, lock_type))
+               MYSQL_YYABORT;
+             /* If table is to be write locked, protect from a impending GRL. */
+             if (lock_type >= TL_WRITE_ALLOW_WRITE)
+@@ -12514,7 +12449,7 @@ handler:
+             lex->expr_allows_subselect= FALSE;
+             lex->sql_command = SQLCOM_HA_READ;
+             lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
+-            Item *one= new (YYTHD->mem_root) Item_int((int32) 1);
++            Item *one= new (thd->mem_root) Item_int((int32) 1);
+             if (one == NULL)
+               MYSQL_YYABORT;
+             lex->current_select->select_limit= one;
+@@ -12836,10 +12771,10 @@ grant_user:
+             $$=$1; $1->password=$4;
+             if ($4.length)
+             {
+-              if (YYTHD->variables.old_passwords)
++              if (thd->variables.old_passwords)
+               {
+                 char *buff= 
+-                  (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
++                  (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
+                 if (buff == NULL)
+                   MYSQL_YYABORT;
+                 my_make_scrambled_password_323(buff, $4.str, $4.length);
+@@ -12849,7 +12784,7 @@ grant_user:
+               else
+               {
+                 char *buff= 
+-                  (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
++                  (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
+                 if (buff == NULL)
+                   MYSQL_YYABORT;
+                 my_make_scrambled_password(buff, $4.str, $4.length);
+@@ -12881,7 +12816,7 @@ column_list:
+ column_list_id:
+           ident
+           {
+-            String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
++            String *new_str = new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
+             if (new_str == NULL)
+               MYSQL_YYABORT;
+             List_iterator <LEX_COLUMN> iter(Lex->columns);
+@@ -12981,14 +12916,14 @@ opt_work:
+ opt_chain:
+           /* empty */
+-          { $$= (YYTHD->variables.completion_type == 1); }
++          { $$= (thd->variables.completion_type == 1); }
+         | AND_SYM NO_SYM CHAIN_SYM { $$=0; }
+         | AND_SYM CHAIN_SYM        { $$=1; }
+         ;
+ opt_release:
+           /* empty */
+-          { $$= (YYTHD->variables.completion_type == 2); }
++          { $$= (thd->variables.completion_type == 2); }
+         | RELEASE_SYM        { $$=1; }
+         | NO_SYM RELEASE_SYM { $$=0; }
+ ;
+@@ -13102,7 +13037,6 @@ union_opt:
+ union_order_or_limit:
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
+             SELECT_LEX *sel= lex->current_select;
+@@ -13118,7 +13052,6 @@ union_order_or_limit:
+           }
+           order_or_limit
+           {
+-            THD *thd= YYTHD;
+             thd->lex->current_select->no_table_names_allowed= 0;
+             thd->where= "";
+           }
+@@ -13255,14 +13188,14 @@ no_definer:
+               from older master servers (i.e. to create non-suid trigger in this
+               case).
+             */
+-            YYTHD->lex->definer= 0;
++            thd->lex->definer= 0;
+           }
+         ;
+ definer:
+           DEFINER_SYM EQ user
+           {
+-            YYTHD->lex->definer= get_current_user(YYTHD, $3);
++            thd->lex->definer= get_current_user(thd, $3);
+           }
+         ;
+@@ -13307,7 +13240,6 @@ view_suid:
+ view_tail:
+           view_suid VIEW_SYM table_ident
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sql_command= SQLCOM_CREATE_VIEW;
+             /* first table in list is target VIEW name */
+@@ -13347,7 +13279,6 @@ view_select:
+           }
+           view_select_aux view_check_option
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= Lex;
+             uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
+             void *create_view_select= thd->memdup(lex->create_view_select.str, len);
+@@ -13403,7 +13334,6 @@ trigger_tail:
+           EACH_SYM
+           ROW_SYM
+           { /* $15 */
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+             sp_head *sp;
+@@ -13437,8 +13367,8 @@ trigger_tail:
+             sp_head *sp= lex->sphead;
+             lex->sql_command= SQLCOM_CREATE_TRIGGER;
+-            sp->set_stmt_end(YYTHD);
+-            sp->restore_thd_mem_root(YYTHD);
++            sp->set_stmt_end(thd);
++            sp->restore_thd_mem_root(thd);
+             if (sp->is_not_allowed_in_function("trigger"))
+               MYSQL_YYABORT;
+@@ -13448,7 +13378,7 @@ trigger_tail:
+               sp_proc_stmt alternatives are not saving/restoring LEX, so
+               lex->query_tables can be wiped out.
+             */
+-            if (!lex->select_lex.add_table_to_list(YYTHD, $9,
++            if (!lex->select_lex.add_table_to_list(thd, $9,
+                                                    (LEX_STRING*) 0,
+                                                    TL_OPTION_UPDATING,
+                                                    TL_IGNORE))
+@@ -13466,7 +13396,6 @@ udf_tail:
+           AGGREGATE_SYM remember_name FUNCTION_SYM ident
+           RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             if (is_native_function(thd, & $4))
+             {
+@@ -13484,7 +13413,6 @@ udf_tail:
+         | remember_name FUNCTION_SYM ident
+           RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             if (is_native_function(thd, & $3))
+             {
+@@ -13507,7 +13435,6 @@ sf_tail:
+           sp_name /* $3 */
+           '(' /* $4 */
+           { /* $5 */
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+             sp_head *sp;
+@@ -13565,7 +13492,7 @@ sf_tail:
+               MYSQL_YYABORT;
+             }
+-            if (sp->fill_field_definition(YYTHD, lex,
++            if (sp->fill_field_definition(thd, lex,
+                                           (enum enum_field_types) $11,
+                                           &sp->m_return_field_def))
+               MYSQL_YYABORT;
+@@ -13574,7 +13501,6 @@ sf_tail:
+           }
+           sp_c_chistics /* $13 */
+           { /* $14 */
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             Lex_input_stream *lip= YYLIP;
+@@ -13583,7 +13509,6 @@ sf_tail:
+           }
+           sp_proc_stmt /* $15 */
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             sp_head *sp= lex->sphead;
+@@ -13654,10 +13579,10 @@ sp_tail:
+             sp= new sp_head();
+             if (sp == NULL)
+               MYSQL_YYABORT;
+-            sp->reset_thd_mem_root(YYTHD);
++            sp->reset_thd_mem_root(thd);
+             sp->init(lex);
+             sp->m_type= TYPE_ENUM_PROCEDURE;
+-            sp->init_sp_name(YYTHD, $3);
++            sp->init_sp_name(thd, $3);
+             lex->sphead= sp;
+           }
+@@ -13672,7 +13597,6 @@ sp_tail:
+           sp_pdparam_list
+           ')'
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
+@@ -13680,7 +13604,6 @@ sp_tail:
+           }
+           sp_c_chistics
+           {
+-            THD *thd= YYTHD;
+             LEX *lex= thd->lex;
+             lex->sphead->m_chistics= &lex->sp_chistics;
+@@ -13691,9 +13614,9 @@ sp_tail:
+             LEX *lex= Lex;
+             sp_head *sp= lex->sphead;
+-            sp->set_stmt_end(YYTHD);
++            sp->set_stmt_end(thd);
+             lex->sql_command= SQLCOM_CREATE_PROCEDURE;
+-            sp->restore_thd_mem_root(YYTHD);
++            sp->restore_thd_mem_root(thd);
+           }
+         ;
+@@ -13730,21 +13653,21 @@ xid:
+           text_string
+           {
+             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
+-            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
++            if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
+               MYSQL_YYABORT;
+             Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
+           }
+           | text_string ',' text_string
+           {
+             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
+-            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
++            if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
+               MYSQL_YYABORT;
+             Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
+           }
+           | text_string ',' text_string ',' ulong_num
+           {
+             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
+-            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
++            if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))
+               MYSQL_YYABORT;
+             Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
+           }
index c1fddff16e47bc9496ad7a1f91c099ca0ea5f170..3d87b7d0a748c5d49b43c8e39b841fd1e6289a9b 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=http://www.tuxera.com/opensource/
 PKG_MD5SUM:=f11d563816249d730a00498983485f3a
 
 PKG_LICENSE:=GPL-2.0 LGPL-2.0
-PKG_LICENSE_FILE:=COPYING COPYING.LIB
+PKG_LICENSE_FILES:=COPYING COPYING.LIB
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/utils/open-plc-utils/Makefile b/utils/open-plc-utils/Makefile
new file mode 100644 (file)
index 0000000..c7e19f1
--- /dev/null
@@ -0,0 +1,103 @@
+#
+# Copyright (C) 2013-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=open-plc-utils
+PKG_VERSION:=2013-01-29
+PKG_RELEASE:=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/qca/open-plc-utils.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=6beeb6fe6ce2b16b14284c26e1b9220b68044591
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/open-plc-utils/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Qualcomm Atheros Power Line Communication utilities
+  URL:=https://github.com/qca/open-plc-utils/blob/master/README
+endef
+
+define Package/open-plc-utils
+  $(call Package/open-plc-utils/Default)
+  MENU:=1
+endef
+
+define GenPlugin
+  define Package/$(addprefix open-plc-utils-,$(1))
+    $(call Package/open-plc-utils/Default)
+    DEPENDS:=open-plc-utils
+    TITLE:=Utility $(2) from the Open PLC utilities
+  endef
+
+   define Package/$(addprefix open-plc-utils-,$(1))/description
+     Utility $(2) from the Open PLC utilities package.
+   endef
+endef
+
+OPEN_PLC_UTILS_APPS:=efbu efeu efru efsu edru edsu nics \
+                    hpavkey hpavkeys rkey mac2pw mac2pwd \
+                    mdioblock mdioblock2 mdiodump mdiogen \
+                    hpav mme \
+                    chknvm chknvm2 nvmsplit nvmmerge \
+                    chkpib chkpib2 setpib getpib modpib pib2xml \
+                    pibcomp pibdump pibruin xml2pib psin psout pskey \
+                    psgraph psnotch pibrump \
+                    int6k int6kboot int6keth int6kf int6khost \
+                    int64host int6kid int6klist int6klog int6kmdio \
+                    int6kmdio2 int6kmod int6kstat int6ktest int6krate \
+                    int6krule int6ktone int6kwait CMEncrypt sada \
+                    coqos_add coqos_info coqos_man coqos_mod coqos_rel \
+                    mdustats ampboot amphost ampID amplist amprate \
+                    ampstat amptest amptool amptone ampwait \
+                    plcboot plchost plcID plclist plcrate plcrule \
+                    plcstat plctest plctool plctone \
+                    plcwait plchostd plcget plcset plcotst plcfwd \
+                    plcdevs plclog plcmdio16 plcmdio32 \
+                    config2cfg sdram \
+                    int6kuart int6kbaud ttysig ptsctl weeder ttysend \
+                    ttyrecv ttycat int6kdetect
+
+$(foreach a,$(OPEN_PLC_UTILS_APPS),$(eval $(call GenPlugin,$(a))))
+
+define Build/Compile
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               EXTRA_CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+               LDFLAGS="$(TARGET_CFLAGS) $(TARGET_LDFLAGS)" \
+               CROSS="$(TARGET_CROSS)" \
+               ROOTFS="$(PKG_INSTALL_DIR)" \
+               OWNER="$(shell id -u $(shell whoami))" \
+               GROUP="$(shell id -g $(shell whoami))" \
+               all install
+endef
+
+define Package/open-plc-utils/install
+endef
+
+define BuildPlugin
+  define Package/$(1)/install
+       $(INSTALL_DIR) $$(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/bin/$(subst open-plc-utils-,,$(1)) \
+               $$(1)/usr/bin/
+  endef
+
+  $$(eval $$(call BuildPackage,$(1)))
+endef
+
+$(eval $(call BuildPackage,open-plc-utils))
+$(foreach a,$(OPEN_PLC_UTILS_APPS),$(eval $(call BuildPlugin,open-plc-utils-$(a))))
diff --git a/utils/openocd/Makefile b/utils/openocd/Makefile
new file mode 100644 (file)
index 0000000..929574b
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=openocd
+PKG_VERSION:=v0.8.0-258-gd537cfa
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://git.code.sf.net/p/openocd/code
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_MAINTAINER:=Paul Fertser <fercerpav@gmail.com>
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/openocd
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=OpenOCD Utility
+  URL:=http://openocd.sf.net/
+  DEPENDS:=+libusb-1.0 +libftdi +hidapi
+endef
+
+define Package/openocd/description
+OpenOCD provides on-chip programming and debugging support with a
+layered architecture of JTAG interface and TAP support including:
+
+- (X)SVF playback to faciliate automated boundary scan and FPGA/CPLD
+  programming;
+- debug target support (e.g. ARM, MIPS): single-stepping,
+  breakpoints/watchpoints, gprof profiling, etc;
+- flash chip drivers (e.g. CFI, NAND, internal flash);
+- embedded TCL interpreter for easy scripting.
+
+Several network interfaces are available for interacting with OpenOCD:
+telnet, TCL, and GDB. The GDB server enables OpenOCD to function as a
+"remote target" for source-level debugging of embedded systems using
+the GNU GDB program (and the others who talk GDB protocol, e.g. IDA
+Pro).
+endef
+
+CONFIGURE_ARGS += \
+       --prefix="/usr" \
+       --disable-werror \
+       --enable-dummy \
+       --enable-sysfsgpio \
+       --enable-usb_blaster_libftdi \
+        --enable-openjtag_ftdi \
+        --enable-presto_libftdi
+
+define Build/Compile
+        +$(MAKE_VARS) \
+        $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH)
+endef
+
+define Package/openocd/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/share/openocd
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/openocd $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/share/openocd/scripts $(1)/usr/share/openocd
+endef
+
+$(eval $(call BuildPackage,openocd))
index f17357055f0eb5d8a0991b36b11f2f4d9ae0fb5a..a7b8301490fe90bdbc2d07a3da5c2d99c01c7f59 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=opensc
-PKG_VERSION:=20140317
+PKG_VERSION:=20141126
 PKG_RELEASE:=1
 PKG_LICENSE:=LGPL-2.1+
 PKG_LICENSE_FILES:=COPYING
@@ -19,7 +19,7 @@ PKG_RELEASE=$(PKG_SOURCE_VERSION)
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/OpenSC/OpenSC.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=de6d61405b271e22244376e4817e16b49018e1ce
+PKG_SOURCE_VERSION:=8aadbbd678730dbafb819382da553439887499fd
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_BUILD_DEPENDS:=+libpcsclite
 PKG_FIXUP:=libtool
index 0d79422ca0b81d4c5c9876b694b9e53c546b6294..08b2a8324a386474345b1d0cd1c66804b524f83f 100644 (file)
@@ -1,18 +1,18 @@
-From c706491fc9b08d4cc6d7b254cf936d6b8d8691bc Mon Sep 17 00:00:00 2001
+From 471b40173b73f213ee72bf05735abf3357658197 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Wed, 20 Feb 2013 11:54:30 +0700
-Subject: [PATCH 01/18] OpenPGP: Detect and support Gnuk Token.
+Subject: [PATCH 01/26] OpenPGP: Detect and support Gnuk Token.
 
 http://www.fsij.org/gnuk/
 ---
  src/libopensc/card-openpgp.c | 61 ++++++++++++++++++++++++++++++++++----------
  src/libopensc/cards.h        |  1 +
- src/tools/openpgp-tool.c     |  9 +++++--
- 3 files changed, 56 insertions(+), 15 deletions(-)
+ src/tools/openpgp-tool.c     |  7 ++++-
+ 3 files changed, 55 insertions(+), 14 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 743e79c..716052b 100644
+index 6774fe1..c785a55 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
 @@ -43,6 +43,7 @@
@@ -66,7 +66,7 @@ index 743e79c..716052b 100644
                                priv->ext_caps |= EXT_CAP_SM;
  
                        if ((priv->bcd_version >= OPENPGP_CARD_2_0) && (blob->len >= 10)) {
-@@ -1055,12 +1060,18 @@ static int
+@@ -1057,12 +1062,18 @@ static int
  pgp_get_pubkey(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
  {
        sc_apdu_t       apdu;
@@ -86,7 +86,7 @@ index 743e79c..716052b 100644
        apdu.lc = 2;
        apdu.data = ushort2bebytes(idbuf, tag);
        apdu.datalen = 2;
-@@ -1152,6 +1163,7 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
+@@ -1154,6 +1165,7 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
        u8 ins = 0xDA;
        u8 p1 = tag >> 8;
        u8 p2 = tag & 0xFF;
@@ -94,7 +94,7 @@ index 743e79c..716052b 100644
        int r;
  
        LOG_FUNC_CALLED(card->ctx);
-@@ -1193,13 +1205,17 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
+@@ -1195,13 +1207,17 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
  
        /* Build APDU */
        if (buf != NULL && buf_len > 0) {
@@ -114,7 +114,7 @@ index 743e79c..716052b 100644
                apdu.datalen = buf_len;
                apdu.lc = buf_len;
        }
-@@ -1326,6 +1342,7 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
+@@ -1328,6 +1344,7 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
        struct pgp_priv_data    *priv = DRVDATA(card);
        sc_security_env_t       *env = &priv->sec_env;
        sc_apdu_t               apdu;
@@ -122,7 +122,7 @@ index 743e79c..716052b 100644
        int                     r;
  
        LOG_FUNC_CALLED(card->ctx);
-@@ -1334,14 +1351,19 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
+@@ -1336,14 +1353,19 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
                LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
                                "invalid operation");
  
@@ -144,7 +144,7 @@ index 743e79c..716052b 100644
                break;
        case 0x01:
        default:
-@@ -1350,7 +1372,7 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
+@@ -1352,7 +1374,7 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
        }
  
        apdu.lc = data_len;
@@ -153,7 +153,7 @@ index 743e79c..716052b 100644
        apdu.datalen = data_len;
        apdu.le = ((outlen >= 256) && !(card->caps & SC_CARD_CAP_APDU_EXT)) ? 256 : outlen;
        apdu.resp    = out;
-@@ -1374,6 +1396,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
+@@ -1376,6 +1398,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
        struct pgp_priv_data    *priv = DRVDATA(card);
        sc_security_env_t       *env = &priv->sec_env;
        sc_apdu_t       apdu;
@@ -161,7 +161,7 @@ index 743e79c..716052b 100644
        u8              *temp = NULL;
        int             r;
  
-@@ -1398,7 +1421,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
+@@ -1400,7 +1423,7 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
        case 0x01: /* Decryption key */
        case 0x02: /* authentication key */
                /* PSO DECIPHER */
@@ -170,7 +170,7 @@ index 743e79c..716052b 100644
                break;
        case 0x00: /* signature key */
        default:
-@@ -1407,8 +1430,13 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
+@@ -1409,8 +1432,13 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
                                "invalid key reference");
        }
  
@@ -209,10 +209,10 @@ index 743e79c..716052b 100644
                 * sc_format_apdu() */
                apdu_le = card->max_recv_size;
 diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
-index 0fbf9ca..01b08fd 100644
+index 7be6667..a3f3634 100644
 --- a/src/libopensc/cards.h
 +++ b/src/libopensc/cards.h
-@@ -104,6 +104,7 @@ enum {
+@@ -105,6 +105,7 @@ enum {
        SC_CARD_TYPE_OPENPGP_BASE = 9000,
        SC_CARD_TYPE_OPENPGP_V1,
        SC_CARD_TYPE_OPENPGP_V2,
@@ -221,27 +221,18 @@ index 0fbf9ca..01b08fd 100644
        /* jcop driver */
        SC_CARD_TYPE_JCOP_BASE = 10000,
 diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
-index 7058aaa..8b5e327 100644
+index f42e6d6..a24a395 100644
 --- a/src/tools/openpgp-tool.c
 +++ b/src/tools/openpgp-tool.c
-@@ -32,6 +32,7 @@
- #include "libopensc/asn1.h"
+@@ -33,6 +33,7 @@
  #include "libopensc/cards.h"
  #include "libopensc/cardctl.h"
+ #include "libopensc/errors.h"
 +#include "libopensc/log.h"
  #include "util.h"
+ #include "libopensc/log.h"
  
- #define       OPT_RAW         256
-@@ -216,7 +217,7 @@ static void display_data(const struct ef_name_map *mapping, char *value)
-                       } else {
-                               const char *label = mapping->name;
--                              printf("%s:%*s%s\n", label, 10-strlen(label), "", value);
-+                              printf("%s:%*s%s\n", label, 10 - (int)strlen(label), "", value);
-                       }
-               }
-       }
-@@ -390,6 +391,8 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
+@@ -396,6 +397,8 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
        sc_path_t path;
        sc_file_t *file;
  
@@ -250,7 +241,7 @@ index 7058aaa..8b5e327 100644
        if (key_id < 1 || key_id > 3) {
                printf("Unknown key ID %d.\n", key_id);
                return 1;
-@@ -481,8 +484,10 @@ int main(int argc, char **argv)
+@@ -487,8 +490,10 @@ int main(int argc, char **argv)
  
        /* check card type */
        if ((card->type != SC_CARD_TYPE_OPENPGP_V1) &&
@@ -263,5 +254,5 @@ index 7058aaa..8b5e327 100644
                goto out;
        }
 -- 
-1.9.3
+2.1.3
 
index cf8cae6d7350ee85202aa9365451253d82b2c8b2..c08a6e0a35b3b30a8cd0005f491621171abb2245 100644 (file)
@@ -1,8 +1,8 @@
-From ecc6460d17147b37def27a9b776e1fc5a61408d0 Mon Sep 17 00:00:00 2001
+From 00a2c08c9125103ee0bff9af9e7ff42c5cdc14fe Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Fri, 12 Apr 2013 17:24:00 +0700
-Subject: [PATCH 02/18] OpenPGP: Add Gnuk in pkcs15 emulation layer.
+Subject: [PATCH 02/26] OpenPGP: Add Gnuk in pkcs15 emulation layer.
 
 ---
  src/libopensc/pkcs15-openpgp.c | 6 ++++--
@@ -10,10 +10,10 @@ Subject: [PATCH 02/18] OpenPGP: Add Gnuk in pkcs15 emulation layer.
  2 files changed, 5 insertions(+), 2 deletions(-)
 
 diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
-index d9dc074..5a8a1ca 100644
+index 4daaa98..fdf720a 100644
 --- a/src/libopensc/pkcs15-openpgp.c
 +++ b/src/libopensc/pkcs15-openpgp.c
-@@ -155,7 +155,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
+@@ -151,7 +151,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
        u8              c4data[10];
        u8              c5data[70];
        int             r, i;
@@ -23,7 +23,7 @@ index d9dc074..5a8a1ca 100644
        sc_path_t path;
        sc_file_t *file;
  
-@@ -367,7 +368,8 @@ failed:    sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP e
+@@ -363,7 +364,8 @@ failed:    sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP e
  
  static int openpgp_detect_card(sc_pkcs15_card_t *p15card)
  {
@@ -34,17 +34,17 @@ index d9dc074..5a8a1ca 100644
        else
                return SC_ERROR_WRONG_CARD;
 diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c
-index e2f6004..a9f8c0b 100644
+index ffbf642..d2c086c 100644
 --- a/src/libopensc/pkcs15-syn.c
 +++ b/src/libopensc/pkcs15-syn.c
-@@ -112,6 +112,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
+@@ -115,6 +115,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
                case SC_CARD_TYPE_GEMSAFEV1_PTEID:
                case SC_CARD_TYPE_OPENPGP_V1:
                case SC_CARD_TYPE_OPENPGP_V2:
 +              case SC_CARD_TYPE_OPENPGP_GNUK:
                case SC_CARD_TYPE_SC_HSM:
-                       return 1;
-               default:
+               case SC_CARD_TYPE_DNIE_BASE:
+               case SC_CARD_TYPE_DNIE_BLANK:
 -- 
-1.9.3
+2.1.3
 
index fa15d792c5878194c618363714d37d732346360e..9e96cfef62534e2bb0d9a595f2cbf4da7f038dfd 100644 (file)
@@ -1,8 +1,8 @@
-From 5f751ba5628f9d85e9d8dca9939a93f49d2525d0 Mon Sep 17 00:00:00 2001
+From 2d348b60ab8c22791b56f291600954abd716a791 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Fri, 22 Mar 2013 17:37:16 +0700
-Subject: [PATCH 03/18] OpenPGP: Include private DO to filesystem at driver
+Subject: [PATCH 03/26] OpenPGP: Include private DO to filesystem at driver
  initialization.
 
 In old implementation, the DOs which their access is restricted by
@@ -13,7 +13,7 @@ leading to that we cannot read their data later, even if we verified PIN.
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 716052b..ead07ae 100644
+index c785a55..1cc3923 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
 @@ -357,7 +357,7 @@ pgp_init(sc_card_t *card)
@@ -26,5 +26,5 @@ index 716052b..ead07ae 100644
                        child = pgp_new_blob(card, priv->mf, info->id, sc_file_new());
  
 -- 
-1.9.3
+2.1.3
 
index 114412f2298b05128a9de4a9334565ff272f5891..b6408de7f69aeb71e0a7b84e915b64f659102c80 100644 (file)
@@ -1,8 +1,8 @@
-From fbf8e392db4456de97796259a62ccb972fe24df8 Mon Sep 17 00:00:00 2001
+From fda9b6dd088e734de372fc85c091f88e8607bc2e Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Tue, 26 Feb 2013 17:37:16 +0700
-Subject: [PATCH 04/18] PKCS15-OpenPGP: Declare DATA objects.
+Subject: [PATCH 04/26] PKCS15-OpenPGP: Declare DATA objects.
 
 Begin to support read/write DATA object for PKCS-OpenPGP binding.
 This object is used by TrueCrypt.
@@ -11,18 +11,18 @@ This object is used by TrueCrypt.
  1 file changed, 35 insertions(+)
 
 diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
-index 5a8a1ca..9f239ef 100644
+index fdf720a..fea2805 100644
 --- a/src/libopensc/pkcs15-openpgp.c
 +++ b/src/libopensc/pkcs15-openpgp.c
-@@ -36,6 +36,7 @@ typedef USHORT ushort;
- #endif
+@@ -32,6 +32,7 @@
+ #include "log.h"
  
  int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
 +static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *);
  
  
  #define       PGP_USER_PIN_FLAGS      (SC_PKCS15_PIN_FLAG_CASE_SENSITIVE \
-@@ -45,6 +46,8 @@ int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
+@@ -41,6 +42,8 @@ int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
                                | SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED \
                                | SC_PKCS15_PIN_FLAG_SO_PIN)
  
@@ -31,7 +31,7 @@ index 5a8a1ca..9f239ef 100644
  typedef struct _pgp_pin_cfg {
        const char      *label;
        int             reference;
-@@ -359,6 +362,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
+@@ -355,6 +358,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
                        goto failed;
        }
  
@@ -41,7 +41,7 @@ index 5a8a1ca..9f239ef 100644
        return 0;
  
  failed:       sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP emulation: %s\n",
-@@ -366,6 +372,35 @@ failed:   sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP e
+@@ -362,6 +368,35 @@ failed:   sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP e
        return r;
  }
  
@@ -78,5 +78,5 @@ index 5a8a1ca..9f239ef 100644
  {
        if (p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2
 -- 
-1.9.3
+2.1.3
 
index c28ed10cbf1216048c9ed06baeb30ef2a4687946..0dc4954629cafa421143c7166729cf7d707a784a 100644 (file)
@@ -1,20 +1,20 @@
-From 4cdc5f3102f5ad93d263eea2f8206bb5e9fffc6c Mon Sep 17 00:00:00 2001
+From 6d138f0199575516bfaad18cbbafcfa2ee61e58f Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Mon, 4 Mar 2013 11:28:08 +0700
-Subject: [PATCH 05/18] OpenPGP: Support erasing (reset) card.
+Subject: [PATCH 05/26] OpenPGP: Support erasing (reset) card.
 
 Command: openpgp-tool --erase
 ---
  src/libopensc/card-openpgp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
- src/tools/openpgp-tool.c     | 23 +++++++++++++++-
- 2 files changed, 86 insertions(+), 1 deletion(-)
+ src/tools/openpgp-tool.c     | 2++++++++++++++-
+ 2 files changed, 85 insertions(+), 1 deletion(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index ead07ae..42a9684 100644
+index 1cc3923..7349876 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -2197,6 +2197,66 @@ out:
+@@ -2195,6 +2195,66 @@ out:
  
  #endif /* ENABLE_OPENSSL */
  
@@ -81,7 +81,7 @@ index ead07ae..42a9684 100644
  /* ABI: card ctl: perform special card-specific operations */
  static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
  {
-@@ -2221,6 +2281,10 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
+@@ -2219,6 +2279,10 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
                LOG_FUNC_RETURN(card->ctx, r);
                break;
  #endif /* ENABLE_OPENSSL */
@@ -93,53 +93,52 @@ index ead07ae..42a9684 100644
  
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
 diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
-index 8b5e327..0d360a3 100644
+index a24a395..de1c9d4 100644
 --- a/src/tools/openpgp-tool.c
 +++ b/src/tools/openpgp-tool.c
-@@ -76,6 +76,7 @@ static int opt_verify = 0;
- static char *verifytype = NULL;
- static int opt_pin = 0;
+@@ -78,6 +78,7 @@ static int opt_pin = 0;
  static char *pin = NULL;
+ static int opt_dump_do = 0;
+ static u8 do_dump_idx;
 +static int opt_erase = 0;
  
  static const char *app_name = "openpgp-tool";
  
-@@ -92,6 +93,7 @@ static const struct option options[] = {
+@@ -94,6 +95,7 @@ static const struct option options[] = {
        { "help",      no_argument,       NULL, 'h'        },
        { "verbose",   no_argument,       NULL, 'v'        },
        { "version",   no_argument,       NULL, 'V'        },
 +      { "erase",     no_argument,       NULL, 'E'        },
        { "verify",    required_argument, NULL, OPT_VERIFY },
        { "pin",       required_argument, NULL, OPT_PIN },
-       { NULL, 0, NULL, 0 }
-@@ -110,6 +112,7 @@ static const char *option_help[] = {
+       { "do",        required_argument, NULL, 'd' },
+@@ -113,6 +115,7 @@ static const char *option_help[] = {
  /* h */       "Print this help message",
  /* v */       "Verbose operation. Use several times to enable debug output.",
  /* V */       "Show version number",
 +/* E */       "Erase (reset) the card",
        "Verify PIN (CHV1, CHV2, CHV3...)",
-       "PIN string"
- };
-@@ -228,7 +231,7 @@ static int decode_options(int argc, char **argv)
+       "PIN string",
+ /* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)"
+@@ -232,7 +235,7 @@ static int decode_options(int argc, char **argv)
  {
        int c;
  
--      while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvV", options, (int *) 0)) != EOF) {
-+      while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVE", options, (int *) 0)) != EOF) {
+-      while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:", options, (int *) 0)) != EOF) {
++      while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:E", options, (int *) 0)) != EOF) {
                switch (c) {
                case 'r':
                        opt_reader = optarg;
-@@ -288,6 +291,9 @@ static int decode_options(int argc, char **argv)
-                       show_version();
-                       exit(EXIT_SUCCESS);
-                       break;
+@@ -296,6 +299,8 @@ static int decode_options(int argc, char **argv)
+                       do_dump_idx = optarg[0] - '0';
+                       opt_dump_do++;
+                       actions++;
 +              case 'E':
 +                      opt_erase++;
-+                      break;
+                       break;
                default:
                        util_print_usage_and_die(app_name, options, option_help, NULL);
-               }
-@@ -446,6 +452,18 @@ int do_verify(sc_card_t *card, u8 *type, u8* pin)
+@@ -452,6 +457,18 @@ int do_verify(sc_card_t *card, char *type, char *pin)
        return r;
  }
  
@@ -158,7 +157,7 @@ index 8b5e327..0d360a3 100644
  int main(int argc, char **argv)
  {
        sc_context_t *ctx = NULL;
-@@ -521,6 +539,9 @@ int main(int argc, char **argv)
+@@ -531,6 +548,9 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
  
@@ -169,5 +168,5 @@ index 8b5e327..0d360a3 100644
        sc_unlock(card);
        sc_disconnect_card(card);
 -- 
-1.9.3
+2.1.3
 
index f73cb22f5c2fc816a5e32d165e9a530e7b065cec..915f6842c0c42833a0ca8fa2f6430b9e03bc9dbc 100644 (file)
@@ -1,18 +1,18 @@
-From bbbedd3b358f80a7f98df2b22cf541cb007dd62e Mon Sep 17 00:00:00 2001
+From 469b6567d9adc4af6f49fa65534162673060454d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Mon, 4 Mar 2013 18:13:03 +0700
-Subject: [PATCH 06/18] openpgp-tool: Support deleting key in Gnuk.
+Subject: [PATCH 06/26] openpgp-tool: Support deleting key in Gnuk.
 
 ---
- src/tools/openpgp-tool.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 143 insertions(+), 1 deletion(-)
+ src/tools/openpgp-tool.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 142 insertions(+)
 
 diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
-index 0d360a3..239c86b 100644
+index de1c9d4..374819a 100644
 --- a/src/tools/openpgp-tool.c
 +++ b/src/tools/openpgp-tool.c
-@@ -39,6 +39,7 @@
+@@ -41,6 +41,7 @@
  #define       OPT_PRETTY      257
  #define       OPT_VERIFY      258
  #define       OPT_PIN     259
@@ -20,33 +20,31 @@ index 0d360a3..239c86b 100644
  
  /* define structures */
  struct ef_name_map {
-@@ -77,6 +78,7 @@ static char *verifytype = NULL;
- static int opt_pin = 0;
- static char *pin = NULL;
+@@ -79,6 +80,7 @@ static char *pin = NULL;
+ static int opt_dump_do = 0;
+ static u8 do_dump_idx;
  static int opt_erase = 0;
 +static int opt_delkey = 0;
  
  static const char *app_name = "openpgp-tool";
  
-@@ -96,6 +98,7 @@ static const struct option options[] = {
+@@ -98,6 +100,7 @@ static const struct option options[] = {
        { "erase",     no_argument,       NULL, 'E'        },
        { "verify",    required_argument, NULL, OPT_VERIFY },
        { "pin",       required_argument, NULL, OPT_PIN },
 +      { "del-key",   required_argument, NULL, OPT_DELKEY },
+       { "do",        required_argument, NULL, 'd' },
        { NULL, 0, NULL, 0 }
  };
-@@ -114,7 +117,8 @@ static const char *option_help[] = {
- /* V */       "Show version number",
+@@ -118,6 +121,7 @@ static const char *option_help[] = {
  /* E */       "Erase (reset) the card",
        "Verify PIN (CHV1, CHV2, CHV3...)",
--      "PIN string"
-+      "PIN string",
-+      "Delete key (1, 2, 3 or all)"
+       "PIN string",
++      "Delete key (1, 2, 3 or all)",
+ /* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)"
  };
  
- static const struct ef_name_map openpgp_data[] = {
-@@ -294,6 +298,14 @@ static int decode_options(int argc, char **argv)
+@@ -302,6 +306,14 @@ static int decode_options(int argc, char **argv)
                case 'E':
                        opt_erase++;
                        break;
@@ -61,7 +59,7 @@ index 0d360a3..239c86b 100644
                default:
                        util_print_usage_and_die(app_name, options, option_help, NULL);
                }
-@@ -452,6 +464,133 @@ int do_verify(sc_card_t *card, u8 *type, u8* pin)
+@@ -457,6 +469,133 @@ int do_verify(sc_card_t *card, char *type, char *pin)
        return r;
  }
  
@@ -195,7 +193,7 @@ index 0d360a3..239c86b 100644
  int do_erase(sc_card_t *card)
  {
        int r;
-@@ -539,6 +678,9 @@ int main(int argc, char **argv)
+@@ -548,6 +687,9 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
  
@@ -206,5 +204,5 @@ index 0d360a3..239c86b 100644
                exit_status != do_erase(card);
  
 -- 
-1.9.3
+2.1.3
 
index 1d487af32dde4ca8345e5827f8c7ad5385eb671d..7d8045679b931a22407d190016400377ab907115 100644 (file)
@@ -1,8 +1,8 @@
-From b6bc7a497e1fe20104f923de1092a35d137ba553 Mon Sep 17 00:00:00 2001
+From d210faa377bcec63876f84b82540b110ede16e57 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Mon, 4 Mar 2013 18:14:51 +0700
-Subject: [PATCH 07/18] OpenPGP: Correct building Extended Header List when
+Subject: [PATCH 07/26] OpenPGP: Correct building Extended Header List when
  importing keys.
 
 ---
@@ -10,10 +10,10 @@ Subject: [PATCH 07/18] OpenPGP: Correct building Extended Header List when
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 42a9684..47c1938 100644
+index 7349876..91c311b 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -1978,7 +1978,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info
+@@ -1977,7 +1977,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info
        u8 *p = NULL;
        u8 *components[] = {key_info->e, key_info->p, key_info->q, key_info->n};
        size_t componentlens[] = {key_info->e_len, key_info->p_len, key_info->q_len, key_info->n_len};
@@ -23,5 +23,5 @@ index 42a9684..47c1938 100644
                "public exponent",
                "prime p",
 -- 
-1.9.3
+2.1.3
 
index 25a69d4cb61ad2841112d633caa24731ca61431a..17aaf92ca9edc1cdb9730c0c4f8c2ecf6aaeb66a 100644 (file)
@@ -1,8 +1,8 @@
-From d1b8d3588336abac4876c1d537d8e8e5e578bc02 Mon Sep 17 00:00:00 2001
+From df98874784a77c96a7a1be54412a02a53fdd3a3e Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Mon, 25 Mar 2013 11:58:38 +0700
-Subject: [PATCH 08/18] OpenPGP: Read some empty DOs from Gnuk.
+Subject: [PATCH 08/26] OpenPGP: Read some empty DOs from Gnuk.
 
 In Gnuk, some empty DOs are returned as not exist, instead of existing with empty value.
 So, we will consider them exist in driver.
@@ -11,10 +11,10 @@ So, we will consider them exist in driver.
  1 file changed, 25 insertions(+)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 47c1938..9b08bbb 100644
+index 91c311b..e7b25c0 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -813,6 +813,23 @@ pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id,
+@@ -815,6 +815,23 @@ pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id,
                }
        }
  
@@ -38,7 +38,7 @@ index 47c1938..9b08bbb 100644
        return SC_ERROR_FILE_NOT_FOUND;
  }
  
-@@ -1147,6 +1164,14 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
+@@ -1149,6 +1166,14 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
        LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
  
        r = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -54,5 +54,5 @@ index 47c1938..9b08bbb 100644
  
        LOG_FUNC_RETURN(card->ctx, apdu.resplen);
 -- 
-1.9.3
+2.1.3
 
index 5abf6f8db23e9a761feb6a05df22ec4854d63c2f..a75a2c2ce6ab6dc90d2c804828cfde38d9452dfc 100644 (file)
@@ -1,8 +1,8 @@
-From 6a4457cde65ef44f05b0689415ae7165b06fb8bf Mon Sep 17 00:00:00 2001
+From 42adc35954e18e24f253f710b16d850d1872bce5 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Wed, 27 Mar 2013 11:38:42 +0700
-Subject: [PATCH 09/18] PKCS15-OpenPGP: Do not show empty DO in pkcs15
+Subject: [PATCH 09/26] PKCS15-OpenPGP: Do not show empty DO in pkcs15
  emu_init.
 
 ---
@@ -10,10 +10,10 @@ Subject: [PATCH 09/18] PKCS15-OpenPGP: Do not show empty DO in pkcs15
  1 file changed, 18 insertions(+)
 
 diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
-index 9f239ef..850dd74 100644
+index fea2805..51a2032 100644
 --- a/src/libopensc/pkcs15-openpgp.c
 +++ b/src/libopensc/pkcs15-openpgp.c
-@@ -385,16 +385,34 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card)
+@@ -381,16 +381,34 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card)
                sc_pkcs15_object_t dat_obj;
                char name[8];
                char path[9];
@@ -49,5 +49,5 @@ index 9f239ef..850dd74 100644
                r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info);
        }
 -- 
-1.9.3
+2.1.3
 
index a3c75309c903afd4dc801f2d5840b26e574edecd..7b0f493ccbd663f12729ff6f6e54945341e6b06f 100644 (file)
@@ -1,8 +1,8 @@
-From 88ded8fc5802c073caa71b649cee5a3116699b2a Mon Sep 17 00:00:00 2001
+From f085e6a5f386875b5b071ef3bf115e4d9bb33bdb Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Wed, 27 Mar 2013 11:39:33 +0700
-Subject: [PATCH 10/18] PKCS15-OpenPGP: Allow to store data to pkcs15 data
+Subject: [PATCH 10/26] PKCS15-OpenPGP: Allow to store data to pkcs15 data
  object.
 
 Only one DO is supported now.
@@ -12,10 +12,10 @@ Only one DO is supported now.
  2 files changed, 38 insertions(+), 2 deletions(-)
 
 diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
-index 850dd74..b701041 100644
+index 51a2032..4cc1c39 100644
 --- a/src/libopensc/pkcs15-openpgp.c
 +++ b/src/libopensc/pkcs15-openpgp.c
-@@ -397,7 +397,7 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card)
+@@ -393,7 +393,7 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card)
                 */
                r = read_file(p15card->card, path, content, sizeof(content));
                if (r <= 0 ) {
@@ -87,5 +87,5 @@ index f3a4962..1455580 100755
                r = SC_ERROR_NOT_IMPLEMENTED;
        }
 -- 
-1.9.3
+2.1.3
 
index 8fc34642d0c14155d6d6a549fb16ef17a2d70ac5..d133e805955ab8b419b60ad64c830e93242d9384 100644 (file)
@@ -1,8 +1,8 @@
-From 7231ee09bb628f0401939778decce818ef6e3665 Mon Sep 17 00:00:00 2001
+From 752f8981bed49a98d3592ead3aa50e743318dea8 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Fri, 5 Apr 2013 17:18:50 +0700
-Subject: [PATCH 11/18] OpenPGP: Provide enough buffer to read pubkey from
+Subject: [PATCH 11/26] OpenPGP: Provide enough buffer to read pubkey from
  Gnuk.
 
 ---
@@ -10,7 +10,7 @@ Subject: [PATCH 11/18] OpenPGP: Provide enough buffer to read pubkey from
  1 file changed, 23 insertions(+), 5 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 9b08bbb..8a1a270 100644
+index e7b25c0..1913eca 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
 @@ -263,7 +263,12 @@ static struct do_info             pgp2_objects[] = {      /* OpenPGP card spec 2.0 */
@@ -27,7 +27,7 @@ index 9b08bbb..8a1a270 100644
  
  #define DRVDATA(card)        ((struct pgp_priv_data *) ((card)->drv_data))
  struct pgp_priv_data {
-@@ -729,6 +734,14 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
+@@ -731,6 +736,14 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
                u8      buffer[2048];
                size_t  buf_len = (card->caps & SC_CARD_CAP_APDU_EXT)
                                  ? sizeof(buffer) : 256;
@@ -42,7 +42,7 @@ index 9b08bbb..8a1a270 100644
                int     r = blob->info->get_fn(card, blob->id, buffer, buf_len);
  
                if (r < 0) {    /* an error occurred */
-@@ -1830,6 +1843,7 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
+@@ -1828,6 +1841,7 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
        u8 apdu_case;
        u8 *apdu_data;
        size_t apdu_le;
@@ -83,5 +83,5 @@ index 9b08bbb..8a1a270 100644
        /* Send */
        sc_log(card->ctx, "Waiting for the card to generate key...");
 -- 
-1.9.3
+2.1.3
 
index 0d54d96fc35e9adfe32b2ebec31798184d2eb951..3a2526f4e87c7d63116ea12327f87042678f4cd7 100644 (file)
@@ -1,18 +1,18 @@
-From d8f63eb6fcc1441c12a44850da2fa22a6fe81634 Mon Sep 17 00:00:00 2001
+From 5110ae3ba33d165c43ea5eca8f929a82d81cb3fe Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Thu, 11 Apr 2013 11:47:51 +0700
-Subject: [PATCH 12/18] OpenPGP: Support write certificate for Gnuk.
+Subject: [PATCH 12/26] OpenPGP: Support write certificate for Gnuk.
 
 ---
  src/libopensc/card-openpgp.c | 158 +++++++++++++++++++++++++++++++++----------
  1 file changed, 123 insertions(+), 35 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 8a1a270..d9db948 100644
+index 1913eca..7cea84f 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -725,6 +725,8 @@ pgp_iterate_blobs(struct blob *blob, int level, void (*func)())
+@@ -727,6 +727,8 @@ pgp_iterate_blobs(struct blob *blob, int level, void (*func)())
  static int
  pgp_read_blob(sc_card_t *card, struct blob *blob)
  {
@@ -21,7 +21,7 @@ index 8a1a270..d9db948 100644
        if (blob->data != NULL)
                return SC_SUCCESS;
        if (blob->info == NULL)
-@@ -735,6 +737,11 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
+@@ -737,6 +739,11 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
                size_t  buf_len = (card->caps & SC_CARD_CAP_APDU_EXT)
                                  ? sizeof(buffer) : 256;
  
@@ -33,7 +33,7 @@ index 8a1a270..d9db948 100644
                /* Buffer length for Gnuk pubkey */
                if (card->type == SC_CARD_TYPE_OPENPGP_GNUK &&
                    (blob->id == 0xa400 || blob->id == 0xb600 || blob->id == 0xb800
-@@ -1190,49 +1197,75 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
+@@ -1192,49 +1199,75 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
        LOG_FUNC_RETURN(card->ctx, apdu.resplen);
  }
  
@@ -143,7 +143,7 @@ index 8a1a270..d9db948 100644
  
        /* Extended Header list (004D DO) needs a variant of PUT DATA command */
        if (tag == 0x004D) {
-@@ -1258,15 +1291,70 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
+@@ -1260,15 +1293,70 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
                apdu.lc = buf_len;
        }
        else {
@@ -216,5 +216,5 @@ index 8a1a270..d9db948 100644
        if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
                sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Please verify PIN first.");
 -- 
-1.9.3
+2.1.3
 
index 67d79dd6f8cfd4475dc7f3808cc28e2e40234d5c..48afb37390fb8c58ae33d2dd81d0ffa08ca006c2 100644 (file)
@@ -1,8 +1,8 @@
-From e5c94d3f1f7e6a96a98815d6e51190498c357fb6 Mon Sep 17 00:00:00 2001
+From 7823e836e8279c8d77786d8f10ffaa83cf50bf1d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Wed, 10 Apr 2013 18:35:58 +0700
-Subject: [PATCH 13/18] pkcs15-openpgp: Change to sc_put_data instead of
+Subject: [PATCH 13/26] pkcs15-openpgp: Change to sc_put_data instead of
  sc_update_binary when writing certificate.
 
 ---
@@ -27,5 +27,5 @@ index 1455580..be1291e 100755
  
        case SC_PKCS15_TYPE_DATA_OBJECT:
 -- 
-1.9.3
+2.1.3
 
index cf1a07c6478200b1ac36c37c099fb6caad7a4e09..0fa8f2c3d3ae879b824a1186044428fe6c881c00 100644 (file)
@@ -1,8 +1,8 @@
-From df8a78e3c8c9d9d591c0d3fa31db7e010eb2c8c2 Mon Sep 17 00:00:00 2001
+From 3ff1f7234abb4c42273adedbe06d9e7f9f3a5f9d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Thu, 11 Apr 2013 16:18:31 +0700
-Subject: [PATCH 14/18] OpenPGP: Overcome the restriction of even data length
+Subject: [PATCH 14/26] OpenPGP: Overcome the restriction of even data length
  of Gnuk.
 
 When write certificate with odd length to Gnuk, we add zero padding to make it even.
@@ -11,10 +11,10 @@ When write certificate with odd length to Gnuk, we add zero padding to make it e
  1 file changed, 18 insertions(+), 2 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index d9db948..a666163 100644
+index 7cea84f..7a77a71 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -1206,6 +1206,10 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
+@@ -1208,6 +1208,10 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
        sc_apdu_t apdu;
        u8 *part;
        size_t plen;
@@ -25,7 +25,7 @@ index d9db948..a666163 100644
        int r = SC_SUCCESS;
  
        LOG_FUNC_CALLED(ctx);
-@@ -1236,8 +1240,20 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
+@@ -1238,8 +1242,20 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
                        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, i, 0);
                }
                apdu.flags |= SC_APDU_FLAGS_CHAINING;
@@ -49,5 +49,5 @@ index d9db948..a666163 100644
                r = sc_transmit_apdu(card, &apdu);
                LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
 -- 
-1.9.3
+2.1.3
 
index cc88a12db74ce3ff843480228e238453d42c961e..2389cd10992bfa4bafadd01f8cce7bf9dbb8fd88 100644 (file)
@@ -1,18 +1,18 @@
-From 693b3ac5a53e89a0cdeab0f728d24a6e16864f5c Mon Sep 17 00:00:00 2001
+From 9af45c4cf052e3a6059a3004082f9ee3d2b3b2bf Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Fri, 12 Apr 2013 15:33:31 +0700
-Subject: [PATCH 15/18] OpenPGP: Delete key as file, for Gnuk.
+Subject: [PATCH 15/26] OpenPGP: Delete key as file, for Gnuk.
 
 ---
  src/libopensc/card-openpgp.c | 51 +++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 50 insertions(+), 1 deletion(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index a666163..19d3b04 100644
+index 7a77a71..4d0500d 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -2437,6 +2437,44 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
+@@ -2435,6 +2435,44 @@ static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
  }
  
@@ -57,7 +57,7 @@ index a666163..19d3b04 100644
  /* ABI: DELETE FILE */
  static int
  pgp_delete_file(sc_card_t *card, const sc_path_t *path)
-@@ -2444,6 +2482,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
+@@ -2442,6 +2480,7 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
        struct pgp_priv_data *priv = DRVDATA(card);
        struct blob *blob;
        sc_file_t *file;
@@ -65,7 +65,7 @@ index a666163..19d3b04 100644
        int r;
  
        LOG_FUNC_CALLED(card->ctx);
-@@ -2459,10 +2498,20 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
+@@ -2457,10 +2496,20 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
        if (blob == priv->mf)
                LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
  
@@ -88,5 +88,5 @@ index a666163..19d3b04 100644
                /* call pgp_put_data() with zero-sized NULL-buffer to zap the DO contents */
                r = pgp_put_data(card, file->id, NULL, 0);
 -- 
-1.9.3
+2.1.3
 
index c49de13c0a906ecb3b6062d25842ca25961f507f..76c8624e3091fef3a5c31292ecf80ab7d0217f33 100644 (file)
@@ -1,18 +1,18 @@
-From f96f7536a8c2efd0ba41fd94fe3334e5fa556854 Mon Sep 17 00:00:00 2001
+From ee23d262768e7e54ed0fc554bc0b869c65868ace Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Tue, 16 Apr 2013 10:19:34 +0700
-Subject: [PATCH 16/18] OpenPGP: Correct parameter checking.
+Subject: [PATCH 16/26] OpenPGP: Correct parameter checking.
 
 ---
  src/libopensc/card-openpgp.c | 9 +++++++--
  1 file changed, 7 insertions(+), 2 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 19d3b04..196c094 100644
+index 4d0500d..beeee83 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -1221,6 +1221,8 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
+@@ -1223,6 +1223,8 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
                LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
                /* Check response */
                r = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -21,7 +21,7 @@ index 19d3b04..196c094 100644
                LOG_FUNC_RETURN(card->ctx, length);
        }
  
-@@ -2448,6 +2450,11 @@ gnuk_delete_key(sc_card_t *card, u8 key_id)
+@@ -2446,6 +2448,11 @@ gnuk_delete_key(sc_card_t *card, u8 key_id)
  
        LOG_FUNC_CALLED(ctx);
  
@@ -33,7 +33,7 @@ index 19d3b04..196c094 100644
        /* Delete fingerprint */
        sc_log(ctx, "Delete fingerprints");
        r = pgp_put_data(card, 0xC6 + key_id, NULL, 0);
-@@ -2466,8 +2473,6 @@ gnuk_delete_key(sc_card_t *card, u8 key_id)
+@@ -2464,8 +2471,6 @@ gnuk_delete_key(sc_card_t *card, u8 key_id)
                data = "\x4D\x02\xB8";
        else if (key_id == 3)
                data = "\x4D\x02\xA4";
@@ -43,5 +43,5 @@ index 19d3b04..196c094 100644
        r = pgp_put_data(card, 0x4D, data, strlen(data) + 1);
  
 -- 
-1.9.3
+2.1.3
 
index 50501e09584cb9896941761f08422d718b0d19b9..2bb6fccafb3a97570f1afd27c4170737e15d585c 100644 (file)
@@ -1,18 +1,18 @@
-From 8a69525a60391b46db4994033527d219d2adaa4e Mon Sep 17 00:00:00 2001
+From f4aec38233010953cea72c367bccc71c3687b2f1 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Tue, 16 Apr 2013 16:02:17 +0700
-Subject: [PATCH 17/18] OpenPGP: Make code neater
+Subject: [PATCH 17/26] OpenPGP: Make code neater
 
 ---
  src/libopensc/card-openpgp.c | 8 ++------
  1 file changed, 2 insertions(+), 6 deletions(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index 196c094..c4ef3b6 100644
+index beeee83..ca0d01b 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -1220,10 +1220,7 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
+@@ -1222,10 +1222,7 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
                r = sc_transmit_apdu(card, &apdu);
                LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
                /* Check response */
@@ -24,7 +24,7 @@ index 196c094..c4ef3b6 100644
        }
  
        /* Ref: gnuk_put_binary_libusb.py and gnuk_token.py in Gnuk source tree */
-@@ -1260,8 +1257,7 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
+@@ -1262,8 +1259,7 @@ static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length)
                r = sc_transmit_apdu(card, &apdu);
                LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
                /* Check response */
@@ -35,5 +35,5 @@ index 196c094..c4ef3b6 100644
                /* To next part */
                i++;
 -- 
-1.9.3
+2.1.3
 
index b05cc59c4eb471d65c5b77d123c6170e51b6b5fc..774ed58a11fe985da614b1729e33f79460ea2844 100644 (file)
@@ -1,18 +1,18 @@
-From a099f951d085d3abfefeead14a4af06913cb67d2 Mon Sep 17 00:00:00 2001
+From c84c84169f7a73eab27f6a9b13b77432baa5c3f8 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
  <ng.hong.quan@gmail.com>
 Date: Wed, 8 May 2013 16:51:21 +0700
-Subject: [PATCH 18/18] Move declaration to top of block.
+Subject: [PATCH 18/26] Move declaration to top of block.
 
 ---
  src/libopensc/card-openpgp.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
-index c4ef3b6..7f2006e 100644
+index ca0d01b..037ef73 100644
 --- a/src/libopensc/card-openpgp.c
 +++ b/src/libopensc/card-openpgp.c
-@@ -736,6 +736,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
+@@ -738,6 +738,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
                u8      buffer[2048];
                size_t  buf_len = (card->caps & SC_CARD_CAP_APDU_EXT)
                                  ? sizeof(buffer) : 256;
@@ -20,7 +20,7 @@ index c4ef3b6..7f2006e 100644
  
                /* Buffer length for certificate */
                if (blob->id == DO_CERT && priv->max_cert_size > 0) {
-@@ -749,7 +750,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
+@@ -751,7 +752,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
                        buf_len = MAXLEN_RESP_PUBKEY_GNUK;
                }
  
@@ -30,5 +30,5 @@ index c4ef3b6..7f2006e 100644
                if (r < 0) {    /* an error occurred */
                        blob->status = r;
 -- 
-1.9.3
+2.1.3
 
diff --git a/utils/opensc/patches/0019-OpenPGP-Make-indentation-consistent-space-tab.patch b/utils/opensc/patches/0019-OpenPGP-Make-indentation-consistent-space-tab.patch
new file mode 100644 (file)
index 0000000..3702d61
--- /dev/null
@@ -0,0 +1,182 @@
+From c6abf7976f64be5191dc80fecdbcb07daab7a2e0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 3 Nov 2013 01:45:56 +0800
+Subject: [PATCH 19/26] OpenPGP: Make indentation consistent (space -> tab).
+
+---
+ src/libopensc/card-openpgp.c | 22 ++++++++---------
+ src/tools/openpgp-tool.c     | 56 ++++++++++++++++++++++----------------------
+ 2 files changed, 39 insertions(+), 39 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index 037ef73..ae40940 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -192,12 +192,12 @@ static struct do_info            pgp1_objects[] = {      /* OpenPGP card spec 1.1 */
+       { 0x5f35, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  NULL,               sc_put_data },
+       { 0x5f50, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  sc_get_data,        sc_put_data },
+       { 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL,               NULL        },
+-      { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER,  pgp_get_pubkey,     NULL        },
+-      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
+-      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER,  pgp_get_pubkey,     NULL        },
+-      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
+-      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER,  pgp_get_pubkey,     NULL        },
+-      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
++      { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+       { 0, 0, 0, NULL, NULL },
+ };
+@@ -253,11 +253,11 @@ static struct do_info            pgp2_objects[] = {      /* OpenPGP card spec 2.0 */
+       /* The 0xA401, 0xB601, 0xB801 are just symbolic, it does not represent any real DO.
+        * However, their R/W access condition may block the process of importing key in pkcs15init.
+        * So we set their accesses condition as WRITE_PIN3 (writable). */
+-      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
+-      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER,  pgp_get_pubkey,     NULL        },
+-      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
+-      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER,  pgp_get_pubkey,     NULL        },
+-      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL        },
++      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+       { 0, 0, 0, NULL, NULL },
+ };
+diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
+index 374819a..a0334ca 100644
+--- a/src/tools/openpgp-tool.c
++++ b/src/tools/openpgp-tool.c
+@@ -37,11 +37,11 @@
+ #include "util.h"
+ #include "libopensc/log.h"
+-#define       OPT_RAW         256
+-#define       OPT_PRETTY      257
+-#define       OPT_VERIFY      258
+-#define       OPT_PIN     259
+-#define       OPT_DELKEY  260
++#define OPT_RAW     256
++#define OPT_PRETTY  257
++#define OPT_VERIFY  258
++#define OPT_PIN     259
++#define OPT_DELKEY  260
+ /* define structures */
+ struct ef_name_map {
+@@ -142,10 +142,10 @@ static const struct ef_name_map openpgp_data[] = {
+ static void show_version(void)
+ {
+       fprintf(stderr,
+-              "openpgp-tool - OpenPGP card utility version " PACKAGE_VERSION "\n"
+-              "\n"
+-              "Copyright (c) 2012 Peter Marschall <peter@adpm.de>\n"
+-              "Licensed under LGPL v2\n");
++              "openpgp-tool - OpenPGP card utility version " PACKAGE_VERSION "\n"
++              "\n"
++              "Copyright (c) 2012 Peter Marschall <peter@adpm.de>\n"
++              "Licensed under LGPL v2\n");
+ }
+@@ -176,16 +176,16 @@ static char *prettify_language(char *str)
+ {
+       if (str != NULL) {
+               switch (strlen(str)) {
+-                      case 8: memmove(str+7, str+6, 1+strlen(str+6));
++                      case 8: memmove(str+7, str+6, 1+strlen(str+6));
+                               str[6] = ',';
+                               /* fall through */
+-                      case 6: memmove(str+5, str+4, 1+strlen(str+4));
++                      case 6: memmove(str+5, str+4, 1+strlen(str+4));
+                               str[4] = ',';
+                               /* fall through */
+-                      case 4: memmove(str+3, str+2, 1+strlen(str+2));
++                      case 4: memmove(str+3, str+2, 1+strlen(str+2));
+                               str[2] = ',';
+                               /* fall through */
+-                      case 2:  return str;
++                      case 2: return str;
+               }
+       }
+       return NULL;
+@@ -197,10 +197,10 @@ static char *prettify_gender(char *str)
+ {
+       if (str != NULL) {
+               switch (*str) {
+-                      case '0':  return "unknown";
+-                      case '1':  return "male";
+-                      case '2':  return "female";
+-                      case '9':  return "not applicable";
++                      case '0': return "unknown";
++                      case '1': return "male";
++                      case '2': return "female";
++                      case '9': return "not applicable";
+               }
+       }
+       return NULL;
+@@ -218,7 +218,7 @@ static void display_data(const struct ef_name_map *mapping, char *value)
+                               char *envvar;
+                               envvar = malloc(strlen(mapping->env_name) +
+-                                              strlen(value) + 2);
++                                              strlen(value) + 2);
+                               if (envvar != NULL) {
+                                       strcpy(envvar, mapping->env_name);
+                                       strcat(envvar, "=");
+@@ -346,20 +346,20 @@ static int do_userinfo(sc_card_t *card)
+               if (!count)
+                       continue;
+-              if (count > (int)sizeof(buf) - 1)   {
++              if (count > (int)sizeof(buf) - 1) {
+                       fprintf(stderr, "Too small buffer to read the OpenPGP data\n");
+                       return EXIT_FAILURE;
+               }
+-      
+-              r = sc_read_binary(card, 0, buf, count, 0);
+-                      if (r < 0) {
++
++              r = sc_read_binary(card, 0, buf, count, 0);
++              if (r < 0) {
+                       fprintf(stderr, "%s: read failed - %s\n", openpgp_data[i].ef, sc_strerror(r));
+                       return EXIT_FAILURE;
+-              }
+-                      if (r != count) {
+-                        fprintf(stderr, "%s: expecting %d, got only %d bytes\n", openpgp_data[i].ef, count, r);
++              }
++              if (r != count) {
++                      fprintf(stderr, "%s: expecting %d, got only %d bytes\n", openpgp_data[i].ef, count, r);
+                       return EXIT_FAILURE;
+-              }
++              }
+               buf[count] = '\0';
+@@ -628,7 +628,7 @@ int main(int argc, char **argv)
+       r = sc_context_create(&ctx, &ctx_param);
+       if (r) {
+               util_fatal("failed to establish context: %s\n",
+-                      sc_strerror(r));
++                         sc_strerror(r));
+               return EXIT_FAILURE;
+       }
+@@ -640,7 +640,7 @@ int main(int argc, char **argv)
+       r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
+       if (r) {
+               util_fatal("failed to connect to card: %s\n",
+-                      sc_strerror(r));
++                         sc_strerror(r));
+               return EXIT_FAILURE;
+       }
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0020-OpenPGP-Don-t-use-sc_log-in-openpgp-tool.patch b/utils/opensc/patches/0020-OpenPGP-Don-t-use-sc_log-in-openpgp-tool.patch
new file mode 100644 (file)
index 0000000..b73826f
--- /dev/null
@@ -0,0 +1,84 @@
+From 9acf5c1ad7d8a32b472203d3bd8860ea2cbde0e7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 3 Nov 2013 02:53:35 +0800
+Subject: [PATCH 20/26] OpenPGP: Don't use sc_log in openpgp-tool.
+
+---
+ src/tools/openpgp-tool.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
+index a0334ca..505abd9 100644
+--- a/src/tools/openpgp-tool.c
++++ b/src/tools/openpgp-tool.c
+@@ -414,8 +414,6 @@ int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
+       sc_path_t path;
+       sc_file_t *file;
+-      LOG_FUNC_CALLED(card->ctx);
+-
+       if (key_id < 1 || key_id > 3) {
+               printf("Unknown key ID %d.\n", key_id);
+               return 1;
+@@ -479,14 +477,14 @@ int delete_key_gnuk(sc_card_t *card, u8 key_id)
+       u8 *data = NULL;
+       /* Delete fingerprint */
+-      sc_log(ctx, "Delete fingerprints");
++      fprintf(stdout, "Delete fingerprints");
+       r |= sc_put_data(card, 0xC6 + key_id, NULL, 0);
+       /* Delete creation time */
+-      sc_log(ctx, "Delete creation time");
++      fprintf(stdout, "Delete creation time");
+       r |= sc_put_data(card, 0xCD + key_id, NULL, 0);
+       /* Rewrite Extended Header List */
+-      sc_log(ctx, "Rewrite Extended Header List");
++      fprintf(stdout, "Rewrite Extended Header List");
+       if (key_id == 1)
+               data = "\x4D\x02\xB6";
+@@ -534,15 +532,18 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id)
+               /* Build APDU from binary array */
+               r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
+               if (r) {
+-                      sc_log(ctx, "Failed to build APDU");
+-                      LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
++                      fprintf(stderr, "Failed to build APDU: %s\n", sc_strerror(r));
++                      return r;
+               }
+               apdu.resp = rbuf;
+               apdu.resplen = sizeof(rbuf);
+               /* Send APDU to card */
+               r = sc_transmit_apdu(card, &apdu);
+-              LOG_TEST_RET(ctx, r, "Transmiting APDU failed");
++              if (r) {
++                      fprintf(stderr, "Transmiting APDU failed: %s\n", sc_strerror(r));
++                      return r;
++              }
+       }
+       /* TODO: Rewrite Extended Header List.
+        * Not support by OpenGPG v2 yet */
+@@ -557,7 +558,7 @@ int delete_key(sc_card_t *card, u8 key_id)
+       LOG_FUNC_CALLED(ctx);
+       /* Check key ID */
+       if (key_id < 1 || key_id > 3) {
+-              sc_log(ctx, "Invalid key ID %d", key_id);
++              fprintf(stderr, "Invalid key ID %d", key_id);
+               LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
+       }
+@@ -649,7 +650,7 @@ int main(int argc, char **argv)
+           (card->type != SC_CARD_TYPE_OPENPGP_V2) &&
+           (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) {
+               util_error("not an OpenPGP card");
+-              sc_log(card->ctx, "Card type %X", card->type);
++              fprintf(stderr, "Card type %X\n", card->type);
+               exit_status = EXIT_FAILURE;
+               goto out;
+       }
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0021-OpenPGP-Don-t-reimplement-gnuk_delete_key-in-openpgp.patch b/utils/opensc/patches/0021-OpenPGP-Don-t-reimplement-gnuk_delete_key-in-openpgp.patch
new file mode 100644 (file)
index 0000000..dc8fe84
--- /dev/null
@@ -0,0 +1,112 @@
+From 0fdbf868976172486af210accafbab163452ff78 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 3 Nov 2013 11:26:25 +0800
+Subject: [PATCH 21/26] OpenPGP: Don't reimplement gnuk_delete_key in
+ openpgp-tool.
+
+---
+ src/tools/openpgp-tool.c | 64 ++++++------------------------------------------
+ 1 file changed, 8 insertions(+), 56 deletions(-)
+
+diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
+index 505abd9..a7796e7 100644
+--- a/src/tools/openpgp-tool.c
++++ b/src/tools/openpgp-tool.c
+@@ -468,38 +468,6 @@ int do_verify(sc_card_t *card, char *type, char *pin)
+ }
+ /**
+- * Delete key, for Gnuk.
+- **/
+-int delete_key_gnuk(sc_card_t *card, u8 key_id)
+-{
+-      sc_context_t *ctx = card->ctx;
+-      int r = SC_SUCCESS;
+-      u8 *data = NULL;
+-
+-      /* Delete fingerprint */
+-      fprintf(stdout, "Delete fingerprints");
+-      r |= sc_put_data(card, 0xC6 + key_id, NULL, 0);
+-      /* Delete creation time */
+-      fprintf(stdout, "Delete creation time");
+-      r |= sc_put_data(card, 0xCD + key_id, NULL, 0);
+-
+-      /* Rewrite Extended Header List */
+-      fprintf(stdout, "Rewrite Extended Header List");
+-
+-      if (key_id == 1)
+-              data = "\x4D\x02\xB6";
+-      else if (key_id == 2)
+-              data = "\x4D\x02\xB8";
+-      else if (key_id == 3)
+-              data = "\x4D\x02\xA4";
+-      else
+-              return SC_ERROR_INVALID_ARGUMENTS;
+-
+-      r |= sc_put_data(card, 0x4D, data, strlen(data) + 1);
+-      return r;
+-}
+-
+-/**
+  * Delete key, for OpenPGP card.
+  * This function is not complete and is reserved for future version (> 2) of OpenPGP card.
+  **/
+@@ -547,32 +515,13 @@ int delete_key_openpgp(sc_card_t *card, u8 key_id)
+       }
+       /* TODO: Rewrite Extended Header List.
+        * Not support by OpenGPG v2 yet */
+-      LOG_FUNC_RETURN(ctx, r);
+-}
+-
+-int delete_key(sc_card_t *card, u8 key_id)
+-{
+-      sc_context_t *ctx = card->ctx;
+-      int r;
+-
+-      LOG_FUNC_CALLED(ctx);
+-      /* Check key ID */
+-      if (key_id < 1 || key_id > 3) {
+-              fprintf(stderr, "Invalid key ID %d", key_id);
+-              LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
+-      }
+-
+-      if (card->type == SC_CARD_TYPE_OPENPGP_GNUK)
+-              r = delete_key_gnuk(card, key_id);
+-      else
+-              r = delete_key_openpgp(card, key_id);
+-
+-      LOG_FUNC_RETURN(ctx, r);
++      return r;
+ }
+ int do_delete_key(sc_card_t *card, u8 key_id)
+ {
+       sc_context_t *ctx = card->ctx;
++      sc_path_t path;
+       int r = SC_SUCCESS;
+       /* Currently, only Gnuk supports deleting keys */
+@@ -586,13 +535,16 @@ int do_delete_key(sc_card_t *card, u8 key_id)
+               return SC_ERROR_INVALID_ARGUMENTS;
+       }
+       if (key_id == 1 || key_id == 'a') {
+-              r |= delete_key(card, 1);
++              sc_format_path("B601", &path);
++              r |= sc_delete_file(card, &path);
+       }
+       if (key_id == 2 || key_id == 'a') {
+-              r |= delete_key(card, 2);
++              sc_format_path("B801", &path);
++              r |= sc_delete_file(card, &path);
+       }
+       if (key_id == 3 || key_id == 'a') {
+-              r |= delete_key(card, 3);
++              sc_format_path("A401", &path);
++              r |= sc_delete_file(card, &path);
+       }
+       return r;
+ }
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0022-OpenPGP-Use-directly-binary-array-of-APDUs-for-ERASE.patch b/utils/opensc/patches/0022-OpenPGP-Use-directly-binary-array-of-APDUs-for-ERASE.patch
new file mode 100644 (file)
index 0000000..6297783
--- /dev/null
@@ -0,0 +1,87 @@
+From 0cd2a488d86006bb2740a4e73e7a0d859e1bf33c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 13 Jul 2014 17:37:59 +0800
+Subject: [PATCH 22/26] OpenPGP: Use directly binary array of APDUs for ERASE
+ command.
+
+I used a string presentation before and it needed an extra conversion step.
+---
+ src/libopensc/card-openpgp.c | 47 +++++++++++++++++++++++---------------------
+ 1 file changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index ae40940..724fe73 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -2347,24 +2347,27 @@ out:
+ static int pgp_erase_card(sc_card_t *card)
+ {
+       sc_context_t *ctx = card->ctx;
+-      u8 *apdustring[10] = {
+-              "00:20:00:81:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:81:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:81:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:81:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:83:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:83:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:83:08:40:40:40:40:40:40:40:40",
+-              "00:20:00:83:08:40:40:40:40:40:40:40:40",
+-              "00:e6:00:00",
+-              "00:44:00:00"
++      /* Special series of commands to erase OpenPGP card,
++       * according to https://www.crypto-stick.com/en/faq
++       * (How to reset a Crypto Stick? question).
++       * Gnuk is known not to support this feature. */
++      u8 apdu_binaries[10][13] = {
++              {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40},
++              {0, 0xe6, 0, 0},
++              {0, 0x44, 0, 0}
+       };
++      u8 apdu_lens[10] = {13, 13, 13, 13, 13, 13, 13, 13, 4, 4};
+       u8 buf[SC_MAX_APDU_BUFFER_SIZE];
+       u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
+       sc_apdu_t apdu;
+-      size_t len0;
+-      int commandsnum = 10;
+-      int i, r;
++      int i, l, r;
+       LOG_FUNC_CALLED(ctx);
+@@ -2376,17 +2379,17 @@ static int pgp_erase_card(sc_card_t *card)
+       sc_log(ctx, "Card is OpenPGP v2. Erase card.");
+       /* Iterate over 10 commands above */
+-      for (i = 0; i < commandsnum; i++) {
+-              /* Convert the string to binary array */
+-              len0 = sizeof(buf);
+-              sc_hex_to_bin(apdustring[i], buf, &len0);
+-              printf("Sending: ");
+-              for (r = 0; r < len0; r++)
+-                      printf("%02X ", buf[r]);
++      for (i = 0; i < sizeof(apdu_lens); i++) {
++              /* Length of the binary array of the current command */
++              l = apdu_lens[i];
++              /* Print the command to console */
++              printf("Sending %d: ", i);
++              for (r = 0; r < l; r++)
++                      printf("%02X ", apdu_binaries[i][r]);
+               printf("\n");
+               /* Build APDU from binary array */
+-              r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
++              r = sc_bytes2apdu(card->ctx, apdu_binaries[i], l, &apdu);
+               if (r) {
+                       sc_log(ctx, "Failed to build APDU");
+                       LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0023-OpenPGP-Rename-private-blob-type-to-avoid-confusing-.patch b/utils/opensc/patches/0023-OpenPGP-Rename-private-blob-type-to-avoid-confusing-.patch
new file mode 100644 (file)
index 0000000..f859f7c
--- /dev/null
@@ -0,0 +1,339 @@
+From 6f56ea4cfc52323002d818731a50a31e863b6843 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 13 Jul 2014 19:41:36 +0800
+Subject: [PATCH 23/26] OpenPGP: Rename private "blob" type to avoid confusing
+ with variable name.
+
+This name has been used for both data type and variable name of that
+type.
+---
+ src/libopensc/card-openpgp.c | 96 ++++++++++++++++++++++----------------------
+ 1 file changed, 49 insertions(+), 47 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index 724fe73..ca3173c 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -111,9 +111,9 @@ enum _card_state {
+       CARD_STATE_ACTIVATED      = 0x05
+ };
+-struct blob {
+-      struct blob *   next;   /* pointer to next sibling */
+-      struct blob *   parent; /* pointer to parent */
++typedef struct pgp_blob {
++      struct pgp_blob *       next;   /* pointer to next sibling */
++      struct pgp_blob *       parent; /* pointer to parent */
+       struct do_info *info;
+       sc_file_t *     file;
+@@ -122,8 +122,8 @@ struct blob {
+       unsigned char * data;
+       unsigned int    len;
+-      struct blob *   files;  /* pointer to 1st child */
+-};
++      struct pgp_blob *       files;  /* pointer to 1st child */
++} pgp_blob_t;
+ struct do_info {
+       unsigned int    id;             /* ID of the DO in question */
+@@ -141,12 +141,12 @@ struct do_info {
+ static int            pgp_get_card_features(sc_card_t *card);
+ static int            pgp_finish(sc_card_t *card);
+-static void           pgp_iterate_blobs(struct blob *, int, void (*func)());
++static void           pgp_iterate_blobs(pgp_blob_t *, int, void (*func)());
+-static int            pgp_get_blob(sc_card_t *card, struct blob *blob,
+-                               unsigned int id, struct blob **ret);
+-static struct blob *  pgp_new_blob(sc_card_t *, struct blob *, unsigned int, sc_file_t *);
+-static void           pgp_free_blob(struct blob *);
++static int            pgp_get_blob(sc_card_t *card, pgp_blob_t *blob,
++                               unsigned int id, pgp_blob_t **ret);
++static pgp_blob_t *   pgp_new_blob(sc_card_t *, pgp_blob_t *, unsigned int, sc_file_t *);
++static void           pgp_free_blob(pgp_blob_t *);
+ static int            pgp_get_pubkey(sc_card_t *, unsigned int,
+                               u8 *, size_t);
+ static int            pgp_get_pubkey_pem(sc_card_t *, unsigned int,
+@@ -272,8 +272,8 @@ static struct do_info              pgp2_objects[] = {      /* OpenPGP card spec 2.0 */
+ #define DRVDATA(card)        ((struct pgp_priv_data *) ((card)->drv_data))
+ struct pgp_priv_data {
+-      struct blob *           mf;
+-      struct blob *           current;        /* currently selected file */
++      pgp_blob_t *            mf;
++      pgp_blob_t *            current;        /* currently selected file */
+       enum _version           bcd_version;
+       struct do_info          *pgp_objects;
+@@ -311,7 +311,7 @@ pgp_init(sc_card_t *card)
+       sc_file_t       *file = NULL;
+       struct do_info  *info;
+       int             r;
+-      struct blob     *child = NULL;
++      pgp_blob_t      *child = NULL;
+       LOG_FUNC_CALLED(card->ctx);
+@@ -389,7 +389,7 @@ pgp_get_card_features(sc_card_t *card)
+       unsigned char *hist_bytes = card->atr.value;
+       size_t atr_len = card->atr.len;
+       size_t i = 0;
+-      struct blob *blob, *blob6e, *blob73;
++      pgp_blob_t *blob, *blob6e, *blob73;
+       /* parse card capabilities from historical bytes */
+       while ((i < atr_len) && (hist_bytes[i] != 0x73))
+@@ -526,7 +526,7 @@ pgp_finish(sc_card_t *card)
+ /* internal: fill a blob's data */
+ static int
+-pgp_set_blob(struct blob *blob, const u8 *data, size_t len)
++pgp_set_blob(pgp_blob_t *blob, const u8 *data, size_t len)
+ {
+       if (blob->data)
+               free(blob->data);
+@@ -620,16 +620,16 @@ pgp_attach_acl(sc_card_t *card, sc_file_t *file, struct do_info *info)
+ }
+ /* internal: append a blob to the list of children of a given parent blob */
+-static struct blob *
+-pgp_new_blob(sc_card_t *card, struct blob *parent, unsigned int file_id,
++static pgp_blob_t *
++pgp_new_blob(sc_card_t *card, pgp_blob_t *parent, unsigned int file_id,
+               sc_file_t *file)
+ {
+-      struct blob *blob = NULL;
++      pgp_blob_t *blob = NULL;
+       if (file == NULL)
+               return NULL;
+-      if ((blob = calloc(1, sizeof(struct blob))) != NULL) {
++      if ((blob = calloc(1, sizeof(pgp_blob_t))) != NULL) {
+               struct pgp_priv_data *priv = DRVDATA (card);
+               struct do_info *info;
+@@ -643,7 +643,7 @@ pgp_new_blob(sc_card_t *card, struct blob *parent, unsigned int file_id,
+               blob->parent = parent;
+               if (parent != NULL) {
+-                      struct blob **p;
++                      pgp_blob_t **p;
+                       /* set file's path = parent's path + file's id */
+                       blob->file->path = parent->file->path;
+@@ -681,11 +681,11 @@ pgp_new_blob(sc_card_t *card, struct blob *parent, unsigned int file_id,
+ /* internal: free a blob including its content */
+ static void
+-pgp_free_blob(struct blob *blob)
++pgp_free_blob(pgp_blob_t *blob)
+ {
+       if (blob) {
+               if (blob->parent) {
+-                      struct blob **p;
++                      pgp_blob_t **p;
+                       /* remove blob from list of parent's children */
+                       for (p = &blob->parent->files; *p != NULL && *p != blob; p = &(*p)->next)
+@@ -705,14 +705,14 @@ pgp_free_blob(struct blob *blob)
+ /* internal: iterate through the blob tree, calling a function for each blob */
+ static void
+-pgp_iterate_blobs(struct blob *blob, int level, void (*func)())
++pgp_iterate_blobs(pgp_blob_t *blob, int level, void (*func)())
+ {
+       if (blob) {
+               if (level > 0) {
+-                      struct blob *child = blob->files;
++                      pgp_blob_t *child = blob->files;
+                       while (child != NULL) {
+-                              struct blob *next = child->next;
++                              pgp_blob_t *next = child->next;
+                               pgp_iterate_blobs(child, level-1, func);
+                               child = next;
+@@ -725,7 +725,7 @@ pgp_iterate_blobs(struct blob *blob, int level, void (*func)())
+ /* internal: read a blob's contents from card */
+ static int
+-pgp_read_blob(sc_card_t *card, struct blob *blob)
++pgp_read_blob(sc_card_t *card, pgp_blob_t *blob)
+ {
+       struct pgp_priv_data *priv = DRVDATA (card);
+@@ -772,7 +772,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
+  * The OpenPGP card has a TLV encoding according ASN.1 BER-encoding rules.
+  */
+ static int
+-pgp_enumerate_blob(sc_card_t *card, struct blob *blob)
++pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob)
+ {
+       const u8        *in;
+       int             r;
+@@ -789,7 +789,7 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob)
+               unsigned int    cla, tag, tmptag;
+               size_t          len;
+               const u8        *data = in;
+-              struct blob     *new;
++              pgp_blob_t      *new;
+               r = sc_asn1_read_tag(&data, blob->len - (in - blob->data),
+                                       &cla, &tag, &len);
+@@ -819,10 +819,10 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob)
+ /* internal: find a blob by ID below a given parent, filling its contents when necessary */
+ static int
+-pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id,
+-              struct blob **ret)
++pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, unsigned int id,
++              pgp_blob_t **ret)
+ {
+-      struct blob             *child;
++      pgp_blob_t              *child;
+       int                     r;
+       if ((r = pgp_enumerate_blob(card, blob)) < 0)
+@@ -858,10 +858,10 @@ pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id,
+ /* Internal: search recursively for a blob by ID below a given root */
+ static int
+-pgp_seek_blob(sc_card_t *card, struct blob *root, unsigned int id,
+-              struct blob **ret)
++pgp_seek_blob(sc_card_t *card, pgp_blob_t *root, unsigned int id,
++              pgp_blob_t **ret)
+ {
+-      struct blob     *child;
++      pgp_blob_t      *child;
+       int                     r;
+       if ((r = pgp_get_blob(card, root, id, ret)) == 0)
+@@ -883,11 +883,11 @@ pgp_seek_blob(sc_card_t *card, struct blob *root, unsigned int id,
+ }
+ /* internal: find a blob by tag - pgp_seek_blob with optimizations */
+-static struct blob *
++static pgp_blob_t *
+ pgp_find_blob(sc_card_t *card, unsigned int tag)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *blob = NULL;
++      pgp_blob_t *blob = NULL;
+       int r;
+       /* Check if current selected blob is which we want to test*/
+@@ -941,7 +941,7 @@ static int
+ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob     *blob;
++      pgp_blob_t      *blob;
+       unsigned int    path_start = 0;
+       unsigned int    n;
+       sc_path_t dummy_path;
+@@ -1022,7 +1022,7 @@ static int
+ pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob     *blob;
++      pgp_blob_t      *blob;
+       unsigned int    k;
+       int             r;
+@@ -1058,7 +1058,7 @@ pgp_read_binary(sc_card_t *card, unsigned int idx,
+               u8 *buf, size_t count, unsigned long flags)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob     *blob;
++      pgp_blob_t      *blob;
+       int             r;
+       LOG_FUNC_CALLED(card->ctx);
+@@ -1134,7 +1134,7 @@ static int
+ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob     *blob, *mod_blob, *exp_blob;
++      pgp_blob_t      *blob, *mod_blob, *exp_blob;
+       sc_pkcs15_pubkey_t pubkey;
+       u8              *data;
+       size_t          len;
+@@ -1329,7 +1329,7 @@ static int
+ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *affected_blob = NULL;
++      pgp_blob_t *affected_blob = NULL;
+       struct do_info *dinfo = NULL;
+       int r;
+@@ -1603,7 +1603,7 @@ static int
+ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *algo_blob;
++      pgp_blob_t *algo_blob;
+       unsigned int old_modulus_len;     /* Measured in bit */
+       unsigned int old_exponent_len;
+       const unsigned int tag = 0x00C0 | key_info->keytype;
+@@ -1708,7 +1708,7 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime,
+       u8 *p; /* Use this pointer to set fp_buffer content */
+       size_t pk_packet_len;
+       unsigned int tag;
+-      struct blob *fpseq_blob;
++      pgp_blob_t *fpseq_blob;
+       u8 *newdata;
+       int r;
+@@ -1797,7 +1797,7 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len,
+                        u8* exponent, size_t exponent_len, u8 key_id)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *pk_blob;
++      pgp_blob_t *pk_blob;
+       unsigned int blob_id;
+       sc_pkcs15_pubkey_t pubkey;
+       u8 *data = NULL;
+@@ -1939,6 +1939,8 @@ static int pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen
+  **/
+ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
+ {
++      struct pgp_priv_data *priv = DRVDATA(card);
++      pgp_blob_t *algo_blob;
+       sc_apdu_t apdu;
+       /* Temporary variables to hold APDU params */
+       u8 apdu_case;
+@@ -2132,7 +2134,7 @@ pgp_build_extended_header_list(sc_card_t *card, sc_cardctl_openpgp_keystore_info
+       };
+       size_t comp_to_add = 3;
+       size_t req_e_len = 0;     /* The exponent length specified in Algorithm Attributes */
+-      struct blob *alat_blob;
++      pgp_blob_t *alat_blob;
+       u8 i;
+       int r;
+@@ -2483,7 +2485,7 @@ static int
+ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *blob;
++      pgp_blob_t *blob;
+       sc_file_t *file;
+       u8 key_id;
+       int r;
+@@ -2533,7 +2535,7 @@ pgp_update_binary(sc_card_t *card, unsigned int idx,
+                 const u8 *buf, size_t count, unsigned long flags)
+ {
+       struct pgp_priv_data *priv = DRVDATA(card);
+-      struct blob *blob = priv->current;
++      pgp_blob_t *blob = priv->current;
+       int r = SC_SUCCESS;
+       LOG_FUNC_CALLED(card->ctx);
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0024-OpenPGP-Fix-crash-after-accessing-inexistent-file.patch b/utils/opensc/patches/0024-OpenPGP-Fix-crash-after-accessing-inexistent-file.patch
new file mode 100644 (file)
index 0000000..7d8a0ff
--- /dev/null
@@ -0,0 +1,41 @@
+From 8a87a4ee9107f250254d5c93c6fd62224c400ce7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Mon, 14 Jul 2014 01:30:28 +0800
+Subject: [PATCH 24/26] OpenPGP: Fix crash after accessing inexistent file.
+
+---
+ src/libopensc/card-openpgp.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index ca3173c..94c69ae 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -973,7 +973,6 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
+                        * So we set its size to be the same as max certificate size the card supports. */
+                       (*ret)->size = priv->max_cert_size;
+               }
+-              priv->current = NULL;
+               LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
+       }
+@@ -990,7 +989,6 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
+               /* This file ID is refered when importing key&certificate via pkcs15init, like above.
+                * We pretend to successfully find this inexistent file. */
+               if (id == 0x4402 || id == 0x5f48) {
+-                      priv->current = NULL;
+                       if (ret == NULL)
+                               /* No need to return file */
+                               LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
+@@ -1002,7 +1000,6 @@ pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret)
+               }
+               if (r < 0) {    /* failure */
+-                      priv->current = NULL;
+                       LOG_FUNC_RETURN(card->ctx, r);
+               }
+       }
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0025-Replace-hardcode.patch b/utils/opensc/patches/0025-Replace-hardcode.patch
new file mode 100644 (file)
index 0000000..0eb750c
--- /dev/null
@@ -0,0 +1,148 @@
+From da70a41383e2ab81fbcc89fb1067f5a189e0fb97 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
+ <ng.hong.quan@gmail.com>
+Date: Sun, 9 Nov 2014 15:58:40 +0700
+Subject: [PATCH 25/26] Replace hardcode.
+
+---
+ src/libopensc/card-openpgp.c | 72 +++++++++++++++++++++++++-------------------
+ 1 file changed, 41 insertions(+), 31 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index 94c69ae..1e6e338 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -152,6 +152,24 @@ static int                pgp_get_pubkey(sc_card_t *, unsigned int,
+ static int            pgp_get_pubkey_pem(sc_card_t *, unsigned int,
+                               u8 *, size_t);
++/* The DO holding X.509 certificate is constructed but does not contain child DO.
++ * We should notice this when building fake file system later. */
++#define DO_CERT                  0x7f21
++/* Control Reference Template of private keys. Ref: Section 4.3.3.7 of OpenPGP card v2 spec.
++ * Here we seen it as DO just for convenient */
++#define DO_SIGN                  0xb600
++#define DO_ENCR                  0xb800
++#define DO_AUTH                  0xa400
++/* These DO does not exist. They are defined and used just for ease of implementation */
++#define DO_SIGN_SYM              0xb601
++#define DO_ENCR_SYM              0xb801
++#define DO_AUTH_SYM              0xa401
++/* Maximum length for response buffer when reading pubkey. This value is calculated with
++ * 4096-bit key length */
++#define MAXLEN_RESP_PUBKEY       527
++/* Gnuk only support 1 key length (2048 bit) */
++#define MAXLEN_RESP_PUBKEY_GNUK  271
++
+ static struct do_info         pgp1_objects[] = {      /* OpenPGP card spec 1.1 */
+       { 0x004f, SIMPLE,      READ_ALWAYS | WRITE_NEVER, NULL,               NULL        },
+       { 0x005b, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  NULL,               sc_put_data },
+@@ -192,12 +210,12 @@ static struct do_info            pgp1_objects[] = {      /* OpenPGP card spec 1.1 */
+       { 0x5f35, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  NULL,               sc_put_data },
+       { 0x5f50, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  sc_get_data,        sc_put_data },
+       { 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL,               NULL        },
+-      { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
+-      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+-      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
+-      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+-      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
+-      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { DO_AUTH,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
++      { DO_AUTH_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
++      { DO_SIGN,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
++      { DO_SIGN_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
++      { DO_ENCR,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
++      { DO_ENCR_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
+       { 0, 0, 0, NULL, NULL },
+ };
+@@ -246,30 +264,21 @@ static struct do_info            pgp2_objects[] = {      /* OpenPGP card spec 2.0 */
+       { 0x5f52, SIMPLE,      READ_ALWAYS | WRITE_NEVER, sc_get_data,        NULL        },
+       /* The 7F21 is constructed DO in spec, but in practice, its content can be retrieved
+        * as simple DO (no need to parse TLV). */
+-      { 0x7f21, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  sc_get_data,        sc_put_data },
++      { DO_CERT, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  sc_get_data,        sc_put_data },
+       { 0x7f48, CONSTRUCTED, READ_NEVER  | WRITE_NEVER, NULL,               NULL        },
+       { 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL,               NULL        },
+-      { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
++      { DO_AUTH,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
+       /* The 0xA401, 0xB601, 0xB801 are just symbolic, it does not represent any real DO.
+        * However, their R/W access condition may block the process of importing key in pkcs15init.
+        * So we set their accesses condition as WRITE_PIN3 (writable). */
+-      { 0xa401, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+-      { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
+-      { 0xb601, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
+-      { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL        },
+-      { 0xb801, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL        },
++      { DO_AUTH_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
++      { DO_SIGN,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
++      { DO_SIGN_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
++      { DO_ENCR,     CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey,     NULL   },
++      { DO_ENCR_SYM, SIMPLE,      READ_ALWAYS | WRITE_PIN3,  pgp_get_pubkey_pem, NULL   },
+       { 0, 0, 0, NULL, NULL },
+ };
+-/* The DO holding X.509 certificate is constructed but does not contain child DO.
+- * We should notice this when building fake file system later. */
+-#define DO_CERT                  0x7f21
+-/* Maximum length for response buffer when reading pubkey. This value is calculated with
+- * 4096-bit key length */
+-#define MAXLEN_RESP_PUBKEY       527
+-/* Gnuk only support 1 key length (2048 bit) */
+-#define MAXLEN_RESP_PUBKEY_GNUK  271
+-
+ #define DRVDATA(card)        ((struct pgp_priv_data *) ((card)->drv_data))
+ struct pgp_priv_data {
+       pgp_blob_t *            mf;
+@@ -747,8 +756,9 @@ pgp_read_blob(sc_card_t *card, pgp_blob_t *blob)
+               /* Buffer length for Gnuk pubkey */
+               if (card->type == SC_CARD_TYPE_OPENPGP_GNUK &&
+-                  (blob->id == 0xa400 || blob->id == 0xb600 || blob->id == 0xb800
+-                   || blob->id == 0xa401 || blob->id == 0xb601 || blob->id == 0xb801)) {
++                  (blob->id == DO_AUTH || blob->id == DO_SIGN || blob->id == DO_ENCR
++                   || blob->id == DO_AUTH_SYM || blob->id == DO_SIGN_SYM
++                   || blob->id == DO_ENCR_SYM)) {
+                       buf_len = MAXLEN_RESP_PUBKEY_GNUK;
+               }
+@@ -1804,11 +1814,11 @@ pgp_update_pubkey_blob(sc_card_t *card, u8* modulus, size_t modulus_len,
+       LOG_FUNC_CALLED(card->ctx);
+       if (key_id == SC_OPENPGP_KEY_SIGN)
+-              blob_id = 0xB601;
++              blob_id = DO_SIGN_SYM;
+       else if (key_id == SC_OPENPGP_KEY_ENCR)
+-              blob_id = 0xB801;
++              blob_id = DO_ENCR_SYM;
+       else if (key_id == SC_OPENPGP_KEY_AUTH)
+-              blob_id = 0xA401;
++              blob_id = DO_AUTH_SYM;
+       else {
+               sc_log(card->ctx, "Unknown key id %X.", key_id);
+               LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
+@@ -2501,17 +2511,17 @@ pgp_delete_file(sc_card_t *card, const sc_path_t *path)
+               LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+       if (card->type != SC_CARD_TYPE_OPENPGP_GNUK &&
+-          (file->id == 0xB601 || file->id == 0xB801 || file->id == 0xA401)) {
++          (file->id == DO_SIGN_SYM || file->id == DO_ENCR_SYM || file->id == DO_AUTH_SYM)) {
+               /* These tags are just symbolic. We don't really delete it. */
+               r = SC_SUCCESS;
+       }
+-      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB601) {
++      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_SIGN_SYM) {
+               r = gnuk_delete_key(card, 1);
+       }
+-      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB801) {
++      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_ENCR_SYM) {
+               r = gnuk_delete_key(card, 2);
+       }
+-      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xA401) {
++      else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_AUTH_SYM) {
+               r = gnuk_delete_key(card, 3);
+       }
+       else {
+-- 
+2.1.3
+
diff --git a/utils/opensc/patches/0026-hardcode-defines-for-DO-s.patch b/utils/opensc/patches/0026-hardcode-defines-for-DO-s.patch
new file mode 100644 (file)
index 0000000..d106e86
--- /dev/null
@@ -0,0 +1,53 @@
+From b9dae832db54b206a15bcc12e290cef50f31c3d0 Mon Sep 17 00:00:00 2001
+From: george <ggkitsas@yahoo.com>
+Date: Tue, 11 Nov 2014 16:16:15 +0100
+Subject: [PATCH 26/26] hardcode->defines for DO's
+
+---
+ src/libopensc/card-openpgp.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
+index 1e6e338..8464914 100644
+--- a/src/libopensc/card-openpgp.c
++++ b/src/libopensc/card-openpgp.c
+@@ -164,6 +164,18 @@ static int                pgp_get_pubkey_pem(sc_card_t *, unsigned int,
+ #define DO_SIGN_SYM              0xb601
+ #define DO_ENCR_SYM              0xb801
+ #define DO_AUTH_SYM              0xa401
++/* Private DO's */
++#define DO_PRIV1                 0x0101
++#define DO_PRIV2                 0x0102
++#define DO_PRIV3                 0x0103
++#define DO_PRIV4                 0x0104
++/* Cardholder information DO's */
++#define DO_CARDHOLDER            0x65
++#define DO_NAME                  0x5b
++#define DO_LANG_PREF             0x5f2d
++#define DO_SEX                   0x5f35
++
++
+ /* Maximum length for response buffer when reading pubkey. This value is calculated with
+  * 4096-bit key length */
+ #define MAXLEN_RESP_PUBKEY       527
+@@ -851,7 +863,7 @@ pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, unsigned int id,
+       /* Special case:
+        * Gnuk does not have default value for children of DO 65 (DOs 5B, 5F2D, 5F35)
+        * So, if these blob was not found, we create it. */
+-      if (blob->id == 0x65 && (id == 0x5B || id == 0x5F2D || id == 0x5F35)) {
++      if (blob->id == DO_CARDHOLDER && (id == DO_NAME || id == DO_LANG_PREF || id == DO_SEX)) {
+               sc_log(card->ctx, "Create blob %X under %X", id, blob->id);
+               child = pgp_new_blob(card, blob, id, sc_file_new());
+               if (child) {
+@@ -1198,7 +1210,7 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
+       /* For Gnuk card, if there is no certificate, it returns error instead of empty data.
+        * So, for this case, we ignore error and consider success */
+       if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND && card->type == SC_CARD_TYPE_OPENPGP_GNUK
+-        && (tag == DO_CERT || tag == 0x0101 || tag == 0x0102 || tag == 0x0103 || tag == 0x0104)) {
++        && (tag == DO_CERT || tag == DO_PRIV1 || tag == DO_PRIV2 || tag == DO_PRIV3 || tag == DO_PRIV4)) {
+               r = SC_SUCCESS;
+               apdu.resplen = 0;
+       }
+-- 
+2.1.3
+
index da13a4e116caf13a52f36d527df3f1c54ea80e36..e53b84328181c161924b9c3a64da1a8ab21bf02f 100644 (file)
@@ -16,7 +16,7 @@ PKG_SOURCE_URL:=http://downloads.xiph.org/releases/opus/
 PKG_MD5SUM:=20682e4d8d1ae9ec5af3cf43e808b8cb
 
 PKG_LICENSE:=BSD-2-Clause
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
 
 PKG_INSTALL:=1
index 82d016b7e1c2ff756a58b202a1e16204a106d1f0..d3b0765f85b7dd1dc1b3ab38940a86c3d8238bd8 100644 (file)
@@ -8,12 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pciutils
-PKG_VERSION:=3.2.1
+PKG_VERSION:=3.3.0
 PKG_RELEASE:=1
+PKG_USE_MIPS16:=0
 
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@KERNEL/software/utils/pciutils
-PKG_MD5SUM:=425b1acad6854cc2bbb06ac8e48e76fc
+PKG_MD5SUM:=bf6ce5c50b273ffc2d27f659e929a37e
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 
 PKG_LICENSE:=GPL-2.0
index 583eb9a60edc41c38ad4af23a1261061a9603216..610a7553083d792342313da70aca471bbd5495a9 100644 (file)
@@ -1,6 +1,6 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -108,7 +108,7 @@ distclean: clean
+@@ -111,7 +111,7 @@ distclean: clean
  install: all
  # -c is ignored on Linux, but required on FreeBSD
        $(DIRINSTALL) -m 755 $(DESTDIR)$(SBINDIR) $(DESTDIR)$(IDSDIR) $(DESTDIR)$(MANDIR)/man8 $(DESTDIR)$(MANDIR)/man7
index 9c1a067550d257711942de56758b47316325e81a..c6d690681572880b2f06544f403e27996d182fb7 100644 (file)
@@ -1,6 +1,6 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -85,7 +85,7 @@ lspci: LDLIBS+=$(LIBKMOD_LIBS)
+@@ -88,7 +88,7 @@ lspci: LDLIBS+=$(LIBKMOD_LIBS)
  ls-kernel.o: CFLAGS+=$(LIBKMOD_CFLAGS)
  
  update-pciids: update-pciids.sh
index dbd46aab4f4246abb6edf68e51afda67661c8efb..c38d1cfc57104351810778f1dafd989bf3bbfac8 100644 (file)
@@ -6,6 +6,6 @@
  echo_n "Looking for access methods..."
 -LIBRESOLV=-lresolv
 +LIBRESOLV=
+ LIBEXT=so
  
  case $sys in
-       linux*)
index df0cdeaecd08884f2c7da0c2c095a6e3e64f8fd9..f5387f0399a8657c978894564a70e440182d46cd 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pcsc-lite
-PKG_VERSION:=1.8.11
+PKG_VERSION:=1.8.13
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=https://alioth.debian.org/frs/download.php/file/3991
-PKG_MD5SUM:=73502ca4ba6526727f9f49c63d805408
+PKG_SOURCE_URL:=https://alioth.debian.org/frs/download.php/file/4126
+PKG_MD5SUM:=4dcd22d20a6df8810fac5480cc320b6d
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 PKG_LICENSE:=BSD-3-Clause
 PKG_LICENSE_FILES:=COPYING
diff --git a/utils/procps/Makefile b/utils/procps/Makefile
new file mode 100644 (file)
index 0000000..25d1ddb
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=procps
+PKG_VERSION:=3.2.8
+PKG_RELEASE:=1
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING COPYING.LIB
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://procps.sourceforge.net
+PKG_MD5SUM:=9532714b6846013ca9898984ba4cd7e0
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+PROCPS_APPLETS := \
+    ps free pgrep pkill pmap pwdx skill w \
+    slabtop snice tload top vmstat watch
+
+define Package/procps/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libncurses
+  TITLE:=proc utilities
+  URL:=http://procps.sourceforge.net/
+  MAINTAINER:=Gergely Kiss <mail.gery@gmail.com>
+endef
+
+define Package/procps
+  $(call Package/procps/Default)
+  MENU:=1
+endef
+
+define Package/procps/description
+ procps is the package that has a bunch of small useful utilities that give
+ information about processes using the /proc filesystem. The package
+ includes the programs ps, top, vmstat, w, kill, free, slabtop, and skill.
+endef
+
+define GenPlugin
+ define Package/$(1)
+   $(call Package/procps/Default)
+   DEPENDS:=procps
+   TITLE:=Applet $(2) from the procps package
+   DEFAULT:=y
+ endef
+
+ define Package/$(1)/description
+  Installs the applet $(2).
+ endef
+endef
+
+$(foreach a,$(PROCPS_APPLETS),$(eval $(call GenPlugin,procps-$(a),$(a))))
+
+MAKE_FLAGS += \
+       CFLAGS="$(TARGET_CFLAGS)" \
+       CPPFLAGS="$(TARGET_CPPFLAGS)" \
+       LDFLAGS="$(TARGET_LDFLAGS)" \
+
+define Package/procps/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/proc/libproc-$(PKG_VERSION).so $(1)/usr/lib/
+endef
+
+AUXDIR_ps := "ps/"
+
+define BuildPlugin
+  define Package/$(1)/install
+       $(INSTALL_DIR) $$(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(AUXDIR_$(2))$(2) $$(1)/usr/bin/
+  endef
+
+  $$(eval $$(call BuildPackage,$(1)))
+endef
+
+$(foreach a,$(PROCPS_APPLETS),$(eval $(call BuildPlugin,procps-$(a),$(a))))
+$(eval $(call BuildPackage,procps))
diff --git a/utils/procps/patches/010-make_fix.patch b/utils/procps/patches/010-make_fix.patch
new file mode 100644 (file)
index 0000000..74b1d3c
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -174,7 +174,7 @@ INSTALL := $(BINFILES) $(MANFILES)
+ # want this rule first, use := on ALL, and ALL not filled in yet
+ all: do_all
+--include */module.mk
++-include proc/module.mk ps/module.mk 
+ do_all:    $(ALL)
diff --git a/utils/procps/patches/020_hz_fix.patch b/utils/procps/patches/020_hz_fix.patch
new file mode 100644 (file)
index 0000000..1954453
--- /dev/null
@@ -0,0 +1,41 @@
+--- a/proc/sysinfo.c
++++ b/proc/sysinfo.c
+@@ -209,7 +209,12 @@ static int check_for_privs(void){
+   return !!rc;
+ }
++#if __GNUC__ < 4 || __GNUC_MINOR__ < 3
+ static void init_libproc(void) __attribute__((constructor));
++#else
++static void init_libproc(void) __attribute__((constructor(200)));
++#endif
++
+ static void init_libproc(void){
+   have_privs = check_for_privs();
+   // ought to count CPUs in /proc/stat instead of relying
+--- a/proc/version.c
++++ b/proc/version.c
+@@ -33,7 +33,12 @@ void display_version(void) {
+ int linux_version_code;
++#if __GNUC__ < 4 || __GNUC_MINOR__ < 3
+ static void init_Linux_version(void) __attribute__((constructor));
++#else
++static void init_Linux_version(void) __attribute__((constructor(100)));
++#endif
++
+ static void init_Linux_version(void) {
+     static struct utsname uts;
+     int x = 0, y = 0, z = 0;  /* cleared in case sscanf() < 3 */
+--- a/proc/module.mk
++++ b/proc/module.mk
+@@ -76,7 +76,7 @@ proc/$(ANAME): $(LIBOBJ)
+ #proc/$(SONAME): proc/library.map
+ proc/$(SONAME): $(LIBOBJ)
+-      $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -shared -Wl,-soname,$(SONAME) -Wl,--version-script=proc/library.map -o $@ $^ -lc
++      $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -shared -Wl,-soname,$(SONAME) -Wl,--version-script=proc/library.map -o $@ $(sort $^) -lc
+ # AUTOMATIC DEPENDENCY GENERATION -- GCC AND GNUMAKE DEPENDENT
diff --git a/utils/procps/patches/030-fix-string-problems.patch b/utils/procps/patches/030-fix-string-problems.patch
new file mode 100644 (file)
index 0000000..de3756b
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/proc/sig.c
++++ b/proc/sig.c
+@@ -214,7 +214,7 @@ void pretty_print_signals(void){
+   while(++i <= number_of_signals){
+     int n;
+     n = printf("%2d %s", i, signal_number_to_name(i));
+-    if(i%7) printf("           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
++    if(i%7) printf("%s", "           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
+     else printf("\n");
+   }
+   if((i-1)%7) printf("\n");
diff --git a/utils/rpcd-mod-lxc/Makefile b/utils/rpcd-mod-lxc/Makefile
new file mode 100644 (file)
index 0000000..154336b
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rpcd-mod-lxc
+PKG_RELEASE=20141012
+
+PKG_LICENSE:=ISC
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/rpcd-mod-lxc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=LXC rpcd module
+  DEPENDS:=+rpcd +liblxc
+  MAINTAINER:=Luka Perkov <luka@openwrt.org>
+endef
+
+define Build/Prepare
+       $(CP) ./files/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/rpcd-mod-lxc/install
+       $(INSTALL_DIR) $(1)/usr/lib/rpcd
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/lxc.so $(1)/usr/lib/rpcd/
+endef
+
+$(eval $(call BuildPackage,rpcd-mod-lxc))
diff --git a/utils/rpcd-mod-lxc/files/CMakeLists.txt b/utils/rpcd-mod-lxc/files/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4a728a0
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.6)
+PROJECT(rpcd-mod-lxc)
+ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -Wmissing-declarations)
+
+INCLUDE_DIRECTORIES(include)
+FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
+
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
+
+SET(SOURCES lxc.c)
+
+ADD_LIBRARY(rpcd-mod-lxc SHARED ${SOURCES})
+
+FIND_LIBRARY(lxc NAMES lxc liblxc)
+TARGET_LINK_LIBRARIES(rpcd-mod-lxc ${lxc})
+
+SET_TARGET_PROPERTIES(rpcd-mod-lxc PROPERTIES OUTPUT_NAME lxc PREFIX "")
+INSTALL(TARGETS rpcd-mod-lxc LIBRARY DESTINATION lib)
diff --git a/utils/rpcd-mod-lxc/files/lxc.c b/utils/rpcd-mod-lxc/files/lxc.c
new file mode 100644 (file)
index 0000000..0d52f16
--- /dev/null
@@ -0,0 +1,504 @@
+/*
+ * rpcd-lxc-plugin
+ *
+ * Copyright (C) 2014 Cisco Systems, Inc.
+ * Author: Luka Perkov <luka@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <libubus.h>
+
+#include <lxc/lxccontainer.h>
+
+#include <rpcd/plugin.h>
+
+static struct blob_buf buf;
+
+struct rpc_lxc {
+       /* ubus options */
+       char *name;
+       char *config;
+       /* lxc container */
+       struct lxc_container *container;
+};
+
+enum {
+       RPC_LXC_NAME,
+       RPC_LXC_CONFIG,
+       __RPC_LXC_MAX,
+};
+
+enum {
+       RPC_LXC_SHUTDOWN_NAME,
+       RPC_LXC_SHUTDOWN_CONFIG,
+       RPC_LXC_SHUTDOWN_TIMEOUT,
+       __RPC_LXC_SHUTDOWN_MAX,
+};
+
+enum {
+       RPC_LXC_RENAME_NAME,
+       RPC_LXC_RENAME_CONFIG,
+       RPC_LXC_RENAME_NEWNAME,
+       __RPC_LXC_RENAME_MAX,
+};
+
+enum {
+       RPC_LXC_CREATE_NAME,
+       RPC_LXC_CREATE_CONFIG,
+       RPC_LXC_CREATE_TEMPLATE,
+       RPC_LXC_CREATE_FLAGS,
+       RPC_LXC_CREATE_ARGS,
+       __RPC_LXC_CREATE_MAX,
+};
+
+static const struct blobmsg_policy rpc_lxc_min_policy[__RPC_LXC_MAX] = {
+       [RPC_LXC_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_STRING },
+};
+
+static const struct blobmsg_policy rpc_lxc_shutdown_policy[__RPC_LXC_SHUTDOWN_MAX] = {
+       [RPC_LXC_SHUTDOWN_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_SHUTDOWN_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_SHUTDOWN_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 },
+};
+
+static const struct blobmsg_policy rpc_lxc_rename_policy[__RPC_LXC_RENAME_MAX] = {
+       [RPC_LXC_RENAME_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_RENAME_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_RENAME_NEWNAME] = { .name = "newname", .type = BLOBMSG_TYPE_STRING },
+};
+
+static const struct blobmsg_policy rpc_lxc_create_policy[__RPC_LXC_CREATE_MAX] = {
+       [RPC_LXC_CREATE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_CREATE_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_CREATE_TEMPLATE] = { .name = "template", .type = BLOBMSG_TYPE_STRING },
+       [RPC_LXC_CREATE_FLAGS] = { .name = "flags", .type = BLOBMSG_TYPE_INT32 },
+       [RPC_LXC_CREATE_ARGS] = { .name = "args", .type = BLOBMSG_TYPE_ARRAY },
+};
+
+static struct rpc_lxc *
+rpc_lxc_init(struct blob_attr *tb[__RPC_LXC_MAX])
+{
+       struct rpc_lxc *l = NULL;
+
+       l = calloc(1, sizeof(struct rpc_lxc));
+       if (!l) return NULL;
+
+       if (tb[RPC_LXC_NAME]) {
+               l->name = blobmsg_data(tb[RPC_LXC_NAME]);
+       } else {
+               goto error;
+       }
+
+       if (tb[RPC_LXC_CONFIG]) {
+               l->config = blobmsg_data(tb[RPC_LXC_CONFIG]);
+       } else {
+               l->config = NULL;
+       }
+
+       l->container = lxc_container_new(l->name, l->config);
+       if (!l->container) {
+               goto error;
+       }
+
+       return l;
+error:
+       free(l);
+       return NULL;
+}
+
+static void
+rpc_lxc_done(struct rpc_lxc *l)
+{
+       if (l) {
+               lxc_container_put(l->container);
+               free(l);
+       }
+
+       return;
+}
+
+static int
+rpc_lxc_start(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->start(l->container, 0, NULL)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+
+static int
+rpc_lxc_reboot(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->reboot(l->container)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_shutdown(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_SHUTDOWN_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_shutdown_policy, __RPC_LXC_SHUTDOWN_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       /* define default timeout */
+       int timeout = 30;
+       if (tb[RPC_LXC_SHUTDOWN_TIMEOUT]) {
+               timeout = blobmsg_get_u32(tb[RPC_LXC_SHUTDOWN_TIMEOUT]);
+       }
+
+       if (!l->container->shutdown(l->container, timeout)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_stop(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->stop(l->container)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_freeze(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->freeze(l->container)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_unfreeze(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->unfreeze(l->container)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_rename(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_RENAME_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_rename_policy, __RPC_LXC_RENAME_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!tb[RPC_LXC_RENAME_NEWNAME]) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       if (l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       char *newname = blobmsg_data(tb[RPC_LXC_RENAME_NEWNAME]);
+       if (!newname || !l->container->rename(l->container, newname)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_create(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_CREATE_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       char *template = "none";
+       int flags = 0;
+       char **args = NULL;
+
+       blobmsg_parse(rpc_lxc_create_policy, __RPC_LXC_CREATE_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (tb[RPC_LXC_CREATE_TEMPLATE])
+               template = blobmsg_data(tb[RPC_LXC_CREATE_TEMPLATE]);
+
+       if (tb[RPC_LXC_CREATE_FLAGS])
+               flags = blobmsg_get_u32(tb[RPC_LXC_CREATE_FLAGS]);
+
+       if (tb[RPC_LXC_CREATE_ARGS]) {
+               struct blob_attr *cur;
+               int num, rem;
+
+               num = blobmsg_check_array(tb[RPC_LXC_CREATE_ARGS], BLOBMSG_TYPE_STRING);
+
+               // trailing NULL is needed
+               args = calloc(num + 1, sizeof(char *));
+               if (!args) {
+                       rc = UBUS_STATUS_UNKNOWN_ERROR;
+                       goto out;
+               }
+
+               num = 0;
+               blobmsg_for_each_attr(cur, tb[RPC_LXC_CREATE_ARGS], rem)
+               {
+                       if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
+                               continue;
+
+                       args[num++] = (char *) blobmsg_data(cur);
+               }
+       }
+
+       if (!l->container->create(l->container, template, NULL, NULL, flags, args)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       free(args);
+       return rc;
+}
+
+static int
+rpc_lxc_destroy(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+       struct blob_attr *tb[__RPC_LXC_MAX];
+       struct rpc_lxc *l = NULL;
+       int rc;
+
+       blobmsg_parse(rpc_lxc_min_policy, __RPC_LXC_MAX, tb, blob_data(msg), blob_len(msg));
+
+       l = rpc_lxc_init(tb);
+       if (!l) return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (l->container->is_running(l->container)) {
+               rc = UBUS_STATUS_UNKNOWN_ERROR;
+               goto out;
+       }
+
+       if (!l->container->destroy(l->container)) {
+               rc = UBUS_STATUS_INVALID_ARGUMENT;
+               goto out;
+       }
+
+       rc = UBUS_STATUS_OK;
+out:
+       rpc_lxc_done(l);
+       return rc;
+}
+
+static int
+rpc_lxc_list(struct ubus_context *ctx, struct ubus_object *obj,
+               struct ubus_request_data *req, const char *method,
+               struct blob_attr *msg)
+{
+
+       blob_buf_init(&buf, 0);
+
+       int rc;
+       char **names;
+       struct lxc_container **cret;
+
+       rc = list_all_containers(NULL, &names, &cret);
+       if (rc == -1)
+               return UBUS_STATUS_UNKNOWN_ERROR;
+
+       for (int i = 0; i < rc; i++) {
+               struct lxc_container *c = cret[i];
+               blobmsg_add_string(&buf, names[i], c->state(c));
+
+               free(names[i]);
+               lxc_container_put(c);
+       }
+
+       ubus_send_reply(ctx, req, buf.head);
+
+       return UBUS_STATUS_OK;
+}
+
+static int
+rpc_lxc_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx)
+{
+       static const struct ubus_method lxc_methods[] = {
+               UBUS_METHOD("start", rpc_lxc_start, rpc_lxc_min_policy),
+               UBUS_METHOD("reboot", rpc_lxc_reboot, rpc_lxc_min_policy),
+               UBUS_METHOD("shutdown", rpc_lxc_shutdown, rpc_lxc_shutdown_policy),
+               UBUS_METHOD("stop", rpc_lxc_stop, rpc_lxc_min_policy),
+               UBUS_METHOD("freeze", rpc_lxc_freeze, rpc_lxc_min_policy),
+               UBUS_METHOD("unfreeze", rpc_lxc_unfreeze, rpc_lxc_min_policy),
+               UBUS_METHOD("rename", rpc_lxc_rename, rpc_lxc_rename_policy),
+               UBUS_METHOD("create", rpc_lxc_create, rpc_lxc_create_policy),
+               UBUS_METHOD("destroy", rpc_lxc_destroy, rpc_lxc_min_policy),
+               UBUS_METHOD_NOARG("list", rpc_lxc_list),
+       };
+
+       static struct ubus_object_type lxc_type =
+               UBUS_OBJECT_TYPE("luci-rpc-lxc", lxc_methods);
+
+       static struct ubus_object obj = {
+               .name = "lxc",
+               .type = &lxc_type,
+               .methods = lxc_methods,
+               .n_methods = ARRAY_SIZE(lxc_methods),
+       };
+
+       return ubus_add_object(ctx, &obj);
+}
+
+struct rpc_plugin rpc_plugin = {
+       .init = rpc_lxc_api_init
+};
index fe099c3f2d93f15055a666807427819dd10d5775..98c02353514480e279e65c59aafaa92050ce8b18 100644 (file)
@@ -21,6 +21,7 @@ PKG_MD5SUM:=c466e2e7df95fa8e318e46437da87686
 PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
 
 PKG_FIXUP:=autoreconf
+PKG_CHECK_FORMAT_SECURITY:=0
 
 include $(INCLUDE_DIR)/package.mk
 
index a731fe0c355125b1b94f0e6d06bbf6e4ca59ad7f..ad9bb11554e8ef50667d73f143b2f3c40de094e1 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2008-2013 OpenWrt.org
+# Copyright (C) 2008-2014 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=shadow
 PKG_VERSION:=4.2.1
-PKG_RELEASE:=2
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://pkg-shadow.alioth.debian.org/releases
@@ -21,9 +21,8 @@ PKG_FIXUP:=autoreconf
 PKG_BUILD_PARALLEL:=1
 PKG_INSTALL:=1
 
-PKG_BUILD_DEPENDS:=libintl
-
 include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
 
 SHADOW_APPLETS := \
        chage groupadd groupdel groupmod groups passwd su \
@@ -63,12 +62,8 @@ define Package/shadow/install
        true
 endef
 
-define Package/shadow-utils/install
-endef
-
 define Package/shadow-utils
   $(call Package/shadow/Default)
-  DEPENDS:=+ALL:shadow
 endef
 
 define Package/shadow-utils/config
@@ -78,6 +73,7 @@ define Package/shadow-utils/config
     config shadow-all
       bool "Include all PLD shadow utilities"
       select PACKAGE_shadow
+      default y
 
     comment "Utilities"
 
@@ -96,6 +92,7 @@ Package/shadow-utils/description = $(Package/shadow/description)
 define Package/shadow-common
   $(call Package/shadow/Default)
   TITLE:=Shared definitions for the PLD Linux shadow utilities
+  DEPENDS:=$(ICONV_DEPENDS) $(INTL_DEPENDS)
   HIDDEN:=1
 endef
 
@@ -124,6 +121,9 @@ define Package/shadow-common/install
        $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/login.defs $(1)/etc/
 endef
 
+define Package/shadow-utils/install
+       true
+endef
 
 define BuildPlugin
   define Package/shadow-$(1)/install
diff --git a/utils/sispmctl/Makefile b/utils/sispmctl/Makefile
new file mode 100644 (file)
index 0000000..ad6c1e3
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2008-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sispmctl
+PKG_VERSION:=3.1+20120206
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=5ff4a05a5bcb6a64a9d6f77fed47014512f66b11
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://git.code.sf.net/p/sispmctl/git
+PKG_MAINTAINER:=Richard Kunze <richard.kunze@web.de>
+PKG_LICENSE:=GPL-2.0+
+
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sispmctl
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Silver Shield PM Control for Linux
+  URL:=http://sispmctl.sourceforge.net/
+  DEPENDS:=+libusb-compat
+endef
+
+define Package/sispmctl/description
+ The sispmctl tool can control Gembird SIS-PM Silver Shield
+ programmable power outlet strips (also known under the name
+ Revolt Intelli-Plug) from the command line.
+ .
+ It can be used to switch on or off any of the programmable
+ power sockets of the SIS-PM via USB. It can also show the
+ current status of each power socket, and it can handle
+ multiple SIS-PM devices, too.
+endef
+
+TARGET_CFLAGS += -D_GNU_SOURCE
+CONFIGURE_ARGS += \
+       --enable-webless \
+       --disable-dependency-tracking
+
+define Package/sispmctl/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,sispmctl))
diff --git a/utils/sispmctl/patches/001-fix-includes.patch b/utils/sispmctl/patches/001-fix-includes.patch
new file mode 100644 (file)
index 0000000..218e22e
--- /dev/null
@@ -0,0 +1,25 @@
+--- a/src/sispm_ctl.c
++++ b/src/sispm_ctl.c
+@@ -33,6 +33,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <time.h>
++#include <sys/types.h>
+ #include <usb.h>
+ #include <assert.h>
+ #include "sispm_ctl.h"
+--- a/src/main.c
++++ b/src/main.c
+@@ -34,11 +34,11 @@
+ #define __USE_XOPEN
+ #include <time.h>
+ #include <signal.h>
+-#include <usb.h>
+ #include <assert.h>
+ #include <getopt.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
++#include <usb.h>
+ #include <fcntl.h>
index d33917c60c0a72c19db627b462fedbf95a3cde1e..b09165a0980fbff38f4d521c14cfb693d43b3999 100644 (file)
@@ -17,6 +17,9 @@ PKG_SOURCE_URL:=@SF/smartmontools
 PKG_MD5SUM:=2ea0c62206e110192a97b59291b17f54
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -60,13 +63,6 @@ CONFIGURE_VARS += \
        LDFLAGS="$$$$LDFLAGS" \
        LIBS="-nodefaultlibs -lc -luClibc++ -lm $(LIBGCC_S) -lc" \
 
-define Build/Configure
-       (cd $(PKG_BUILD_DIR); rm -rf config.{cache,status} ; \
-               ./autogen.sh \
-       );
-       $(call Build/Configure/Default)
-endef
-
 define Build/Compile
        $(MAKE) -C $(PKG_BUILD_DIR) \
                BUILD_INFO='"(localbuild)"' \
diff --git a/utils/smstools3/Makefile b/utils/smstools3/Makefile
new file mode 100644 (file)
index 0000000..12d4ecf
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=smstools3
+PKG_VERSION:=3.1.15
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Gérald Kerma <dreagle@doukki.net>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_PARALLEL:=0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://smstools3.kekekasvi.com/packages/
+PKG_MD5SUM:=0241ef60e646fac1a06254a848e61ed7
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+PKG_BUILD_DEPENDS:=libiconv-full iconv socket nsl
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/smstools3
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=SMS Server Tools 3
+  DEPENDS:=+libiconv-full +iconv
+  URL:=http://smstools3.kekekasvi.com/
+endef
+
+define Package/smstools3/description
+ The SMS Server Tools 3 is a SMS Gateway software which can send and receive
+ short messages through GSM modems and mobile phones.
+endef
+
+TARGET_CFLAGS = -D NUMBER_OF_MODEMS=1
+TARGET_CFLAGS += -D USE_ICONV
+TARGET_CFLAGS += -D DISABLE_INET_SOCKET
+TARGET_CFLAGS += -W -Wall
+TARGET_CFLAGS += -D_FILE_OFFSET_BITS=64
+
+TARGET_LDFLAGS += -liconv
+
+BINDIR=/usr/local/bin
+
+define Build/Compile
+       $(MAKE) -C "$(PKG_BUILD_DIR)"/src \
+               CC="$(TARGET_CC)" \
+               USER_CFLAGS='$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS) \
+               -I"$(STAGING_DIR)/usr/lib/libiconv-full/include"' \
+               USER_LDFLAGS='$(TARGET_LFLAGS) $(EXTRA_LDFLAGS) -L"$(STAGING_DIR)/usr/lib/libiconv-full/lib"' \
+               all
+endef
+
+define Package/smstools3/install
+       $(INSTALL_DIR) $(1)/$(BINDIR)
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smsd $(1)/$(BINDIR)/smsd
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/sendsms $(1)/$(BINDIR)/sendsms
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/sms2html $(1)/$(BINDIR)/sms2html
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/sms2unicode $(1)/$(BINDIR)/sms2unicode
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/unicode2sms $(1)/$(BINDIR)/unicode2sms
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_DATA) -m 0755 ./files/smstools3.init $(1)/etc/init.d/smstools3
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) -m 0755 ./files/smstools3.conf $(1)/etc/smsd.conf
+endef
+
+$(eval $(call BuildPackage,smstools3))
diff --git a/utils/smstools3/files/smstools3.conf b/utils/smstools3/files/smstools3.conf
new file mode 100644 (file)
index 0000000..c8732e3
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Description: Main configuration file for the smsd
+#
+
+devices = GSM1
+incoming = /var/spool/sms/incoming
+outgoing = /var/spool/sms/outgoing
+checked = /var/spool/sms/checked
+failed = /var/spool/sms/failed
+sent = /var/spool/sms/sent
+receive_before_send = no
+autosplit = 3
+
+[GSM1]
+init = AT+CPMS="ME","ME","ME"
+device = /dev/ttyUSB0
+incoming = yes
+pin = 0000
+baudrate = 9600
+
diff --git a/utils/smstools3/files/smstools3.init b/utils/smstools3/files/smstools3.init
new file mode 100644 (file)
index 0000000..1638c60
--- /dev/null
@@ -0,0 +1,152 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2014 OpenWrt.org
+# smsd initscript openwrt mod
+
+START=99
+STOP=99
+
+EXTRA_COMMANDS="status"
+EXTRA_HELP="        status  View pid and service status "
+
+# Set USER and GROUP, if necessary:
+USER=""
+GROUP=""
+
+# If an unpriviledged user is selected, make sure that next two
+# files are writable by that user:
+PIDFILE="/var/run/smsd.pid"
+INFOFILE="/var/run/smsd.working"
+# Logfile can also be defined in here:
+LOGFILE="/var/log/smsd.log"
+
+DAEMON=/usr/local/bin/smsd
+# A program which turns power off for couple of seconds:
+RESETMODEMS=/usr/local/bin/smsd_resetmodems
+NAME=smsd
+PSOPT=""
+
+# Set/edit this before starting service !!!!!
+WRT_SPOOL=/var/spool
+
+# Maximum time to stop smsd, after that it gets killed hardly:
+MAXWAIT=45
+
+boot() {
+       start
+}
+
+start() {
+       test -x $DAEMON || exit 0
+
+       echo "Creating minimum spool directories"
+       mkdir -p $WRT_SPOOL
+       mkdir -p $WRT_SPOOL/sms
+       mkdir -p $WRT_SPOOL/sms/incoming
+       mkdir -p $WRT_SPOOL/sms/outgoing
+       mkdir -p $WRT_SPOOL/sms/checked
+       mkdir -p $WRT_SPOOL/sms/failed
+       mkdir -p $WRT_SPOOL/sms/sent
+
+       echo -n "Starting SMS Daemon: "
+       MSG="."
+       ARGS="-n MAINPROCESS -p$PIDFILE -i$INFOFILE"
+       [ "x$USER" != x ] && ARGS="$ARGS -u$USER"
+       [ "x$GROUP" != x ] && ARGS="$ARGS -g$GROUP"
+       [ "x$LOGFILE" != x ] && ARGS="$ARGS -l$LOGFILE"
+       PID=`cat $PIDFILE 2>/dev/null`
+       if [ "x$PID" != x ]; then
+         if kill -0 $PID 2>/dev/null; then
+           MSG=" already running ($PID)."
+         else
+           PID=""
+         fi
+       fi
+       if [ "x$PID" = x ]; then
+         if ps $PSOPT | grep $NAME | grep -v grep >/dev/null; then
+           MSG=" already running."
+         else
+           $DAEMON $ARGS
+           sleep 1
+           PIDS=`ps $PSOPT | grep $NAME | grep -v grep`
+           [ "x$PIDS" = x ] && MSG=" failed."
+         fi
+       fi
+       echo "$NAME$MSG"
+}
+
+stop() {
+       if ps $PSOPT | grep $NAME | grep -v grep >/dev/null; then
+         PID=`cat $PIDFILE 2>/dev/null`
+         if [ "x$PID" != x ]; then
+           P=`kill -0 $PID 2>/dev/null`
+           [ "x$P" != x ] && PID=""
+         fi
+         if [ "x$PID" != x ]; then
+           kill $PID
+         else
+           kill `ps $PSOPT | grep $NAME | grep -v grep | awk '{print $1}'` >/dev/null 2>&1
+         fi
+         sleep 1
+         if ps $PSOPT | grep $NAME | grep -v grep >/dev/null; then
+           echo "Allowing $NAME to terminate gracefully within $MAXWAIT seconds"
+           infofound=0
+           dots=0
+           seconds=0
+           while ps $PSOPT | grep $NAME | grep -v grep >/dev/null; do
+             if [ $infofound -lt 1 ]; then
+               if [ -f $INFOFILE ]; then
+                 infofound=1
+                 if [ $dots -gt 0 ]; then
+                   echo ""
+                   dots=0
+                 fi
+                 $ECHO -n "$NAME is currently "
+                 cat $INFOFILE
+                 echo "Time counting is now disabled and we will wait until this job is complete."
+               fi
+             fi
+             [ $infofound -lt 1 ] && seconds=`expr $seconds + 1`
+             echo -n "."
+             dots=`expr $dots + 1`
+             if [ "$seconds" -ge $MAXWAIT ]; then
+               if [ $dots -gt 0 ]; then
+                 echo ""
+                 dots=0
+               fi
+               echo "Timeout occured, killing $NAME hardly."
+               kill -9 `ps $PSOPT | grep $NAME | grep -v grep | awk '{print $1}'` >/dev/null 2>&1
+               [ -f $PIDFILE ] && rm $PIDFILE
+               seconds=0
+             fi
+             sleep 1
+           done
+           [ $dots -gt 0 ] && echo ""
+           #echo "$NAME is stopped."
+         fi
+       fi
+}
+
+restart() {
+       stop
+       start
+}
+
+
+status() {
+       PID=$(cat $PIDFILE)
+
+       test -e $PIDFILE
+       if [ $? == 0 ]; then
+               echo $NAME " running! pid $PID"
+       else
+               echo $NAME " not running !!!"
+       fi
+}
+
+reset() {
+       $0 stop
+       [ -f "$RESETMODEMS" ] && "$RESETMODEMS"
+       sleep 30
+       $0 start
+}
+
diff --git a/utils/smstools3/patches/001-smsd.patch b/utils/smstools3/patches/001-smsd.patch
new file mode 100644 (file)
index 0000000..6761661
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/src/smsd.c       2010-09-21 13:47:48.000000000 +0300
++++ b/src/smsd.c       2013-03-05 05:26:26.000000000 +0300
+@@ -5200,8 +5200,8 @@
+       int result = 1;
+       char *cmd;
+       char *p;
+-      char answer[500];
+-      char buffer[600];
++      char answer[1024];
++      char buffer[1024];
+       int fd;
+       int log_retry = 3;
+       int i;
diff --git a/utils/smstools3/patches/002-Makefile.patch b/utils/smstools3/patches/002-Makefile.patch
new file mode 100644 (file)
index 0000000..a8445ef
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/src/Makefile     2014-12-20 18:33:55.654252867 +0100
++++ b/src/Makefile     2014-12-20 18:31:10.241359741 +0100
+@@ -43,7 +43,7 @@
+ ifneq (,$(findstring SOLARIS,$(CFLAGS)))
+ ifeq (,$(findstring DISABLE_INET_SOCKET,$(CFLAGS)))
+-override LFLAGS += -lsocket -lnsl
++      override LFLAGS += -lsocket -lnsl
+ endif
+ endif
+
diff --git a/utils/sockread/Makefile b/utils/sockread/Makefile
new file mode 100644 (file)
index 0000000..d3c15d4
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# This software is licensed under the CC0-1.0 license.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sockread
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+PKG_LICENSE:=CC0-1.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sockread
+       SECTION:=utils
+       CATEGORY:=Utilities
+       TITLE:=sockread
+       MAINTAINER:=Moritz Warning <moritzwarning@web.de>
+endef
+
+define Package/sockread/description
+       sockread writes and reads data from a Unix domain socket
+       represented as a special file on the file system.
+endef
+
+define Build/Prepare
+       mkdir -p $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/sockread/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/sockread $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,sockread))
diff --git a/utils/sockread/src/Makefile b/utils/sockread/src/Makefile
new file mode 100644 (file)
index 0000000..fe4f8a7
--- /dev/null
@@ -0,0 +1,11 @@
+CC ?= gcc
+CFLAGS ?= -O2 -Wall -pedantic
+CFLAGS += -std=gnu99
+
+.PHONY: clean
+
+sockread:
+       $(CC) $(CFLAGS) main.c -o sockread
+
+clean:
+       rm -f sockread
diff --git a/utils/sockread/src/main.c b/utils/sockread/src/main.c
new file mode 100644 (file)
index 0000000..06c21de
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+int main(int argc, char *argv[]) {
+       char buf[1024];
+       ssize_t r;
+
+       if (argc != 2) {
+               fprintf(stderr, "Write to and read from a Unix domain socket.\n\nUsage: %s <socket>\n", argv[0]);
+               return 1;
+       }
+
+       size_t addrlen = strlen(argv[1]);
+
+       /* Allocate enough space for arbitrary-length paths */
+       char addrbuf[offsetof(struct sockaddr_un, sun_path) + addrlen + 1];
+       memset(addrbuf, 0, sizeof(addrbuf));
+
+       struct sockaddr_un *addr = (struct sockaddr_un *)addrbuf;
+       addr->sun_family = AF_UNIX;
+       memcpy(addr->sun_path, argv[1], addrlen+1);
+
+       int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0) {
+               fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+               return 1;
+       }
+
+       if (connect(fd, (struct sockaddr*)addr, sizeof(addrbuf)) < 0) {
+               fprintf(stderr, "Can't connect to `%s': %s\n", argv[1], strerror(errno));
+               return 1;
+       }
+
+       /* Check if stdin refers to a terminal */
+       if (!isatty(fileno(stdin))) {
+               /* Read from stdin and write to socket */
+               while (0 < (r = fread(buf, 1, sizeof(buf), stdin))) {
+                       send(fd, buf, r, 0);
+               }
+       }
+
+       /* Read from socket and write to stdout */
+       while (1) {
+               r = recv(fd, buf, sizeof(buf), 0);
+               if (r < 0) {
+                       fprintf(stderr, "read: %s\n", strerror(errno));
+                       return 1;
+               }
+
+               if (r == 0)
+                       return 0;
+
+               fwrite(buf, r, 1, stdout);
+       }
+
+       return 0;
+}
index ad4c2ede03f4f86d19b26678abbe581359fe3c2a..c1f6b9b748a00e93e795f1728895c8c3864a6838 100644 (file)
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=stm32flash
-PKG_VERSION:=0.3
+PKG_VERSION:=0.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://releases.stm32flash.googlecode.com/git
-PKG_MD5SUM:=a806c6b10b186b7d06a7eab12c3bc880
+PKG_MD5SUM:=ec9b5c8bae67f9a489786546d088bd14
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
 PKG_MAINTAINER:=Christian Pointner <equinox@spreadspace.org>
 PKG_LICENSE:=GPL-2.0+
-PKG_LICENSE_FILE:=gpl-2.0.txt
+PKG_LICENSE_FILES:=gpl-2.0.txt
 include $(INCLUDE_DIR)/package.mk
 
 define Package/stm32flash
diff --git a/utils/stoken/Makefile b/utils/stoken/Makefile
new file mode 100644 (file)
index 0000000..7fcbdad
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=stoken
+PKG_VERSION:=0.8
+PKG_REV:=c4d79ffbf5053e44be4b64da22b1b7fb6a51daf2
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/cernekee/stoken.git
+
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REV).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+PKG_LICENSE:=LGPL-2.1
+PKG_INSTALL:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/stoken/Default
+  TITLE:=stoken is a tokencode generator compatible with RSA SecurID 128-bit (AES)
+  URL:=http://sourceforge.net/p/stoken/
+  DEPENDS:= +libxml2 +libnettle
+endef
+
+define Package/stoken
+  $(call Package/stoken/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libstoken
+  MENU:=1
+endef
+
+define Package/stoken/description
+  stoken is a tokencode generator compatible with RSA SecurID 128-bit (AES). This package contains the cli
+endef
+
+define Package/libstoken
+  $(call Package/stoken/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+endef
+
+CONFIGURE_ARGS += \
+       --with-nettle
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libstoken*.{la,a,so*} $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/stoken.pc \
+               $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/stoken/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/stoken $(1)/usr/bin/
+endef
+
+define Package/libstoken/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libstoken*.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,stoken))
+$(eval $(call BuildPackage,libstoken))
diff --git a/utils/sumo/Makefile b/utils/sumo/Makefile
new file mode 100644 (file)
index 0000000..7aa3c8b
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sumo
+PKG_VERSION:=0.22.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-src-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/sumo
+PKG_MD5SUM:=d239a3f94fdb905fdaf1648f2b71fd42
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_ARGS += \
+       --with-xerces-includes=$(STAGING_DIR)/usr/include/xercesc \
+       --disable-debug \
+       --disable-dependency-tracking \
+       --disable-silent-rules
+
+define Package/sumo
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=SUMO - Simulation of Urban MObility
+  URL:=http://sumo-sim.org/
+  DEPENDS:=+libstdcpp +libxerces-c
+endef
+
+define Package/sumo/description
+  SUMO is a free and open traffic simulation suite which is available since 2001.
+  SUMO allows modelling of intermodal traffic systems including road vehicles,
+  public transport and pedestrians. Included with SUMO is a wealth of supporting
+  tools which handle tasks such as route finding, visualization, network import
+  and emission calculation. SUMO can be enhanced with custom models and provides
+  various APIs to remotely control the simulation.
+endef
+
+define Package/sumo/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/{activitygen,dfrouter,duarouter,emissionsDrivingCycle,emissionsMap,jtrrouter,marouter,netconvert,netgenerate,od2trips,polyconvert,TraCITestClient} $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sumo $(1)/usr/bin/sumo-bin
+       $(INSTALL_DIR) $(1)/usr/sbin
+       $(INSTALL_BIN) files/sumo.sh $(1)/usr/sbin/sumo
+       $(INSTALL_DIR) $(1)/usr/share/sumo
+       $(CP) $(PKG_BUILD_DIR)/data $(1)/usr/share/sumo/
+endef
+
+$(eval $(call BuildPackage,sumo))
diff --git a/utils/sumo/files/sumo.sh b/utils/sumo/files/sumo.sh
new file mode 100644 (file)
index 0000000..2ae8df8
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Copyright (C) 2015 OpenWrt.org
+
+SUMO_HOME=/usr/share/sumo sumo-bin $@
+
+exit 0
diff --git a/utils/taskwarrior/Makefile b/utils/taskwarrior/Makefile
new file mode 100644 (file)
index 0000000..d42e9ab
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=taskwarrior
+PKG_VERSION:=2.4.0
+PKG_RELEASE:=1
+
+PKG_LICENSE:=MIT
+
+PKG_SOURCE:=task-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.taskwarrior.org/download/
+PKG_MD5SUM:=de4b64b3d28bb9636af219a486552cd0
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/task-$(PKG_VERSION)
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/taskwarrior
+  TITLE:=taskwarrior
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libstdcpp +libuuid +libgnutls
+  URL:=http://taskwarrior.org/
+endef
+
+TARGET_LDFLAGS += -ldl
+
+define Package/taskwarrior/description
+ taskwarrior is a command-line todo list manager
+endef
+
+define Package/taskwarrior/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/task $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,taskwarrior))
index c77eb8af311c451e2c2fb0b0863ab2f83b87616e..a50f1820024482240a8376c2cf3bb6de43e2d98a 100644 (file)
@@ -14,7 +14,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=ftp://ftp.astron.com/pub/tcsh/
 PKG_MD5SUM:=6eed09dbd4223ab5b6955378450d228a
 PKG_LICENSE:=BSD-4-Clause-UC
-PKG_LICENSE_FILE:=Copyright
+PKG_LICENSE_FILES:=Copyright
 
 PKG_MAINTAINER:=Nuno Goncalves <nunojpg@gmail.com>
 
index 4855d6d3182fc036f37ec08392d6259446452c84..1a7e6d147c62a609823855e7faf301f6b25272e2 100644 (file)
@@ -16,6 +16,7 @@ PKG_SOURCE_URL:=@SF/tmux
 PKG_MD5SUM:=b07601711f96f1d260b390513b509a2d
 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
 PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 
index 7b9e6611ffef9d4a0ccf396d718fa8da99bb0a93..733d074bacd0d4476fe09046d425f5e549bae6b1 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tracertools
-PKG_VERSION:=20140905
+PKG_VERSION:=20141027
 PKG_RELEASE=$(PKG_SOURCE_VERSION)
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
 
@@ -16,7 +16,7 @@ PKG_LICENSE:=GPL-3.0
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gitorious.org/tracertools/tracertools.git
-PKG_SOURCE_VERSION:=4a6eb477a850e102f37b6f6690b0797ec664f36d
+PKG_SOURCE_VERSION:=9ba70d1fe4f3c0f24d565d98c79fee71711823f0
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
@@ -37,7 +37,6 @@ endef
 define Package/tracertools/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/tracerstat $(1)/usr/bin/
-       ln -s tracerstat $(1)/usr/bin/tracerreq
 endef
 
 $(eval $(call BuildPackage,tracertools))
index 68464f8ced975b0329710290feae7d547195cb23..5b365cdd992997714436e1545aae065695033bce 100644 (file)
@@ -20,7 +20,7 @@ PKG_SOURCE_VERSION:=$(PKG_REV)
 
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 PKG_LICENSE:=GPL-3.0+
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 include $(INCLUDE_DIR)/package.mk
 
index 10c70cb68e017697280fd689c6e26ff4d679ee2d..9b7a54c3b2d1c8d8dcebcf22143447048b25de58 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=unrar
-PKG_VERSION:=5.1.7
+PKG_VERSION:=5.2.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=unrarsrc-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.rarlab.com/rar
-PKG_MD5SUM:=af571529a358c972872b91792ffc0a80
+PKG_MD5SUM:=9611a2a5d5b6dce39ee5b3770bab2387
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 
 PKG_LICENSE:=UnRAR
index e553b7aa99648e25e00f222390023c8c46bb9401..ca82e13535c5bebd6d2264bcb491cb605d1d7d63 100644 (file)
@@ -1,6 +1,5 @@
-diff -uprN a/unrar/makefile b/unrar/makefile
---- a/makefile 2014-06-12 13:36:14.723816266 +0200
-+++ b/makefile 2014-06-12 13:36:36.174531961 +0200
+--- a/makefile
++++ b/makefile
 @@ -2,12 +2,12 @@
  # Makefile for UNIX - unrar
  
index a90d6d33f1509a30b8af115ab7345cca7fbbea08..65ab016672157b115c6d9e2ca609aad45a93d03f 100644 (file)
@@ -8,17 +8,17 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=usbmuxd
-PKG_VERSION:=1.0.8
+PKG_VERSION:=1.1.1
 PKG_RELEASE:=2
 PKG_SOURCE_PROTO:=git
 
 PKG_MAINTAINER:=Lukasz Baj <l.baj@radytek.com>
 PKG_LICENSE:=GPL-2.0
-PKG_LICENSE_FILE:=COPYING.GPLv2
+PKG_LICENSE_FILES:=COPYING.GPLv2
 
 PKG_SOURCE_URL:=https://github.com/libimobiledevice/usbmuxd.git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=2f6d9d5f7047d4dd5ea9970721ba902301621ab2
+PKG_SOURCE_VERSION:=4bd7cd0d28e7f5920de51470b863f3aeee00409d
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
 
 PKG_FIXUP:=autoreconf
index 72c7f271acd42464c480fbce82f919e8e7cee16e..512057c2a5dd5d2d1764a496c6224ce7a0d25078 100644 (file)
@@ -17,7 +17,7 @@ PKG_MD5SUM:=fe77d801ba69e0fb9b4914a04b9ff506
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 
 PKG_LICENSE:=GPL-3.0+
-PKG_LICENSE_FILE:=COPYING
+PKG_LICENSE_FILES:=COPYING
 
 PKG_INSTALL:=1
 
diff --git a/utils/zoneinfo/Makefile b/utils/zoneinfo/Makefile
new file mode 100644 (file)
index 0000000..6f1b6ef
--- /dev/null
@@ -0,0 +1,242 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# Author: Michael Geddes
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zoneinfo
+PKG_VERSION:=2015a
+PKG_VERSION_CODE:=2015a
+PKG_RELEASE:=1
+
+#As i couldn't find real license used "Public Domain"
+#as referense to http://www.iana.org/time-zones/repository/tz-link.html
+PKG_LICENSE:=Public Domain
+
+PKG_SOURCE:=tzdata$(PKG_VERSION).tar.gz
+PKG_SOURCE_CODE:=tzcode$(PKG_VERSION_CODE).tar.gz
+PKG_SOURCE_URL:=http://www.iana.org/time-zones/repository/releases
+PKG_MD5SUM:=4ed11c894a74a5ea64201b1c6dbb8831
+
+include $(INCLUDE_DIR)/package.mk
+
+define Download/tzcode
+   FILE=$(PKG_SOURCE_CODE)
+   URL=$(PKG_SOURCE_URL)
+   MD5SUM:=8f375ede46ae137fbac047ac431bda37
+endef
+
+$(eval $(call Download,tzcode))
+
+define Package/zoneinfo/Default
+  SUBMENU:=zoneinfo
+  TITLE:=Zone Information
+  SECTION:=utils
+  CATEGORY:=Utilities
+  MAINTAINER=Vladimir Ulrich <admin@evl.su>
+endef
+
+define Package/zoneinfo-core
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (core)
+endef
+
+define Package/zoneinfo-simple
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (simple)
+endef
+
+define Package/zoneinfo-africa
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Africa)
+endef
+
+define Package/zoneinfo-northamerica
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (NorthAmerica)
+endef
+
+define Package/zoneinfo-southamerica
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (SouthAmerica)
+endef
+
+define Package/zoneinfo-poles
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Arctic, Antarctic)
+endef
+
+define Package/zoneinfo-asia
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Asia)
+endef
+
+define Package/zoneinfo-atlantic
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Atlantic)
+endef
+
+define Package/zoneinfo-australia-nz
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Australia-NZ)
+endef
+
+define Package/zoneinfo-pacific
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Pacific)
+endef
+
+define Package/zoneinfo-europe
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (Europe)
+endef
+
+define Package/zoneinfo-india
+$(call Package/zoneinfo/Default)
+  TITLE:=Zone Information (India)
+endef
+
+define Build/Prepare
+       (cd $(PKG_BUILD_DIR) && tar -xzf $(DL_DIR)/$(PKG_SOURCE_CODE) && tar -xzf $(DL_DIR)/$(PKG_SOURCE))
+endef
+
+define Build/Compile
+       CFLAGS="$(HOST_CFLAGS)" \
+       $(MAKE) -C $(PKG_BUILD_DIR) -f Makefile \
+               $(HOST_CONFIGURE_OPTS) \
+               CC="$(HOSTCC)" \
+               LD="\$$$$(CC)" \
+               CPPFLAGS="$(HOST_CPPFLAGS)" \
+               LDFLAGS="$(HOST_LDFLAGS)" \
+               TOPDIR="$(PKG_INSTALL_DIR)" \
+               TZDIR="$(PKG_INSTALL_DIR)/zoneinfo" \
+               install
+endef
+
+define Package/zoneinfo-core/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in \
+               CET CST6CDT EET EST EST5EDT GB-Eire Eire \
+               GB    GMT   GMT+0 GMT-0 GMT0  Greenwich  \
+               HST   MET   MST   MST7MDT                \
+               PRC   PST8PDT ROC ROK     UCT   UTC      \
+               Universal W-SU WET Zulu Etc/* zone.tab ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-simple/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Pacific/Honolulu     \
+               America/Anchorage   America/Los_Angeles America/Denver   \
+               America/Chicago     America/New_York    America/Caracas  \
+               America/Sao_Paulo   Europe/London       Europe/Paris     \
+               Africa/Cairo        Europe/Moscow       Asia/Dubai       \
+               Asia/Karachi        Asia/Dhaka          Asia/Bankok      \
+               Asia/Hong_Kong      Asia/Tokyo          Australia/Darwin \
+               Australia/Adelaide  Australia/Brisbane  Australia/Sydney \
+               Australia/Perth     Pacific/Noumea ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-africa/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo/Africa
+       $(CP) $(PKG_INSTALL_DIR)/zoneinfo/Africa/* \
+             $(1)/usr/share/zoneinfo/Africa
+endef
+
+define Package/zoneinfo-northamerica/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in US America Canada Mexico Cuba Jamaica Navajo ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+       rm  -rf $(1)/usr/share/zoneinfo/America/Argentina
+endef
+
+define Package/zoneinfo-southamerica/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Brazil Chile ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo/America/Argentina
+       $(CP) $(PKG_INSTALL_DIR)/zoneinfo/America/Argentina/* \
+             $(1)/usr/share/zoneinfo/America/Argentina
+endef
+
+define Package/zoneinfo-poles/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Antarctica Arctic ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-asia/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Asia Japan Singapore Hongkong ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-atlantic/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Atlantic Iceland ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-australia-nz/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in NZ NZ-CHAT Australia ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-pacific/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Pacific Kwajalein ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-europe/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Europe Portugal Poland ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+define Package/zoneinfo-india/install
+       $(INSTALL_DIR) $(1)/usr/share/zoneinfo
+       for i in Indian ; do \
+         $(CP) $(PKG_INSTALL_DIR)/zoneinfo/$$$$i \
+             $(1)/usr/share/zoneinfo ; \
+       done
+endef
+
+$(eval $(call BuildPackage,zoneinfo-simple))
+$(eval $(call BuildPackage,zoneinfo-core))
+$(eval $(call BuildPackage,zoneinfo-africa))
+$(eval $(call BuildPackage,zoneinfo-northamerica))
+$(eval $(call BuildPackage,zoneinfo-southamerica))
+$(eval $(call BuildPackage,zoneinfo-poles))
+$(eval $(call BuildPackage,zoneinfo-asia))
+$(eval $(call BuildPackage,zoneinfo-atlantic))
+$(eval $(call BuildPackage,zoneinfo-australia-nz))
+$(eval $(call BuildPackage,zoneinfo-pacific))
+$(eval $(call BuildPackage,zoneinfo-europe))
+$(eval $(call BuildPackage,zoneinfo-india))