aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml57
-rw-r--r--configure.ac121
-rwxr-xr-xcontrib/devtools/github-merge.sh4
-rwxr-xr-xcontrib/devtools/symbol-check.py6
-rw-r--r--contrib/linearize/README.md34
-rw-r--r--contrib/linearize/example-linearize.cfg13
-rwxr-xr-xcontrib/linearize/linearize-data.py208
-rwxr-xr-x[-rw-r--r--]contrib/linearize/linearize-hashes.py (renamed from contrib/linearize/linearize.py)40
-rw-r--r--depends/.gitignore5
-rw-r--r--depends/Makefile114
-rw-r--r--depends/README55
-rw-r--r--depends/README.packages116
-rw-r--r--depends/README.usage29
-rw-r--r--depends/builders/darwin.mk22
-rw-r--r--depends/builders/default.mk20
-rw-r--r--depends/builders/linux.mk2
-rwxr-xr-xdepends/config.guess1420
-rw-r--r--depends/config.site.in84
-rwxr-xr-xdepends/config.sub1794
-rw-r--r--depends/funcs.mk223
-rw-r--r--depends/hosts/darwin.mk8
-rw-r--r--depends/hosts/default.mk23
-rw-r--r--depends/hosts/linux.mk23
-rw-r--r--depends/hosts/mingw32.mk2
-rw-r--r--depends/packages/bdb.mk29
-rw-r--r--depends/packages/boost.mk42
-rw-r--r--depends/packages/dbus.mk23
-rw-r--r--depends/packages/expat.mk21
-rw-r--r--depends/packages/fontconfig.mk22
-rw-r--r--depends/packages/freetype.mk22
-rw-r--r--depends/packages/libX11.mk23
-rw-r--r--depends/packages/libXau.mk23
-rw-r--r--depends/packages/libXext.mk22
-rw-r--r--depends/packages/libxcb.mk30
-rw-r--r--depends/packages/miniupnpc.mk28
-rw-r--r--depends/packages/native_ccache.mk25
-rw-r--r--depends/packages/native_cctools.mk80
-rw-r--r--depends/packages/native_cdrkit.mk26
-rw-r--r--depends/packages/native_comparisontool.mk44
-rw-r--r--depends/packages/native_libdmg-hfsplus.mk22
-rw-r--r--depends/packages/native_libuuid.mk24
-rw-r--r--depends/packages/native_openssl.mk21
-rw-r--r--depends/packages/native_protobuf.mk25
-rw-r--r--depends/packages/openssl.mk40
-rw-r--r--depends/packages/packages.mk14
-rw-r--r--depends/packages/protobuf.mk28
-rw-r--r--depends/packages/qrencode.mk22
-rw-r--r--depends/packages/qt.mk89
-rw-r--r--depends/packages/xcb_proto.mk27
-rw-r--r--depends/packages/xextproto.mk21
-rw-r--r--depends/packages/xproto.mk21
-rw-r--r--depends/packages/xtrans.mk22
-rw-r--r--depends/patches/boost/darwin_boost_atomic-1.patch35
-rw-r--r--depends/patches/boost/darwin_boost_atomic-2.patch55
-rw-r--r--depends/patches/native_cdrkit/cdrkit-deterministic.patch86
-rw-r--r--depends/patches/qt/fix-xcb-include-order.patch21
-rw-r--r--depends/patches/qt/mac-qmake.conf23
-rw-r--r--doc/README.md1
-rw-r--r--doc/assets-attribution.md1
-rw-r--r--doc/bootstrap.md2
-rw-r--r--doc/build-osx.md27
-rw-r--r--doc/build-unix.md6
-rw-r--r--doc/travis-ci.txt39
-rwxr-xr-xqa/pull-tester/run-bitcoind-for-test.sh.in2
-rw-r--r--src/Makefile.am38
-rw-r--r--src/Makefile.qt.include6
-rw-r--r--src/Makefile.qttest.include4
-rw-r--r--src/Makefile.test.include19
-rw-r--r--src/addrman.cpp14
-rw-r--r--src/alert.cpp6
-rw-r--r--src/alert.h7
-rw-r--r--src/bitcoin-cli.cpp2
-rw-r--r--src/bitcoin-tx.cpp41
-rw-r--r--src/bitcoind.cpp1
-rw-r--r--src/coins.cpp60
-rw-r--r--src/coins.h56
-rw-r--r--src/compat.h25
-rw-r--r--src/compat/glibcxx_compat.cpp2
-rw-r--r--src/core.cpp40
-rw-r--r--src/core.h9
-rw-r--r--src/core_write.cpp1
-rw-r--r--src/crypter.cpp30
-rw-r--r--src/crypter.h5
-rw-r--r--src/db.cpp2
-rw-r--r--src/db.h1
-rw-r--r--src/init.cpp7
-rw-r--r--src/keystore.cpp1
-rw-r--r--src/keystore.h9
-rw-r--r--src/leveldbwrapper.h4
-rw-r--r--src/m4/ax_boost_base.m46
-rw-r--r--src/m4/bitcoin_find_bdb48.m44
-rw-r--r--src/m4/bitcoin_qt.m414
-rw-r--r--src/main.cpp189
-rw-r--r--src/main.h82
-rw-r--r--src/miner.cpp31
-rw-r--r--src/net.cpp188
-rw-r--r--src/net.h162
-rw-r--r--src/netbase.cpp24
-rw-r--r--src/netbase.h5
-rw-r--r--src/noui.cpp1
-rw-r--r--src/pow.cpp1
-rw-r--r--src/protocol.cpp6
-rw-r--r--src/protocol.h4
-rw-r--r--src/qt/bitcoin.cpp1
-rw-r--r--src/qt/bitcoin.qrc2
-rw-r--r--src/qt/bitcoingui.cpp5
-rw-r--r--src/qt/clientmodel.cpp1
-rw-r--r--src/qt/forms/overviewpage.ui6
-rw-r--r--src/qt/guiutil.cpp19
-rw-r--r--src/qt/guiutil.h9
-rw-r--r--src/qt/optionsdialog.cpp1
-rw-r--r--src/qt/paymentserver.cpp1
-rw-r--r--src/qt/peertablemodel.cpp10
-rw-r--r--src/qt/res/icons/toolbar.pngbin815 -> 0 bytes
-rw-r--r--src/qt/res/icons/toolbar_testnet.pngbin678 -> 0 bytes
-rw-r--r--src/qt/transactiondesc.cpp1
-rw-r--r--src/qt/utilitydialog.cpp5
-rw-r--r--src/qt/walletmodel.cpp20
-rw-r--r--src/qt/walletmodel.h5
-rw-r--r--src/random.cpp4
-rw-r--r--src/rpcblockchain.cpp25
-rw-r--r--src/rpcdump.cpp2
-rw-r--r--src/rpcmining.cpp1
-rw-r--r--src/rpcnet.cpp33
-rw-r--r--src/rpcprotocol.cpp4
-rw-r--r--src/rpcrawtransaction.cpp4
-rw-r--r--src/rpcserver.cpp203
-rw-r--r--src/rpcserver.h2
-rw-r--r--src/rpcwallet.cpp2
-rw-r--r--src/script.cpp17
-rw-r--r--src/script.h9
-rw-r--r--src/serialize.h112
-rw-r--r--src/test/DoS_tests.cpp1
-rw-r--r--src/test/alert_tests.cpp3
-rw-r--r--src/test/allocator_tests.cpp2
-rw-r--r--src/test/base32_tests.cpp2
-rw-r--r--src/test/base64_tests.cpp2
-rw-r--r--src/test/bctest.py53
-rwxr-xr-xsrc/test/bitcoin-util-test.py12
-rw-r--r--src/test/checkblock_tests.cpp1
-rw-r--r--src/test/crypto_tests.cpp2
-rw-r--r--src/test/data/bitcoin-util-test.json38
-rw-r--r--src/test/data/blanktx.hex1
-rw-r--r--src/test/data/tt-delin1-out.hex1
-rw-r--r--src/test/data/tt-delout1-out.hex1
-rw-r--r--src/test/data/tt-locktime317000-out.hex1
-rw-r--r--src/test/data/tx394b54bb.hex1
-rw-r--r--src/test/data/txcreate1.hex1
-rw-r--r--src/test/hash_tests.cpp2
-rw-r--r--src/test/rpc_tests.cpp32
-rw-r--r--src/test/script_tests.cpp11
-rw-r--r--src/test/test_bitcoin.cpp1
-rw-r--r--src/test/timedata_tests.cpp38
-rw-r--r--src/test/univalue_tests.cpp275
-rw-r--r--src/test/util_tests.cpp28
-rw-r--r--src/timedata.cpp6
-rw-r--r--src/timedata.h59
-rw-r--r--src/tinyformat.h3
-rw-r--r--src/txdb.cpp25
-rw-r--r--src/txdb.h10
-rw-r--r--src/txmempool.cpp18
-rw-r--r--src/txmempool.h12
-rw-r--r--src/uint256.cpp3
-rw-r--r--src/univalue/gen.cpp78
-rw-r--r--src/univalue/univalue.cpp2
-rw-r--r--src/univalue/univalue_escapes.h262
-rw-r--r--src/univalue/univalue_write.cpp32
-rw-r--r--src/util.cpp596
-rw-r--r--src/util.h301
-rw-r--r--src/utilmoneystr.cpp75
-rw-r--r--src/utilmoneystr.h19
-rw-r--r--src/utilstrencodings.cpp496
-rw-r--r--src/utilstrencodings.h97
-rw-r--r--src/utiltime.cpp66
-rw-r--r--src/utiltime.h20
-rw-r--r--src/version.cpp28
-rw-r--r--src/version.h6
-rw-r--r--src/wallet.cpp25
-rw-r--r--src/wallet.h35
-rw-r--r--src/walletdb.cpp3
181 files changed, 8202 insertions, 1755 deletions
diff --git a/.gitignore b/.gitignore
index e21ea92552..24af4cb72e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,8 @@ src/m4/ltsugar.m4
src/m4/ltversion.m4
src/m4/lt~obsolete.m4
+src/univalue/gen
+
src/qt/*.moc
src/qt/moc_*.cpp
src/qt/forms/ui_*.h
@@ -41,6 +43,7 @@ src/qt/test/moc*.cpp
*.bak
*.rej
*.orig
+*.pyc
*.o
*.o-*
*.patch
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..2073e71769
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,57 @@
+# errata:
+# - A travis bug causes caches to trample eachother when using the same
+# compiler key (which we don't use anyway). This is worked around for now by
+# using the phony compilers "true X". These can be removed when the travis
+# bug is fixed. See: https://github.com/travis-ci/casher/issues/6
+
+os: linux
+language: cpp
+env:
+ global:
+ - MAKEJOBS=-j3
+ - RUN_TESTS=false
+ - CCACHE_SIZE=100M
+ - CCACHE_TEMPDIR=/tmp/.ccache-temp
+ - CCACHE_COMPRESS=1
+ - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
+cache:
+ apt: true
+ directories:
+ - depends/built
+ - $HOME/.ccache
+matrix:
+ fast_finish: true
+ include:
+ - compiler: "true 1"
+ env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG"--enable-glibc-back-compat"
+ - compiler: "true 2"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_WALLET=1 NO_UPNP=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ - compiler: "true 3"
+ env: HOST=x86_64-unknown-linux-gnu RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ - compiler: "true 4"
+ env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ - compiler: "true 6"
+ env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev" GOAL="deploy"
+ - compiler: "true 7"
+ env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev" GOAL="deploy"
+install:
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-upgrade -qq $PACKAGES; fi
+before_script:
+ - unset CC; unset CXX
+ - mkdir -p depends/SDKs
+ - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS || (echo "Build failure. Verbose build follows." && make -C depends V=1 HOST=$HOST $DEP_OPTS)
+script:
+ - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
+ - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
+ - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE
+ - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi
+ - ./autogen.sh
+ - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
+ - make distdir PACKAGE=bitcoin VERSION=$HOST
+ - cd bitcoin-$HOST
+ - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
+ - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
+ - if [ "$RUN_TESTS" = "true" ]; then make check; fi
+after_script:
+ - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi
diff --git a/configure.ac b/configure.ac
index 0b2a429e02..700f4ab709 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,12 @@ AC_ARG_ENABLE([hardening],
[use_hardening=$enableval],
[use_hardening=yes])
+AC_ARG_ENABLE([reduce-exports],
+ [AS_HELP_STRING([--enable-reduce-exports],
+ [attempt to reduce exported symbols in the resulting executables (default is yes)])],
+ [use_reduce_exports=$enableval],
+ [use_reduce_exports=auto])
+
AC_ARG_ENABLE([ccache],
[AS_HELP_STRING([--enable-ccache],
[use ccache for building (default is yes if ccache is found)])],
@@ -304,7 +310,6 @@ AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
dnl Check for pthread compile/link requirements
AX_PTHREAD
-INCLUDES="$INCLUDES $PTHREAD_CFLAGS"
# The following macro will add the necessary defines to bitcoin-config.h, but
# they also need to be passed down to any subprojects. Pull the results out of
@@ -332,7 +337,10 @@ if test x$use_glibc_compat != xno; then
#__fdelt_chk's params and return type have changed from long unsigned int to long int.
# See which one is present here.
AC_MSG_CHECKING(__fdelt_chk type)
- AC_TRY_COMPILE([#define __USE_FORTIFY_LEVEL 2
+ AC_TRY_COMPILE([#ifdef _FORTIFY_SOURCE
+ #undef _FORTIFY_SOURCE
+ #endif
+ #define _FORTIFY_SOURCE 2
#include <sys/select.h>
extern "C" long unsigned int __fdelt_warn(long unsigned int);],[],
[ fdelt_type="long unsigned int"],
@@ -375,7 +383,7 @@ if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
fi
-AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h])
+AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
@@ -394,6 +402,36 @@ AC_TRY_COMPILE([#include <sys/socket.h>],
AC_SEARCH_LIBS([clock_gettime],[rt])
+AC_MSG_CHECKING([for visibility attribute])
+AC_LINK_IFELSE([AC_LANG_SOURCE([
+ int foo_def( void ) __attribute__((visibility("default")));
+ int main(){}
+ ])],
+ [
+ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ if test x$use_reduce_exports = xyes; then
+ AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.])
+ fi
+ AC_MSG_WARN([Cannot find a working visibility attribute. Disabling reduced exports.])
+ use_reduce_exports=no
+ ]
+)
+
+if test x$use_reduce_exports != xno; then
+ AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
+ [
+ if test x$use_reduce_exports = xyes; then
+ AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])
+ fi
+ AC_MSG_WARN([Cannot set default symbol visibility. Disabling reduced exports.])
+ use_reduce_exports=no
+ ])
+fi
+
LEVELDB_CPPFLAGS=
LIBLEVELDB=
LIBMEMENV=
@@ -424,6 +462,40 @@ AX_BOOST_PROGRAM_OPTIONS
AX_BOOST_THREAD
AX_BOOST_CHRONO
+
+if test x$use_reduce_exports != xno; then
+ AC_MSG_CHECKING([for working boost reduced exports])
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= 104900
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ ],[:
+ if test x$use_reduce_exports = xauto; then
+ use_reduce_exports=no
+ else
+ if test x$use_reduce_exports = xyes; then
+ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.])
+ fi
+ fi
+ AC_MSG_RESULT(no)
+ AC_MSG_WARN([boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.])
+ ])
+ CPPFLAGS="$TEMP_CPPFLAGS"
+fi
+
+if test x$use_reduce_exports != xno; then
+ CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
+ AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
+fi
+
if test x$use_tests = xyes; then
if test x$HEXDUMP = x; then
@@ -453,7 +525,6 @@ if test x$use_tests = xyes; then
fi
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB"
-BOOST_INCLUDES="$BOOST_CPPFLAGS"
dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if
@@ -509,15 +580,15 @@ if test x$boost_sleep != xyes; then
AC_MSG_ERROR(No working boost sleep implementation found. If on ubuntu 13.10 with libboost1.54-all-dev remove libboost.1.54-all-dev and use libboost1.53-all-dev)
fi
-AC_ARG_WITH([cli],
- [AS_HELP_STRING([--with-cli],
- [with CLI (default is yes)])],
- [build_bitcoin_cli=$withval],
- [build_bitcoin_cli=yes])
+AC_ARG_WITH([utils],
+ [AS_HELP_STRING([--with-utils],
+ [build bitcoin-cli bitcoin-tx (default=yes)])],
+ [build_bitcoin_utils=$withval],
+ [build_bitcoin_utils=yes])
AC_ARG_WITH([daemon],
[AS_HELP_STRING([--with-daemon],
- [with daemon (default is yes)])],
+ [build bitcoind daemon (default=yes)])],
[build_bitcoind=$withval],
[build_bitcoind=yes])
@@ -533,8 +604,8 @@ if test x$use_pkgconfig = xyes; then
m4_ifdef(
[PKG_CHECK_MODULES],
[
- PKG_CHECK_MODULES([SSL], [libssl], [INCLUDES="$INCLUDES $SSL_CFLAGS"; LIBS="$LIBS $SSL_LIBS"], [AC_MSG_ERROR(openssl not found.)])
- PKG_CHECK_MODULES([CRYPTO], [libcrypto], [INCLUDES="$INCLUDES $CRYPTO_CFLAGS"; LIBS="$LIBS $CRYPTO_LIBS"], [AC_MSG_ERROR(libcrypto not found.)])
+ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)])
+ PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)])
BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])])
if test x$use_qr != xno; then
BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])])
@@ -543,10 +614,10 @@ if test x$use_pkgconfig = xyes; then
)
else
AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing))
- AC_CHECK_LIB([crypto], [main],, AC_MSG_ERROR(libcrypto missing))
+ AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing))
AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
- AC_CHECK_LIB([ssl], [main],, AC_MSG_ERROR(libssl missing))
+ AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing))
BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],,BITCOIN_QT_FAIL(libprotobuf not found)))
if test x$use_qr != xno; then
@@ -561,9 +632,9 @@ AC_MSG_CHECKING([whether to build bitcoind])
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
AC_MSG_RESULT($build_bitcoind)
-AC_MSG_CHECKING([whether to build bitcoin-cli])
-AM_CONDITIONAL([BUILD_BITCOIN_CLI], [test x$build_bitcoin_cli = xyes])
-AC_MSG_RESULT($build_bitcoin_cli)
+AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)])
+AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes])
+AC_MSG_RESULT($build_bitcoin_utils)
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
@@ -585,6 +656,9 @@ if test "x$use_ccache" != "xno"; then
fi
AC_MSG_RESULT($use_ccache)
fi
+if test "x$use_ccache" = "xyes"; then
+ AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"])
+fi
dnl enable wallet
AC_MSG_CHECKING([if wallet should be enabled])
@@ -671,8 +745,15 @@ else
AC_MSG_RESULT([no])
fi
-if test "x$use_tests$build_bitcoind$use_qt" = "xnonono"; then
- AC_MSG_ERROR([No targets! Please specify at least one of: --enable-cli --enable-daemon --enable-gui or --enable-tests])
+AC_MSG_CHECKING([whether to reduce exports])
+if test x$use_reduce_exports != xno; then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+ AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-daemon --with-gui or --enable-tests])
fi
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
@@ -703,10 +784,10 @@ AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE)
AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR)
+AC_SUBST(RELDFLAGS)
AC_SUBST(LIBTOOL_LDFLAGS)
AC_SUBST(USE_UPNP)
AC_SUBST(USE_QRCODE)
-AC_SUBST(INCLUDES)
AC_SUBST(BOOST_LIBS)
AC_SUBST(TESTDEFS)
AC_SUBST(LEVELDB_TARGET_FLAGS)
diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh
index e42b71a54a..3217a06195 100755
--- a/contrib/devtools/github-merge.sh
+++ b/contrib/devtools/github-merge.sh
@@ -49,11 +49,11 @@ fi
# Initialize source branches.
git checkout -q "$BRANCH"
if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then
- if ! git log -1q "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then
+ if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then
echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2
exit 3
fi
- if ! git log -1q "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then
+ if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then
echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2
exit 3
fi
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index 8dd6d8f037..f3999f1c0b 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -41,6 +41,10 @@ MAX_VERSIONS = {
'GLIBCXX': (3,4,13),
'GLIBC': (2,11)
}
+# Ignore symbols that are exported as part of every executable
+IGNORE_EXPORTS = {
+'_edata', '_end', '_init', '__bss_start', '_fini'
+}
READELF_CMD = '/usr/bin/readelf'
CPPFILT_CMD = '/usr/bin/c++filt'
@@ -105,6 +109,8 @@ if __name__ == '__main__':
retval = 1
# Check exported symbols
for sym,version in read_symbols(filename, False):
+ if sym in IGNORE_EXPORTS:
+ continue
print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
retval = 1
diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md
index 70b9f034cd..b5c6e7824e 100644
--- a/contrib/linearize/README.md
+++ b/contrib/linearize/README.md
@@ -1,2 +1,32 @@
-### Linearize ###
-Construct a linear, no-fork, best version of the blockchain. \ No newline at end of file
+# Linearize
+Construct a linear, no-fork, best version of the blockchain.
+
+## Step 1: Download hash list
+
+ $ ./linearize-hashes.py linearize.cfg > hashlist.txt
+
+Required configuration file settings for linearize-hashes:
+* RPC: rpcuser, rpcpassword
+
+Optional config file setting for linearize-hashes:
+* RPC: host, port
+* Block chain: min_height, max_height
+
+## Step 2: Copy local block data
+
+ $ ./linearize-data.py linearize.cfg
+
+Required configuration file settings:
+* "input": bitcoind blocks/ directory containing blkNNNNN.dat
+* "hashlist": text file containing list of block hashes, linearized-hashes.py
+output.
+* "output_file": bootstrap.dat
+ or
+* "output": output directory for linearized blocks/blkNNNNN.dat output
+
+Optional config file setting for linearize-data:
+* "netmagic": network magic number
+* "max_out_sz": maximum output file size (default 1000*1000*1000)
+* "split_year": Split files when a new year is first seen, in addition to
+reaching a maximum file size.
+
diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg
index f5cdab5325..071345f23a 100644
--- a/contrib/linearize/example-linearize.cfg
+++ b/contrib/linearize/example-linearize.cfg
@@ -1,12 +1,17 @@
-# bitcoind RPC settings
+# bitcoind RPC settings (linearize-hashes)
rpcuser=someuser
rpcpassword=somepassword
host=127.0.0.1
port=8332
-# bootstrap.dat settings
+# bootstrap.dat hashlist settings (linearize-hashes)
+max_height=313000
+
+# bootstrap.dat input/output settings (linearize-data)
netmagic=f9beb4d9
-max_height=279000
-output=bootstrap.dat
+input=/home/example/.bitcoin/blocks
+output_file=/home/example/Downloads/bootstrap.dat
+hashlist=hashlist.txt
+split_year=1
diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py
new file mode 100755
index 0000000000..ea94f25fae
--- /dev/null
+++ b/contrib/linearize/linearize-data.py
@@ -0,0 +1,208 @@
+#!/usr/bin/python
+#
+# linearize-data.py: Construct a linear, no-fork version of the chain.
+#
+# Copyright (c) 2013 The Bitcoin developers
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+import json
+import struct
+import re
+import base64
+import httplib
+import sys
+import hashlib
+import datetime
+
+settings = {}
+
+
+def uint32(x):
+ return x & 0xffffffffL
+
+def bytereverse(x):
+ return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
+ (((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
+
+def bufreverse(in_buf):
+ out_words = []
+ for i in range(0, len(in_buf), 4):
+ word = struct.unpack('@I', in_buf[i:i+4])[0]
+ out_words.append(struct.pack('@I', bytereverse(word)))
+ return ''.join(out_words)
+
+def wordreverse(in_buf):
+ out_words = []
+ for i in range(0, len(in_buf), 4):
+ out_words.append(in_buf[i:i+4])
+ out_words.reverse()
+ return ''.join(out_words)
+
+def calc_hdr_hash(blk_hdr):
+ hash1 = hashlib.sha256()
+ hash1.update(blk_hdr)
+ hash1_o = hash1.digest()
+
+ hash2 = hashlib.sha256()
+ hash2.update(hash1_o)
+ hash2_o = hash2.digest()
+
+ return hash2_o
+
+def calc_hash_str(blk_hdr):
+ hash = calc_hdr_hash(blk_hdr)
+ hash = bufreverse(hash)
+ hash = wordreverse(hash)
+ hash_str = hash.encode('hex')
+ return hash_str
+
+def get_blk_year(blk_hdr):
+ members = struct.unpack("<I", blk_hdr[68:68+4])
+ dt = datetime.datetime.fromtimestamp(members[0])
+ return dt.year
+
+def get_block_hashes(settings):
+ blkindex = []
+ f = open(settings['hashlist'], "r")
+ for line in f:
+ line = line.rstrip()
+ blkindex.append(line)
+
+ print("Read " + str(len(blkindex)) + " hashes")
+
+ return blkindex
+
+def mkblockset(blkindex):
+ blkmap = {}
+ for hash in blkindex:
+ blkmap[hash] = True
+ return blkmap
+
+def copydata(settings, blkindex, blkset):
+ inFn = 0
+ inF = None
+ outFn = 0
+ outsz = 0
+ outF = None
+ blkCount = 0
+
+ lastYear = 0
+ splitYear = False
+ fileOutput = True
+ maxOutSz = settings['max_out_sz']
+ if 'output' in settings:
+ fileOutput = False
+ if settings['split_year'] != 0:
+ splitYear = True
+
+ while True:
+ if not inF:
+ fname = "%s/blk%05d.dat" % (settings['input'], inFn)
+ print("Input file" + fname)
+ inF = open(fname, "rb")
+
+ inhdr = inF.read(8)
+ if (not inhdr or (inhdr[0] == "\0")):
+ inF.close()
+ inF = None
+ inFn = inFn + 1
+ continue
+
+ inMagic = inhdr[:4]
+ if (inMagic != settings['netmagic']):
+ print("Invalid magic:" + inMagic)
+ return
+ inLenLE = inhdr[4:]
+ su = struct.unpack("<I", inLenLE)
+ inLen = su[0]
+ rawblock = inF.read(inLen)
+ blk_hdr = rawblock[:80]
+
+ hash_str = calc_hash_str(blk_hdr)
+ if not hash_str in blkset:
+ print("Skipping unknown block " + hash_str)
+ continue
+
+ if not fileOutput and ((outsz + inLen) > maxOutSz):
+ outF.close()
+ outF = None
+ outFn = outFn + 1
+ outsz = 0
+
+ if splitYear:
+ blkYear = get_blk_year(blk_hdr)
+ if blkYear > lastYear:
+ print("New year " + str(blkYear) + " @ " + hash_str)
+ lastYear = blkYear
+ if outF:
+ outF.close()
+ outF = None
+ outFn = outFn + 1
+ outsz = 0
+
+ if not outF:
+ if fileOutput:
+ fname = settings['output_file']
+ else:
+ fname = "%s/blk%05d.dat" % (settings['output'], outFn)
+ print("Output file" + fname)
+ outF = open(fname, "wb")
+
+ outF.write(inhdr)
+ outF.write(rawblock)
+ outsz = outsz + inLen + 8
+
+ blkCount = blkCount + 1
+
+ if (blkCount % 1000) == 0:
+ print("Wrote " + str(blkCount) + " blocks")
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print "Usage: linearize-data.py CONFIG-FILE"
+ sys.exit(1)
+
+ f = open(sys.argv[1])
+ for line in f:
+ # skip comment lines
+ m = re.search('^\s*#', line)
+ if m:
+ continue
+
+ # parse key=value lines
+ m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
+ if m is None:
+ continue
+ settings[m.group(1)] = m.group(2)
+ f.close()
+
+ if 'netmagic' not in settings:
+ settings['netmagic'] = 'f9beb4d9'
+ if 'input' not in settings:
+ settings['input'] = 'input'
+ if 'hashlist' not in settings:
+ settings['hashlist'] = 'hashlist.txt'
+ if 'split_year' not in settings:
+ settings['split_year'] = 0
+ if 'max_out_sz' not in settings:
+ settings['max_out_sz'] = 1000L * 1000 * 1000
+
+ settings['max_out_sz'] = long(settings['max_out_sz'])
+ settings['split_year'] = int(settings['split_year'])
+ settings['netmagic'] = settings['netmagic'].decode('hex')
+
+ if 'output_file' not in settings and 'output' not in settings:
+ print("Missing output file / directory")
+ sys.exit(1)
+
+ blkindex = get_block_hashes(settings)
+ blkset = mkblockset(blkindex)
+
+ if not "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" in blkset:
+ print("not found")
+ else:
+ copydata(settings, blkindex, blkset)
+
+
diff --git a/contrib/linearize/linearize.py b/contrib/linearize/linearize-hashes.py
index 650f7d3684..791b71bc33 100644..100755
--- a/contrib/linearize/linearize.py
+++ b/contrib/linearize/linearize-hashes.py
@@ -1,7 +1,6 @@
#!/usr/bin/python
#
-# linearize.py: Construct a linear, no-fork, best version of the blockchain.
-#
+# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
#
# Copyright (c) 2013 The Bitcoin developers
# Distributed under the MIT/X11 software license, see the accompanying
@@ -15,9 +14,6 @@ import base64
import httplib
import sys
-ERR_SLEEP = 15
-MAX_NONCE = 1000000L
-
settings = {}
class BitcoinRPC:
@@ -62,34 +58,18 @@ class BitcoinRPC:
def getblockhash(self, index):
return self.rpc('getblockhash', [index])
-def getblock(rpc, settings, n):
- hash = rpc.getblockhash(n)
- hexdata = rpc.getblock(hash, False)
- data = hexdata.decode('hex')
-
- return data
-
-def get_blocks(settings):
+def get_block_hashes(settings):
rpc = BitcoinRPC(settings['host'], settings['port'],
settings['rpcuser'], settings['rpcpassword'])
- outf = open(settings['output'], 'ab')
-
for height in xrange(settings['min_height'], settings['max_height']+1):
- data = getblock(rpc, settings, height)
-
- outhdr = settings['netmagic']
- outhdr += struct.pack("<i", len(data))
+ hash = rpc.getblockhash(height)
- outf.write(outhdr)
- outf.write(data)
-
- if (height % 1000) == 0:
- sys.stdout.write("Wrote block " + str(height) + "\n")
+ print(hash)
if __name__ == '__main__':
if len(sys.argv) != 2:
- print "Usage: linearize.py CONFIG-FILE"
+ print "Usage: linearize-hashes.py CONFIG-FILE"
sys.exit(1)
f = open(sys.argv[1])
@@ -106,10 +86,6 @@ if __name__ == '__main__':
settings[m.group(1)] = m.group(2)
f.close()
- if 'netmagic' not in settings:
- settings['netmagic'] = 'f9beb4d9'
- if 'output' not in settings:
- settings['output'] = 'bootstrap.dat'
if 'host' not in settings:
settings['host'] = '127.0.0.1'
if 'port' not in settings:
@@ -117,16 +93,14 @@ if __name__ == '__main__':
if 'min_height' not in settings:
settings['min_height'] = 0
if 'max_height' not in settings:
- settings['max_height'] = 279000
+ settings['max_height'] = 313000
if 'rpcuser' not in settings or 'rpcpassword' not in settings:
print "Missing username and/or password in cfg file"
sys.exit(1)
- settings['netmagic'] = settings['netmagic'].decode('hex')
settings['port'] = int(settings['port'])
settings['min_height'] = int(settings['min_height'])
settings['max_height'] = int(settings['max_height'])
- get_blocks(settings)
-
+ get_block_hashes(settings)
diff --git a/depends/.gitignore b/depends/.gitignore
new file mode 100644
index 0000000000..82c48638b0
--- /dev/null
+++ b/depends/.gitignore
@@ -0,0 +1,5 @@
+SDKs/
+work/
+built/
+sources/
+config.site
diff --git a/depends/Makefile b/depends/Makefile
new file mode 100644
index 0000000000..bd5f0bf536
--- /dev/null
+++ b/depends/Makefile
@@ -0,0 +1,114 @@
+.NOTPARALLEL :
+
+SOURCES_PATH ?= $(BASEDIR)/sources
+BASE_CACHE ?= $(BASEDIR)/built
+SDK_PATH ?= $(BASEDIR)/SDKs
+NO_QT ?=
+NO_WALLET ?=
+NO_UPNP ?=
+
+BUILD = $(shell ./config.guess)
+HOST ?= $(BUILD)
+PATCHES_PATH = $(BASEDIR)/patches
+BASEDIR = $(CURDIR)
+HASH_LENGTH:=11
+
+host:=$(BUILD)
+ifneq ($(HOST),)
+host:=$(HOST)
+host_toolchain:=$(HOST)-
+endif
+
+base_build_dir=$(BASEDIR)/work/build
+base_staging_dir=$(BASEDIR)/work/staging
+canonical_host:=$(shell ./config.sub $(HOST))
+build:=$(shell ./config.sub $(BUILD))
+
+build_arch =$(firstword $(subst -, ,$(build)))
+build_vendor=$(word 2,$(subst -, ,$(build)))
+full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build))
+build_os:=$(findstring linux,$(full_build_os))
+build_os+=$(findstring darwin,$(full_build_os))
+build_os:=$(strip $(build_os))
+ifeq ($(build_os),)
+build_os=$(full_build_os)
+endif
+
+host_arch=$(firstword $(subst -, ,$(canonical_host)))
+host_vendor=$(word 2,$(subst -, ,$(canonical_host)))
+full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host))
+host_os:=$(findstring linux,$(full_host_os))
+host_os+=$(findstring darwin,$(full_host_os))
+host_os+=$(findstring mingw32,$(full_host_os))
+host_os:=$(strip $(host_os))
+ifeq ($(host_os),)
+host_os=$(full_host_os)
+endif
+
+$(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
+$(host_arch)_$(host_os)_host=$(host)
+host_prefix=$($(host_arch)_$(host_os)_prefix)
+build_prefix=$(host_prefix)/native
+build_host=$(build)
+
+AT_$(V):=
+AT_:=@
+AT:=$(AT_$(V))
+
+all: install
+
+include hosts/$(host_os).mk
+include hosts/default.mk
+include builders/$(build_os).mk
+include builders/default.mk
+include packages/packages.mk
+
+qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages)
+qt_native_packages_$(NO_QT) = $(qt_native_packages)
+wallet_packages_$(NO_WALLET) = $(wallet_packages)
+upnp_packages_$(NO_UPNP) = $(upnp_packages)
+
+packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
+native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) $(qt_native_packages_)
+all_packages = $(packages) $(native_packages)
+
+meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
+
+$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain)
+
+include funcs.mk
+
+toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin)
+final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in)
+final_build_id+=$(shell echo -n $(final_build_id_long) | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
+$(host_prefix)/.stamp_$(final_build_id): | $(native_packages) $(packages)
+ $(AT)rm -rf $(@D)
+ $(AT)mkdir -p $(@D)
+ $(AT)echo copying packages: $|
+ $(AT)echo to: $(@D)
+ $(AT)cd $(@D); $(foreach package,$|, tar xf $($(package)_cached); )
+ $(AT)touch $@
+
+$(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id)
+ $(AT)@mkdir -p $(@D)
+ $(AT)sed -e 's|@HOST@|$(host)|' \
+ -e 's|@CC@|$(toolchain_path)$(host_CC)|' \
+ -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \
+ -e 's|@AR@|$(toolchain_path)$(host_AR)|' \
+ -e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \
+ -e 's|@NM@|$(toolchain_path)$(host_NM)|' \
+ -e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
+ -e 's|@build_os@|$(build_os)|' \
+ -e 's|@host_os@|$(host_os)|' \
+ -e 's|@CFLAGS@|$(host_CFLAGS)|' \
+ -e 's|@CXXFLAGS@|$(host_CXXFLAGS)|' \
+ -e 's|@LDFLAGS@|$(host_LDFLAGS)|' \
+ -e 's|@no_qt@|$(NO_QT)|' \
+ -e 's|@no_wallet@|$(NO_WALLET)|' \
+ -e 's|@no_upnp@|$(NO_UPNP)|' \
+ $< > $@
+ $(AT)touch $@
+
+install: $(host_prefix)/share/config.site
+download: $(all_sources)
+.PHONY: install cached
diff --git a/depends/README b/depends/README
new file mode 100644
index 0000000000..fed2f9b5ab
--- /dev/null
+++ b/depends/README
@@ -0,0 +1,55 @@
+This is a system of building and caching dependencies necessary for building
+Bitcoin.
+
+There are several features that make it different from most similar systems:
+
+- It is designed to be builder and host agnostic
+
+In theory, binaries for any target OS/architecture can be created, from a
+builder running any OS/architecture. In practice, build-side tools must be
+specified when the defaults don't fit, and packages must be ammended to work
+on new hosts. For now, a build architecture of x86_64 is assumed, either on
+Linux or OSX.
+
+- No reliance on timestamps
+
+File presence is used to determine what needs to be built. This makes the
+results distributable and easily digestable by automated builders.
+
+- Each build only has its specified dependencies available at build-time.
+
+For each build, the sysroot is wiped and the (recursive) dependencies are
+installed. This makes each build deterministic, since there will never be any
+unknown files available to cause side-effects.
+
+- Each package is cached and only rebuilt as needed.
+
+Before building, a unique build-id is generated for each package. This id
+consists of a hash of all files used to build the package (Makefiles, packages,
+etc), and as well as a hash of the same data for each recursive dependency. If
+any portion of a package's build recipe changes, it will be rebuilt as well as
+any other package that depends on it. If any of the main makefiles (Makefile,
+funcs.mk, etc) are changed, all packages will be rebuilt. After building, the
+results are cached into a tarball that can be re-used and distributed.
+
+- Package build results are (relatively) deterministic.
+
+Each package is configured and patched so that it will yield the same
+build-results with each consequent build, within a reasonable set of
+constraints. Some things like timestamp insertion are unavoidable, and are
+beyond the scope of this system. Additionally, the toolchain itself must be
+capable of deterministic results. When revisions are properly bumped, a cached
+build should represent an exact single payload.
+
+- Sources are fetched and verified automatically
+
+Each package must define its source location and checksum. The build will fail
+if the fetched source does not match. Sources may be pre-seeded and/or cached
+as desired.
+
+- Self-cleaning
+
+Build and staging dirs are wiped after use, and any previous version of a
+cached result is removed following a successful build. Automated builders
+should be able to build each revision and store the results with no further
+intervention.
diff --git a/depends/README.packages b/depends/README.packages
new file mode 100644
index 0000000000..c35abfbdc1
--- /dev/null
+++ b/depends/README.packages
@@ -0,0 +1,116 @@
+Each recipe consists of 3 main parts: defining identifiers, setting build
+variables, and defining build commands.
+
+The package "mylib" will be used here as an example
+
+General tips:
+mylib_foo is written as $(package)_foo in order to make recipes more similar.
+
+Identifiers:
+Each package is required to define at least these variables:
+ $(package)_version:
+ Version of the upstream library or program. If there is no version, a
+ placeholder such as 1.0 can be used.
+ $(package)_download_path:
+ Location of the upstream source, without the file-name. Usually http or
+ ftp.
+ $(package)_file_name:
+ The upstream source filename available at the download path.
+ $(package)_sha256_hash:
+ The sha256 hash of the upstream file
+
+These variables are optional:
+ $(package)_build_subdir:
+ cd to this dir before running configure/build/stage commands.
+ $(package)_download_file:
+ The file-name of the upstream source if it differs from how it should be
+ stored locally. This can be used to avoid storing file-names with strange
+ characters.
+ $(package)_dependencies:
+ Names of any other packages that this one depends on.
+ $(package)_patches:
+ Filenames of any patches needed to build the package
+
+
+Build Variables:
+After defining the main identifiers, build variables may be added or customized
+before running the build commands. They should be added to a function called
+$(package)_set_vars. For example:
+
+define $(package)_set_vars
+...
+endef
+
+Most variables can be prefixed with the host, architecture, or both, to make
+the modifications specific to that case. For example:
+
+ Universal: $(package)_cc=gcc
+ Linux only: $(package)_linux_cc=gcc
+ x86_64 only: $(package)_x86_64_cc = gcc
+ x86_64 linux only: $(package)_x86_64_linux_cc = gcc
+
+These variables may be set to override or append their default values.
+ $(package)_cc
+ $(package)_cxx
+ $(package)_objc
+ $(package)_objcxx
+ $(package)_ar
+ $(package)_ranlib
+ $(package)_libtool
+ $(package)_nm
+ $(package)_cflags
+ $(package)_cxxflags
+ $(package)_ldflags
+ $(package)_cppflags
+ $(package)_config_env
+ $(package)_build_env
+ $(package)_stage_env
+
+The *_env variables are used to add environment variables to the respective
+commands.
+
+Other variables may be defined as needed.
+
+Build commands:
+
+ For each build, a unique build dir and staging dir are created. For example,
+ work/build/mylib/1.0-1adac830f6e and work/staging/mylib/1.0-1adac830f6e.
+
+ The following build commands are available for each recipe:
+
+ $(package)_fetch_cmds:
+ Runs from: build dir
+ Fetch the source file. If undefined, it will be fetched and verified
+ against its hash.
+ $(package)_extract_cmds:
+ Runs from: build dir
+ Verify the source file against its hash and extract it. If undefined, the
+ source is assumed to be a tarball.
+ $(package)_preprocess_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Preprocess the source as necessary. If undefined, does nothing.
+ $(package)_config_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Configure the source. If undefined, does nothing.
+ $(package)_build_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Build the source. If undefined, does nothing.
+ $(package)_stage_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Stage the build results. If undefined, does nothing.
+
+ The following variables are available for each recipe:
+ $(1)_staging_dir: package's destination sysroot path
+ $(1)_staging_prefix_dir: prefix path inside of the package's staging dir
+ $(1)_extract_dir: path to the package's extracted sources
+ $(1)_build_dir: path where configure/build/stage commands will be run
+ $(1)_patch_dir: path where the package's patches (if any) are found
+
+Notes on build commands:
+
+For packages built with autotools, $($(package)_autoconf) can be used in the
+configure step to (usually) correctly configure automatically. Any
+$($(package)_config_opts) will be appended.
+
+Most autotools projects can be properly staged using:
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
diff --git a/depends/README.usage b/depends/README.usage
new file mode 100644
index 0000000000..f50714f1f1
--- /dev/null
+++ b/depends/README.usage
@@ -0,0 +1,29 @@
+To build dependencies for the current arch+OS:
+ make
+To build for another arch/OS:
+ make HOST=host-platform-triplet && make HOST=host-platform-triplet
+ (For example: make HOST=i686-w64-mingw32 -j4)
+
+A prefix will be generated that's suitable for plugging into Bitcoin's
+configure. In the above example, a dir named i686-w64-mingw32 will be
+created. To use it for Bitcoin:
+
+./configure --prefix=`pwd`/depends/i686-w64-mingw32
+
+No other options are needed, the paths are automatically configured.
+
+Dependency Options:
+The following can be set when running make: make FOO=bar
+
+SOURCES_PATH: downloaded sources will be placed here
+BASE_CACHE: built packages will be placed here
+SDK_PATH: Path where sdk's can be found (used by OSX)
+NO_QT: Don't download/build/cache qt and its dependencies
+NO_WALLET: Don't download/build/cache libs needed to enable the wallet
+NO_UPNP: Don't download/build/cache packages needed for enabling upnp
+
+If some packages are not built, for example 'make NO_WALLET=1', the appropriate
+options will be passed to bitcoin's configure. In this case, --disable-wallet.
+
+Additional targets:
+download: run 'make download' to fetch sources without building them
diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk
new file mode 100644
index 0000000000..6b734648f0
--- /dev/null
+++ b/depends/builders/darwin.mk
@@ -0,0 +1,22 @@
+build_darwin_CC: = $(shell xcrun -f clang)
+build_darwin_CXX: = $(shell xcrun -f clang++)
+build_darwin_AR: = $(shell xcrun -f ar)
+build_darwin_RANLIB: = $(shell xcrun -f ranlib)
+build_darwin_STRIP: = $(shell xcrun -f strip)
+build_darwin_OTOOL: = $(shell xcrun -f otool)
+build_darwin_NM: = $(shell xcrun -f nm)
+build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
+build_darwin_SHA256SUM = shasum -a 256
+build_darwin_DOWNLOAD = curl -L -o
+
+#darwin host on darwin builder. overrides darwin host preferences.
+darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)
+darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION)
+darwin_AR:=$(shell xcrun -f ar)
+darwin_RANLIB:=$(shell xcrun -f ranlib)
+darwin_STRIP:=$(shell xcrun -f strip)
+darwin_LIBTOOL:=$(shell xcrun -f libtool)
+darwin_OTOOL:=$(shell xcrun -f otool)
+darwin_NM:=$(shell xcrun -f nm)
+darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
+darwin_native_toolchain=
diff --git a/depends/builders/default.mk b/depends/builders/default.mk
new file mode 100644
index 0000000000..f097db65d6
--- /dev/null
+++ b/depends/builders/default.mk
@@ -0,0 +1,20 @@
+default_build_CC = gcc
+default_build_CXX = g++
+default_build_AR = ar
+default_build_RANLIB = ranlib
+default_build_STRIP = strip
+default_build_NM = nm
+default_build_OTOOL = otool
+default_build_INSTALL_NAME_TOOL = install_name_tool
+
+define add_build_tool_func
+build_$(build_os)_$1 ?= $$(default_build_$1)
+build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1)
+build_$1=$$(build_$(build_arch)_$(build_os)_$1)
+endef
+$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var))))
+define add_build_flags_func
+build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1)
+build_$1=$$(build_$(build_arch)_$(build_os)_$1)
+endef
+$(foreach flags, CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_build_flags_func,$(flags))))
diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk
new file mode 100644
index 0000000000..d98ba597dc
--- /dev/null
+++ b/depends/builders/linux.mk
@@ -0,0 +1,2 @@
+build_linux_SHA256SUM = sha256sum
+build_linux_DOWNLOAD = wget -nv -O
diff --git a/depends/config.guess b/depends/config.guess
new file mode 100755
index 0000000000..1f5c50c0d1
--- /dev/null
+++ b/depends/config.guess
@@ -0,0 +1,1420 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-03-23'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/depends/config.site.in b/depends/config.site.in
new file mode 100644
index 0000000000..4012f5a8d1
--- /dev/null
+++ b/depends/config.site.in
@@ -0,0 +1,84 @@
+cross_compiling=maybe
+host_alias=@HOST@
+ac_tool_prefix=${host_alias}-
+
+if test -z $with_boost; then
+ with_boost=$prefix
+fi
+if test -z $with_qt_plugindir; then
+ with_qt_plugindir=$prefix/plugins
+fi
+if test -z $with_qt_translationdir; then
+ with_qt_translationdir=$prefix/translations
+fi
+if test -z $with_qt_bindir; then
+ with_qt_bindir=$prefix/native/bin
+fi
+if test -z $with_protoc_bindir; then
+ with_protoc_bindir=$prefix/native/bin
+fi
+if test -z $with_comparison_tool; then
+ with_comparison_tool=$prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar
+fi
+
+
+if test -z $enable_wallet && test -n "@no_wallet@"; then
+ enable_wallet=no
+fi
+
+if test -z $with_miniupnpc && test -n "@no_upnp@"; then
+ with_miniupnpc=no
+fi
+
+if test -z $with_gui && test -n "@no_qt@"; then
+ with_gui=no
+fi
+
+if test @host_os@ == darwin; then
+ BREW=no
+ PORT=no
+fi
+
+if test @host_os@ == mingw32; then
+ if test -z $with_qt_incdir; then
+ with_qt_incdir=$prefix/include
+ fi
+ if test -z $with_qt_libdir; then
+ with_qt_libdir=$prefix/lib
+ fi
+fi
+
+export PATH=$prefix/native/bin:$PATH
+export PKG_CONFIG="`which pkg-config` --static"
+export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig
+export PKG_CONFIG_PATH=$prefix/share/pkgconfig
+export CPPFLAGS=-I$prefix/include/
+
+export CC="@CC@"
+export CXX="@CXX@"
+export OBJC="${CC}"
+export OBJCXX="${CXX}"
+export CCACHE=$prefix/native/bin/ccache
+
+if test -n "@AR@"; then
+ export AR=@AR@
+ ac_cv_path_ac_pt_AR=${AR}
+fi
+
+if test -n "@RANLIB@"; then
+ export RANLIB=@RANLIB@
+ ac_cv_path_ac_pt_RANLIB=${RANLIB}
+fi
+
+if test -n "@NM@"; then
+ export NM=@NM@
+ ac_cv_path_ac_pt_NM=${NM}
+fi
+
+if test -n "@CFLAGS@"; then
+ export CFLAGS="@CFLAGS@ $CFLAGS"
+fi
+if test -n "@CXXFLAGS@"; then
+ export CXXFLAGS="@CXXFLAGS@ $CXXFLAGS"
+fi
+export LDFLAGS="-L$prefix/lib @LDFLAGS@ $LDFLAGS"
diff --git a/depends/config.sub b/depends/config.sub
new file mode 100755
index 0000000000..d654d03cdc
--- /dev/null
+++ b/depends/config.sub
@@ -0,0 +1,1794 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-05-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/depends/funcs.mk b/depends/funcs.mk
new file mode 100644
index 0000000000..b5d8b0ee2e
--- /dev/null
+++ b/depends/funcs.mk
@@ -0,0 +1,223 @@
+define int_vars
+#Set defaults for vars which may be overridden per-package
+$(1)_cc=$($($(1)_type)_CC)
+$(1)_cxx=$($($(1)_type)_CXX)
+$(1)_objc=$($($(1)_type)_OBJC)
+$(1)_objcxx=$($($(1)_type)_OBJCXX)
+$(1)_ar=$($($(1)_type)_AR)
+$(1)_ranlib=$($($(1)_type)_RANLIB)
+$(1)_libtool=$($($(1)_type)_LIBTOOL)
+$(1)_nm=$($($(1)_type)_NM)
+$(1)_cflags=$($($(1)_type)_CFLAGS)
+$(1)_cxxflags=$($($(1)_type)_CXXFLAGS)
+$(1)_ldflags=$($($(1)_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
+$(1)_cppflags:=-I$($($(1)_type)_prefix)/include
+$(1)_recipe_hash:=
+endef
+
+define int_get_all_dependencies
+$(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies))))
+endef
+
+define fetch_file
+(test -f $(SOURCES_PATH)/$(3) || \
+ ( mkdir -p $$($(1)_extract_dir) && $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(3).temp" "$(2)" && \
+ echo "$(4) $$($(1)_extract_dir)/$(3).temp" > $$($(1)_extract_dir)/.$(3).hash && \
+ $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$(3).hash && \
+ mv $$($(1)_extract_dir)/$(3).temp $(SOURCES_PATH)/$(3) ))
+endef
+
+define int_get_build_recipe_hash
+$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches))))
+$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM)))
+endef
+
+define int_get_build_id
+$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
+$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies)))
+$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
+$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash) $($(1)_build_id_deps))
+$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
+final_build_id_long+=$($(package)_build_id_long)
+
+#compute package-specific paths
+$(1)_build_subdir?=.
+$(1)_download_file?=$($(1)_file_name)
+$(1)_source:=$(SOURCES_PATH)/$($(1)_file_name)
+$(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
+$(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix)
+$(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
+$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
+$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
+$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
+$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
+
+#stamps
+$(1)_fetched=$$($(1)_extract_dir)/.stamp_fetched
+$(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted
+$(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed
+$(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned
+$(1)_built=$$($(1)_build_dir)/.stamp_built
+$(1)_configured=$$($(1)_build_dir)/.stamp_configured
+$(1)_staged=$$($(1)_staging_dir)/.stamp_staged
+$(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed
+$(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path))
+
+
+#default commands
+$(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)/$$($(1)_download_file)),$($(1)_file_name),$($(1)_sha256_hash))
+$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source)
+$(1)_preprocess_cmds ?=
+$(1)_build_cmds ?=
+$(1)_config_cmds ?=
+$(1)_stage_cmds ?=
+$(1)_set_vars ?=
+
+
+all_sources+=$$($(1)_fetched)
+endef
+#$(foreach dep_target,$($(1)_all_dependencies),$(eval $(1)_dependency_targets=$($(dep_target)_cached)))
+
+
+define int_config_attach_build_config
+$(eval $(call $(1)_set_vars,$(1)))
+$(1)_cflags+=$($(1)_cflags_$(host_arch))
+$(1)_cflags+=$($(1)_cflags_$(host_os))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os))
+
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_os))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os))
+
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch))
+$(1)_cppflags+=$($(1)_cppflags_$(host_os))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os))
+
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch))
+$(1)_ldflags+=$($(1)_ldflags_$(host_os))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os))
+
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_os))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os))
+
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_os))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os))
+
+$(1)_config_env+=$($(1)_config_env_$(host_arch))
+$(1)_config_env+=$($(1)_config_env_$(host_os))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os))
+
+$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
+$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
+$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
+
+ifneq ($($(1)_nm),)
+$(1)_autoconf += NM="$$($(1)_nm)"
+endif
+ifneq ($($(1)_ranlib),)
+$(1)_autoconf += RANLIB="$$($(1)_ranlib)"
+endif
+ifneq ($($(1)_ar),)
+$(1)_autoconf += AR="$$($(1)_ar)"
+endif
+ifneq ($($(1)_cflags),)
+$(1)_autoconf += CFLAGS="$$($(1)_cflags)"
+endif
+ifneq ($($(1)_cxxflags),)
+$(1)_autoconf += CXXFLAGS="$$($(1)_cxxflags)"
+endif
+ifneq ($($(1)_cppflags),)
+$(1)_autoconf += CPPFLAGS="$$($(1)_cppflags)"
+endif
+ifneq ($($(1)_ldflags),)
+$(1)_autoconf += LDFLAGS="$$($(1)_ldflags)"
+endif
+endef
+
+define int_add_cmds
+$($(1)_fetched):
+ $(AT)echo Fetching $(1)...
+ $(AT)mkdir -p $$(@D) $(SOURCES_PATH)
+ $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1))
+ $(AT)touch $$@
+$($(1)_extracted): | $($(1)_fetched)
+ $(AT)echo Extracting $(1)...
+ $(AT)mkdir -p $$(@D)
+ $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1))
+ $(AT)touch $$@
+$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted)
+ $(AT)echo Preprocessing $(1)...
+ $(AT)mkdir -p $$(@D) $($(1)_patch_dir)
+ $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;)
+ $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_configured): | $($(1)_preprocessed)
+ $(AT)echo Configuring $(1)...
+ $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); )
+ $(AT)mkdir -p $$(@D)
+ $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_built): | $($(1)_configured)
+ $(AT)echo Building $(1)...
+ $(AT)mkdir -p $$(@D)
+ $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_staged): | $($(1)_built)
+ $(AT)echo Staging $(1)...
+ $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix)
+ $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1))
+ $(AT)rm -rf $($(1)_extract_dir)
+ $(AT)touch $$@
+$($(1)_postprocessed): | $($(1)_staged)
+ $(AT)echo Postprocessing $(1)...
+ $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds)
+ $(AT)touch $$@
+$($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed)
+ $(AT)echo Caching $(1)...
+ $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T -
+ $(AT)mkdir -p $$(@D)
+ $(AT)rm -rf $$(@D) && mkdir -p $$(@D)
+ $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@)
+ $(AT)rm -rf $($(1)_staging_dir)
+
+.PHONY: $(1)
+$(1): | $($(1)_cached)
+.SECONDARY: $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched)
+
+endef
+
+# These functions create the build targets for each package. They must be
+# broken down into small steps so that each part is done for all packages
+# before moving on to the next step. Otherwise, a package's info
+# (build-id for example) would only be avilable to another package if it
+# happened to be computed already.
+
+#set the type for host/build packages.
+$(foreach native_package,$(native_packages),$(eval $(native_package)_type=build))
+$(foreach package,$(packages),$(eval $(package)_type=$(host_arch)_$(host_os)))
+
+#set overridable defaults
+$(foreach package,$(all_packages),$(eval $(call int_vars,$(package))))
+
+#include package files
+$(foreach package,$(all_packages),$(eval include packages/$(package).mk))
+
+#compute a hash of all files that comprise this package's build recipe
+$(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package))))
+
+#generate a unique id for this package, incorporating its dependencies as well
+$(foreach package,$(all_packages),$(eval $(call int_get_build_id,$(package))))
+
+#compute final vars after reading package vars
+$(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$(package))))
+
+#create build targets
+$(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package))))
+
+#special exception: if a toolchain package exists, all non-native packages depend on it
+$(foreach package,$(packages),$(eval $($(package)_unpacked): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) ))
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
new file mode 100644
index 0000000000..9e2415655e
--- /dev/null
+++ b/depends/hosts/darwin.mk
@@ -0,0 +1,8 @@
+OSX_MIN_VERSION=10.6
+OSX_SDK_VERSION=10.7
+OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
+darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
+darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
+darwin_CFLAGS=-pipe -O2
+darwin_CXXFLAGS=$(darwin_CFLAGS)
+darwin_native_toolchain=native_cctools
diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk
new file mode 100644
index 0000000000..b9fe5d858a
--- /dev/null
+++ b/depends/hosts/default.mk
@@ -0,0 +1,23 @@
+default_host_CC = $(host_toolchain)gcc
+default_host_CXX = $(host_toolchain)g++
+default_host_AR = $(host_toolchain)ar
+default_host_RANLIB = $(host_toolchain)ranlib
+default_host_STRIP = $(host_toolchain)strip
+default_host_LIBTOOL = $(host_toolchain)libtool
+default_host_INSTALL_NAME_TOOL = $(host_toolchain)install_name_tool
+default_host_OTOOL = $(host_toolchain)otool
+default_host_NM = $(host_toolchain)nm
+
+define add_host_tool_func
+$(host_os)_$1?=$$(default_host_$1)
+$(host_arch)_$(host_os)_$1?=$$($(host_os)_$1)
+host_$1=$$($(host_arch)_$(host_os)_$1)
+endef
+
+define add_host_flags_func
+$(host_arch)_$(host_os)_$1 += $($(host_os)_$1)
+host_$1 = $$($(host_arch)_$(host_os)_$1)
+endef
+
+$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool))))
+$(foreach flags,CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
new file mode 100644
index 0000000000..194d71d557
--- /dev/null
+++ b/depends/hosts/linux.mk
@@ -0,0 +1,23 @@
+linux_CFLAGS=-pipe -O2
+linux_CXXFLAGS=$(linux_CFLAGS)
+
+ifeq (86,$(findstring 86,$(build_arch)))
+i686_linux_CC=gcc -m32
+i686_linux_CXX=g++ -m32
+i686_linux_AR=ar
+i686_linux_RANLIB=ranlib
+i686_linux_NM=nm
+i686_linux_STRIP=strip
+
+x86_64_linux_CC=gcc -m64
+x86_64_linux_CXX=g++ -m64
+x86_64_linux_AR=ar
+x86_64_linux_RANLIB=ranlib
+x86_64_linux_NM=nm
+x86_64_linux_STRIP=strip
+else
+i686_linux_CC=$(default_host_CC) -m32
+i686_linux_CXX=$(default_host_CXX) -m32
+x86_64_linux_CC=$(default_host_CC) -m64
+x86_64_linux_CXX=$(default_host_CXX) -m64
+endif
diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk
new file mode 100644
index 0000000000..ffe4a55842
--- /dev/null
+++ b/depends/hosts/mingw32.mk
@@ -0,0 +1,2 @@
+mingw32_CFLAGS=-pipe -O2
+mingw32_CXXFLAGS=$(mingw32_CFLAGS)
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
new file mode 100644
index 0000000000..503409c5e5
--- /dev/null
+++ b/depends/packages/bdb.mk
@@ -0,0 +1,29 @@
+package=bdb
+$(package)_version=4.8.30
+$(package)_download_path=http://download.oracle.com/berkeley-db
+$(package)_file_name=db-$($(package)_version).NC.tar.gz
+$(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef
+$(package)_build_subdir=build_unix
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared --enable-cxx
+$(package)_config_opts_mingw32=--enable-mingw
+$(package)_config_opts_x86_64_linux=--with-pic
+$(package)_config_opts_arm_linux=--with-pic
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h
+endef
+
+define $(package)_config_cmds
+ ../dist/$($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) libdb_cxx-4.8.a libdb-4.8.a
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install_lib install_include
+endef
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
new file mode 100644
index 0000000000..a3cacbcbb6
--- /dev/null
+++ b/depends/packages/boost.mk
@@ -0,0 +1,42 @@
+package=boost
+$(package)_version=1_55_0
+$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.55.0
+$(package)_file_name=$(package)_$($(package)_version).tar.bz2
+$(package)_sha256_hash=fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52
+$(package)_patches=darwin_boost_atomic-1.patch darwin_boost_atomic-2.patch
+
+define $(package)_set_vars
+$(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam
+$(package)_config_opts+=variant=release threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
+$(package)_config_opts_linux=threadapi=pthread runtime-link=shared
+$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared
+$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static
+$(package)_config_opts_x86_64_mingw32=address-model=64
+$(package)_config_opts_i686_mingw32=address-model=32
+$(package)_config_opts_i686_linux=address-model=32 architecture=x86
+$(package)_toolset_$(host_os)=gcc
+$(package)_archiver_$(host_os)=$($(package)_ar)
+$(package)_toolset_darwin=darwin
+$(package)_archiver_darwin=$($(package)_libtool)
+$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test
+$(package)_cxxflags_x86_64_linux=-fPIC
+$(package)_cxxflags_arm_linux=-fPIC
+endef
+
+define $(package)_preprocess_cmds
+ patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-1.patch && \
+ patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-2.patch && \
+ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
+endef
+
+define $(package)_config_cmds
+ ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries)
+endef
+
+define $(package)_build_cmds
+ ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) stage
+endef
+
+define $(package)_stage_cmds
+ ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) install
+endef
diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk
new file mode 100644
index 0000000000..8ac9ab742b
--- /dev/null
+++ b/depends/packages/dbus.mk
@@ -0,0 +1,23 @@
+package=dbus
+$(package)_version=1.8.6
+$(package)_download_path=http://dbus.freedesktop.org/releases/dbus
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=eded83ca007b719f32761e60fd8b9ffd0f5796a4caf455b01b5a5ef740ebd23f
+$(package)_dependencies=expat
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C dbus libdbus-1.la
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA
+endef
diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk
new file mode 100644
index 0000000000..1ac4435374
--- /dev/null
+++ b/depends/packages/expat.mk
@@ -0,0 +1,21 @@
+package=expat
+$(package)_version=2.1.0
+$(package)_download_path=http://sourceforge.net/projects/expat/files/expat/$($(package)_version)
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=823705472f816df21c8f6aa026dd162b280806838bb55b3432b0fb1fcca7eb86
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk
new file mode 100644
index 0000000000..2cf553ed96
--- /dev/null
+++ b/depends/packages/fontconfig.mk
@@ -0,0 +1,22 @@
+package=fontconfig
+$(package)_version=2.11.1
+$(package)_download_path=http://www.freedesktop.org/software/fontconfig/release/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=dc62447533bca844463a3c3fd4083b57c90f18a70506e7a9f4936b5a1e516a99
+$(package)_dependencies=freetype expat
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-docs --disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk
new file mode 100644
index 0000000000..b83cbd93ea
--- /dev/null
+++ b/depends/packages/freetype.mk
@@ -0,0 +1,22 @@
+package=freetype
+$(package)_version=2.5.3
+$(package)_download_path=http://downloads.sourceforge.net/$(package)
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=c0848b29d52ef3ca27ad92e08351f023c5e24ce8cea7d8fe69fc96358e65f75e
+
+define $(package)_set_vars
+ $(package)_config_opts=--without-zlib --without-png --disable-static
+ $(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk
new file mode 100644
index 0000000000..144021e34b
--- /dev/null
+++ b/depends/packages/libX11.mk
@@ -0,0 +1,23 @@
+package=libX11
+$(package)_version=1.6.2
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=2aa027e837231d2eeea90f3a4afe19948a6eb4c8b2bec0241eba7dbc8106bd16
+$(package)_dependencies=libxcb xtrans xextproto xproto
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-xkb --disable-static
+$(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk
new file mode 100644
index 0000000000..8c9b21846b
--- /dev/null
+++ b/depends/packages/libXau.mk
@@ -0,0 +1,23 @@
+package=libXau
+$(package)_version=1.0.8
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2
+$(package)_dependencies=xproto
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared
+ $(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libXext.mk b/depends/packages/libXext.mk
new file mode 100644
index 0000000000..4db836066f
--- /dev/null
+++ b/depends/packages/libXext.mk
@@ -0,0 +1,22 @@
+package=libXext
+$(package)_version=1.3.2
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=f829075bc646cdc085fa25d98d5885d83b1759ceb355933127c257e8e50432e0
+$(package)_dependencies=xproto xextproto libX11 libXau
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk
new file mode 100644
index 0000000000..f29b577f8a
--- /dev/null
+++ b/depends/packages/libxcb.mk
@@ -0,0 +1,30 @@
+package=libxcb
+$(package)_version=1.10
+$(package)_download_path=http://xcb.freedesktop.org/dist
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5
+$(package)_dependencies=xcb_proto libXau xproto
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-static
+endef
+
+define $(package)_preprocess_cmds
+ sed "s/pthread-stubs//" -i configure
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf share/man share/doc
+endef
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
new file mode 100644
index 0000000000..6dd7d93b07
--- /dev/null
+++ b/depends/packages/miniupnpc.mk
@@ -0,0 +1,28 @@
+package=miniupnpc
+$(package)_version=1.9
+$(package)_download_path=http://miniupnp.free.fr/files
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464
+
+define $(package)_set_vars
+$(package)_build_opts=CC="$($(package)_cc)"
+$(package)_build_opts_darwin=OS=Darwin
+$(package)_build_opts_mingw32=-f Makefile.mingw
+$(package)_build_env+=CFLAGS="$($(package)_cflags)" AR="$($(package)_ar)"
+endef
+
+define $(package)_preprocess_cmds
+ mkdir dll && \
+ sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \
+ sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw
+endef
+
+define $(package)_build_cmds
+ $(MAKE) libminiupnpc.a $($(package)_build_opts)
+endef
+
+define $(package)_stage_cmds
+ mkdir -p $($(package)_staging_prefix_dir)/include/miniupnpc $($(package)_staging_prefix_dir)/lib &&\
+ install *.h $($(package)_staging_prefix_dir)/include/miniupnpc &&\
+ install libminiupnpc.a $($(package)_staging_prefix_dir)/lib
+endef
diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk
new file mode 100644
index 0000000000..3226e89a63
--- /dev/null
+++ b/depends/packages/native_ccache.mk
@@ -0,0 +1,25 @@
+package=native_ccache
+$(package)_version=3.1.9
+$(package)_download_path=http://samba.org/ftp/ccache
+$(package)_file_name=ccache-$($(package)_version).tar.bz2
+$(package)_sha256_hash=04d3e2e438ac8d4cc4b110b68cdd61bd59226c6588739a4a386869467f5ced7c
+
+define $(package)_set_vars
+$(package)_config_opts=
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf lib include
+endef
diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk
new file mode 100644
index 0000000000..e3ba9685b4
--- /dev/null
+++ b/depends/packages/native_cctools.mk
@@ -0,0 +1,80 @@
+package=native_cctools
+$(package)_version=809
+$(package)_download_path=http://www.opensource.apple.com/tarballs/cctools
+$(package)_file_name=cctools-$($(package)_version).tar.gz
+$(package)_sha256_hash=03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad
+$(package)_build_subdir=cctools2odcctools/odcctools-$($(package)_version)
+$(package)_dependencies=native_libuuid native_openssl
+$(package)_ld64_download_file=ld64-127.2.tar.gz
+$(package)_ld64_download_path=http://www.opensource.apple.com/tarballs/ld64
+$(package)_ld64_file_name=$($(package)_ld64_download_file)
+$(package)_ld64_sha256_hash=97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142
+$(package)_dyld_download_file=dyld-195.5.tar.gz
+$(package)_dyld_download_path=http://www.opensource.apple.com/tarballs/dyld
+$(package)_dyld_file_name=$($(package)_dyld_download_file)
+$(package)_dyld_sha256_hash=2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c
+$(package)_toolchain4_download_file=10cc648683617cca8bcbeae507888099b41b530c.tar.gz
+$(package)_toolchain4_download_path=https://github.com/mingwandroid/toolchain4/archive
+$(package)_toolchain4_file_name=toolchain4-1.tar.gz
+$(package)_toolchain4_sha256_hash=18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca
+$(package)_clang_download_file=clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
+$(package)_clang_download_path=http://llvm.org/releases/3.2
+$(package)_clang_file_name=clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
+$(package)_clang_sha256_hash=b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff
+
+define $(package)_fetch_cmds
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_ld64_download_path)/$($(package)_ld64_download_file),$($(package)_ld64_file_name),$($(package)_ld64_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_dyld_download_path)/$($(package)_dyld_download_file),$($(package)_dyld_file_name),$($(package)_dyld_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_clang_download_path)/$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_toolchain4_download_path)/$($(package)_toolchain4_download_file),$($(package)_toolchain4_file_name),$($(package)_toolchain4_sha256_hash))
+endef
+
+define $(package)_set_vars
+$(package)_config_opts=--target=$(host) --with-sysroot=$(OSX_SDK)
+$(package)_cflags+=-m32
+$(package)_cxxflags+=-m32
+$(package)_cppflags+=-D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
+$(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
+$(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib
+endef
+define $(package)_extract_cmds
+ tar --strip-components=1 -xf $(SOURCES_PATH)/$($(package)_toolchain4_file_name) && \
+ ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \
+ ln -sf $(SOURCES_PATH)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \
+ ln -sf $(SOURCES_PATH)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \
+ tar xf $(SOURCES_PATH)/$($(package)_clang_file_name) && \
+ mkdir -p $(SDK_PATH) sdks &&\
+ cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk
+endef
+
+define $(package)_preprocess_cmds
+ sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" cctools2odcctools/extract.sh && \
+ sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" cctools2odcctools/extract.sh && \
+ sed -i "s|/llvmCore/include/llvm-c|/include/llvm-c \$$$${LLVM_CLANG_DIR}/include/llvm |" cctools2odcctools/extract.sh && \
+ sed -i "s|fAC_INIT|AC_INIT|" cctools2odcctools/files/configure.ac && \
+ sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' cctools2odcctools/files/configure.ac && \
+ cd cctools2odcctools; ./extract.sh --osxver $(OSX_SDK_VERSION) && \
+ sed -i "s|define\tPC|define\tPC_|" odcctools-809/include/architecture/sparc/reg.h
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install && \
+ cd ../../clang+llvm-3.2-x86-linux-ubuntu-12.04 && \
+ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/3.2/include && \
+ mkdir -p $($(package)_staging_prefix_dir)/bin && \
+ cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\
+ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \
+ cp lib/clang/3.2/include/* $($(package)_staging_prefix_dir)/lib/clang/3.2/include/ && \
+ echo "#!/bin/sh" > $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
+ echo "exit 0" >> $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
+ chmod +x $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil
+endef
diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk
new file mode 100644
index 0000000000..2cc388b4b3
--- /dev/null
+++ b/depends/packages/native_cdrkit.mk
@@ -0,0 +1,26 @@
+package=native_cdrkit
+$(package)_version=1.1.11
+$(package)_download_path=http://distro.ibiblio.org/fatdog/source/c
+$(package)_file_name=cdrkit-$($(package)_version).tar.bz2
+$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
+$(package)_patches=cdrkit-deterministic.patch
+
+define $(package)_preprocess_cmds
+ patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch
+endef
+
+define $(package)_config_cmds
+ cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) genisoimage
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C genisoimage install
+endef
+
+define $(package)_postprocess_cmds
+ rm bin/isovfy bin/isoinfo bin/isodump bin/isodebug bin/devdump
+endef
diff --git a/depends/packages/native_comparisontool.mk b/depends/packages/native_comparisontool.mk
new file mode 100644
index 0000000000..5eef73052f
--- /dev/null
+++ b/depends/packages/native_comparisontool.mk
@@ -0,0 +1,44 @@
+package=native_comparisontool
+$(package)_version=1
+$(package)_download_path=https://github.com/TheBlueMatt/test-scripts/raw/master/BitcoindComparisonTool_jar
+$(package)_file_name=BitcoindComparisonTool.jar
+$(package)_sha256_hash=a08b1a55523e7f57768cb66c35f47a926710e5b6c82822e1ccfbe38fcce37db2
+$(package)_guava_file_name=guava-13.0.1.jar
+$(package)_guava_sha256_hash=feb4b5b2e79a63b72ec47a693b1cf35cf1cea1f60a2bb2615bf21f74c7a60bb0
+$(package)_h2_file_name=h2-1.3.167.jar
+$(package)_h2_sha256_hash=fa97521a2e72174485a96276bcf6f573d5e44ca6aba2f62de87b33b5bb0d4b91
+$(package)_sc-light-jdk15on_file_name=sc-light-jdk15on-1.47.0.2.jar
+$(package)_sc-light-jdk15on_sha256_hash=931f39d351429fb96c2f749e7ecb1a256a8ebbf5edca7995c9cc085b94d1841d
+$(package)_slf4j-api_file_name=slf4j-api-1.6.4.jar
+$(package)_slf4j-api_sha256_hash=367b909030f714ee1176ab096b681e06348f03385e98d1bce0ed801b5452357e
+$(package)_slf4j-jdk14_file_name=slf4j-jdk14-1.6.4.jar
+$(package)_slf4j-jdk14_sha256_hash=064bd81796710f713f9f4a2309c0e032309934c2d2b4f7d3b6958325e584e13f
+
+define $(package)_fetch_cmds
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_guava_file_name),$($(package)_guava_file_name),$($(package)_guava_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_h2_file_name),$($(package)_h2_file_name),$($(package)_h2_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_sc-light-jdk15on_file_name),$($(package)_sc-light-jdk15on_file_name),$($(package)_sc-light-jdk15on_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_slf4j-api_file_name),$($(package)_slf4j-api_file_name),$($(package)_slf4j-api_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path)/$($(package)_slf4j-jdk14_file_name),$($(package)_slf4j-jdk14_file_name),$($(package)_slf4j-jdk14_sha256_hash))
+endef
+
+define $(package)_extract_cmds
+echo none
+endef
+
+define $(package)_configure_cmds
+endef
+
+define $(package)_build_cmds
+endef
+
+define $(package)_stage_cmds
+ mkdir -p $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar && \
+ cp $(SOURCES_PATH)/$($(package)_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
+ cp $(SOURCES_PATH)/$($(package)_guava_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
+ cp $(SOURCES_PATH)/$($(package)_h2_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
+ cp $(SOURCES_PATH)/$($(package)_sc-light-jdk15on_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
+ cp $(SOURCES_PATH)/$($(package)_slf4j-api_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
+ cp $(SOURCES_PATH)/$($(package)_slf4j-jdk14_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/
+endef
diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk
new file mode 100644
index 0000000000..a4ffb6046c
--- /dev/null
+++ b/depends/packages/native_libdmg-hfsplus.mk
@@ -0,0 +1,22 @@
+package=native_libdmg-hfsplus
+$(package)_version=0.1
+$(package)_download_path=https://github.com/theuni/libdmg-hfsplus/archive
+$(package)_file_name=libdmg-hfsplus-v$($(package)_version).tar.gz
+$(package)_sha256_hash=6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3
+$(package)_build_subdir=build
+
+define $(package)_preprocess_cmds
+ mkdir build
+endef
+
+define $(package)_config_cmds
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix)/bin ..
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C dmg
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install
+endef
diff --git a/depends/packages/native_libuuid.mk b/depends/packages/native_libuuid.mk
new file mode 100644
index 0000000000..b25540f80d
--- /dev/null
+++ b/depends/packages/native_libuuid.mk
@@ -0,0 +1,24 @@
+package:=native_libuuid
+$(package)_version=1.41.14
+$(package)_download_path=http://downloads.sourceforge.net/e2fsprogs
+$(package)_file_name=e2fsprogs-libs-$($(package)_version).tar.gz
+$(package)_sha256_hash=dbc7a138a3218d9b80a0626b5b692d76934d6746d8cbb762751be33785d8d9f5
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-elf-shlibs --disable-uuidd
+$(package)_cflags+=-m32
+$(package)_ldflags+=-m32
+$(package)_cxxflags+=-m32
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C lib/uuid
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C lib/uuid install
+endef
diff --git a/depends/packages/native_openssl.mk b/depends/packages/native_openssl.mk
new file mode 100644
index 0000000000..1f25d6afcc
--- /dev/null
+++ b/depends/packages/native_openssl.mk
@@ -0,0 +1,21 @@
+package=native_openssl
+$(package)_version=1.0.1h
+$(package)_download_path=https://www.openssl.org/source
+$(package)_file_name=openssl-$($(package)_version).tar.gz
+$(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093
+define $(package)_set_vars
+$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic32 -m32
+endef
+
+define $(package)_config_cmds
+ ./Configure $($(package)_build_config_opts) &&\
+ sed -i "s|engines apps test|engines|" Makefile
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -j1
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
+endef
diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk
new file mode 100644
index 0000000000..ed1a771f0d
--- /dev/null
+++ b/depends/packages/native_protobuf.mk
@@ -0,0 +1,25 @@
+package=native_protobuf
+$(package)_version=2.5.0
+$(package)_download_path=https://protobuf.googlecode.com/files
+$(package)_file_name=protobuf-$($(package)_version).tar.bz2
+$(package)_sha256_hash=13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C src protoc
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf lib include
+endef
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
new file mode 100644
index 0000000000..1fb8edb099
--- /dev/null
+++ b/depends/packages/openssl.mk
@@ -0,0 +1,40 @@
+package=openssl
+$(package)_version=1.0.1h
+$(package)_download_path=https://www.openssl.org/source
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093
+
+define $(package)_set_vars
+$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
+$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso
+$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2
+$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl3
+$(package)_config_opts+=$($(package)_cflags)
+$(package)_config_opts_x86_64_linux=-fPIC linux-x86_64
+$(package)_config_opts_arm_linux=-fPIC linux-generic32
+$(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc
+$(package)_config_opts_x86_64_mingw32=mingw64
+$(package)_config_opts_i686_mingw32=mingw
+$(package)_config_opts_i686_linux=linux-generic32 -fPIC
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old "/define DATE/d" crypto/Makefile && \
+ sed -i.old "s|engines apps test|engines|" Makefile.org
+endef
+
+define $(package)_config_cmds
+ ./Configure $($(package)_config_opts)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -j1 build_libs libcrypto.pc libssl.pc openssl.pc
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf share bin etc
+endef
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
new file mode 100644
index 0000000000..260cadb214
--- /dev/null
+++ b/depends/packages/packages.mk
@@ -0,0 +1,14 @@
+packages:=boost openssl
+native_packages := native_ccache native_comparisontool
+
+qt_native_packages = native_protobuf
+qt_packages = qt qrencode protobuf
+qt_linux_packages=expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
+
+wallet_packages=bdb
+
+upnp_packages=miniupnpc
+
+ifneq ($(build_os),darwin)
+darwin_native_packages=native_libuuid native_openssl native_cctools native_cdrkit native_libdmg-hfsplus
+endif
diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk
new file mode 100644
index 0000000000..716f837853
--- /dev/null
+++ b/depends/packages/protobuf.mk
@@ -0,0 +1,28 @@
+package=protobuf
+$(package)_version=$(native_$(package)_version)
+$(package)_download_path=$(native_$(package)_download_path)
+$(package)_file_name=$(native_$(package)_file_name)
+$(package)_sha256_hash=$(native_$(package)_sha256_hash)
+$(package)_dependencies=native_$(package)
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc
+ $(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C src libprotobuf.la
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA
+endef
+
+define $(package)_postprocess_cmds
+ rm lib/libprotoc.a
+endef
diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk
new file mode 100644
index 0000000000..69d2982cbc
--- /dev/null
+++ b/depends/packages/qrencode.mk
@@ -0,0 +1,22 @@
+package=qrencode
+$(package)_version=3.4.3
+$(package)_download_path=https://fukuchi.org/works/qrencode/
+$(package)_file_name=qrencode-$(qrencode_version).tar.bz2
+$(package)_sha256_hash=dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared -without-tools --disable-sdltest
+$(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
new file mode 100644
index 0000000000..cce7d6e6ef
--- /dev/null
+++ b/depends/packages/qt.mk
@@ -0,0 +1,89 @@
+PACKAGE=qt
+$(package)_version=5.2.1
+$(package)_download_path=http://download.qt-project.org/official_releases/qt/5.2/$($(package)_version)/single
+$(package)_file_name=$(package)-everywhere-opensource-src-$($(package)_version).tar.gz
+$(package)_sha256_hash=84e924181d4ad6db00239d87250cc89868484a14841f77fb85ab1f1dbdcd7da1
+$(package)_dependencies=openssl
+$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext
+$(package)_build_subdir=qtbase
+$(package)_qt_libs=corelib network widgets gui plugins testlib
+$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch
+
+define $(package)_set_vars
+$(package)_config_opts = -release -opensource -confirm-license
+$(package)_config_opts += -no-audio-backend -no-sql-tds -no-glib -no-icu
+$(package)_config_opts += -no-cups -no-iconv -no-gif -no-audio-backend -no-freetype
+$(package)_config_opts += -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch
+$(package)_config_opts += -no-gif -no-feature-style-plastique
+$(package)_config_opts += -no-qml-debug -no-pch -no-nis -nomake examples -nomake tests
+$(package)_config_opts += -no-feature-style-cde -no-feature-style-s60 -no-feature-style-motif
+$(package)_config_opts += -no-feature-style-windowsmobile -no-feature-style-windowsce
+$(package)_config_opts += -no-feature-style-cleanlooks
+$(package)_config_opts += -no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql
+$(package)_config_opts += -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2
+$(package)_config_opts += -skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport
+$(package)_config_opts += -skip qtdeclarative -skip qtmultimedia -skip qtimageformats -skip qtx11extras
+$(package)_config_opts += -skip qtlocation -skip qtsensors -skip qtquick1 -skip qtxmlpatterns
+$(package)_config_opts += -skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity -skip qtmacextras
+$(package)_config_opts += -skip qtwinextras -skip qtxmlpatterns -skip qtscript -skip qtdoc
+
+$(package)_config_opts += -prefix $(host_prefix) -bindir $(build_prefix)/bin
+$(package)_config_opts += -no-c++11 -openssl-linked -v -static -silent -pkg-config
+$(package)_config_opts += -qt-libpng -qt-libjpeg -qt-zlib -qt-pcre
+
+ifneq ($(build_os),darwin)
+$(package)_config_opts_darwin = -xplatform macx-clang-linux -device-option MAC_SDK_PATH=$(OSX_SDK) -device-option CROSS_COMPILE="$(host)-"
+$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host)
+endif
+
+$(package)_config_opts_linux = -qt-xkbcommon -qt-xcb -no-eglfs -no-linuxfb -system-freetype -no-sm -fontconfig -no-xinput2 -no-libudev -no-egl -no-opengl
+$(package)_config_opts_arm_linux = -platform linux-g++ -xplatform $(host)
+$(package)_config_opts_i686_linux = -xplatform linux-g++-32
+$(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-"
+$(package)_build_env = QT_RCC_TEST=1
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
+ sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \
+ sed -i.old "/XIproto.h/d" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \
+ mkdir -p qtbase/mkspecs/macx-clang-linux &&\
+ cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \
+ patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch
+endef
+
+define $(package)_config_cmds
+ export PKG_CONFIG_SYSROOT_DIR=/ && \
+ export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \
+ export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \
+ export CPATH=$(host_prefix)/include && \
+ ./configure $($(package)_config_opts) && \
+ $(MAKE) sub-src-clean && \
+ cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \
+ cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. &&\
+ cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile
+endef
+
+define $(package)_build_cmds
+ export CPATH=$(host_prefix)/include && \
+ $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \
+ $(MAKE) -C ../qttools/src/linguist/lrelease && \
+ $(MAKE) -C ../qttranslations
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. &&\
+ $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \
+ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \
+ if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \
+ cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \
+ fi
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf mkspecs/ lib/cmake/ && \
+ rm lib/libQt5Bootstrap.a lib/lib*.la lib/lib*.prl
+endef
diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk
new file mode 100644
index 0000000000..726e3048c3
--- /dev/null
+++ b/depends/packages/xcb_proto.mk
@@ -0,0 +1,27 @@
+package=xcb_proto
+$(package)_version=1.10
+$(package)_download_path=http://xcb.freedesktop.org/dist
+$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2
+$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared
+ $(package)_config_opts_x86_64_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ find -name "*.pyc" -delete && \
+ find -name "*.pyo" -delete
+endef
diff --git a/depends/packages/xextproto.mk b/depends/packages/xextproto.mk
new file mode 100644
index 0000000000..98a11eb497
--- /dev/null
+++ b/depends/packages/xextproto.mk
@@ -0,0 +1,21 @@
+package=xextproto
+$(package)_version=7.3.0
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=f3f4b23ac8db9c3a9e0d8edb591713f3d70ef9c3b175970dd8823dfc92aa5bb0
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk
new file mode 100644
index 0000000000..50a90b2685
--- /dev/null
+++ b/depends/packages/xproto.mk
@@ -0,0 +1,21 @@
+package=xproto
+$(package)_version=7.0.26
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk
new file mode 100644
index 0000000000..b973149797
--- /dev/null
+++ b/depends/packages/xtrans.mk
@@ -0,0 +1,22 @@
+package=xtrans
+$(package)_version=1.3.4
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc33544f583a
+$(package)_dependencies=
+
+define $(package)_set_vars
+$(package)_config_opts_x86_64_linux=--with-pic --disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/patches/boost/darwin_boost_atomic-1.patch b/depends/patches/boost/darwin_boost_atomic-1.patch
new file mode 100644
index 0000000000..97f59cb7e4
--- /dev/null
+++ b/depends/patches/boost/darwin_boost_atomic-1.patch
@@ -0,0 +1,35 @@
+diff --git a/include/boost/atomic/detail/cas128strong.hpp b/include/boost/atomic/detail/cas128strong.hpp
+index 906c13e..dcb4d7d 100644
+--- a/include/boost/atomic/detail/cas128strong.hpp
++++ b/include/boost/atomic/detail/cas128strong.hpp
+@@ -196,15 +196,17 @@ class base_atomic<T, void, 16, Sign>
+
+ public:
+ BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
+- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
++ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
+ {
++ memset(&v_, 0, sizeof(v_));
+ memcpy(&v_, &v, sizeof(value_type));
+ }
+
+ void
+ store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type value_s = 0;
++ storage_type value_s;
++ memset(&value_s, 0, sizeof(value_s));
+ memcpy(&value_s, &value, sizeof(value_type));
+ platform_fence_before_store(order);
+ platform_store128(value_s, &v_);
+@@ -247,7 +249,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+
diff --git a/depends/patches/boost/darwin_boost_atomic-2.patch b/depends/patches/boost/darwin_boost_atomic-2.patch
new file mode 100644
index 0000000000..ca50765200
--- /dev/null
+++ b/depends/patches/boost/darwin_boost_atomic-2.patch
@@ -0,0 +1,55 @@
+diff --git a/include/boost/atomic/detail/gcc-atomic.hpp b/include/boost/atomic/detail/gcc-atomic.hpp
+index a130590..4af99a1 100644
+--- a/include/boost/atomic/detail/gcc-atomic.hpp
++++ b/include/boost/atomic/detail/gcc-atomic.hpp
+@@ -958,14 +958,16 @@ class base_atomic<T, void, 16, Sign>
+
+ public:
+ BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
+- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
++ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
+ {
++ memset(&v_, 0, sizeof(v_));
+ memcpy(&v_, &v, sizeof(value_type));
+ }
+
+ void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type tmp = 0;
++ storage_type tmp;
++ memset(&tmp, 0, sizeof(tmp));
+ memcpy(&tmp, &v, sizeof(value_type));
+ __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
+ }
+@@ -980,7 +982,8 @@ class base_atomic<T, void, 16, Sign>
+
+ value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type tmp = 0;
++ storage_type tmp;
++ memset(&tmp, 0, sizeof(tmp));
+ memcpy(&tmp, &v, sizeof(value_type));
+ tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
+ value_type res;
+@@ -994,7 +997,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+ const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false,
+@@ -1010,7 +1015,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+ const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true,
diff --git a/depends/patches/native_cdrkit/cdrkit-deterministic.patch b/depends/patches/native_cdrkit/cdrkit-deterministic.patch
new file mode 100644
index 0000000000..8ab0993dc4
--- /dev/null
+++ b/depends/patches/native_cdrkit/cdrkit-deterministic.patch
@@ -0,0 +1,86 @@
+--- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400
++++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500
+@@ -1139,8 +1139,9 @@
+ scan_directory_tree(struct directory *this_dir, char *path,
+ struct directory_entry *de)
+ {
+- DIR *current_dir;
++ int current_file;
+ char whole_path[PATH_MAX];
++ struct dirent **d_list;
+ struct dirent *d_entry;
+ struct directory *parent;
+ int dflag;
+@@ -1164,7 +1165,8 @@
+ this_dir->dir_flags |= DIR_WAS_SCANNED;
+
+ errno = 0; /* Paranoia */
+- current_dir = opendir(path);
++ //current_dir = opendir(path);
++ current_file = scandir(path, &d_list, NULL, alphasort);
+ d_entry = NULL;
+
+ /*
+@@ -1173,12 +1175,12 @@
+ */
+ old_path = path;
+
+- if (current_dir) {
++ if (current_file >= 0) {
+ errno = 0;
+- d_entry = readdir(current_dir);
++ d_entry = d_list[0];
+ }
+
+- if (!current_dir || !d_entry) {
++ if (current_file < 0 || !d_entry) {
+ int ret = 1;
+
+ #ifdef USE_LIBSCHILY
+@@ -1191,8 +1193,8 @@
+ de->isorec.flags[0] &= ~ISO_DIRECTORY;
+ ret = 0;
+ }
+- if (current_dir)
+- closedir(current_dir);
++ if(d_list)
++ free(d_list);
+ return (ret);
+ }
+ #ifdef ABORT_DEEP_ISO_ONLY
+@@ -1208,7 +1210,7 @@
+ errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n");
+ errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n");
+ }
+- closedir(current_dir);
++ free(d_list);
+ return (1);
+ }
+ #endif
+@@ -1250,13 +1252,13 @@
+ * The first time through, skip this, since we already asked
+ * for the first entry when we opened the directory.
+ */
+- if (dflag)
+- d_entry = readdir(current_dir);
++ if (dflag && current_file >= 0)
++ d_entry = d_list[current_file];
+ dflag++;
+
+- if (!d_entry)
++ if (current_file < 0)
+ break;
+-
++ current_file--;
+ /* OK, got a valid entry */
+
+ /* If we do not want all files, then pitch the backups. */
+@@ -1348,7 +1350,7 @@
+ insert_file_entry(this_dir, whole_path, d_entry->d_name);
+ #endif /* APPLE_HYB */
+ }
+- closedir(current_dir);
++ free(d_list);
+
+ #ifdef APPLE_HYB
+ /*
diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch
new file mode 100644
index 0000000000..bf6c6dca36
--- /dev/null
+++ b/depends/patches/qt/fix-xcb-include-order.patch
@@ -0,0 +1,21 @@
+--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:17:27.384458441 -0400
++++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:18:28.620459303 -0400
+@@ -101,10 +101,6 @@
+ }
+ }
+
+-DEFINES += $$QMAKE_DEFINES_XCB
+-LIBS += $$QMAKE_LIBS_XCB
+-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
+-
+ CONFIG += qpa/genericunixfontdatabase
+
+ contains(QT_CONFIG, dbus) {
+@@ -141,3 +137,7 @@
+ INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
+ }
+ }
++
++DEFINES += $$QMAKE_DEFINES_XCB
++LIBS += $$QMAKE_LIBS_XCB
++INCLUDEPATH += $$QMAKE_CFLAGS_XCB
diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf
new file mode 100644
index 0000000000..f7302265bc
--- /dev/null
+++ b/depends/patches/qt/mac-qmake.conf
@@ -0,0 +1,23 @@
+MAKEFILE_GENERATOR = UNIX
+CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname
+QMAKE_INCREMENTAL_STYLE = sublib
+include(../common/macx.conf)
+include(../common/gcc-base-mac.conf)
+include(../common/clang.conf)
+include(../common/clang-mac.conf)
+QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH}
+QMAKE_XCODE_VERSION=4.3
+QMAKE_XCODE_DEVELOPER_PATH=/Developer
+QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION}
+QMAKE_MAC_SDK=macosx
+QMAKE_MAC_SDK.macosx.path = $$QMAKE_MAC_SDK_PATH
+QMAKE_MAC_SDK.macosx.platform_name = macosx
+QMAKE_CFLAGS += -target $${MAC_TARGET}
+QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
+QMAKE_LFLAGS += -target $${MAC_TARGET}
+QMAKE_AR = $${CROSS_COMPILE}ar cq
+QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
+QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool
+QMAKE_INSTALL_NAME_TOOL=$${CROSS_COMPILE}install_name_tool
+load(qt_config)
diff --git a/doc/README.md b/doc/README.md
index f8bb8020d4..10c9ad1799 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -46,7 +46,6 @@ The following are developer notes on how to build Bitcoin on your native platfor
- [OSX Build Notes](build-osx.md)
- [Unix Build Notes](build-unix.md)
-- [Windows Build Notes](build-msw.md)
Development
---------------------
diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md
index 61b457a282..cd864f254d 100644
--- a/doc/assets-attribution.md
+++ b/doc/assets-attribution.md
@@ -100,5 +100,4 @@ Jonas Schnelli
src/qt/res/icons/bitcoin.icns, src/qt/res/src/bitcoin.svg,
src/qt/res/src/bitcoin.ico, src/qt/res/src/bitcoin.png,
src/qt/res/src/bitcoin_testnet.png, docs/bitcoin_logo_doxygen.png,
- src/qt/res/icons/toolbar.png, src/qt/res/icons/toolbar_testnet.png,
src/qt/res/images/splash.png, src/qt/res/images/splash_testnet.png
diff --git a/doc/bootstrap.md b/doc/bootstrap.md
index 685b768f8b..7ce71abaad 100644
--- a/doc/bootstrap.md
+++ b/doc/bootstrap.md
@@ -4,7 +4,7 @@ Normally the Bitcoin client will download the transaction and network informatio
### Requirements
-A fresh install of the Bitcoin client software.
+- A fresh install of the Bitcoin client software.
### Download the blockchain via Bittorent
diff --git a/doc/build-osx.md b/doc/build-osx.md
index bc42723b12..ade9eb466b 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -69,21 +69,30 @@ Instructions: Homebrew
#### Install dependencies using Homebrew
- brew install autoconf automake libtool berkeley-db4 boost miniupnpc openssl pkg-config protobuf qt
+ brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt
-Note: After you have installed the dependencies, you should check that the Homebrew installed version of OpenSSL is the one available for compilation. You can check this by typing
+#### Installing berkeley-db4 using Homebrew
- openssl version
+The homebrew package for berkeley-db4 has been broken for some time. It will install without Java though.
-into Terminal. You should see OpenSSL 1.0.1h 5 Jun 2014.
+Running this command takes you into brew's interactive mode, which allows you to configure, make, and install by hand:
+```
+$ brew install https://raw.github.com/mxcl/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
+```
-If not, you can ensure that the Homebrew OpenSSL is correctly linked by running
+These rest of these commands are run inside brew interactive mode:
+```
+/private/tmp/berkeley-db4-UGpd0O/db-4.8.30 $ cd ..
+/private/tmp/berkeley-db4-UGpd0O $ db-4.8.30/dist/configure --prefix=/usr/local/Cellar/berkeley-db4/4.8.30 --mandir=/usr/local/Cellar/berkeley-db4/4.8.30/share/man --enable-cxx
+/private/tmp/berkeley-db4-UGpd0O $ make
+/private/tmp/berkeley-db4-UGpd0O $ make install
+/private/tmp/berkeley-db4-UGpd0O $ exit
+```
- brew link openssl --force
+After exiting, you'll get a warning that the install is keg-only, which means it wasn't symlinked to `/usr/local`. You don't need it to link it to build bitcoin, but if you want to, here's how:
+
+ $ brew --force link berkeley-db4
-Rerunning "openssl version" should now return the correct version. If it
-doesn't, make sure `/usr/local/bin` comes before `/usr/bin` in your
-PATH.
### Building `bitcoind`
diff --git a/doc/build-unix.md b/doc/build-unix.md
index 0f381d56c5..8a76a8b2cd 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -76,10 +76,6 @@ for Ubuntu 12.04 and later:
Ubuntu 12.04 and later have packages for libdb5.1-dev and libdb5.1++-dev,
but using these will break binary wallet compatibility, and is not recommended.
-for Ubuntu 13.10:
- libboost1.54 will not work,
- remove libboost1.54-all-dev and install libboost1.53-all-dev instead.
-
for Debian 7 (Wheezy) and later:
The oldstable repository contains db4.8 packages.
Add the following line to /etc/apt/sources.list,
@@ -113,7 +109,7 @@ To build with Qt 4 you need the following:
For Qt 5 you need the following:
- sudo apt-get install libqt5gui5 libqt5core5 libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev
+ sudo apt-get install libqt5gui5 libqt5core5 libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
libqrencode (optional) can be installed with:
diff --git a/doc/travis-ci.txt b/doc/travis-ci.txt
new file mode 100644
index 0000000000..01f7d02a86
--- /dev/null
+++ b/doc/travis-ci.txt
@@ -0,0 +1,39 @@
+Support for using travis-ci has been added in order to automate pull-testing.
+See https://travis-ci.org/ for more info
+
+This procedure is different than the pull-tester that came before it in a few
+ways.
+
+There is nothing to administer. This is a major feature as it means
+that builds have no local state. Because there is no ability to login to the
+builders to install packages (tools, dependencies, etc), the entire build
+procedure must instead be controlled by a declarative script (.travis.yml).
+This script declares each build configuration, creates virtual machines as
+necessary, builds, then discards the virtual machines.
+
+A build matrix is constructed to test a wide range of configurations, rather
+than a single pass/fail. This helps to catch build failures and logic errors
+that present on platforms other than the ones the author has tested. This
+matrix is defined in the build script and can be changed at any time.
+
+All builders use the dependency-generator in the depends dir, rather than
+using apt-get to install build dependencies. This guarantees that the tester
+is using the same versions as Gitian, so the build results are nearly identical
+to what would be found in a final release. However, this also means that builds
+will fail if new dependencies are introduced without being added to the
+dependency generator.
+
+In order to avoid rebuilding all dependencies for each build, the binaries are
+cached and re-used when possible. Changes in the dependency-generator will
+trigger cache-invalidation and rebuilds as necessary.
+
+These caches can be manually removed if necessary. This is one of the the very few
+manual operations that is possible with Travis, and it can be done by the
+Bitcoin Core committer via the Travis web interface.
+
+In some cases, secure strings may be needed for hiding sensitive info such as
+private keys or URLs. The travis client may be used to create these strings:
+http://docs.travis-ci.com/user/encryption-keys/
+
+For the details of the build descriptor, see the official docs:
+http://docs.travis-ci.com/user/build-configuration/
diff --git a/qa/pull-tester/run-bitcoind-for-test.sh.in b/qa/pull-tester/run-bitcoind-for-test.sh.in
index e186bd7a23..67318e5a4c 100755
--- a/qa/pull-tester/run-bitcoind-for-test.sh.in
+++ b/qa/pull-tester/run-bitcoind-for-test.sh.in
@@ -9,7 +9,7 @@ mkdir -p "$DATADIR"/regtest
touch "$DATADIR/regtest/debug.log"
tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
WAITER=$!
-PORT=`expr 10000 + $BASHPID % 55536`
+PORT=`expr 10000 + $$ % 55536`
"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
BITCOIND=$!
diff --git a/src/Makefile.am b/src/Makefile.am
index 727a88c3e7..655bfc88c3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,3 @@
-AM_CPPFLAGS = $(INCLUDES)
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS)
if USE_LIBSECP256K1
@@ -22,7 +21,7 @@ $(LIBLEVELDB) $(LIBMEMENV):
endif
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
-BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
+BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
if USE_LIBSECP256K1
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
@@ -56,12 +55,10 @@ if BUILD_BITCOIND
bin_PROGRAMS += bitcoind
endif
-if BUILD_BITCOIN_CLI
- bin_PROGRAMS += bitcoin-cli
+if BUILD_BITCOIN_UTILS
+ bin_PROGRAMS += bitcoin-cli bitcoin-tx
endif
-bin_PROGRAMS += bitcoin-tx
-
.PHONY: FORCE
# bitcoin core #
BITCOIN_CORE_H = \
@@ -112,6 +109,9 @@ BITCOIN_CORE_H = \
ui_interface.h \
uint256.h \
util.h \
+ utilstrencodings.h \
+ utilmoneystr.h \
+ utiltime.h \
version.h \
walletdb.h \
wallet.h \
@@ -188,6 +188,7 @@ univalue_libbitcoin_univalue_a_SOURCES = \
univalue/univalue.cpp \
univalue/univalue_read.cpp \
univalue/univalue_write.cpp \
+ univalue/univalue_escapes.h \
univalue/univalue.h
# common: shared between bitcoind, and bitcoin-qt and non-server tools
@@ -221,6 +222,9 @@ libbitcoin_util_a_SOURCES = \
sync.cpp \
uint256.cpp \
util.cpp \
+ utilstrencodings.cpp \
+ utilmoneystr.cpp \
+ utiltime.cpp \
version.cpp \
$(BITCOIN_CORE_H)
@@ -230,6 +234,7 @@ libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
endif
# cli: shared between bitcoin-cli and bitcoin-qt
+libbitcoin_cli_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_cli_a_SOURCES = \
rpcclient.cpp \
$(BITCOIN_CORE_H)
@@ -261,8 +266,9 @@ if TARGET_WINDOWS
bitcoind_SOURCES += bitcoind-res.rc
endif
-bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS)
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS)
# bitcoin-cli binary #
bitcoin_cli_LDADD = \
@@ -270,7 +276,10 @@ bitcoin_cli_LDADD = \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
- $(BOOST_LIBS)
+ $(BOOST_LIBS) \
+ $(SSL_LIBS) \
+ $(CRYPTO_LIBS)
+
bitcoin_cli_SOURCES = \
bitcoin-cli.cpp
@@ -285,15 +294,24 @@ bitcoin_tx_LDADD = \
$(LIBBITCOIN_UNIVALUE) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_CRYPTO) \
- $(BOOST_LIBS)
+ $(LIBBITCOIN_CRYPTO)
+
+if USE_LIBSECP256K1
+ bitcoin_tx_LDADD += secp256k1/libsecp256k1.la
+endif
+
+ bitcoin_tx_LDADD += $(BOOST_LIBS) \
+ $(SSL_LIBS) \
+ $(CRYPTO_LIBS)
bitcoin_tx_SOURCES = bitcoin-tx.cpp
bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
#
+bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS)
if TARGET_WINDOWS
bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif
+bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS)
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 2052264dc9..28d7053fc4 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -245,8 +245,6 @@ RES_ICONS = \
qt/res/icons/remove.png \
qt/res/icons/send.png \
qt/res/icons/synced.png \
- qt/res/icons/toolbar.png \
- qt/res/icons/toolbar_testnet.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction_conflicted.png \
@@ -360,11 +358,11 @@ if ENABLE_WALLET
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
- $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
+ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
if USE_LIBSECP256K1
qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
-qt_bitcoin_qt_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS)
+qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS)
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index d49b2240ea..2cba5b7e1e 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -32,11 +32,11 @@ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
- $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
+ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
if USE_LIBSECP256K1
qt_test_test_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
-qt_test_test_bitcoin_qt_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS)
+qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS)
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 72451fba9a..b4360831bb 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -1,8 +1,20 @@
-TESTS += test/test_bitcoin
+TESTS += test/test_bitcoin test/bitcoin-util-test.py
bin_PROGRAMS += test/test_bitcoin
TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
+
+EXTRA_DIST += \
+ test/bctest.py \
+ test/bitcoin-util-test.py \
+ test/data/bitcoin-util-test.json \
+ test/data/blanktx.hex \
+ test/data/tt-delin1-out.hex \
+ test/data/tt-delout1-out.hex \
+ test/data/tt-locktime317000-out.hex \
+ test/data/tx394b54bb.hex \
+ test/data/txcreate1.hex
+
JSON_TEST_FILES = \
test/data/script_valid.json \
test/data/base58_keys_valid.json \
@@ -49,8 +61,10 @@ BITCOIN_TESTS =\
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/test_bitcoin.cpp \
+ test/timedata_tests.cpp \
test/transaction_tests.cpp \
test/uint256_tests.cpp \
+ test/univalue_tests.cpp \
test/util_tests.cpp \
test/scriptnum_tests.cpp \
test/sighash_tests.cpp
@@ -74,7 +88,8 @@ if USE_LIBSECP256K1
test_test_bitcoin_LDADD += secp256k1/libsecp256k1.la
endif
-test_test_bitcoin_LDADD += $(BDB_LIBS)
+test_test_bitcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
+test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS)
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 3628af2eab..704766dbf8 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -492,17 +492,23 @@ int CAddrMan::Check_()
void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
{
- int nNodes = ADDRMAN_GETADDR_MAX_PCT*vRandom.size()/100;
+ unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100;
if (nNodes > ADDRMAN_GETADDR_MAX)
nNodes = ADDRMAN_GETADDR_MAX;
- // perform a random shuffle over the first nNodes elements of vRandom (selecting from all)
- for (int n = 0; n<nNodes; n++)
+ // gather a list of random nodes, skipping those of low quality
+ for (unsigned int n = 0; n < vRandom.size(); n++)
{
+ if (vAddr.size() >= nNodes)
+ break;
+
int nRndPos = GetRandInt(vRandom.size() - n) + n;
SwapRandom(n, nRndPos);
assert(mapInfo.count(vRandom[n]) == 1);
- vAddr.push_back(mapInfo[vRandom[n]]);
+
+ const CAddrInfo& ai = mapInfo[vRandom[n]];
+ if (!ai.IsTerrible())
+ vAddr.push_back(ai);
}
}
diff --git a/src/alert.cpp b/src/alert.cpp
index 258a2b52c4..3271ecfbfd 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -19,6 +19,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
using namespace std;
@@ -80,11 +81,6 @@ std::string CUnsignedAlert::ToString() const
strStatusBar);
}
-void CUnsignedAlert::print() const
-{
- LogPrintf("%s", ToString());
-}
-
void CAlert::SetNull()
{
CUnsignedAlert::SetNull();
diff --git a/src/alert.h b/src/alert.h
index da140be5e5..b9d850b565 100644
--- a/src/alert.h
+++ b/src/alert.h
@@ -60,15 +60,14 @@ public:
READWRITE(setSubVer);
READWRITE(nPriority);
- READWRITE(strComment);
- READWRITE(strStatusBar);
- READWRITE(strReserved);
+ READWRITE(LIMITED_STRING(strComment, 65536));
+ READWRITE(LIMITED_STRING(strStatusBar, 256));
+ READWRITE(LIMITED_STRING(strReserved, 256));
)
void SetNull();
std::string ToString() const;
- void print() const;
};
/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 0609adcab3..871aaf93df 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -8,6 +8,8 @@
#include "rpcclient.h"
#include "rpcprotocol.h"
#include "chainparamsbase.h"
+#include "utilstrencodings.h"
+#include "version.h"
#include <boost/filesystem/operations.hpp>
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 299315424b..75f0fb69f2 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -4,6 +4,7 @@
#include "base58.h"
#include "util.h"
+#include "utilmoneystr.h"
#include "core.h"
#include "main.h" // for MAX_BLOCK_SIZE
#include "keystore.h"
@@ -13,6 +14,7 @@
#include <stdio.h>
#include <boost/assign/list_of.hpp>
+#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost::assign;
@@ -283,12 +285,12 @@ static const struct {
const char *flagStr;
int flags;
} sighashOptions[N_SIGHASH_OPTS] = {
- "ALL", SIGHASH_ALL,
- "NONE", SIGHASH_NONE,
- "SINGLE", SIGHASH_SINGLE,
- "ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY,
- "NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY,
- "SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY,
+ {"ALL", SIGHASH_ALL},
+ {"NONE", SIGHASH_NONE},
+ {"SINGLE", SIGHASH_SINGLE},
+ {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
+ {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
+ {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
};
static bool findSighashFlags(int& flags, const string& flagStr)
@@ -501,13 +503,34 @@ static void OutputTx(const CTransaction& tx)
OutputTxHex(tx);
}
+static string readStdin()
+{
+ char buf[4096];
+ string ret;
+
+ while (!feof(stdin)) {
+ size_t bread = fread(buf, 1, sizeof(buf), stdin);
+ ret.append(buf, bread);
+ if (bread < sizeof(buf))
+ break;
+ }
+
+ if (ferror(stdin))
+ throw runtime_error("error reading stdin");
+
+ boost::algorithm::trim_right(ret);
+
+ return ret;
+}
+
static int CommandLineRawTx(int argc, char* argv[])
{
string strPrint;
int nRet = 0;
try {
- // Skip switches
- while (argc > 1 && IsSwitchChar(argv[1][0])) {
+ // Skip switches; Permit common stdin convention "-"
+ while (argc > 1 && IsSwitchChar(argv[1][0]) &&
+ (argv[1][1] != 0)) {
argc--;
argv++;
}
@@ -522,6 +545,8 @@ static int CommandLineRawTx(int argc, char* argv[])
// param: hex-encoded bitcoin transaction
string strHexTx(argv[1]);
+ if (strHexTx == "-") // "-" implies standard input
+ strHexTx = readStdin();
if (!DecodeHexTx(txDecodeTmp, strHexTx))
throw runtime_error("invalid transaction encoding");
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 880955481b..5be8708979 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -12,6 +12,7 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
/* Introduction text for doxygen: */
diff --git a/src/coins.cpp b/src/coins.cpp
index fe40911db7..7bfb84ef3e 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -52,30 +52,30 @@ bool CCoins::Spend(int nPos) {
}
-bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; }
+bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
-bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
-uint256 CCoinsView::GetBestBlock() { return uint256(0); }
+bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
+uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
-bool CCoinsView::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
-bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
+bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
+bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
-bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); }
+bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
-bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
-uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
+bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
+uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
-bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
-bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
+bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
+bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); }
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
-bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
+bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
if (cacheCoins.count(txid)) {
coins = cacheCoins[txid];
return true;
@@ -99,19 +99,29 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
return ret;
}
+CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const {
+ /* Avoid redundant implementation with the const-cast. */
+ return const_cast<CCoinsViewCache*>(this)->FetchCoins(txid);
+}
+
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
CCoinsMap::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end());
return it->second;
}
+const CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) const {
+ /* Avoid redundant implementation with the const-cast. */
+ return const_cast<CCoinsViewCache*>(this)->GetCoins(txid);
+}
+
bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
cacheCoins[txid] = coins;
return true;
}
-bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
- CCoinsMap::iterator it = FetchCoins(txid);
+bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
+ CCoinsMap::const_iterator it = FetchCoins(txid);
// We're using vtx.empty() instead of IsPruned here for performance reasons,
// as we only care about the case where an transaction was replaced entirely
// in a reorganization (which wipes vout entirely, as opposed to spending
@@ -119,7 +129,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
return (it != cacheCoins.end() && !it->second.vout.empty());
}
-uint256 CCoinsViewCache::GetBestBlock() {
+uint256 CCoinsViewCache::GetBestBlock() const {
if (hashBlock == uint256(0))
hashBlock = base->GetBestBlock();
return hashBlock;
@@ -130,32 +140,34 @@ bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
return true;
}
-bool CCoinsViewCache::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
- for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
- cacheCoins[it->first] = it->second;
+bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
+ cacheCoins[it->first].swap(it->second);
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
hashBlock = hashBlockIn;
return true;
}
bool CCoinsViewCache::Flush() {
bool fOk = base->BatchWrite(cacheCoins, hashBlock);
- if (fOk)
- cacheCoins.clear();
+ cacheCoins.clear();
return fOk;
}
-unsigned int CCoinsViewCache::GetCacheSize() {
+unsigned int CCoinsViewCache::GetCacheSize() const {
return cacheCoins.size();
}
-const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input)
+const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const
{
const CCoins &coins = GetCoins(input.prevout.hash);
assert(coins.IsAvailable(input.prevout.n));
return coins.vout[input.prevout.n];
}
-int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx)
+int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const
{
if (tx.IsCoinBase())
return 0;
@@ -167,7 +179,7 @@ int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx)
return nResult;
}
-bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
+bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase()) {
// first check whether information about the prevout hash is available
@@ -188,7 +200,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
return true;
}
-double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight)
+double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
{
if (tx.IsCoinBase())
return 0.0;
diff --git a/src/coins.h b/src/coins.h
index 9f90fe6bd0..08913531d8 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -247,7 +247,10 @@ private:
public:
CCoinsKeyHasher();
- uint64_t operator()(const uint256& key) const {
+ // This *must* return size_t. With Boost 1.46 on 32-bit systems the
+ // unordered_map will behave unpredictably if the custom hasher returns a
+ // uint64_t, resulting in failures when syncing the chain (#4634).
+ size_t operator()(const uint256& key) const {
return key.GetHash(salt);
}
};
@@ -273,26 +276,27 @@ class CCoinsView
{
public:
// Retrieve the CCoins (unspent transaction outputs) for a given txid
- virtual bool GetCoins(const uint256 &txid, CCoins &coins);
+ virtual bool GetCoins(const uint256 &txid, CCoins &coins) const;
// Modify the CCoins for a given txid
virtual bool SetCoins(const uint256 &txid, const CCoins &coins);
// Just check whether we have data for a given txid.
// This may (but cannot always) return true for fully spent transactions
- virtual bool HaveCoins(const uint256 &txid);
+ virtual bool HaveCoins(const uint256 &txid) const;
// Retrieve the block hash whose state this CCoinsView currently represents
- virtual uint256 GetBestBlock();
+ virtual uint256 GetBestBlock() const;
// Modify the currently active block hash
virtual bool SetBestBlock(const uint256 &hashBlock);
- // Do a bulk modification (multiple SetCoins + one SetBestBlock)
- virtual bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
+ // Do a bulk modification (multiple SetCoins + one SetBestBlock).
+ // The passed mapCoins can be modified.
+ virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
// Calculate statistics about the unspent transaction output set
- virtual bool GetStats(CCoinsStats &stats);
+ virtual bool GetStats(CCoinsStats &stats) const;
// As we use CCoinsViews polymorphically, have a virtual destructor
virtual ~CCoinsView() {}
@@ -307,14 +311,14 @@ protected:
public:
CCoinsViewBacked(CCoinsView &viewIn);
- bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins);
- bool HaveCoins(const uint256 &txid);
- uint256 GetBestBlock();
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock);
void SetBackend(CCoinsView &viewIn);
- bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
- bool GetStats(CCoinsStats &stats);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool GetStats(CCoinsStats &stats) const;
};
@@ -322,31 +326,36 @@ public:
class CCoinsViewCache : public CCoinsViewBacked
{
protected:
- uint256 hashBlock;
- CCoinsMap cacheCoins;
+
+ /* Make mutable so that we can "fill the cache" even from Get-methods
+ declared as "const". */
+ mutable uint256 hashBlock;
+ mutable CCoinsMap cacheCoins;
public:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
// Standard CCoinsView methods
- bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins);
- bool HaveCoins(const uint256 &txid);
- uint256 GetBestBlock();
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock);
- bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
// Return a modifiable reference to a CCoins. Check HaveCoins first.
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
// copying.
CCoins &GetCoins(const uint256 &txid);
+ const CCoins &GetCoins(const uint256 &txid) const;
// Push the modifications applied to this cache to its base.
// Failure to call this method before destruction will cause the changes to be forgotten.
+ // If false is returned, the state of this cache (and its backing view) will be undefined.
bool Flush();
// Calculate the size of the cache (in number of transactions)
- unsigned int GetCacheSize();
+ unsigned int GetCacheSize() const;
/** Amount of bitcoins coming in to a transaction
Note that lightweight clients may not know anything besides the hash of previous transactions,
@@ -355,18 +364,19 @@ public:
@param[in] tx transaction for which we are checking input total
@return Sum of value of all inputs (scriptSigs)
*/
- int64_t GetValueIn(const CTransaction& tx);
+ int64_t GetValueIn(const CTransaction& tx) const;
// Check whether all prevouts of the transaction are present in the UTXO set represented by this view
- bool HaveInputs(const CTransaction& tx);
+ bool HaveInputs(const CTransaction& tx) const;
// Return priority of tx at height nHeight
- double GetPriority(const CTransaction &tx, int nHeight);
+ double GetPriority(const CTransaction &tx, int nHeight) const;
- const CTxOut &GetOutputFor(const CTxIn& input);
+ const CTxOut &GetOutputFor(const CTxIn& input) const;
private:
CCoinsMap::iterator FetchCoins(const uint256 &txid);
+ CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
};
#endif
diff --git a/src/compat.h b/src/compat.h
index 52c7817130..4fc28a36e0 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -59,4 +59,29 @@ typedef u_int SOCKET;
#define SOCKET_ERROR -1
#endif
+#ifdef WIN32
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#endif
+#else
+#define MAX_PATH 1024
+#endif
+
+// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0
+#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef WIN32
+// PRIO_MAX is not defined on Solaris
+#ifndef PRIO_MAX
+#define PRIO_MAX 20
+#endif
+#define THREAD_PRIORITY_LOWEST PRIO_MAX
+#define THREAD_PRIORITY_BELOW_NORMAL 2
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
+#endif
+
#endif // _BITCOIN_COMPAT_H
diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp
index 417166aeda..cbe059735b 100644
--- a/src/compat/glibcxx_compat.cpp
+++ b/src/compat/glibcxx_compat.cpp
@@ -64,6 +64,8 @@ template istream& istream::_M_extract(unsigned short&);
out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
+length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
+
// Used with permission.
// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
diff --git a/src/core.cpp b/src/core.cpp
index 149b3532a1..71d6fea610 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -5,18 +5,13 @@
#include "core.h"
-#include "util.h"
+#include "tinyformat.h"
std::string COutPoint::ToString() const
{
return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
}
-void COutPoint::print() const
-{
- LogPrintf("%s\n", ToString());
-}
-
CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
{
prevout = prevoutIn;
@@ -46,11 +41,6 @@ std::string CTxIn::ToString() const
return str;
}
-void CTxIn::print() const
-{
- LogPrintf("%s\n", ToString());
-}
-
CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
nValue = nValueIn;
@@ -67,11 +57,6 @@ std::string CTxOut::ToString() const
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
}
-void CTxOut::print() const
-{
- LogPrintf("%s\n", ToString());
-}
-
CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize)
{
if (nSize > 0)
@@ -92,8 +77,7 @@ int64_t CFeeRate::GetFee(size_t nSize) const
std::string CFeeRate::ToString() const
{
- std::string result = FormatMoney(nSatoshisPerK) + " BTC/kB";
- return result;
+ return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN);
}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
@@ -171,11 +155,6 @@ std::string CTransaction::ToString() const
return str;
}
-void CTransaction::print() const
-{
- LogPrintf("%s", ToString());
-}
-
// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
@@ -285,9 +264,10 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
return hash;
}
-void CBlock::print() const
+std::string CBlock::ToString() const
{
- LogPrintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
+ std::stringstream s;
+ s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
GetHash().ToString(),
nVersion,
hashPrevBlock.ToString(),
@@ -296,11 +276,11 @@ void CBlock::print() const
vtx.size());
for (unsigned int i = 0; i < vtx.size(); i++)
{
- LogPrintf(" ");
- vtx[i].print();
+ s << " " << vtx[i].ToString() << "\n";
}
- LogPrintf(" vMerkleTree: ");
+ s << " vMerkleTree: ";
for (unsigned int i = 0; i < vMerkleTree.size(); i++)
- LogPrintf("%s ", vMerkleTree[i].ToString());
- LogPrintf("\n");
+ s << " " << vMerkleTree[i].ToString();
+ s << "\n";
+ return s.str();
}
diff --git a/src/core.h b/src/core.h
index fb64e6c08e..e3ceac97aa 100644
--- a/src/core.h
+++ b/src/core.h
@@ -14,6 +14,9 @@
class CTransaction;
+static const int64_t COIN = 100000000;
+static const int64_t CENT = 1000000;
+
/** No amount larger than this (in satoshi) is valid */
static const int64_t MAX_MONEY = 21000000 * COIN;
inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
@@ -47,7 +50,6 @@ public:
}
std::string ToString() const;
- void print() const;
};
/** An inpoint - a combination of a transaction and an index n into its vin */
@@ -107,7 +109,6 @@ public:
}
std::string ToString() const;
- void print() const;
};
@@ -200,7 +201,6 @@ public:
}
std::string ToString() const;
- void print() const;
};
@@ -279,7 +279,6 @@ public:
}
std::string ToString() const;
- void print() const;
};
/** A mutable version of CTransaction. */
@@ -497,7 +496,7 @@ public:
std::vector<uint256> GetMerkleBranch(int nIndex) const;
static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
- void print() const;
+ std::string ToString() const;
};
diff --git a/src/core_write.cpp b/src/core_write.cpp
index 37dd69f7b8..b395b5c090 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -8,6 +8,7 @@
#include "core.h"
#include "serialize.h"
#include "util.h"
+#include "utilmoneystr.h"
#include "base58.h"
using namespace std;
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 4c43e3a798..8aa2bb0517 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -5,6 +5,7 @@
#include "crypter.h"
#include "script.h"
+#include "util.h"
#include <string>
#include <vector>
@@ -152,6 +153,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
if (!SetCrypted())
return false;
+ bool keyPass = false;
+ bool keyFail = false;
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
for (; mi != mapCryptedKeys.end(); ++mi)
{
@@ -159,16 +162,35 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CKeyingMaterial vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- return false;
+ {
+ keyFail = true;
+ break;
+ }
if (vchSecret.size() != 32)
- return false;
+ {
+ keyFail = true;
+ break;
+ }
CKey key;
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- if (key.GetPubKey() == vchPubKey)
+ if (key.GetPubKey() != vchPubKey)
+ {
+ keyFail = true;
break;
- return false;
+ }
+ keyPass = true;
+ if (fDecryptionThoroughlyChecked)
+ break;
+ }
+ if (keyPass && keyFail)
+ {
+ LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.");
+ assert(false);
}
+ if (keyFail || !keyPass)
+ return false;
vMasterKey = vMasterKeyIn;
+ fDecryptionThoroughlyChecked = true;
}
NotifyStatusChanged(this);
return true;
diff --git a/src/crypter.h b/src/crypter.h
index 4791428b48..f16fcef9c7 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -121,6 +121,9 @@ private:
// if fUseCrypto is false, vMasterKey must be empty
bool fUseCrypto;
+ // keeps track of whether Unlock has run a thourough check before
+ bool fDecryptionThoroughlyChecked;
+
protected:
bool SetCrypted();
@@ -130,7 +133,7 @@ protected:
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
public:
- CCryptoKeyStore() : fUseCrypto(false)
+ CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false)
{
}
diff --git a/src/db.cpp b/src/db.cpp
index eb40f3cc40..8c139843a1 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -9,6 +9,7 @@
#include "hash.h"
#include "protocol.h"
#include "util.h"
+#include "utilstrencodings.h"
#include <stdint.h>
@@ -17,6 +18,7 @@
#endif
#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
#include <boost/version.hpp>
#include <openssl/rand.h>
diff --git a/src/db.h b/src/db.h
index 66d7f31917..bba267b84f 100644
--- a/src/db.h
+++ b/src/db.h
@@ -17,7 +17,6 @@
#include <boost/filesystem/path.hpp>
#include <db_cxx.h>
-class CAddrMan;
struct CBlockLocator;
class CDiskBlockIndex;
class COutPoint;
diff --git a/src/init.cpp b/src/init.cpp
index 8ae228bbbe..e972413c4b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -19,6 +19,7 @@
#include "txdb.h"
#include "ui_interface.h"
#include "util.h"
+#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
#include "db.h"
#include "wallet.h"
@@ -36,6 +37,7 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/thread.hpp>
#include <openssl/crypto.h>
using namespace boost;
@@ -247,7 +249,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n";
strUsage += " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n";
strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n";
- strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n";
+ strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
strUsage += " -permitbaremultisig " + _("Relay non-P2SH multisig (default: 1)") + "\n";
strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n";
strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
@@ -1029,8 +1031,7 @@ bool AppInit2(boost::thread_group& threadGroup)
CBlock block;
ReadBlockFromDisk(block, pindex);
block.BuildMerkleTree();
- block.print();
- LogPrintf("\n");
+ LogPrintf("%s\n", block.ToString());
nFound++;
}
}
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 2a4c88d565..c6322eadce 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -8,6 +8,7 @@
#include "crypter.h"
#include "key.h"
#include "script.h"
+#include "util.h"
#include <boost/foreach.hpp>
diff --git a/src/keystore.h b/src/keystore.h
index 72411a1387..6a3a0dc13e 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -8,21 +8,12 @@
#include "key.h"
#include "sync.h"
-#include "script.h" // for CNoDestination
#include <boost/signals2/signal.hpp>
#include <boost/variant.hpp>
class CScript;
-/** A txout script template with a specific destination. It is either:
- * * CNoDestination: no destination set
- * * CKeyID: TX_PUBKEYHASH destination
- * * CScriptID: TX_SCRIPTHASH destination
- * A CTxDestination is the internal data type encoded in a CBitcoinAddress
- */
-typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
-
/** A virtual base class for key stores */
class CKeyStore
{
diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h
index 043a56bf38..452df92839 100644
--- a/src/leveldbwrapper.h
+++ b/src/leveldbwrapper.h
@@ -82,7 +82,7 @@ public:
CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~CLevelDBWrapper();
- template<typename K, typename V> bool Read(const K& key, V& value) throw(leveldb_error) {
+ template<typename K, typename V> bool Read(const K& key, V& value) const throw(leveldb_error) {
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key;
@@ -111,7 +111,7 @@ public:
return WriteBatch(batch, fSync);
}
- template<typename K> bool Exists(const K& key) throw(leveldb_error) {
+ template<typename K> bool Exists(const K& key) const throw(leveldb_error) {
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key;
diff --git a/src/m4/ax_boost_base.m4 b/src/m4/ax_boost_base.m4
index e025a7e1ca..3f24d5ddc6 100644
--- a/src/m4/ax_boost_base.m4
+++ b/src/m4/ax_boost_base.m4
@@ -112,6 +112,12 @@ if test "x$want_boost" = "xyes"; then
;;
esac
+ dnl some arches may advertise a cpu type that doesn't line up with their
+ dnl prefix's cpu type. For example, uname may report armv7l while libs are
+ dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's
+ dnl value for an extra chance of finding the correct path.
+ libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs"
+
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
diff --git a/src/m4/bitcoin_find_bdb48.m4 b/src/m4/bitcoin_find_bdb48.m4
index 72ec49b635..5223163fe5 100644
--- a/src/m4/bitcoin_find_bdb48.m4
+++ b/src/m4/bitcoin_find_bdb48.m4
@@ -44,7 +44,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[
AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[
AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!])
],[
- AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore)])
+ AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)])
])
else
BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx)
@@ -60,7 +60,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[
])
done
if test "x$BDB_LIBS" = "x"; then
- AC_MSG_ERROR(libdb_cxx missing)
+ AC_MSG_ERROR([libdb_cxx missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)])
fi
AC_SUBST(BDB_LIBS)
])
diff --git a/src/m4/bitcoin_qt.m4 b/src/m4/bitcoin_qt.m4
index 4c1d40c394..e141033b19 100644
--- a/src/m4/bitcoin_qt.m4
+++ b/src/m4/bitcoin_qt.m4
@@ -48,8 +48,8 @@ dnl CAUTION: Do not use this inside of a conditional.
AC_DEFUN([BITCOIN_QT_INIT],[
dnl enable qt support
AC_ARG_WITH([gui],
- [AS_HELP_STRING([--with-gui],
- [with GUI (no|qt4|qt5|auto. default is auto, qt4 tried first.)])],
+ [AS_HELP_STRING([--with-gui@<:@=no|qt4|qt5|auto@:>@],
+ [build bitcoin-qt GUI (default=auto, qt4 tried first)])],
[
bitcoin_qt_want_version=$withval
if test x$bitcoin_qt_want_version = xyes; then
@@ -112,11 +112,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
if test x$qt_plugin_path != x; then
QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
- if test x$bitcoin_qt_got_major_vers == x5; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
- else
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
- fi
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
fi
if test x$use_pkgconfig = xyes; then
PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"])
@@ -141,6 +137,10 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
else
if test x$TARGET_OS == xwindows; then
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
+ fi
_BITCOIN_QT_CHECK_STATIC_PLUGINS([
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
diff --git a/src/main.cpp b/src/main.cpp
index ba521b6b19..6567c77e93 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,9 +20,11 @@
#include <sstream>
+#include <boost/dynamic_bitset.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <boost/thread.hpp>
using namespace std;
using namespace boost;
@@ -643,7 +645,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
// 2. P2SH scripts with a crazy number of expensive
// CHECKSIG/CHECKMULTISIG operations
//
-bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs)
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase())
return true; // Coinbases don't use vin normally
@@ -716,7 +718,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx)
return nSigOps;
}
-unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
+unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
{
if (tx.IsCoinBase())
return 0;
@@ -956,9 +958,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (Params().RequireStandard() && !AreInputsStandard(tx, view))
return error("AcceptToMemoryPool: : nonstandard transaction input");
- // Note: if you modify this code to accept non-standard transactions, then
- // you should add code here to check that the transaction does a
- // reasonable number of ECDSA signature verifications.
+ // Check that the transaction doesn't have an excessive number of
+ // sigops, making it impossible to mine. Since the coinbase transaction
+ // itself can contain sigops MAX_TX_SIGOPS is less than
+ // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
+ // merely non-standard transaction.
+ unsigned int nSigOps = GetLegacySigOpCount(tx);
+ nSigOps += GetP2SHSigOpCount(tx, view);
+ if (nSigOps > MAX_TX_SIGOPS)
+ return state.DoS(0,
+ error("AcceptToMemoryPool : too many sigops %s, %d > %d",
+ hash.ToString(), nSigOps, MAX_TX_SIGOPS),
+ REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
int64_t nValueOut = tx.GetValueOut();
int64_t nFees = nValueIn-nValueOut;
@@ -1013,7 +1024,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
pool.addUnchecked(hash, entry);
}
- g_signals.SyncTransaction(tx, NULL);
+ SyncWithWallets(tx, NULL);
return true;
}
@@ -1460,7 +1471,7 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
}
-bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
{
if (!tx.IsCoinBase())
{
@@ -1848,10 +1859,6 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
- // Watch for transactions paying to me
- BOOST_FOREACH(const CTransaction& tx, block.vtx)
- g_signals.SyncTransaction(tx, &block);
-
// Watch for changes to the previous coinbase transaction.
static uint256 hashPrevBestCoinBase;
g_signals.UpdatedTransaction(hashPrevBestCoinBase);
@@ -3052,7 +3059,7 @@ bool CVerifyDB::VerifyDB(int nCheckLevel, int nCheckDepth)
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
- if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) {
+ if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
bool fClean = true;
if (!DisconnectBlock(block, state, pindex, coins, &fClean))
return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
@@ -3228,7 +3235,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
uint64_t nRewind = blkdat.GetPos();
- while (blkdat.good() && !blkdat.eof()) {
+ while (!blkdat.eof()) {
boost::this_thread::interruption_point();
blkdat.SetPos(nRewind);
@@ -3512,6 +3519,75 @@ void static ProcessGetData(CNode* pfrom)
}
}
+struct CCoin {
+ uint32_t nTxVer; // Don't call this nVersion, that name has a special meaning inside IMPLEMENT_SERIALIZE
+ uint32_t nHeight;
+ CTxOut out;
+
+ IMPLEMENT_SERIALIZE(
+ READWRITE(nTxVer);
+ READWRITE(nHeight);
+ READWRITE(out);
+ )
+};
+
+bool ProcessGetUTXOs(const vector<COutPoint> &vOutPoints, bool fCheckMemPool, vector<unsigned char> *result, vector<CCoin> *resultCoins)
+{
+ // Defined by BIP 64.
+ //
+ // Allows a peer to retrieve the CTxOut structures corresponding to the given COutPoints.
+ // Note that this data is not authenticated by anything: this code could just invent any
+ // old rubbish and hand it back, with the peer being unable to tell unless they are checking
+ // the outpoints against some out of band data.
+ //
+ // Also the answer could change the moment after we give it. However some apps can tolerate
+ // this, because they're only using the result as a hint or are willing to trust the results
+ // based on something else. For example we may be a "trusted node" for the peer, or it may
+ // be checking the results given by several nodes for consistency, it may
+ // run the UTXOs returned against scriptSigs of transactions obtained elsewhere (after checking
+ // for a standard script form), and because the height in which the UTXO was defined is provided
+ // a client that has a map of heights to block headers (as SPV clients do, for recent blocks)
+ // can request the creating block via hash.
+ //
+ // IMPORTANT: Clients expect ordering to be preserved!
+ if (vOutPoints.size() > MAX_INV_SZ)
+ return error("message getutxos size() = %u", vOutPoints.size());
+
+ LogPrint("net", "getutxos for %d queries %s mempool\n", vOutPoints.size(), fCheckMemPool ? "with" : "without");
+
+ boost::dynamic_bitset<unsigned char> hits(vOutPoints.size());
+ {
+ LOCK2(cs_main, mempool.cs);
+ CCoinsViewMemPool cvMemPool(*pcoinsTip, mempool);
+ CCoinsViewCache view(fCheckMemPool ? cvMemPool : *pcoinsTip);
+ for (size_t i = 0; i < vOutPoints.size(); i++)
+ {
+ CCoins coins;
+ uint256 hash = vOutPoints[i].hash;
+ if (view.GetCoins(hash, coins))
+ {
+ mempool.pruneSpent(hash, coins);
+ if (coins.IsAvailable(vOutPoints[i].n))
+ {
+ hits[i] = true;
+ // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if
+ // n is valid but points to an already spent output (IsNull).
+ CCoin coin;
+ coin.nTxVer = coins.nVersion;
+ coin.nHeight = coins.nHeight;
+ coin.out = coins.vout.at(vOutPoints[i].n);
+ assert(!coin.out.IsNull());
+ resultCoins->push_back(coin);
+ }
+ }
+ }
+ }
+
+ boost::to_block_range(hits, std::back_inserter(*result));
+ return true;
+}
+
+
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
@@ -3559,7 +3635,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (!vRecv.empty())
vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) {
- vRecv >> pfrom->strSubVer;
+ vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
}
if (!vRecv.empty())
@@ -3860,6 +3936,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
+ else if (strCommand == "getutxos")
+ {
+ bool fCheckMemPool;
+ vector<COutPoint> vOutPoints;
+ vRecv >> fCheckMemPool;
+ vRecv >> vOutPoints;
+
+ vector<unsigned char> bitmap;
+ vector<CCoin> outs;
+ if (ProcessGetUTXOs(vOutPoints, fCheckMemPool, &bitmap, &outs))
+ pfrom->PushMessage("utxos", chainActive.Height(), chainActive.Tip()->GetBlockHash(), bitmap, outs);
+ else
+ Misbehaving(pfrom->GetId(), 20);
+ }
+
+
else if (strCommand == "tx")
{
vector<uint256> vWorkQueue;
@@ -3959,7 +4051,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> block;
LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id);
- // block.print();
CInv inv(MSG_BLOCK, block.GetHash());
pfrom->AddInventoryKnown(inv);
@@ -4183,7 +4274,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (fDebug)
{
string strMsg; unsigned char ccode; string strReason;
- vRecv >> strMsg >> ccode >> strReason;
+ vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
ostringstream ss;
ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
@@ -4194,10 +4285,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> hash;
ss << ": hash " << hash.ToString();
}
- // Truncate to reasonable length and sanitize before printing:
- string s = ss.str();
- if (s.size() > 111) s.erase(111, string::npos);
- LogPrint("net", "Reject %s\n", SanitizeString(s));
+ LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
}
}
@@ -4568,7 +4656,68 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
}
+bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
+{
+ // Open history file to append
+ CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (!fileout)
+ return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(*this);
+ fileout << FLATDATA(Params().MessageStart()) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout);
+ if (fileOutPos < 0)
+ return error("CBlockUndo::WriteToDisk : ftell failed");
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << *this;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ fileout << hasher.GetHash();
+
+ // Flush stdio buffers and commit to disk before returning
+ fflush(fileout);
+ if (!IsInitialBlockDownload())
+ FileCommit(fileout);
+
+ return true;
+}
+
+bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (!filein)
+ return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> *this;
+ filein >> hashChecksum;
+ }
+ catch (std::exception &e) {
+ return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ if (hashChecksum != hasher.GetHash())
+ return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
+
+ return true;
+}
+ std::string CBlockFileInfo::ToString() const {
+ return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst).c_str(), DateTimeStrFormat("%Y-%m-%d", nTimeLast).c_str());
+ }
diff --git a/src/main.h b/src/main.h
index a27020459a..e5357cbfdd 100644
--- a/src/main.h
+++ b/src/main.h
@@ -45,6 +45,8 @@ static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** Maxiumum number of signature check operations in an IsStandard() P2SH script */
static const unsigned int MAX_P2SH_SIGOPS = 15;
+/** The maximum number of sigops we're willing to relay/mine in a single tx */
+static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
/** The maximum number of orphan transactions kept in memory */
static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */
@@ -263,7 +265,7 @@ int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return True if all inputs (scriptSigs) use only standard transaction forms
*/
-bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs);
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
/** Count ECDSA signature operations the old-fashioned (pre-0.6) way
@return number of sigops this transaction's outputs will produce when spent
@@ -277,13 +279,13 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
@return maximum number of sigops required to validate this transaction's inputs
@see CTransaction::FetchInputs
*/
-unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& mapInputs);
+unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);
// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
// instead of being performed inline.
-bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true,
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true,
unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS,
std::vector<CScriptCheck> *pvChecks = NULL);
@@ -310,64 +312,8 @@ public:
READWRITE(vtxundo);
)
- bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
- {
- // Open history file to append
- CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (!fileout)
- return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
-
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(Params().MessageStart()) << nSize;
-
- // Write undo data
- long fileOutPos = ftell(fileout);
- if (fileOutPos < 0)
- return error("CBlockUndo::WriteToDisk : ftell failed");
- pos.nPos = (unsigned int)fileOutPos;
- fileout << *this;
-
- // calculate & write checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- fileout << hasher.GetHash();
-
- // Flush stdio buffers and commit to disk before returning
- fflush(fileout);
- if (!IsInitialBlockDownload())
- FileCommit(fileout);
-
- return true;
- }
-
- bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
- {
- // Open history file to read
- CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (!filein)
- return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
-
- // Read block
- uint256 hashChecksum;
- try {
- filein >> *this;
- filein >> hashChecksum;
- }
- catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
- }
-
- // Verify checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- if (hashChecksum != hasher.GetHash())
- return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
-
- return true;
- }
+ bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock);
+ bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock);
};
@@ -623,9 +569,7 @@ public:
SetNull();
}
- std::string ToString() const {
- return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst).c_str(), DateTimeStrFormat("%Y-%m-%d", nTimeLast).c_str());
- }
+ std::string ToString() const;
// update statistics (does not update nSize)
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
@@ -837,11 +781,6 @@ public:
GetBlockHash().ToString());
}
- void print() const
- {
- LogPrintf("%s\n", ToString());
- }
-
// Check whether this block index entry is valid up to the passed validity level.
bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
{
@@ -933,11 +872,6 @@ public:
hashPrev.ToString());
return str;
}
-
- void print() const
- {
- LogPrintf("%s\n", ToString());
- }
};
/** Capture information about block/transaction validation */
diff --git a/src/miner.cpp b/src/miner.cpp
index ec56c71192..8696edcf6e 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -3,8 +3,6 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <inttypes.h>
-
#include "miner.h"
#include "core.h"
@@ -12,10 +10,14 @@
#include "main.h"
#include "net.h"
#include "pow.h"
+#include "util.h"
+#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
+#include <boost/thread.hpp>
+
using namespace std;
//////////////////////////////////////////////////////////////////////////////
@@ -42,14 +44,6 @@ public:
COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
{
}
-
- void print() const
- {
- LogPrintf("COrphan(hash=%s, dPriority=%.1f, fee=%s)\n",
- ptx->GetHash().ToString(), dPriority, feeRate.ToString());
- BOOST_FOREACH(uint256 hash, setDependsOn)
- LogPrintf(" setDependsOn %s\n", hash.ToString());
- }
};
uint64_t nLastBlockTx = 0;
@@ -402,18 +396,9 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
return CreateNewBlock(scriptPubKey);
}
-bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
+bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
- uint256 hash = pblock->GetHash();
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
-
- if (hash > hashTarget)
- return false;
-
- //// debug print
- LogPrintf("BitcoinMiner:\n");
- LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
- pblock->print();
+ LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
// Found a solution
@@ -500,7 +485,9 @@ void static BitcoinMiner(CWallet *pwallet)
assert(hash == pblock->GetHash());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
- CheckWork(pblock, *pwallet, reservekey);
+ LogPrintf("BitcoinMiner:\n");
+ LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
+ ProcessBlockFound(pblock, *pwallet, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
// In regression test mode, stop mining after a block is found.
diff --git a/src/net.cpp b/src/net.cpp
index 62124514c8..e2adba8517 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -28,6 +28,7 @@
#endif
#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
// Dump addresses to peers.dat every 15 minutes (900s)
#define DUMP_ADDRESSES_INTERVAL 900
@@ -66,7 +67,7 @@ namespace {
//
bool fDiscover = true;
bool fListen = true;
-uint64_t nLocalServices = NODE_NETWORK;
+uint64_t nLocalServices = NODE_NETWORK | NODE_GETUTXOS;
CCriticalSection cs_mapLocalHost;
map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
@@ -307,12 +308,18 @@ bool IsLocal(const CService& addr)
return mapLocalHost.count(addr) > 0;
}
+/** check whether a given network is one we can probably connect to */
+bool IsReachable(enum Network net)
+{
+ LOCK(cs_mapLocalHost);
+ return vfReachable[net] && !vfLimited[net];
+}
+
/** check whether a given address is in a network we can probably connect to */
bool IsReachable(const CNetAddr& addr)
{
- LOCK(cs_mapLocalHost);
enum Network net = addr.GetNetwork();
- return vfReachable[net] && !vfLimited[net];
+ return IsReachable(net);
}
bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
@@ -368,7 +375,7 @@ bool GetMyExternalIP(CNetAddr& ipRet)
const char* pszKeyword;
for (int nLookup = 0; nLookup <= 1; nLookup++)
- for (int nHost = 1; nHost <= 2; nHost++)
+ for (int nHost = 1; nHost <= 1; nHost++)
{
// We should be phasing out our use of sites like these. If we need
// replacements, we should ask for volunteers to put this simple
@@ -393,25 +400,6 @@ bool GetMyExternalIP(CNetAddr& ipRet)
pszKeyword = "Address:";
}
- else if (nHost == 2)
- {
- addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
-
- if (nLookup == 1)
- {
- CService addrIP("www.showmyip.com", 80, true);
- if (addrIP.IsValid())
- addrConnect = addrIP;
- }
-
- pszGet = "GET /simple/ HTTP/1.1\r\n"
- "Host: www.showmyip.com\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
- "Connection: close\r\n"
- "\r\n";
-
- pszKeyword = NULL; // Returns just IP address
- }
if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
return true;
@@ -2050,3 +2038,157 @@ bool CAddrDB::Read(CAddrMan& addr)
return true;
}
+
+unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
+unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
+
+CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
+{
+ nServices = 0;
+ hSocket = hSocketIn;
+ nRecvVersion = INIT_PROTO_VERSION;
+ nLastSend = 0;
+ nLastRecv = 0;
+ nSendBytes = 0;
+ nRecvBytes = 0;
+ nTimeConnected = GetTime();
+ addr = addrIn;
+ addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
+ nVersion = 0;
+ strSubVer = "";
+ fWhitelisted = false;
+ fOneShot = false;
+ fClient = false; // set by version message
+ fInbound = fInboundIn;
+ fNetworkNode = false;
+ fSuccessfullyConnected = false;
+ fDisconnect = false;
+ nRefCount = 0;
+ nSendSize = 0;
+ nSendOffset = 0;
+ hashContinue = 0;
+ pindexLastGetBlocksBegin = 0;
+ hashLastGetBlocksEnd = 0;
+ nStartingHeight = -1;
+ fStartSync = false;
+ fGetAddr = false;
+ fRelayTxes = false;
+ setInventoryKnown.max_size(SendBufferSize() / 1000);
+ pfilter = new CBloomFilter();
+ nPingNonceSent = 0;
+ nPingUsecStart = 0;
+ nPingUsecTime = 0;
+ fPingQueued = false;
+
+ {
+ LOCK(cs_nLastNodeId);
+ id = nLastNodeId++;
+ }
+
+ if (fLogIPs)
+ LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
+ else
+ LogPrint("net", "Added connection peer=%d\n", id);
+
+ // Be shy and don't send version until we hear
+ if (hSocket != INVALID_SOCKET && !fInbound)
+ PushVersion();
+
+ GetNodeSignals().InitializeNode(GetId(), this);
+}
+
+CNode::~CNode()
+{
+ CloseSocket(hSocket);
+
+ if (pfilter)
+ delete pfilter;
+
+ GetNodeSignals().FinalizeNode(GetId());
+}
+
+void CNode::AskFor(const CInv& inv)
+{
+ // We're using mapAskFor as a priority queue,
+ // the key is the earliest time the request can be sent
+ int64_t nRequestTime;
+ limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
+ if (it != mapAlreadyAskedFor.end())
+ nRequestTime = it->second;
+ else
+ nRequestTime = 0;
+ LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str(), id);
+
+ // Make sure not to reuse time indexes to keep things in the same order
+ int64_t nNow = GetTimeMicros() - 1000000;
+ static int64_t nLastTime;
+ ++nLastTime;
+ nNow = std::max(nNow, nLastTime);
+ nLastTime = nNow;
+
+ // Each retry is 2 minutes after the last
+ nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
+ if (it != mapAlreadyAskedFor.end())
+ mapAlreadyAskedFor.update(it, nRequestTime);
+ else
+ mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
+ mapAskFor.insert(std::make_pair(nRequestTime, inv));
+}
+
+void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
+{
+ ENTER_CRITICAL_SECTION(cs_vSend);
+ assert(ssSend.size() == 0);
+ ssSend << CMessageHeader(pszCommand, 0);
+ LogPrint("net", "sending: %s ", pszCommand);
+}
+
+void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
+{
+ ssSend.clear();
+
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+
+ LogPrint("net", "(aborted)\n");
+}
+
+void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
+{
+ // The -*messagestest options are intentionally not documented in the help message,
+ // since they are only used during development to debug the networking code and are
+ // not intended for end-users.
+ if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
+ {
+ LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
+ AbortMessage();
+ return;
+ }
+ if (mapArgs.count("-fuzzmessagestest"))
+ Fuzz(GetArg("-fuzzmessagestest", 10));
+
+ if (ssSend.size() == 0)
+ return;
+
+ // Set the size
+ unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
+ memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
+
+ // Set the checksum
+ uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
+ unsigned int nChecksum = 0;
+ memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
+ memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
+
+ LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
+
+ std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
+ ssSend.GetAndClear(*it);
+ nSendSize += (*it).size();
+
+ // If write queue empty, attempt "optimistic write"
+ if (it == vSendMsg.begin())
+ SocketSendData(this);
+
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+}
diff --git a/src/net.h b/src/net.h
index a8795a4760..bfad32b2c1 100644
--- a/src/net.h
+++ b/src/net.h
@@ -16,7 +16,7 @@
#include "random.h"
#include "sync.h"
#include "uint256.h"
-#include "util.h"
+#include "utilstrencodings.h"
#include <deque>
#include <stdint.h>
@@ -25,6 +25,7 @@
#include <arpa/inet.h>
#endif
+#include <boost/filesystem/path.hpp>
#include <boost/foreach.hpp>
#include <boost/signals2/signal.hpp>
@@ -51,8 +52,8 @@ static const bool DEFAULT_UPNP = USE_UPNP;
static const bool DEFAULT_UPNP = false;
#endif
-inline unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
-inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
+unsigned int ReceiveFloodSize();
+unsigned int SendBufferSize();
void AddOneShot(std::string strDest);
bool RecvLine(SOCKET hSocket, std::string& strLine);
@@ -106,6 +107,7 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
bool SeenLocal(const CService& addr);
bool IsLocal(const CService& addr);
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
+bool IsReachable(enum Network net);
bool IsReachable(const CNetAddr &addr);
void SetReachable(enum Network net, bool fFlag = true);
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
@@ -299,70 +301,8 @@ public:
// Whether a ping is requested.
bool fPingQueued;
- CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), setAddrKnown(5000)
- {
- nServices = 0;
- hSocket = hSocketIn;
- nRecvVersion = INIT_PROTO_VERSION;
- nLastSend = 0;
- nLastRecv = 0;
- nSendBytes = 0;
- nRecvBytes = 0;
- nTimeConnected = GetTime();
- addr = addrIn;
- addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
- nVersion = 0;
- strSubVer = "";
- fWhitelisted = false;
- fOneShot = false;
- fClient = false; // set by version message
- fInbound = fInboundIn;
- fNetworkNode = false;
- fSuccessfullyConnected = false;
- fDisconnect = false;
- nRefCount = 0;
- nSendSize = 0;
- nSendOffset = 0;
- hashContinue = 0;
- pindexLastGetBlocksBegin = 0;
- hashLastGetBlocksEnd = 0;
- nStartingHeight = -1;
- fStartSync = false;
- fGetAddr = false;
- fRelayTxes = false;
- setInventoryKnown.max_size(SendBufferSize() / 1000);
- pfilter = new CBloomFilter();
- nPingNonceSent = 0;
- nPingUsecStart = 0;
- nPingUsecTime = 0;
- fPingQueued = false;
-
- {
- LOCK(cs_nLastNodeId);
- id = nLastNodeId++;
- }
-
- if (fLogIPs)
- LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
- else
- LogPrint("net", "Added connection peer=%d\n", id);
-
- // Be shy and don't send version until we hear
- if (hSocket != INVALID_SOCKET && !fInbound)
- PushVersion();
-
- GetNodeSignals().InitializeNode(GetId(), this);
- }
-
- ~CNode()
- {
- CloseSocket(hSocket);
-
- if (pfilter)
- delete pfilter;
-
- GetNodeSignals().FinalizeNode(GetId());
- }
+ CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
+ ~CNode();
private:
// Network usage totals
@@ -451,96 +391,16 @@ public:
}
}
- void AskFor(const CInv& inv)
- {
- // We're using mapAskFor as a priority queue,
- // the key is the earliest time the request can be sent
- int64_t nRequestTime;
- limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
- if (it != mapAlreadyAskedFor.end())
- nRequestTime = it->second;
- else
- nRequestTime = 0;
- LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str(), id);
-
- // Make sure not to reuse time indexes to keep things in the same order
- int64_t nNow = GetTimeMicros() - 1000000;
- static int64_t nLastTime;
- ++nLastTime;
- nNow = std::max(nNow, nLastTime);
- nLastTime = nNow;
-
- // Each retry is 2 minutes after the last
- nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
- if (it != mapAlreadyAskedFor.end())
- mapAlreadyAskedFor.update(it, nRequestTime);
- else
- mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
- mapAskFor.insert(std::make_pair(nRequestTime, inv));
- }
-
-
+ void AskFor(const CInv& inv);
// TODO: Document the postcondition of this function. Is cs_vSend locked?
- void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
- {
- ENTER_CRITICAL_SECTION(cs_vSend);
- assert(ssSend.size() == 0);
- ssSend << CMessageHeader(pszCommand, 0);
- LogPrint("net", "sending: %s ", pszCommand);
- }
+ void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
// TODO: Document the precondition of this function. Is cs_vSend locked?
- void AbortMessage() UNLOCK_FUNCTION(cs_vSend)
- {
- ssSend.clear();
-
- LEAVE_CRITICAL_SECTION(cs_vSend);
-
- LogPrint("net", "(aborted)\n");
- }
+ void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
// TODO: Document the precondition of this function. Is cs_vSend locked?
- void EndMessage() UNLOCK_FUNCTION(cs_vSend)
- {
- // The -*messagestest options are intentionally not documented in the help message,
- // since they are only used during development to debug the networking code and are
- // not intended for end-users.
- if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
- {
- LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
- AbortMessage();
- return;
- }
- if (mapArgs.count("-fuzzmessagestest"))
- Fuzz(GetArg("-fuzzmessagestest", 10));
-
- if (ssSend.size() == 0)
- return;
-
- // Set the size
- unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
- memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
-
- // Set the checksum
- uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
- assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
- memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
-
- LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
-
- std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
- ssSend.GetAndClear(*it);
- nSendSize += (*it).size();
-
- // If write queue empty, attempt "optimistic write"
- if (it == vSendMsg.begin())
- SocketSendData(this);
-
- LEAVE_CRITICAL_SECTION(cs_vSend);
- }
+ void EndMessage() UNLOCK_FUNCTION(cs_vSend);
void PushVersion();
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 1031e7e38a..d5821d4465 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -13,6 +13,7 @@
#include "sync.h"
#include "uint256.h"
#include "util.h"
+#include "utilstrencodings.h"
#ifdef HAVE_GETADDRINFO_A
#include <netdb.h>
@@ -27,6 +28,7 @@
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
+#include <boost/thread.hpp>
#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
@@ -47,10 +49,20 @@ enum Network ParseNetwork(std::string net) {
boost::to_lower(net);
if (net == "ipv4") return NET_IPV4;
if (net == "ipv6") return NET_IPV6;
- if (net == "tor") return NET_TOR;
+ if (net == "tor" || net == "onion") return NET_TOR;
return NET_UNROUTABLE;
}
+std::string GetNetworkName(enum Network net) {
+ switch(net)
+ {
+ case NET_IPV4: return "ipv4";
+ case NET_IPV6: return "ipv6";
+ case NET_TOR: return "onion";
+ default: return "";
+ }
+}
+
void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
size_t colon = in.find_last_of(':');
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
@@ -864,11 +876,6 @@ uint64_t CNetAddr::GetHash() const
return nRet;
}
-void CNetAddr::print() const
-{
- LogPrintf("CNetAddr(%s)\n", ToString());
-}
-
// private extensions to enum Network, only returned by GetExtNetwork,
// and only used in GetReachabilityFrom
static const int NET_UNKNOWN = NET_MAX + 0;
@@ -1097,11 +1104,6 @@ std::string CService::ToString() const
return ToStringIPPort();
}
-void CService::print() const
-{
- LogPrintf("CService(%s)\n", ToString());
-}
-
void CService::SetPort(unsigned short portIn)
{
port = portIn;
diff --git a/src/netbase.h b/src/netbase.h
index 7d83e35344..2df3c4474d 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -26,7 +26,7 @@ extern bool fNameLookup;
enum Network
{
- NET_UNROUTABLE,
+ NET_UNROUTABLE = 0,
NET_IPV4,
NET_IPV6,
NET_TOR,
@@ -80,7 +80,6 @@ class CNetAddr
bool GetInAddr(struct in_addr* pipv4Addr) const;
std::vector<unsigned char> GetGroup() const;
int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
- void print() const;
CNetAddr(const struct in6_addr& pipv6Addr);
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
@@ -145,7 +144,6 @@ class CService : public CNetAddr
std::string ToString() const;
std::string ToStringPort() const;
std::string ToStringIPPort() const;
- void print() const;
CService(const struct in6_addr& ipv6Addr, unsigned short port);
CService(const struct sockaddr_in6& addr);
@@ -164,6 +162,7 @@ class CService : public CNetAddr
typedef CService proxyType;
enum Network ParseNetwork(std::string net);
+std::string GetNetworkName(enum Network net);
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
bool SetProxy(enum Network net, CService addrProxy);
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
diff --git a/src/noui.cpp b/src/noui.cpp
index 32c861b0d9..8b00fd4057 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -8,6 +8,7 @@
#include "ui_interface.h"
#include "util.h"
+#include <cstdio>
#include <stdint.h>
#include <string>
diff --git a/src/pow.cpp b/src/pow.cpp
index c0d0a7ca20..b091cbec3d 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -9,6 +9,7 @@
#include "core.h"
#include "main.h"
#include "uint256.h"
+#include "util.h"
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 87b2f23873..341de0602a 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -144,9 +144,3 @@ std::string CInv::ToString() const
{
return strprintf("%s %s", GetCommand(), hash.ToString());
}
-
-void CInv::print() const
-{
- LogPrintf("CInv(%s)\n", ToString());
-}
-
diff --git a/src/protocol.h b/src/protocol.h
index 1f23274299..94d313e9c0 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -64,6 +64,7 @@ class CMessageHeader
enum
{
NODE_NETWORK = (1 << 0),
+ NODE_GETUTXOS = (1 << 1),
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that
// isn't getting used, or one not being used much, and notify the
@@ -98,8 +99,6 @@ class CAddress : public CService
READWRITE(*pip);
)
- void print() const;
-
// TODO: make private (improves encapsulation)
public:
uint64_t nServices;
@@ -130,7 +129,6 @@ class CInv
bool IsKnownType() const;
const char* GetCommand() const;
std::string ToString() const;
- void print() const;
// TODO: make private (improves encapsulation)
public:
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index c0dee66931..6cc6b99ceb 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -33,6 +33,7 @@
#include <stdint.h>
#include <boost/filesystem/operations.hpp>
+#include <boost/thread.hpp>
#include <QApplication>
#include <QDebug>
#include <QLibraryInfo>
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index 357c6470d3..6dba62035b 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -4,7 +4,6 @@
<file alias="address-book">res/icons/address-book.png</file>
<file alias="quit">res/icons/quit.png</file>
<file alias="send">res/icons/send.png</file>
- <file alias="toolbar">res/icons/toolbar.png</file>
<file alias="connect_0">res/icons/connect0_16.png</file>
<file alias="connect_1">res/icons/connect1_16.png</file>
<file alias="connect_2">res/icons/connect2_16.png</file>
@@ -24,7 +23,6 @@
<file alias="editcopy">res/icons/editcopy.png</file>
<file alias="add">res/icons/add.png</file>
<file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file>
- <file alias="toolbar_testnet">res/icons/toolbar_testnet.png</file>
<file alias="edit">res/icons/edit.png</file>
<file alias="history">res/icons/history.png</file>
<file alias="overview">res/icons/overview.png</file>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index e3665dfe6e..68d42ce64b 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -24,6 +24,7 @@
#endif
#include "init.h"
+#include "util.h"
#include "ui_interface.h"
#include <iostream>
@@ -508,12 +509,12 @@ void BitcoinGUI::createTrayIcon(bool fIsTestnet)
if (!fIsTestnet)
{
trayIcon->setToolTip(tr("Bitcoin Core client"));
- trayIcon->setIcon(QIcon(":/icons/toolbar"));
+ trayIcon->setIcon(QIcon(":/icons/bitcoin"));
}
else
{
trayIcon->setToolTip(tr("Bitcoin Core client") + " " + tr("[testnet]"));
- trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
+ trayIcon->setIcon(QIcon(":/icons/bitcoin_testnet"));
}
trayIcon->show();
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 4c21eb5594..9c9ff5b3a1 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -13,6 +13,7 @@
#include "main.h"
#include "net.h"
#include "ui_interface.h"
+#include "util.h"
#include <stdint.h>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index 7784a862d7..53d416ef38 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -13,8 +13,8 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QFormLayout" name="formLayout_3">
- <item row="0" column="0" colspan="2">
+ <layout class="QVBoxLayout" name="topLayout">
+ <item>
<widget class="QLabel" name="labelAlerts">
<property name="visible">
<bool>false</bool>
@@ -30,7 +30,7 @@
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 38fbc48a4d..304177ee11 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -124,6 +124,10 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
SendCoinsRecipient rv;
rv.address = uri.path();
+ // Trim any following forward slash which may have been added by the OS
+ if (rv.address.endsWith("/")) {
+ rv.address.truncate(rv.address.length() - 1);
+ }
rv.amount = 0;
#if QT_VERSION < 0x050000
@@ -377,12 +381,6 @@ void openDebugLogfile()
QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug)));
}
-ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
- QObject(parent), size_threshold(size_threshold)
-{
-
-}
-
void SubstituteFonts()
{
#if defined(Q_OS_MAC)
@@ -403,6 +401,13 @@ void SubstituteFonts()
#endif
}
+ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
+ QObject(parent),
+ size_threshold(size_threshold)
+{
+
+}
+
bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
{
if(evt->type() == QEvent::ToolTipChange)
@@ -805,7 +810,7 @@ QString formatDurationStr(int secs)
return strList.join(" ");
}
-QString formatServicesStr(uint64_t mask)
+QString formatServicesStr(quint64 mask)
{
QStringList strList;
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 83739a5f13..67e11e59a0 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -102,14 +102,13 @@ namespace GUIUtil
// Open debug.log
void openDebugLogfile();
+ // Replace invalid default fonts with known good ones
+ void SubstituteFonts();
+
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
representation if needed. This assures that Qt can word-wrap long tooltip messages.
Tooltips longer than the provided size threshold (in characters) are wrapped.
*/
-
- // Replace invalid default fonts with known good ones
- void SubstituteFonts();
-
class ToolTipToRichTextFilter : public QObject
{
Q_OBJECT
@@ -181,7 +180,7 @@ namespace GUIUtil
QString formatDurationStr(int secs);
/* Format CNodeStats.nServices bitmask into a user-readable string */
- QString formatServicesStr(uint64_t mask);
+ QString formatServicesStr(quint64 mask);
/* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/
QString formatPingTime(double dPingTime);
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index fd1d446f9b..c775a7f8d6 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -21,6 +21,7 @@
#include "wallet.h" // for CWallet::minTxFee
#endif
+#include <boost/thread.hpp>
#include <QDir>
#include <QIntValidator>
#include <QLocale>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index a9f1566d62..f6a4b599de 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -11,6 +11,7 @@
#include "base58.h"
#include "ui_interface.h"
+#include "util.h"
#include "wallet.h"
#include <cstdlib>
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index 54b46867ea..cfa05300cf 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -75,8 +75,14 @@ public:
}
// Try to retrieve the CNodeStateStats for each node.
- BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
- stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
+ {
+ TRY_LOCK(cs_main, lockMain);
+ if (lockMain)
+ {
+ BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
+ stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
+ }
+ }
if (sortColumn >= 0)
// sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
diff --git a/src/qt/res/icons/toolbar.png b/src/qt/res/icons/toolbar.png
deleted file mode 100644
index c82d96519c..0000000000
--- a/src/qt/res/icons/toolbar.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/res/icons/toolbar_testnet.png b/src/qt/res/icons/toolbar_testnet.png
deleted file mode 100644
index 5995bc0667..0000000000
--- a/src/qt/res/icons/toolbar_testnet.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 4f6e3169f5..8258e719a3 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -15,6 +15,7 @@
#include "transactionrecord.h"
#include "timedata.h"
#include "ui_interface.h"
+#include "util.h"
#include "wallet.h"
#include <stdint.h>
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 5fb0da145d..7df9d1bc2d 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -10,9 +10,10 @@
#include "clientmodel.h"
#include "guiutil.h"
-#include "clientversion.h"
#include "init.h"
-#include "util.h"
+#include "version.h"
+
+#include <stdio.h>
#include <QLabel>
#include <QRegExp>
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 0ad123f39d..c5f8fb6a9c 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -31,7 +31,6 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
transactionTableModel(0),
recentRequestsTableModel(0),
cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
- cachedNumTransactions(0),
cachedEncryptionStatus(Unencrypted),
cachedNumBlocks(0)
{
@@ -96,18 +95,6 @@ qint64 WalletModel::getWatchImmatureBalance() const
return wallet->GetImmatureWatchOnlyBalance();
}
-int WalletModel::getNumTransactions() const
-{
- int numTransactions = 0;
- {
- LOCK(wallet->cs_wallet);
- // the size of mapWallet contains the number of unique transaction IDs
- // (e.g. payments to yourself generate 2 transactions, but both share the same transaction ID)
- numTransactions = wallet->mapWallet.size();
- }
- return numTransactions;
-}
-
void WalletModel::updateStatus()
{
EncryptionStatus newEncryptionStatus = getEncryptionStatus();
@@ -169,13 +156,6 @@ void WalletModel::updateTransaction(const QString &hash, int status)
// Balance and number of transactions might have changed
checkBalanceChanged();
-
- int newNumTransactions = getNumTransactions();
- if(cachedNumTransactions != newNumTransactions)
- {
- cachedNumTransactions = newNumTransactions;
- emit numTransactionsChanged(newNumTransactions);
- }
}
void WalletModel::updateAddressBook(const QString &address, const QString &label,
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 2bb91d85a9..2a74a6aa79 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -131,7 +131,6 @@ public:
qint64 getWatchBalance() const;
qint64 getWatchUnconfirmedBalance() const;
qint64 getWatchImmatureBalance() const;
- int getNumTransactions() const;
EncryptionStatus getEncryptionStatus() const;
bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
@@ -214,7 +213,6 @@ private:
qint64 cachedWatchOnlyBalance;
qint64 cachedWatchUnconfBalance;
qint64 cachedWatchImmatureBalance;
- qint64 cachedNumTransactions;
EncryptionStatus cachedEncryptionStatus;
int cachedNumBlocks;
@@ -229,9 +227,6 @@ signals:
void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);
- // Number of transactions in wallet changed
- void numTransactionsChanged(int count);
-
// Encryption status of wallet changed
void encryptionStatusChanged(int status);
diff --git a/src/random.cpp b/src/random.cpp
index 0d20d205ac..22c942acc0 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -8,12 +8,14 @@
#ifdef WIN32
#include "compat.h" // for Windows API
#endif
+#include "serialize.h" // for begin_ptr(vec)
#include "util.h" // for LogPrint()
+#include "utilstrencodings.h" // for GetTime()
#ifndef WIN32
#include <sys/time.h>
#endif
-
+#include <limits>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 1e5198b85c..58cab14045 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -7,6 +7,7 @@
#include "main.h"
#include "rpcserver.h"
#include "sync.h"
+#include "util.h"
#include <stdint.h>
@@ -531,3 +532,27 @@ Value getchaintips(const Array& params, bool fHelp)
return res;
}
+
+Value getmempoolinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getmempoolinfo\n"
+ "\nReturns details on the active state of the TX memory pool.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"size\": xxxxx (numeric) Current tx count\n"
+ " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getmempoolinfo", "")
+ + HelpExampleRpc("getmempoolinfo", "")
+ );
+
+ Object ret;
+ ret.push_back(Pair("size", (int64_t) mempool.size()));
+ ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
+
+ return ret;
+}
+
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index ff2361482b..e68ddee040 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -7,6 +7,8 @@
#include "init.h"
#include "main.h"
#include "sync.h"
+#include "utiltime.h"
+#include "util.h"
#include "wallet.h"
#include <fstream>
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index edab427cbf..6e508abcda 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -11,6 +11,7 @@
#include "miner.h"
#include "pow.h"
#include "core_io.h"
+#include "util.h"
#ifdef ENABLE_WALLET
#include "db.h"
#include "wallet.h"
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index 88e7c4ab07..2baa481c4e 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -338,6 +338,26 @@ Value getnettotals(const Array& params, bool fHelp)
return obj;
}
+static Array GetNetworksInfo()
+{
+ Array networks;
+ for(int n=0; n<NET_MAX; ++n)
+ {
+ enum Network network = static_cast<enum Network>(n);
+ if(network == NET_UNROUTABLE)
+ continue;
+ proxyType proxy;
+ Object obj;
+ GetProxy(network, proxy);
+ obj.push_back(Pair("name", GetNetworkName(network)));
+ obj.push_back(Pair("limited", IsLimited(network)));
+ obj.push_back(Pair("reachable", IsReachable(network)));
+ obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.ToStringIPPort() : string()));
+ networks.push_back(obj);
+ }
+ return networks;
+}
+
Value getnetworkinfo(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -351,7 +371,13 @@ Value getnetworkinfo(const Array& params, bool fHelp)
" \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
" \"connections\": xxxxx, (numeric) the number of connections\n"
- " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
+ " \"networks\": [ (array) information per network\n"
+ " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
+ " \"limited\": xxx, (boolean) is the network limited using -onlynet?\n"
+ " \"reachable\": xxx, (boolean) is the network reachable?\n"
+ " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
+ " },\n"
+ " ],\n"
" \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
" \"localaddresses\": [, (array) list of local addresses\n"
" \"address\": \"xxxx\", (string) network address\n"
@@ -364,16 +390,13 @@ Value getnetworkinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getnetworkinfo", "")
);
- proxyType proxy;
- GetProxy(NET_IPV4, proxy);
-
Object obj;
obj.push_back(Pair("version", (int)CLIENT_VERSION));
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
obj.push_back(Pair("timeoffset", GetTimeOffset()));
obj.push_back(Pair("connections", (int)vNodes.size()));
- obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.ToStringIPPort() : string())));
+ obj.push_back(Pair("networks", GetNetworksInfo()));
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
Array localAddresses;
{
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
index 643208b3b6..808b9bbd2a 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -6,6 +6,10 @@
#include "rpcprotocol.h"
#include "util.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+#include "utiltime.h"
+#include "version.h"
#include <stdint.h>
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 763615120a..7cd704193d 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -738,9 +738,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
CValidationState state;
- if (AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees))
- SyncWithWallets(tx, NULL);
- else {
+ if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) {
if(state.IsInvalid())
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
else
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index e7ed73310c..c9133bd3d2 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -23,6 +23,7 @@
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
#include "json/json_spirit_writer_template.h"
using namespace boost;
@@ -82,6 +83,11 @@ void RPCTypeCheck(const Object& o,
}
}
+static inline int64_t roundint64(double d)
+{
+ return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
+}
+
int64_t AmountFromValue(const Value& value)
{
double dAmount = value.get_real();
@@ -135,11 +141,18 @@ vector<unsigned char> ParseHexO(const Object& o, string strKey)
string CRPCTable::help(string strCommand) const
{
string strRet;
+ string category;
set<rpcfn_type> setDone;
+ vector<pair<string, const CRPCCommand*> > vCommands;
+
for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
+ vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
+ sort(vCommands.begin(), vCommands.end());
+
+ BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
{
- const CRPCCommand *pcmd = mi->second;
- string strMethod = mi->first;
+ const CRPCCommand *pcmd = command.second;
+ string strMethod = pcmd->name;
// We already filter duplicates, but these deprecated screw up the sort order
if (strMethod.find("label") != string::npos)
continue;
@@ -162,8 +175,20 @@ string CRPCTable::help(string strCommand) const
// Help text is returned in an exception
string strHelp = string(e.what());
if (strCommand == "")
+ {
if (strHelp.find('\n') != string::npos)
strHelp = strHelp.substr(0, strHelp.find('\n'));
+
+ if (category != pcmd->category)
+ {
+ if (!category.empty())
+ strRet += "\n";
+ category = pcmd->category;
+ string firstLetter = category.substr(0,1);
+ boost::to_upper(firstLetter);
+ strRet += "== " + firstLetter + category.substr(1) + " ==\n";
+ }
+ }
strRet += strHelp + "\n";
}
}
@@ -213,103 +238,106 @@ Value stop(const Array& params, bool fHelp)
static const CRPCCommand vRPCCommands[] =
-{ // name actor (function) okSafeMode threadSafe reqWallet
- // ------------------------ ----------------------- ---------- ---------- ---------
+{ // category name actor (function) okSafeMode threadSafe reqWallet
+ // --------------------- ------------------------ ----------------------- ---------- ---------- ---------
/* Overall control/query calls */
- { "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
- { "help", &help, true, true, false },
- { "stop", &stop, true, true, false },
+ { "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
+ { "control", "help", &help, true, true, false },
+ { "control", "stop", &stop, true, true, false },
/* P2P networking */
- { "getnetworkinfo", &getnetworkinfo, true, false, false },
- { "addnode", &addnode, true, true, false },
- { "getaddednodeinfo", &getaddednodeinfo, true, true, false },
- { "getconnectioncount", &getconnectioncount, true, false, false },
- { "getnettotals", &getnettotals, true, true, false },
- { "getpeerinfo", &getpeerinfo, true, false, false },
- { "ping", &ping, true, false, false },
+ { "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
+ { "network", "addnode", &addnode, true, true, false },
+ { "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false },
+ { "network", "getconnectioncount", &getconnectioncount, true, false, false },
+ { "network", "getnettotals", &getnettotals, true, true, false },
+ { "network", "getpeerinfo", &getpeerinfo, true, false, false },
+ { "network", "ping", &ping, true, false, false },
/* Block chain and UTXO */
- { "getblockchaininfo", &getblockchaininfo, true, false, false },
- { "getbestblockhash", &getbestblockhash, true, false, false },
- { "getblockcount", &getblockcount, true, false, false },
- { "getblock", &getblock, true, false, false },
- { "getblockhash", &getblockhash, true, false, false },
- { "getchaintips", &getchaintips, true, false, false },
- { "getdifficulty", &getdifficulty, true, false, false },
- { "getrawmempool", &getrawmempool, true, false, false },
- { "gettxout", &gettxout, true, false, false },
- { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
- { "verifychain", &verifychain, true, false, false },
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false },
+ { "blockchain", "getbestblockhash", &getbestblockhash, true, false, false },
+ { "blockchain", "getblockcount", &getblockcount, true, false, false },
+ { "blockchain", "getblock", &getblock, true, false, false },
+ { "blockchain", "getblockhash", &getblockhash, true, false, false },
+ { "blockchain", "getchaintips", &getchaintips, true, false, false },
+ { "blockchain", "getdifficulty", &getdifficulty, true, false, false },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false },
+ { "blockchain", "getrawmempool", &getrawmempool, true, false, false },
+ { "blockchain", "gettxout", &gettxout, true, false, false },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
+ { "blockchain", "verifychain", &verifychain, true, false, false },
/* Mining */
- { "getblocktemplate", &getblocktemplate, true, false, false },
- { "getmininginfo", &getmininginfo, true, false, false },
- { "getnetworkhashps", &getnetworkhashps, true, false, false },
- { "prioritisetransaction", &prioritisetransaction, true, false, false },
- { "submitblock", &submitblock, true, true, false },
+ { "mining", "getblocktemplate", &getblocktemplate, true, false, false },
+ { "mining", "getmininginfo", &getmininginfo, true, false, false },
+ { "mining", "getnetworkhashps", &getnetworkhashps, true, false, false },
+ { "mining", "prioritisetransaction", &prioritisetransaction, true, false, false },
+ { "mining", "submitblock", &submitblock, true, true, false },
+
+#ifdef ENABLE_WALLET
+ /* Coin generation */
+ { "generating", "getgenerate", &getgenerate, true, false, false },
+ { "generating", "gethashespersec", &gethashespersec, true, false, false },
+ { "generating", "setgenerate", &setgenerate, true, true, false },
+#endif
/* Raw transactions */
- { "createrawtransaction", &createrawtransaction, true, false, false },
- { "decoderawtransaction", &decoderawtransaction, true, false, false },
- { "decodescript", &decodescript, true, false, false },
- { "getrawtransaction", &getrawtransaction, true, false, false },
- { "sendrawtransaction", &sendrawtransaction, false, false, false },
- { "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false },
+ { "rawtransactions", "decodescript", &decodescript, true, false, false },
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
/* Utility functions */
- { "createmultisig", &createmultisig, true, true , false },
- { "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
- { "verifymessage", &verifymessage, true, false, false },
- { "estimatefee", &estimatefee, true, true, false },
- { "estimatepriority", &estimatepriority, true, true, false },
+ { "util", "createmultisig", &createmultisig, true, true , false },
+ { "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
+ { "util", "verifymessage", &verifymessage, true, false, false },
+ { "util", "estimatefee", &estimatefee, true, true, false },
+ { "util", "estimatepriority", &estimatepriority, true, true, false },
#ifdef ENABLE_WALLET
/* Wallet */
- { "addmultisigaddress", &addmultisigaddress, true, false, true },
- { "backupwallet", &backupwallet, true, false, true },
- { "dumpprivkey", &dumpprivkey, true, false, true },
- { "dumpwallet", &dumpwallet, true, false, true },
- { "encryptwallet", &encryptwallet, true, false, true },
- { "getaccountaddress", &getaccountaddress, true, false, true },
- { "getaccount", &getaccount, true, false, true },
- { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
- { "getbalance", &getbalance, false, false, true },
- { "getnewaddress", &getnewaddress, true, false, true },
- { "getrawchangeaddress", &getrawchangeaddress, true, false, true },
- { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
- { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
- { "gettransaction", &gettransaction, false, false, true },
- { "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
- { "getwalletinfo", &getwalletinfo, false, false, true },
- { "importprivkey", &importprivkey, true, false, true },
- { "importwallet", &importwallet, true, false, true },
- { "importaddress", &importaddress, true, false, true },
- { "keypoolrefill", &keypoolrefill, true, false, true },
- { "listaccounts", &listaccounts, false, false, true },
- { "listaddressgroupings", &listaddressgroupings, false, false, true },
- { "listlockunspent", &listlockunspent, false, false, true },
- { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
- { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
- { "listsinceblock", &listsinceblock, false, false, true },
- { "listtransactions", &listtransactions, false, false, true },
- { "listunspent", &listunspent, false, false, true },
- { "lockunspent", &lockunspent, true, false, true },
- { "move", &movecmd, false, false, true },
- { "sendfrom", &sendfrom, false, false, true },
- { "sendmany", &sendmany, false, false, true },
- { "sendtoaddress", &sendtoaddress, false, false, true },
- { "setaccount", &setaccount, true, false, true },
- { "settxfee", &settxfee, true, false, true },
- { "signmessage", &signmessage, true, false, true },
- { "walletlock", &walletlock, true, false, true },
- { "walletpassphrasechange", &walletpassphrasechange, true, false, true },
- { "walletpassphrase", &walletpassphrase, true, false, true },
-
- /* Wallet-enabled mining */
- { "getgenerate", &getgenerate, true, false, false },
- { "gethashespersec", &gethashespersec, true, false, false },
- { "setgenerate", &setgenerate, true, true, false },
+ { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
+ { "wallet", "backupwallet", &backupwallet, true, false, true },
+ { "wallet", "dumpprivkey", &dumpprivkey, true, false, true },
+ { "wallet", "dumpwallet", &dumpwallet, true, false, true },
+ { "wallet", "encryptwallet", &encryptwallet, true, false, true },
+ { "wallet", "getaccountaddress", &getaccountaddress, true, false, true },
+ { "wallet", "getaccount", &getaccount, true, false, true },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
+ { "wallet", "getbalance", &getbalance, false, false, true },
+ { "wallet", "getnewaddress", &getnewaddress, true, false, true },
+ { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true },
+ { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
+ { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
+ { "wallet", "gettransaction", &gettransaction, false, false, true },
+ { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
+ { "wallet", "getwalletinfo", &getwalletinfo, false, false, true },
+ { "wallet", "importprivkey", &importprivkey, true, false, true },
+ { "wallet", "importwallet", &importwallet, true, false, true },
+ { "wallet", "importaddress", &importaddress, true, false, true },
+ { "wallet", "keypoolrefill", &keypoolrefill, true, false, true },
+ { "wallet", "listaccounts", &listaccounts, false, false, true },
+ { "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true },
+ { "wallet", "listlockunspent", &listlockunspent, false, false, true },
+ { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
+ { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
+ { "wallet", "listsinceblock", &listsinceblock, false, false, true },
+ { "wallet", "listtransactions", &listtransactions, false, false, true },
+ { "wallet", "listunspent", &listunspent, false, false, true },
+ { "wallet", "lockunspent", &lockunspent, true, false, true },
+ { "wallet", "move", &movecmd, false, false, true },
+ { "wallet", "sendfrom", &sendfrom, false, false, true },
+ { "wallet", "sendmany", &sendmany, false, false, true },
+ { "wallet", "sendtoaddress", &sendtoaddress, false, false, true },
+ { "wallet", "setaccount", &setaccount, true, false, true },
+ { "wallet", "settxfee", &settxfee, true, false, true },
+ { "wallet", "signmessage", &signmessage, true, false, true },
+ { "wallet", "walletlock", &walletlock, true, false, true },
+ { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true },
+ { "wallet", "walletpassphrase", &walletpassphrase, true, false, true },
#endif // ENABLE_WALLET
};
@@ -827,11 +855,10 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
if (!HTTPAuthorized(mapHeaders))
{
LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
- /* Deter brute-forcing short passwords.
+ /* Deter brute-forcing
If this results in a DoS the user really
shouldn't have their RPC port exposed. */
- if (mapArgs["-rpcpassword"].size() < 20)
- MilliSleep(250);
+ MilliSleep(250);
conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
return false;
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 176852ca8f..b850d15d4e 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -71,6 +71,7 @@ typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool f
class CRPCCommand
{
public:
+ std::string category;
std::string name;
rpcfn_type actor;
bool okSafeMode;
@@ -199,6 +200,7 @@ extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool f
extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 667ca33ce1..215da2ea12 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -1518,7 +1518,7 @@ Value gettransaction(const Array& params, bool fHelp)
" \"hex\" : \"data\" (string) Raw data for transaction\n"
"}\n"
- "\nbExamples\n"
+ "\nExamples:\n"
+ HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
);
diff --git a/src/script.cpp b/src/script.cpp
index 39ae001db8..28c50a1358 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -18,8 +18,9 @@
#include "util.h"
#include <boost/foreach.hpp>
-#include <boost/tuple/tuple.hpp>
+#include <boost/thread.hpp>
#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/tuple/tuple.hpp>
using namespace std;
using namespace boost;
@@ -1444,18 +1445,6 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
return nResult;
}
-
-class CKeyStoreIsMineVisitor : public boost::static_visitor<bool>
-{
-private:
- const CKeyStore *keystore;
-public:
- CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { }
- bool operator()(const CNoDestination &dest) const { return false; }
- bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); }
- bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); }
-};
-
isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
{
CScript script;
@@ -1886,9 +1875,11 @@ bool CScript::IsPushOnly() const
const_iterator pc = begin();
while (pc < end())
{
+ // Note how a script with an invalid PUSHDATA returns False.
opcodetype opcode;
if (!GetOp(pc, opcode))
return false;
+
// Note that IsPushOnly() *does* consider OP_RESERVED to be a
// push-type opcode, however execution of OP_RESERVED fails, so
// it's not relevant to P2SH as the scriptSig would fail prior to
diff --git a/src/script.h b/src/script.h
index 7cb863d1c9..462e3f2302 100644
--- a/src/script.h
+++ b/src/script.h
@@ -7,7 +7,8 @@
#define H_BITCOIN_SCRIPT
#include "key.h"
-#include "util.h"
+#include "utilstrencodings.h"
+#include "tinyformat.h"
#include <stdexcept>
#include <stdint.h>
@@ -730,6 +731,12 @@ public:
{
return CScriptID(Hash160(*this));
}
+
+ void clear()
+ {
+ // The default std::vector::clear() does not release memory.
+ std::vector<unsigned char>().swap(*this);
+ }
};
/** Compact serializer for scripts.
diff --git a/src/serialize.h b/src/serialize.h
index f876efd9b5..17cb724bee 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -68,7 +68,7 @@ inline const T* end_ptr(const std::vector<T,TAl>& v)
/////////////////////////////////////////////////////////////////
//
// Templates for serializing to anything that looks like a stream,
-// i.e. anything that supports .read(char*, int) and .write(char*, int)
+// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
//
enum
@@ -334,8 +334,9 @@ I ReadVarInt(Stream& is)
}
}
-#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
-#define VARINT(obj) REF(WrapVarInt(REF(obj)))
+#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
+#define VARINT(obj) REF(WrapVarInt(REF(obj)))
+#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
/** Wrapper for serializing arrays and POD.
*/
@@ -398,6 +399,40 @@ public:
}
};
+template<size_t Limit>
+class LimitedString
+{
+protected:
+ std::string& string;
+public:
+ LimitedString(std::string& string) : string(string) {}
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int, int=0)
+ {
+ size_t size = ReadCompactSize(s);
+ if (size > Limit) {
+ throw std::ios_base::failure("String length limit exceeded");
+ }
+ string.resize(size);
+ if (size != 0)
+ s.read((char*)&string[0], size);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream& s, int, int=0) const
+ {
+ WriteCompactSize(s, string.size());
+ if (!string.empty())
+ s.write((char*)&string[0], string.size());
+ }
+
+ unsigned int GetSerializeSize(int, int=0) const
+ {
+ return GetSizeOfCompactSize(string.size()) + string.size();
+ }
+};
+
template<typename I>
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
@@ -841,7 +876,7 @@ public:
CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
- CSizeComputer& write(const char *psz, int nSize)
+ CSizeComputer& write(const char *psz, size_t nSize)
{
this->nSize += nSize;
return *this;
@@ -870,8 +905,6 @@ protected:
typedef CSerializeData vector_type;
vector_type vch;
unsigned int nReadPos;
- short state;
- short exceptmask;
public:
int nType;
int nVersion;
@@ -923,8 +956,6 @@ public:
nReadPos = 0;
nType = nTypeIn;
nVersion = nVersionIn;
- state = 0;
- exceptmask = std::ios::badbit | std::ios::failbit;
}
CDataStream& operator+=(const CDataStream& b)
@@ -1047,19 +1078,7 @@ public:
//
// Stream subset
//
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
bool eof() const { return size() == 0; }
- bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
- bool good() const { return !eof() && (state == 0); }
- void clear(short n) { state = n; } // name conflict with vector clear()
- short exceptions() { return exceptmask; }
- short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
CDataStream* rdbuf() { return this; }
int in_avail() { return size(); }
@@ -1070,18 +1089,15 @@ public:
void ReadVersion() { *this >> nVersion; }
void WriteVersion() { *this << nVersion; }
- CDataStream& read(char* pch, int nSize)
+ CDataStream& read(char* pch, size_t nSize)
{
// Read from the beginning of the buffer
- assert(nSize >= 0);
unsigned int nReadPosNext = nReadPos + nSize;
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
{
- setstate(std::ios::failbit, "CDataStream::read() : end of data");
- memset(pch, 0, nSize);
- nSize = vch.size() - nReadPos;
+ throw std::ios_base::failure("CDataStream::read() : end of data");
}
memcpy(pch, &vch[nReadPos], nSize);
nReadPos = 0;
@@ -1101,7 +1117,7 @@ public:
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
- setstate(std::ios::failbit, "CDataStream::ignore() : end of data");
+ throw std::ios_base::failure("CDataStream::ignore() : end of data");
nReadPos = 0;
vch.clear();
return (*this);
@@ -1110,10 +1126,9 @@ public:
return (*this);
}
- CDataStream& write(const char* pch, int nSize)
+ CDataStream& write(const char* pch, size_t nSize)
{
// Write to the end of the buffer
- assert(nSize >= 0);
vch.insert(vch.end(), pch, pch + nSize);
return (*this);
}
@@ -1174,8 +1189,6 @@ class CAutoFile
{
protected:
FILE* file;
- short state;
- short exceptmask;
public:
int nType;
int nVersion;
@@ -1185,8 +1198,6 @@ public:
file = filenew;
nType = nTypeIn;
nVersion = nVersionIn;
- state = 0;
- exceptmask = std::ios::badbit | std::ios::failbit;
}
~CAutoFile()
@@ -1213,19 +1224,6 @@ public:
//
// Stream subset
//
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
- bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
- bool good() const { return state == 0; }
- void clear(short n = 0) { state = n; }
- short exceptions() { return exceptmask; }
- short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
-
void SetType(int n) { nType = n; }
int GetType() { return nType; }
void SetVersion(int n) { nVersion = n; }
@@ -1238,7 +1236,7 @@ public:
if (!file)
throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
if (fread(pch, 1, nSize, file) != nSize)
- setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
+ throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
return (*this);
}
@@ -1247,7 +1245,7 @@ public:
if (!file)
throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
if (fwrite(pch, 1, nSize, file) != nSize)
- setstate(std::ios::failbit, "CAutoFile::write : write failed");
+ throw std::ios_base::failure("CAutoFile::write : write failed");
return (*this);
}
@@ -1292,16 +1290,7 @@ private:
uint64_t nRewind; // how many bytes we guarantee to rewind
std::vector<char> vchBuf; // the buffer
- short state;
- short exceptmask;
-
protected:
- void setstate(short bits, const char *psz) {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
// read data from the source to fill the buffer
bool Fill() {
unsigned int pos = nSrcPos % vchBuf.size();
@@ -1313,8 +1302,7 @@ protected:
return false;
size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
if (read == 0) {
- setstate(std::ios_base::failbit, feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
- return false;
+ throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
} else {
nSrcPos += read;
return true;
@@ -1327,12 +1315,7 @@ public:
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0),
- state(0), exceptmask(std::ios_base::badbit | std::ios_base::failbit), nType(nTypeIn), nVersion(nVersionIn) {
- }
-
- // check whether no error occurred
- bool good() const {
- return state == 0;
+ nType(nTypeIn), nVersion(nVersionIn) {
}
// check whether we're at the end of the source file
@@ -1391,7 +1374,6 @@ public:
nLongPos = ftell(src);
nSrcPos = nLongPos;
nReadPos = nLongPos;
- state = 0;
return true;
}
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 5e17555e7a..4ecf6e2535 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -14,6 +14,7 @@
#include "pow.h"
#include "script.h"
#include "serialize.h"
+#include "util.h"
#include <stdint.h>
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index b16f3f7f57..4af87cf8ef 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -11,6 +11,7 @@
#include "serialize.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "version.h"
#include <fstream>
@@ -83,7 +84,7 @@ struct ReadAlerts
std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
try {
- while (stream.good())
+ while (!stream.eof())
{
CAlert alert;
stream >> alert;
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index 2752a0b215..69888da3df 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -4,6 +4,8 @@
#include "util.h"
+#include "allocators.h"
+
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(allocator_tests)
diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp
index 87473585e3..68617abbdd 100644
--- a/src/test/base32_tests.cpp
+++ b/src/test/base32_tests.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "util.h"
+#include "utilstrencodings.h"
#include <boost/test/unit_test.hpp>
diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp
index d4a23d9aa0..f2bf3326ad 100644
--- a/src/test/base64_tests.cpp
+++ b/src/test/base64_tests.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "util.h"
+#include "utilstrencodings.h"
#include <boost/test/unit_test.hpp>
diff --git a/src/test/bctest.py b/src/test/bctest.py
new file mode 100644
index 0000000000..1839f4fef4
--- /dev/null
+++ b/src/test/bctest.py
@@ -0,0 +1,53 @@
+# Copyright 2014 BitPay, Inc.
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import subprocess
+import os
+import json
+import sys
+
+def bctest(testDir, testObj):
+ execargs = testObj['exec']
+
+ stdinCfg = None
+ inputData = None
+ if "input" in testObj:
+ filename = testDir + "/" + testObj['input']
+ inputData = open(filename).read()
+ stdinCfg = subprocess.PIPE
+
+ outputFn = None
+ outputData = None
+ if "output_cmp" in testObj:
+ outputFn = testObj['output_cmp']
+ outputData = open(testDir + "/" + outputFn).read()
+
+ proc = subprocess.Popen(execargs, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ try:
+ outs = proc.communicate(input=inputData)
+ except OSError:
+ print("OSError, Failed to execute " + execargs[0])
+ sys.exit(1)
+
+ if outputData and (outs[0] != outputData):
+ print("Output data mismatch for " + outputFn)
+ sys.exit(1)
+
+ wantRC = 0
+ if "return_code" in testObj:
+ wantRC = testObj['return_code']
+ if proc.returncode != wantRC:
+ print("Return code mismatch for " + outputFn)
+ sys.exit(1)
+
+def bctester(testDir, input_basename):
+ input_filename = testDir + "/" + input_basename
+ raw_data = open(input_filename).read()
+ input_data = json.loads(raw_data)
+
+ for testObj in input_data:
+ bctest(testDir, testObj)
+
+ sys.exit(0)
+
diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py
new file mode 100755
index 0000000000..40690c2fed
--- /dev/null
+++ b/src/test/bitcoin-util-test.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+# Copyright 2014 BitPay, Inc.
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import os
+import bctest
+
+if __name__ == '__main__':
+ bctest.bctester(os.environ["srcdir"] + "/test/data",
+ "bitcoin-util-test.json")
+
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index 10352240f4..fdea12846a 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -9,6 +9,7 @@
#include "main.h"
+#include "utiltime.h"
#include <cstdio>
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index a17278b803..a3eec270ee 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -6,7 +6,7 @@
#include "crypto/sha1.h"
#include "crypto/sha2.h"
#include "random.h"
-#include "util.h"
+#include "utilstrencodings.h"
#include <vector>
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
new file mode 100644
index 0000000000..7db87d7c11
--- /dev/null
+++ b/src/test/data/bitcoin-util-test.json
@@ -0,0 +1,38 @@
+[
+ { "exec": ["./bitcoin-tx", "-create"],
+ "output_cmp": "blanktx.hex"
+ },
+ { "exec": ["./bitcoin-tx", "-"],
+ "input": "blanktx.hex",
+ "output_cmp": "blanktx.hex"
+ },
+ { "exec": ["./bitcoin-tx", "-", "delin=1"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-delin1-out.hex"
+ },
+ { "exec": ["./bitcoin-tx", "-", "delin=31"],
+ "input": "tx394b54bb.hex",
+ "return_code": 1
+ },
+ { "exec": ["./bitcoin-tx", "-", "delout=1"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-delout1-out.hex"
+ },
+ { "exec": ["./bitcoin-tx", "-", "delout=2"],
+ "input": "tx394b54bb.hex",
+ "return_code": 1
+ },
+ { "exec": ["./bitcoin-tx", "-", "locktime=317000"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-locktime317000-out.hex"
+ },
+ { "exec":
+ ["./bitcoin-tx", "-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
+ "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
+ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"],
+ "output_cmp": "txcreate1.hex"
+ }
+]
diff --git a/src/test/data/blanktx.hex b/src/test/data/blanktx.hex
new file mode 100644
index 0000000000..36b6f00fb6
--- /dev/null
+++ b/src/test/data/blanktx.hex
@@ -0,0 +1 @@
+01000000000000000000
diff --git a/src/test/data/tt-delin1-out.hex b/src/test/data/tt-delin1-out.hex
new file mode 100644
index 0000000000..42ad840f43
--- /dev/null
+++ b/src/test/data/tt-delin1-out.hex
@@ -0,0 +1 @@
+0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000
diff --git a/src/test/data/tt-delout1-out.hex b/src/test/data/tt-delout1-out.hex
new file mode 100644
index 0000000000..cc60c3fac6
--- /dev/null
+++ b/src/test/data/tt-delout1-out.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000
diff --git a/src/test/data/tt-locktime317000-out.hex b/src/test/data/tt-locktime317000-out.hex
new file mode 100644
index 0000000000..287f420a40
--- /dev/null
+++ b/src/test/data/tt-locktime317000-out.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400
diff --git a/src/test/data/tx394b54bb.hex b/src/test/data/tx394b54bb.hex
new file mode 100644
index 0000000000..33f26cb4d6
--- /dev/null
+++ b/src/test/data/tx394b54bb.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000
diff --git a/src/test/data/txcreate1.hex b/src/test/data/txcreate1.hex
new file mode 100644
index 0000000000..e2981a51c9
--- /dev/null
+++ b/src/test/data/txcreate1.hex
@@ -0,0 +1 @@
+01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index 4568c8769b..b8e290f071 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -3,7 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hash.h"
-#include "util.h"
+#include "utilstrencodings.h"
#include <vector>
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 107c0f06e7..d5475a92bf 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -110,14 +110,14 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign)
BOOST_AUTO_TEST_CASE(rpc_format_monetary_values)
{
- BOOST_CHECK(write_string(ValueFromAmount(0LL), false) == "0.00000000");
- BOOST_CHECK(write_string(ValueFromAmount(1LL), false) == "0.00000001");
- BOOST_CHECK(write_string(ValueFromAmount(17622195LL), false) == "0.17622195");
- BOOST_CHECK(write_string(ValueFromAmount(50000000LL), false) == "0.50000000");
- BOOST_CHECK(write_string(ValueFromAmount(89898989LL), false) == "0.89898989");
- BOOST_CHECK(write_string(ValueFromAmount(100000000LL), false) == "1.00000000");
- BOOST_CHECK(write_string(ValueFromAmount(2099999999999990LL), false) == "20999999.99999990");
- BOOST_CHECK(write_string(ValueFromAmount(2099999999999999LL), false) == "20999999.99999999");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999");
}
static Value ValueFromString(const std::string &str)
@@ -129,14 +129,14 @@ static Value ValueFromString(const std::string &str)
BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
{
- BOOST_CHECK(AmountFromValue(ValueFromString("0.00000001")) == 1LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("0.17622195")) == 17622195LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("0.5")) == 50000000LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("0.50000000")) == 50000000LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("0.89898989")) == 89898989LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("1.00000000")) == 100000000LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("20999999.9999999")) == 2099999999999990LL);
- BOOST_CHECK(AmountFromValue(ValueFromString("20999999.99999999")) == 2099999999999999LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.50000000")), 50000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.89898989")), 89898989LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL);
}
BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index bc9f31c077..77c44501ab 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -394,4 +394,15 @@ BOOST_AUTO_TEST_CASE(script_standard_push)
}
}
+BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
+{
+ // IsPushOnly returns false when given a script containing only pushes that
+ // are invalid due to truncation. IsPushOnly() is consensus critical
+ // because P2SH evaluation uses it, although this specific behavior should
+ // not be consensus critical as the P2SH evaluation would fail first due to
+ // the invalid push. Still, it doesn't hurt to test it explicitly.
+ static const unsigned char direct[] = { 1 };
+ BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly());
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 443b5853b2..68fad8d038 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -16,6 +16,7 @@
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
CClientUIInterface uiInterface;
CWallet* pwalletMain;
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
new file mode 100644
index 0000000000..aa4fa0d500
--- /dev/null
+++ b/src/test/timedata_tests.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+//
+#include "timedata.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_AUTO_TEST_SUITE(timedata_tests)
+
+BOOST_AUTO_TEST_CASE(util_MedianFilter)
+{
+ CMedianFilter<int> filter(5, 15);
+
+ BOOST_CHECK_EQUAL(filter.median(), 15);
+
+ filter.input(20); // [15 20]
+ BOOST_CHECK_EQUAL(filter.median(), 17);
+
+ filter.input(30); // [15 20 30]
+ BOOST_CHECK_EQUAL(filter.median(), 20);
+
+ filter.input(3); // [3 15 20 30]
+ BOOST_CHECK_EQUAL(filter.median(), 17);
+
+ filter.input(7); // [3 7 15 20 30]
+ BOOST_CHECK_EQUAL(filter.median(), 15);
+
+ filter.input(18); // [3 7 18 20 30]
+ BOOST_CHECK_EQUAL(filter.median(), 18);
+
+ filter.input(0); // [0 3 7 18 30]
+ BOOST_CHECK_EQUAL(filter.median(), 7);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
new file mode 100644
index 0000000000..23bc5f6b12
--- /dev/null
+++ b/src/test/univalue_tests.cpp
@@ -0,0 +1,275 @@
+// Copyright 2014 BitPay, Inc.
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <stdint.h>
+#include <vector>
+#include <string>
+#include <map>
+#include "univalue/univalue.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_AUTO_TEST_SUITE(univalue_tests)
+
+BOOST_AUTO_TEST_CASE(univalue_constructor)
+{
+ UniValue v1;
+ BOOST_CHECK(v1.isNull());
+
+ UniValue v2(UniValue::VSTR);
+ BOOST_CHECK(v2.isStr());
+
+ UniValue v3(UniValue::VSTR, "foo");
+ BOOST_CHECK(v3.isStr());
+ BOOST_CHECK_EQUAL(v3.getValStr(), "foo");
+
+ UniValue numTest;
+ BOOST_CHECK(numTest.setNumStr("82"));
+ BOOST_CHECK(numTest.isNum());
+ BOOST_CHECK_EQUAL(numTest.getValStr(), "82");
+
+ uint64_t vu64 = 82;
+ UniValue v4(vu64);
+ BOOST_CHECK(v4.isNum());
+ BOOST_CHECK_EQUAL(v4.getValStr(), "82");
+
+ int64_t vi64 = -82;
+ UniValue v5(vi64);
+ BOOST_CHECK(v5.isNum());
+ BOOST_CHECK_EQUAL(v5.getValStr(), "-82");
+
+ int vi = -688;
+ UniValue v6(vi);
+ BOOST_CHECK(v6.isNum());
+ BOOST_CHECK_EQUAL(v6.getValStr(), "-688");
+
+ double vd = -7.21;
+ UniValue v7(vd);
+ BOOST_CHECK(v7.isNum());
+ BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
+
+ string vs("yawn");
+ UniValue v8(vs);
+ BOOST_CHECK(v8.isStr());
+ BOOST_CHECK_EQUAL(v8.getValStr(), "yawn");
+
+ const char *vcs = "zappa";
+ UniValue v9(vcs);
+ BOOST_CHECK(v9.isStr());
+ BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
+}
+
+BOOST_AUTO_TEST_CASE(univalue_set)
+{
+ UniValue v(UniValue::VSTR, "foo");
+ v.clear();
+ BOOST_CHECK(v.isNull());
+ BOOST_CHECK_EQUAL(v.getValStr(), "");
+
+ BOOST_CHECK(v.setObject());
+ BOOST_CHECK(v.isObject());
+ BOOST_CHECK_EQUAL(v.count(), 0);
+ BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ);
+ BOOST_CHECK(v.empty());
+
+ BOOST_CHECK(v.setArray());
+ BOOST_CHECK(v.isArray());
+ BOOST_CHECK_EQUAL(v.count(), 0);
+
+ BOOST_CHECK(v.setStr("zum"));
+ BOOST_CHECK(v.isStr());
+ BOOST_CHECK_EQUAL(v.getValStr(), "zum");
+
+ BOOST_CHECK(v.setFloat(-1.01));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
+
+ BOOST_CHECK(v.setInt((int)1023));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "1023");
+
+ BOOST_CHECK(v.setInt((int64_t)-1023LL));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-1023");
+
+ BOOST_CHECK(v.setInt((uint64_t)1023ULL));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "1023");
+
+ BOOST_CHECK(v.setNumStr("-688"));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-688");
+
+ BOOST_CHECK(v.setBool(false));
+ BOOST_CHECK_EQUAL(v.isBool(), true);
+ BOOST_CHECK_EQUAL(v.isTrue(), false);
+ BOOST_CHECK_EQUAL(v.isFalse(), true);
+ BOOST_CHECK_EQUAL(v.getBool(), false);
+
+ BOOST_CHECK(v.setBool(true));
+ BOOST_CHECK_EQUAL(v.isBool(), true);
+ BOOST_CHECK_EQUAL(v.isTrue(), true);
+ BOOST_CHECK_EQUAL(v.isFalse(), false);
+ BOOST_CHECK_EQUAL(v.getBool(), true);
+
+ BOOST_CHECK(!v.setNumStr("zombocom"));
+
+ BOOST_CHECK(v.setNull());
+ BOOST_CHECK(v.isNull());
+}
+
+BOOST_AUTO_TEST_CASE(univalue_array)
+{
+ UniValue arr(UniValue::VARR);
+
+ UniValue v((int64_t)1023LL);
+ BOOST_CHECK(arr.push_back(v));
+
+ string vStr("zippy");
+ BOOST_CHECK(arr.push_back(vStr));
+
+ const char *s = "pippy";
+ BOOST_CHECK(arr.push_back(s));
+
+ vector<UniValue> vec;
+ v.setStr("boing");
+ vec.push_back(v);
+
+ v.setStr("going");
+ vec.push_back(v);
+
+ BOOST_CHECK(arr.push_backV(vec));
+
+ BOOST_CHECK_EQUAL(arr.empty(), false);
+ BOOST_CHECK_EQUAL(arr.count(), 5);
+
+ BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
+ BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
+ BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
+ BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
+ BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
+
+ BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
+
+ arr.clear();
+ BOOST_CHECK(arr.empty());
+ BOOST_CHECK_EQUAL(arr.count(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(univalue_object)
+{
+ UniValue obj(UniValue::VOBJ);
+ string strKey, strVal;
+ UniValue v;
+
+ strKey = "age";
+ v.setInt(100);
+ BOOST_CHECK(obj.pushKV(strKey, v));
+
+ strKey = "first";
+ strVal = "John";
+ BOOST_CHECK(obj.pushKV(strKey, strVal));
+
+ strKey = "last";
+ const char *cVal = "Smith";
+ BOOST_CHECK(obj.pushKV(strKey, cVal));
+
+ strKey = "distance";
+ BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25));
+
+ strKey = "time";
+ BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600));
+
+ strKey = "calories";
+ BOOST_CHECK(obj.pushKV(strKey, (int) 12));
+
+ strKey = "temperature";
+ BOOST_CHECK(obj.pushKV(strKey, (double) 90.012));
+
+ UniValue obj2(UniValue::VOBJ);
+ BOOST_CHECK(obj2.pushKV("cat1", 9000));
+ BOOST_CHECK(obj2.pushKV("cat2", 12345));
+
+ BOOST_CHECK(obj.pushKVs(obj2));
+
+ BOOST_CHECK_EQUAL(obj.empty(), false);
+ BOOST_CHECK_EQUAL(obj.count(), 9);
+
+ BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
+ BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
+ BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith");
+ BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25");
+ BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600");
+ BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12");
+ BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012");
+ BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000");
+ BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345");
+
+ BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), "");
+
+ BOOST_CHECK(obj.exists("age"));
+ BOOST_CHECK(obj.exists("first"));
+ BOOST_CHECK(obj.exists("last"));
+ BOOST_CHECK(obj.exists("distance"));
+ BOOST_CHECK(obj.exists("time"));
+ BOOST_CHECK(obj.exists("calories"));
+ BOOST_CHECK(obj.exists("temperature"));
+ BOOST_CHECK(obj.exists("cat1"));
+ BOOST_CHECK(obj.exists("cat2"));
+
+ BOOST_CHECK(!obj.exists("nyuknyuknyuk"));
+
+ map<string, UniValue::VType> objTypes;
+ objTypes["age"] = UniValue::VNUM;
+ objTypes["first"] = UniValue::VSTR;
+ objTypes["last"] = UniValue::VSTR;
+ objTypes["distance"] = UniValue::VNUM;
+ objTypes["time"] = UniValue::VNUM;
+ objTypes["calories"] = UniValue::VNUM;
+ objTypes["temperature"] = UniValue::VNUM;
+ objTypes["cat1"] = UniValue::VNUM;
+ objTypes["cat2"] = UniValue::VNUM;
+ BOOST_CHECK(obj.checkObject(objTypes));
+
+ objTypes["cat2"] = UniValue::VSTR;
+ BOOST_CHECK(!obj.checkObject(objTypes));
+
+ obj.clear();
+ BOOST_CHECK(obj.empty());
+ BOOST_CHECK_EQUAL(obj.count(), 0);
+}
+
+static const char *json1 =
+"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
+
+BOOST_AUTO_TEST_CASE(univalue_readwrite)
+{
+ UniValue v;
+ BOOST_CHECK(v.read(json1));
+
+ string strJson1(json1);
+ BOOST_CHECK(v.read(strJson1));
+
+ BOOST_CHECK(v.isArray());
+ BOOST_CHECK_EQUAL(v.count(), 2);
+
+ BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1");
+
+ UniValue obj = v[1];
+ BOOST_CHECK(obj.isObject());
+ BOOST_CHECK_EQUAL(obj.count(), 3);
+
+ BOOST_CHECK(obj["key1"].isStr());
+ BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str");
+ BOOST_CHECK(obj["key2"].isNum());
+ BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
+ BOOST_CHECK(obj["key3"].isObject());
+
+ BOOST_CHECK_EQUAL(strJson1, v.write());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 068b9f29c8..e077c9de3b 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -4,8 +4,11 @@
#include "util.h"
+#include "core.h"
#include "random.h"
#include "sync.h"
+#include "utilstrencodings.h"
+#include "utilmoneystr.h"
#include <stdint.h>
#include <vector>
@@ -36,31 +39,6 @@ BOOST_AUTO_TEST_CASE(util_criticalsection)
} while(0);
}
-BOOST_AUTO_TEST_CASE(util_MedianFilter)
-{
- CMedianFilter<int> filter(5, 15);
-
- BOOST_CHECK_EQUAL(filter.median(), 15);
-
- filter.input(20); // [15 20]
- BOOST_CHECK_EQUAL(filter.median(), 17);
-
- filter.input(30); // [15 20 30]
- BOOST_CHECK_EQUAL(filter.median(), 20);
-
- filter.input(3); // [3 15 20 30]
- BOOST_CHECK_EQUAL(filter.median(), 17);
-
- filter.input(7); // [3 7 15 20 30]
- BOOST_CHECK_EQUAL(filter.median(), 15);
-
- filter.input(18); // [3 7 18 20 30]
- BOOST_CHECK_EQUAL(filter.median(), 18);
-
- filter.input(0); // [0 3 7 18 30]
- BOOST_CHECK_EQUAL(filter.median(), 7);
-}
-
static const unsigned char ParseHex_expected[65] = {
0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
diff --git a/src/timedata.cpp b/src/timedata.cpp
index 4576786b96..40cdb33f7a 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -8,6 +8,7 @@
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
+#include "utilstrencodings.h"
#include <boost/foreach.hpp>
@@ -35,6 +36,11 @@ int64_t GetAdjustedTime()
return GetTime() + GetTimeOffset();
}
+static int64_t abs64(int64_t n)
+{
+ return (n >= 0 ? n : -n);
+}
+
void AddTimeData(const CNetAddr& ip, int64_t nTime)
{
int64_t nOffsetSample = nTime - GetTime();
diff --git a/src/timedata.h b/src/timedata.h
index 0e7bdc2c1f..d0c84b3183 100644
--- a/src/timedata.h
+++ b/src/timedata.h
@@ -6,9 +6,68 @@
#define BITCOIN_TIMEDATA_H
#include <stdint.h>
+#include <vector>
+#include <algorithm>
+#include <assert.h>
class CNetAddr;
+/** Median filter over a stream of values.
+ * Returns the median of the last N numbers
+ */
+template <typename T> class CMedianFilter
+{
+private:
+ std::vector<T> vValues;
+ std::vector<T> vSorted;
+ unsigned int nSize;
+public:
+ CMedianFilter(unsigned int size, T initial_value):
+ nSize(size)
+ {
+ vValues.reserve(size);
+ vValues.push_back(initial_value);
+ vSorted = vValues;
+ }
+
+ void input(T value)
+ {
+ if(vValues.size() == nSize)
+ {
+ vValues.erase(vValues.begin());
+ }
+ vValues.push_back(value);
+
+ vSorted.resize(vValues.size());
+ std::copy(vValues.begin(), vValues.end(), vSorted.begin());
+ std::sort(vSorted.begin(), vSorted.end());
+ }
+
+ T median() const
+ {
+ int size = vSorted.size();
+ assert(size>0);
+ if(size & 1) // Odd number of elements
+ {
+ return vSorted[size/2];
+ }
+ else // Even number of elements
+ {
+ return (vSorted[size/2-1] + vSorted[size/2]) / 2;
+ }
+ }
+
+ int size() const
+ {
+ return vValues.size();
+ }
+
+ std::vector<T> sorted () const
+ {
+ return vSorted;
+ }
+};
+
/* Functions to keep track of adjusted P2P time */
int64_t GetTimeOffset();
int64_t GetAdjustedTime();
diff --git a/src/tinyformat.h b/src/tinyformat.h
index b6113029f5..73d49a1fe4 100644
--- a/src/tinyformat.h
+++ b/src/tinyformat.h
@@ -121,6 +121,7 @@ namespace tfm = tinyformat;
#include <cassert>
#include <iostream>
#include <sstream>
+#include <stdexcept>
#ifndef TINYFORMAT_ERROR
# define TINYFORMAT_ERROR(reason) assert(0 && reason)
@@ -1007,4 +1008,6 @@ TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, s
} // namespace tinyformat
+#define strprintf tfm::format
+
#endif // TINYFORMAT_H_INCLUDED
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 52cd96283e..d4c6007558 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -9,6 +9,7 @@
#include "pow.h"
#include "uint256.h"
+#include <boost/thread.hpp>
#include <stdint.h>
using namespace std;
@@ -27,7 +28,7 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}
-bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) {
+bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const {
return db.Read(make_pair('c', txid), coins);
}
@@ -37,11 +38,11 @@ bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
return db.WriteBatch(batch);
}
-bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
+bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
return db.Exists(make_pair('c', txid));
}
-uint256 CCoinsViewDB::GetBestBlock() {
+uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain;
if (!db.Read('B', hashBestChain))
return uint256(0);
@@ -54,12 +55,15 @@ bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) {
return db.WriteBatch(batch);
}
-bool CCoinsViewDB::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) {
+bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size());
CLevelDBBatch batch;
- for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
BatchWriteCoins(batch, it->first, it->second);
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
if (hashBlock != uint256(0))
BatchWriteHashBestChain(batch, hashBlock);
@@ -102,8 +106,11 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
return Read('l', nFile);
}
-bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
- leveldb::Iterator *pcursor = db.NewIterator();
+bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
+ /* It seems that there are no "const iterators" for LevelDB. Since we
+ only need read operations on it, use a const-cast to get around
+ that restriction. */
+ leveldb::Iterator *pcursor = const_cast<CLevelDBWrapper*>(&db)->NewIterator();
pcursor->SeekToFirst();
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
@@ -146,7 +153,6 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
}
}
- delete pcursor;
stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
stats.hashSerialized = ss.GetHash();
stats.nTotalAmount = nTotalAmount;
@@ -178,7 +184,7 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
bool CBlockTreeDB::LoadBlockIndexGuts()
{
- leveldb::Iterator *pcursor = NewIterator();
+ boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
ssKeySet << make_pair('b', uint256(0));
@@ -224,7 +230,6 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
}
}
- delete pcursor;
return true;
}
diff --git a/src/txdb.h b/src/txdb.h
index 7d670c2542..f0b6b9e1dd 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -32,13 +32,13 @@ protected:
public:
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
- bool GetCoins(const uint256 &txid, CCoins &coins);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins);
- bool HaveCoins(const uint256 &txid);
- uint256 GetBestBlock();
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock);
- bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
- bool GetStats(CCoinsStats &stats);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool GetStats(CCoinsStats &stats) const;
};
/** Access to the block database (blocks/index/) */
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 29924fff09..8af1f1c91b 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -5,6 +5,7 @@
#include "core.h"
#include "txmempool.h"
+#include "util.h"
#include <boost/circular_buffer.hpp>
@@ -402,6 +403,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry)
for (unsigned int i = 0; i < tx.vin.size(); i++)
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
nTransactionsUpdated++;
+ totalTxSize += entry.GetTxSize();
}
return true;
}
@@ -426,6 +428,8 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed
removed.push_front(tx);
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapNextTx.erase(txin.prevout);
+
+ totalTxSize -= mapTx[hash].GetTxSize();
mapTx.erase(hash);
nTransactionsUpdated++;
}
@@ -477,19 +481,23 @@ void CTxMemPool::clear()
LOCK(cs);
mapTx.clear();
mapNextTx.clear();
+ totalTxSize = 0;
++nTransactionsUpdated;
}
-void CTxMemPool::check(CCoinsViewCache *pcoins) const
+void CTxMemPool::check(const CCoinsViewCache *pcoins) const
{
if (!fSanityCheck)
return;
LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
+ uint64_t checkTotal = 0;
+
LOCK(cs);
for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
unsigned int i = 0;
+ checkTotal += it->second.GetTxSize();
const CTransaction& tx = it->second.GetTx();
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
// Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
@@ -498,7 +506,7 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const
const CTransaction& tx2 = it2->second.GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
} else {
- CCoins &coins = pcoins->GetCoins(txin.prevout.hash);
+ const CCoins &coins = pcoins->GetCoins(txin.prevout.hash);
assert(coins.IsAvailable(txin.prevout.n));
}
// Check whether its inputs are marked in mapNextTx.
@@ -518,6 +526,8 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const
assert(tx.vin.size() > it->second.n);
assert(it->first == it->second.ptx->vin[it->second.n].prevout);
}
+
+ assert(totalTxSize == checkTotal);
}
void CTxMemPool::queryHashes(vector<uint256>& vtxid)
@@ -616,7 +626,7 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
-bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
+bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
// If an entry in the mempool exists, always return that one, as it's guaranteed to never
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
// transactions. First checking the underlying cache risks returning a pruned entry instead.
@@ -628,7 +638,7 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
return (base->GetCoins(txid, coins) && !coins.IsPruned());
}
-bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {
+bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
return mempool.exists(txid) || base->HaveCoins(txid);
}
diff --git a/src/txmempool.h b/src/txmempool.h
index 41b2c52f39..d95c4d970b 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -68,6 +68,7 @@ private:
CMinerPolicyEstimator* minerPolicyEstimator;
CFeeRate minRelayFee; // Passed to constructor to avoid dependency on main
+ uint64_t totalTxSize; // sum of all mempool tx' byte sizes
public:
mutable CCriticalSection cs;
@@ -84,7 +85,7 @@ public:
* all inputs are in the mapNextTx array). If sanity-checking is turned off,
* check does nothing.
*/
- void check(CCoinsViewCache *pcoins) const;
+ void check(const CCoinsViewCache *pcoins) const;
void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
@@ -108,6 +109,11 @@ public:
LOCK(cs);
return mapTx.size();
}
+ uint64_t GetTotalTxSize()
+ {
+ LOCK(cs);
+ return totalTxSize;
+ }
bool exists(uint256 hash)
{
@@ -137,8 +143,8 @@ protected:
public:
CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn);
- bool GetCoins(const uint256 &txid, CCoins &coins);
- bool HaveCoins(const uint256 &txid);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
+ bool HaveCoins(const uint256 &txid) const;
};
#endif /* BITCOIN_TXMEMPOOL_H */
diff --git a/src/uint256.cpp b/src/uint256.cpp
index 08c05594fd..feda0ca5a9 100644
--- a/src/uint256.cpp
+++ b/src/uint256.cpp
@@ -4,7 +4,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "uint256.h"
-#include "util.h"
+
+#include "utilstrencodings.h"
#include <stdio.h>
#include <string.h>
diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp
new file mode 100644
index 0000000000..881948f46e
--- /dev/null
+++ b/src/univalue/gen.cpp
@@ -0,0 +1,78 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// To re-create univalue_escapes.h:
+// $ g++ -o gen gen.cpp
+// $ ./gen > univalue_escapes.h
+//
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "univalue.h"
+
+using namespace std;
+
+static bool initEscapes;
+static const char *escapes[256];
+
+static void initJsonEscape()
+{
+ escapes[(int)'"'] = "\\\"";
+ escapes[(int)'\\'] = "\\\\";
+ escapes[(int)'/'] = "\\/";
+ escapes[(int)'\b'] = "\\b";
+ escapes[(int)'\f'] = "\\f";
+ escapes[(int)'\n'] = "\\n";
+ escapes[(int)'\r'] = "\\r";
+ escapes[(int)'\t'] = "\\t";
+
+ initEscapes = true;
+}
+
+static void outputEscape()
+{
+ printf( "// Automatically generated file. Do not modify.\n"
+ "#ifndef __UNIVALUE_ESCAPES_H__\n"
+ "#define __UNIVALUE_ESCAPES_H__\n"
+ "static const char *escapes[256] = {\n");
+
+ for (unsigned int i = 0; i < 256; i++) {
+ if (!escapes[i]) {
+ printf("\tNULL,\n");
+ } else {
+ printf("\t\"");
+
+ unsigned int si;
+ for (si = 0; si < strlen(escapes[i]); si++) {
+ char ch = escapes[i][si];
+ switch (ch) {
+ case '"':
+ printf("\\\"");
+ break;
+ case '\\':
+ printf("\\\\");
+ break;
+ default:
+ printf("%c", escapes[i][si]);
+ break;
+ }
+ }
+
+ printf("\",\n");
+ }
+ }
+
+ printf( "};\n"
+ "#endif // __UNIVALUE_ESCAPES_H__\n");
+}
+
+int main (int argc, char *argv[])
+{
+ initJsonEscape();
+ outputEscape();
+ return 0;
+}
+
diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp
index afc208bffb..b0171e48c4 100644
--- a/src/univalue/univalue.cpp
+++ b/src/univalue/univalue.cpp
@@ -44,7 +44,7 @@ static bool validNumStr(const string& s)
bool UniValue::setNumStr(const string& val_)
{
- if (!validNumStr(val))
+ if (!validNumStr(val_))
return false;
clear();
diff --git a/src/univalue/univalue_escapes.h b/src/univalue/univalue_escapes.h
new file mode 100644
index 0000000000..1d3a70a968
--- /dev/null
+++ b/src/univalue/univalue_escapes.h
@@ -0,0 +1,262 @@
+// Automatically generated file. Do not modify.
+#ifndef __UNIVALUE_ESCAPES_H__
+#define __UNIVALUE_ESCAPES_H__
+static const char *escapes[256] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\b",
+ "\\t",
+ "\\n",
+ NULL,
+ "\\f",
+ "\\r",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\\"",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\/",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\\\",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+#endif // __UNIVALUE_ESCAPES_H__
diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp
index 1818f5c6f9..042091a827 100644
--- a/src/univalue/univalue_write.cpp
+++ b/src/univalue/univalue_write.cpp
@@ -5,33 +5,14 @@
#include <ctype.h>
#include <stdio.h>
#include "univalue.h"
+#include "univalue_escapes.h"
// TODO: Using UTF8
using namespace std;
-static bool initEscapes;
-static const char *escapes[256];
-
-static void initJsonEscape()
-{
- escapes['"'] = "\\\"";
- escapes['\\'] = "\\\\";
- escapes['/'] = "\\/";
- escapes['\b'] = "\\b";
- escapes['\f'] = "\\f";
- escapes['\n'] = "\\n";
- escapes['\r'] = "\\r";
- escapes['\t'] = "\\t";
-
- initEscapes = true;
-}
-
static string json_escape(const string& inS)
{
- if (!initEscapes)
- initJsonEscape();
-
string outS;
outS.reserve(inS.size() * 2);
@@ -110,8 +91,11 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s
if (prettyIndent)
s += indentStr(prettyIndent, indentLevel);
s += values[i].write(prettyIndent, indentLevel + 1);
- if (i != (values.size() - 1))
- s += ", ";
+ if (i != (values.size() - 1)) {
+ s += ",";
+ if (prettyIndent)
+ s += " ";
+ }
if (prettyIndent)
s += "\n";
}
@@ -130,7 +114,9 @@ void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel,
for (unsigned int i = 0; i < keys.size(); i++) {
if (prettyIndent)
s += indentStr(prettyIndent, indentLevel);
- s += "\"" + json_escape(keys[i]) + "\": ";
+ s += "\"" + json_escape(keys[i]) + "\":";
+ if (prettyIndent)
+ s += " ";
s += values[i].write(prettyIndent, indentLevel + 1);
if (i != (values.size() - 1))
s += ",";
diff --git a/src/util.cpp b/src/util.cpp
index d3fa5182f3..5a4e187f9e 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -3,30 +3,32 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
#include "util.h"
#include "chainparamsbase.h"
#include "random.h"
+#include "serialize.h"
#include "sync.h"
-#include "uint256.h"
-#include "version.h"
+#include "utilstrencodings.h"
+#include "utiltime.h"
#include <stdarg.h>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
#ifndef WIN32
// for posix_fallocate
-#ifdef __linux_
+#ifdef __linux__
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200112L
-#include <sys/prctl.h>
-#endif
+#endif // __linux__
#include <algorithm>
#include <fcntl.h>
@@ -61,6 +63,10 @@
#include <shlobj.h>
#endif
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
@@ -69,6 +75,7 @@
#include <boost/foreach.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
+#include <boost/thread.hpp>
#include <openssl/crypto.h>
#include <openssl/rand.h>
@@ -237,148 +244,6 @@ int LogPrintStr(const std::string &str)
return ret;
}
-string FormatMoney(int64_t n, bool fPlus)
-{
- // Note: not using straight sprintf here because we do NOT want
- // localized number formatting.
- int64_t n_abs = (n > 0 ? n : -n);
- int64_t quotient = n_abs/COIN;
- int64_t remainder = n_abs%COIN;
- string str = strprintf("%d.%08d", quotient, remainder);
-
- // Right-trim excess zeros before the decimal point:
- int nTrim = 0;
- for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
- ++nTrim;
- if (nTrim)
- str.erase(str.size()-nTrim, nTrim);
-
- if (n < 0)
- str.insert((unsigned int)0, 1, '-');
- else if (fPlus && n > 0)
- str.insert((unsigned int)0, 1, '+');
- return str;
-}
-
-
-bool ParseMoney(const string& str, int64_t& nRet)
-{
- return ParseMoney(str.c_str(), nRet);
-}
-
-bool ParseMoney(const char* pszIn, int64_t& nRet)
-{
- string strWhole;
- int64_t nUnits = 0;
- const char* p = pszIn;
- while (isspace(*p))
- p++;
- for (; *p; p++)
- {
- if (*p == '.')
- {
- p++;
- int64_t nMult = CENT*10;
- while (isdigit(*p) && (nMult > 0))
- {
- nUnits += nMult * (*p++ - '0');
- nMult /= 10;
- }
- break;
- }
- if (isspace(*p))
- break;
- if (!isdigit(*p))
- return false;
- strWhole.insert(strWhole.end(), *p);
- }
- for (; *p; p++)
- if (!isspace(*p))
- return false;
- if (strWhole.size() > 10) // guard against 63 bit overflow
- return false;
- if (nUnits < 0 || nUnits > COIN)
- return false;
- int64_t nWhole = atoi64(strWhole);
- int64_t nValue = nWhole*COIN + nUnits;
-
- nRet = nValue;
- return true;
-}
-
-// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
-// even possibly remotely dangerous like & or >
-static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@");
-string SanitizeString(const string& str)
-{
- string strResult;
- for (std::string::size_type i = 0; i < str.size(); i++)
- {
- if (safeChars.find(str[i]) != std::string::npos)
- strResult.push_back(str[i]);
- }
- return strResult;
-}
-
-const signed char p_util_hexdigit[256] =
-{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
- -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-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, };
-
-signed char HexDigit(char c)
-{
- return p_util_hexdigit[(unsigned char)c];
-}
-
-bool IsHex(const string& str)
-{
- BOOST_FOREACH(char c, str)
- {
- if (HexDigit(c) < 0)
- return false;
- }
- return (str.size() > 0) && (str.size()%2 == 0);
-}
-
-vector<unsigned char> ParseHex(const char* psz)
-{
- // convert hex dump to vector
- vector<unsigned char> vch;
- while (true)
- {
- while (isspace(*psz))
- psz++;
- signed char c = HexDigit(*psz++);
- if (c == (signed char)-1)
- break;
- unsigned char n = (c << 4);
- c = HexDigit(*psz++);
- if (c == (signed char)-1)
- break;
- n |= c;
- vch.push_back(n);
- }
- return vch;
-}
-
-vector<unsigned char> ParseHex(const string& str)
-{
- return ParseHex(str.c_str());
-}
-
static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
{
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
@@ -476,334 +341,6 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue)
return SoftSetArg(strArg, std::string("0"));
}
-
-string EncodeBase64(const unsigned char* pch, size_t len)
-{
- static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- string strRet="";
- strRet.reserve((len+2)/3*4);
-
- int mode=0, left=0;
- const unsigned char *pchEnd = pch+len;
-
- while (pch<pchEnd)
- {
- int enc = *(pch++);
- switch (mode)
- {
- case 0: // we have no bits
- strRet += pbase64[enc >> 2];
- left = (enc & 3) << 4;
- mode = 1;
- break;
-
- case 1: // we have two bits
- strRet += pbase64[left | (enc >> 4)];
- left = (enc & 15) << 2;
- mode = 2;
- break;
-
- case 2: // we have four bits
- strRet += pbase64[left | (enc >> 6)];
- strRet += pbase64[enc & 63];
- mode = 0;
- break;
- }
- }
-
- if (mode)
- {
- strRet += pbase64[left];
- strRet += '=';
- if (mode == 1)
- strRet += '=';
- }
-
- return strRet;
-}
-
-string EncodeBase64(const string& str)
-{
- return EncodeBase64((const unsigned char*)str.c_str(), str.size());
-}
-
-vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
-{
- static const int decode64_table[256] =
- {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
- -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
- };
-
- if (pfInvalid)
- *pfInvalid = false;
-
- vector<unsigned char> vchRet;
- vchRet.reserve(strlen(p)*3/4);
-
- int mode = 0;
- int left = 0;
-
- while (1)
- {
- int dec = decode64_table[(unsigned char)*p];
- if (dec == -1) break;
- p++;
- switch (mode)
- {
- case 0: // we have no bits and get 6
- left = dec;
- mode = 1;
- break;
-
- case 1: // we have 6 bits and keep 4
- vchRet.push_back((left<<2) | (dec>>4));
- left = dec & 15;
- mode = 2;
- break;
-
- case 2: // we have 4 bits and get 6, we keep 2
- vchRet.push_back((left<<4) | (dec>>2));
- left = dec & 3;
- mode = 3;
- break;
-
- case 3: // we have 2 bits and get 6
- vchRet.push_back((left<<6) | dec);
- mode = 0;
- break;
- }
- }
-
- if (pfInvalid)
- switch (mode)
- {
- case 0: // 4n base64 characters processed: ok
- break;
-
- case 1: // 4n+1 base64 character processed: impossible
- *pfInvalid = true;
- break;
-
- case 2: // 4n+2 base64 characters processed: require '=='
- if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
- *pfInvalid = true;
- break;
-
- case 3: // 4n+3 base64 characters processed: require '='
- if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
- *pfInvalid = true;
- break;
- }
-
- return vchRet;
-}
-
-string DecodeBase64(const string& str)
-{
- vector<unsigned char> vchRet = DecodeBase64(str.c_str());
- return string((const char*)&vchRet[0], vchRet.size());
-}
-
-string EncodeBase32(const unsigned char* pch, size_t len)
-{
- static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
-
- string strRet="";
- strRet.reserve((len+4)/5*8);
-
- int mode=0, left=0;
- const unsigned char *pchEnd = pch+len;
-
- while (pch<pchEnd)
- {
- int enc = *(pch++);
- switch (mode)
- {
- case 0: // we have no bits
- strRet += pbase32[enc >> 3];
- left = (enc & 7) << 2;
- mode = 1;
- break;
-
- case 1: // we have three bits
- strRet += pbase32[left | (enc >> 6)];
- strRet += pbase32[(enc >> 1) & 31];
- left = (enc & 1) << 4;
- mode = 2;
- break;
-
- case 2: // we have one bit
- strRet += pbase32[left | (enc >> 4)];
- left = (enc & 15) << 1;
- mode = 3;
- break;
-
- case 3: // we have four bits
- strRet += pbase32[left | (enc >> 7)];
- strRet += pbase32[(enc >> 2) & 31];
- left = (enc & 3) << 3;
- mode = 4;
- break;
-
- case 4: // we have two bits
- strRet += pbase32[left | (enc >> 5)];
- strRet += pbase32[enc & 31];
- mode = 0;
- }
- }
-
- static const int nPadding[5] = {0, 6, 4, 3, 1};
- if (mode)
- {
- strRet += pbase32[left];
- for (int n=0; n<nPadding[mode]; n++)
- strRet += '=';
- }
-
- return strRet;
-}
-
-string EncodeBase32(const string& str)
-{
- return EncodeBase32((const unsigned char*)str.c_str(), str.size());
-}
-
-vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
-{
- static const int decode32_table[256] =
- {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
- };
-
- if (pfInvalid)
- *pfInvalid = false;
-
- vector<unsigned char> vchRet;
- vchRet.reserve((strlen(p))*5/8);
-
- int mode = 0;
- int left = 0;
-
- while (1)
- {
- int dec = decode32_table[(unsigned char)*p];
- if (dec == -1) break;
- p++;
- switch (mode)
- {
- case 0: // we have no bits and get 5
- left = dec;
- mode = 1;
- break;
-
- case 1: // we have 5 bits and keep 2
- vchRet.push_back((left<<3) | (dec>>2));
- left = dec & 3;
- mode = 2;
- break;
-
- case 2: // we have 2 bits and keep 7
- left = left << 5 | dec;
- mode = 3;
- break;
-
- case 3: // we have 7 bits and keep 4
- vchRet.push_back((left<<1) | (dec>>4));
- left = dec & 15;
- mode = 4;
- break;
-
- case 4: // we have 4 bits, and keep 1
- vchRet.push_back((left<<4) | (dec>>1));
- left = dec & 1;
- mode = 5;
- break;
-
- case 5: // we have 1 bit, and keep 6
- left = left << 5 | dec;
- mode = 6;
- break;
-
- case 6: // we have 6 bits, and keep 3
- vchRet.push_back((left<<2) | (dec>>3));
- left = dec & 7;
- mode = 7;
- break;
-
- case 7: // we have 3 bits, and keep 0
- vchRet.push_back((left<<5) | dec);
- mode = 0;
- break;
- }
- }
-
- if (pfInvalid)
- switch (mode)
- {
- case 0: // 8n base32 characters processed: ok
- break;
-
- case 1: // 8n+1 base32 characters processed: impossible
- case 3: // +3
- case 6: // +6
- *pfInvalid = true;
- break;
-
- case 2: // 8n+2 base32 characters processed: require '======'
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
- *pfInvalid = true;
- break;
-
- case 4: // 8n+4 base32 characters processed: require '===='
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
- *pfInvalid = true;
- break;
-
- case 5: // 8n+5 base32 characters processed: require '==='
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
- *pfInvalid = true;
- break;
-
- case 7: // 8n+7 base32 characters processed: require '='
- if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
- *pfInvalid = true;
- break;
- }
-
- return vchRet;
-}
-
-string DecodeBase32(const string& str)
-{
- vector<unsigned char> vchRet = DecodeBase32(str.c_str());
- return string((const char*)&vchRet[0], vchRet.size());
-}
-
static std::string FormatException(std::exception* pex, const char* pszThread)
{
#ifdef WIN32
@@ -1095,45 +632,6 @@ void ShrinkDebugFile()
fclose(file);
}
-static int64_t nMockTime = 0; // For unit testing
-
-int64_t GetTime()
-{
- if (nMockTime) return nMockTime;
-
- return time(NULL);
-}
-
-void SetMockTime(int64_t nMockTimeIn)
-{
- nMockTime = nMockTimeIn;
-}
-
-string FormatVersion(int nVersion)
-{
- if (nVersion%100 == 0)
- return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
- else
- return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
-}
-
-string FormatFullVersion()
-{
- return CLIENT_BUILD;
-}
-
-// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
-std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
-{
- std::ostringstream ss;
- ss << "/";
- ss << name << ":" << FormatVersion(nClientVersion);
- if (!comments.empty())
- ss << "(" << boost::algorithm::join(comments, "; ") << ")";
- ss << "/";
- return ss.str();
-}
-
#ifdef WIN32
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
{
@@ -1204,20 +702,6 @@ void RenameThread(const char* name)
#endif
}
-bool ParseInt32(const std::string& str, int32_t *out)
-{
- char *endp = NULL;
- errno = 0; // strtol will not set errno if valid
- long int n = strtol(str.c_str(), &endp, 10);
- if(out) *out = (int)n;
- // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
- // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
- // platforms the size of these types may be different.
- return endp && *endp == 0 && !errno &&
- n >= std::numeric_limits<int32_t>::min() &&
- n <= std::numeric_limits<int32_t>::max();
-}
-
void SetupEnvironment()
{
#ifndef WIN32
@@ -1235,47 +719,15 @@ void SetupEnvironment()
#endif
}
-std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
+void SetThreadPriority(int nPriority)
{
- // std::locale takes ownership of the pointer
- std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
- std::stringstream ss;
- ss.imbue(loc);
- ss << boost::posix_time::from_time_t(nTime);
- return ss.str();
-}
-
-std::string FormatParagraph(const std::string in, size_t width, size_t indent)
-{
- std::stringstream out;
- size_t col = 0;
- size_t ptr = 0;
- while(ptr < in.size())
- {
- // Find beginning of next word
- ptr = in.find_first_not_of(' ', ptr);
- if (ptr == std::string::npos)
- break;
- // Find end of next word
- size_t endword = in.find_first_of(' ', ptr);
- if (endword == std::string::npos)
- endword = in.size();
- // Add newline and indentation if this wraps over the allowed width
- if (col > 0)
- {
- if ((col + endword - ptr) > width)
- {
- out << '\n';
- for(size_t i=0; i<indent; ++i)
- out << ' ';
- col = 0;
- } else
- out << ' ';
- }
- // Append word
- out << in.substr(ptr, endword - ptr);
- col += endword - ptr;
- ptr = endword;
- }
- return out.str();
+#ifdef WIN32
+ SetThreadPriority(GetCurrentThread(), nPriority);
+#else // WIN32
+#ifdef PRIO_THREAD
+ setpriority(PRIO_THREAD, 0, nPriority);
+#else // PRIO_THREAD
+ setpriority(PRIO_PROCESS, 0, nPriority);
+#endif // PRIO_THREAD
+#endif // WIN32
}
diff --git a/src/util.h b/src/util.h
index db2005337b..30f7c15c89 100644
--- a/src/util.h
+++ b/src/util.h
@@ -3,6 +3,10 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+/**
+ * Server/client environment: argument handling, config file parsing,
+ * logging, thread wrappers
+ */
#ifndef BITCOIN_UTIL_H
#define BITCOIN_UTIL_H
@@ -11,84 +15,17 @@
#endif
#include "compat.h"
-#include "serialize.h"
+#include "utiltime.h"
#include "tinyformat.h"
-#include <cstdio>
#include <exception>
#include <map>
-#include <stdarg.h>
#include <stdint.h>
#include <string>
-#include <utility>
#include <vector>
-#ifndef WIN32
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#endif
-
#include <boost/filesystem/path.hpp>
-#include <boost/thread.hpp>
-
-class uint256;
-
-static const int64_t COIN = 100000000;
-static const int64_t CENT = 1000000;
-
-#define BEGIN(a) ((char*)&(a))
-#define END(a) ((char*)&((&(a))[1]))
-#define UBEGIN(a) ((unsigned char*)&(a))
-#define UEND(a) ((unsigned char*)&((&(a))[1]))
-#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
-
-// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
-#define PAIRTYPE(t1, t2) std::pair<t1, t2>
-
-// Align by increasing pointer, must have extra space at end of buffer
-template <size_t nBytes, typename T>
-T* alignup(T* p)
-{
- union
- {
- T* ptr;
- size_t n;
- } u;
- u.ptr = p;
- u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
- return u.ptr;
-}
-
-#ifdef WIN32
-#define MSG_DONTWAIT 0
-
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#endif
-#else
-#define MAX_PATH 1024
-#endif
-// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0
-#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-inline void MilliSleep(int64_t n)
-{
-// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50
-// until fixed in 1.52. Use the deprecated sleep method for the broken case.
-// See: https://svn.boost.org/trac/boost/ticket/7238
-#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
- boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
-#elif defined(HAVE_WORKING_BOOST_SLEEP)
- boost::this_thread::sleep(boost::posix_time::milliseconds(n));
-#else
-//should never get here
-#error missing boost sleep implementation
-#endif
-}
+#include <boost/thread/exceptions.hpp>
extern std::map<std::string, std::string> mapArgs;
extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
@@ -108,7 +45,6 @@ bool LogAcceptCategory(const char* category);
/* Send a string to the log output */
int LogPrintStr(const std::string &str);
-#define strprintf tfm::format
#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
/* When we switch to C++11, this can be switched to variadic templates instead
@@ -147,22 +83,6 @@ static inline bool error(const char* format)
}
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
-std::string FormatMoney(int64_t n, bool fPlus=false);
-bool ParseMoney(const std::string& str, int64_t& nRet);
-bool ParseMoney(const char* pszIn, int64_t& nRet);
-std::string SanitizeString(const std::string& str);
-std::vector<unsigned char> ParseHex(const char* psz);
-std::vector<unsigned char> ParseHex(const std::string& str);
-signed char HexDigit(char c);
-bool IsHex(const std::string& str);
-std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
-std::string DecodeBase64(const std::string& str);
-std::string EncodeBase64(const unsigned char* pch, size_t len);
-std::string EncodeBase64(const std::string& str);
-std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
-std::string DecodeBase32(const std::string& str);
-std::string EncodeBase32(const unsigned char* pch, size_t len);
-std::string EncodeBase32(const std::string& str);
void ParseParameters(int argc, const char*const argv[]);
void FileCommit(FILE *fileout);
bool TruncateFile(FILE *file, unsigned int length);
@@ -183,111 +103,8 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
boost::filesystem::path GetTempPath();
void ShrinkDebugFile();
-int64_t GetTime();
-void SetMockTime(int64_t nMockTimeIn);
-std::string FormatFullVersion();
-std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
void runCommand(std::string strCommand);
-inline std::string i64tostr(int64_t n)
-{
- return strprintf("%d", n);
-}
-
-inline std::string itostr(int n)
-{
- return strprintf("%d", n);
-}
-
-inline int64_t atoi64(const char* psz)
-{
-#ifdef _MSC_VER
- return _atoi64(psz);
-#else
- return strtoll(psz, NULL, 10);
-#endif
-}
-
-inline int64_t atoi64(const std::string& str)
-{
-#ifdef _MSC_VER
- return _atoi64(str.c_str());
-#else
- return strtoll(str.c_str(), NULL, 10);
-#endif
-}
-
-inline int atoi(const std::string& str)
-{
- return atoi(str.c_str());
-}
-
-/**
- * Convert string to signed 32-bit integer with strict parse error feedback.
- * @returns true if the entire string could be parsed as valid integer,
- * false if not the entire string could be parsed or when overflow or underflow occured.
- */
-bool ParseInt32(const std::string& str, int32_t *out);
-
-inline int roundint(double d)
-{
- return (int)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-inline int64_t roundint64(double d)
-{
- return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-inline int64_t abs64(int64_t n)
-{
- return (n >= 0 ? n : -n);
-}
-
-template<typename T>
-std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
-{
- std::string rv;
- static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- rv.reserve((itend-itbegin)*3);
- for(T it = itbegin; it < itend; ++it)
- {
- unsigned char val = (unsigned char)(*it);
- if(fSpaces && it != itbegin)
- rv.push_back(' ');
- rv.push_back(hexmap[val>>4]);
- rv.push_back(hexmap[val&15]);
- }
-
- return rv;
-}
-
-template<typename T>
-inline std::string HexStr(const T& vch, bool fSpaces=false)
-{
- return HexStr(vch.begin(), vch.end(), fSpaces);
-}
-
-/** Format a paragraph of text to a fixed width, adding spaces for
- * indentation to any added line.
- */
-std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
-
-inline int64_t GetTimeMillis()
-{
- return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
-}
-
-inline int64_t GetTimeMicros()
-{
- return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
-}
-
-std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
-
inline bool IsSwitchChar(char c)
{
#ifdef WIN32
@@ -342,113 +159,9 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
*/
bool SoftSetBoolArg(const std::string& strArg, bool fValue);
-/**
- * Timing-attack-resistant comparison.
- * Takes time proportional to length
- * of first argument.
- */
-template <typename T>
-bool TimingResistantEqual(const T& a, const T& b)
-{
- if (b.size() == 0) return a.size() == 0;
- size_t accumulator = a.size() ^ b.size();
- for (size_t i = 0; i < a.size(); i++)
- accumulator |= a[i] ^ b[i%b.size()];
- return accumulator == 0;
-}
-
-/** Median filter over a stream of values.
- * Returns the median of the last N numbers
- */
-template <typename T> class CMedianFilter
-{
-private:
- std::vector<T> vValues;
- std::vector<T> vSorted;
- unsigned int nSize;
-public:
- CMedianFilter(unsigned int size, T initial_value):
- nSize(size)
- {
- vValues.reserve(size);
- vValues.push_back(initial_value);
- vSorted = vValues;
- }
-
- void input(T value)
- {
- if(vValues.size() == nSize)
- {
- vValues.erase(vValues.begin());
- }
- vValues.push_back(value);
-
- vSorted.resize(vValues.size());
- std::copy(vValues.begin(), vValues.end(), vSorted.begin());
- std::sort(vSorted.begin(), vSorted.end());
- }
-
- T median() const
- {
- int size = vSorted.size();
- assert(size>0);
- if(size & 1) // Odd number of elements
- {
- return vSorted[size/2];
- }
- else // Even number of elements
- {
- return (vSorted[size/2-1] + vSorted[size/2]) / 2;
- }
- }
-
- int size() const
- {
- return vValues.size();
- }
-
- std::vector<T> sorted () const
- {
- return vSorted;
- }
-};
-
-#ifdef WIN32
-inline void SetThreadPriority(int nPriority)
-{
- SetThreadPriority(GetCurrentThread(), nPriority);
-}
-#else
-
-// PRIO_MAX is not defined on Solaris
-#ifndef PRIO_MAX
-#define PRIO_MAX 20
-#endif
-#define THREAD_PRIORITY_LOWEST PRIO_MAX
-#define THREAD_PRIORITY_BELOW_NORMAL 2
-#define THREAD_PRIORITY_NORMAL 0
-#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
-
-inline void SetThreadPriority(int nPriority)
-{
- // It's unclear if it's even possible to change thread priorities on Linux,
- // but we really and truly need it for the generation threads.
-#ifdef PRIO_THREAD
- setpriority(PRIO_THREAD, 0, nPriority);
-#else
- setpriority(PRIO_PROCESS, 0, nPriority);
-#endif
-}
-#endif
-
+void SetThreadPriority(int nPriority);
void RenameThread(const char* name);
-inline uint32_t ByteReverse(uint32_t value)
-{
- value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
- return (value<<16) | (value>>16);
-}
-
// Standard wrapper for do-something-forever thread functions.
// "Forever" really means until the thread is interrupted.
// Use it like:
diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp
new file mode 100644
index 0000000000..1bd48d8d4c
--- /dev/null
+++ b/src/utilmoneystr.cpp
@@ -0,0 +1,75 @@
+#include "utilmoneystr.h"
+
+#include "core.h"
+#include "tinyformat.h"
+
+using namespace std;
+
+string FormatMoney(int64_t n, bool fPlus)
+{
+ // Note: not using straight sprintf here because we do NOT want
+ // localized number formatting.
+ int64_t n_abs = (n > 0 ? n : -n);
+ int64_t quotient = n_abs/COIN;
+ int64_t remainder = n_abs%COIN;
+ string str = strprintf("%d.%08d", quotient, remainder);
+
+ // Right-trim excess zeros before the decimal point:
+ int nTrim = 0;
+ for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
+ ++nTrim;
+ if (nTrim)
+ str.erase(str.size()-nTrim, nTrim);
+
+ if (n < 0)
+ str.insert((unsigned int)0, 1, '-');
+ else if (fPlus && n > 0)
+ str.insert((unsigned int)0, 1, '+');
+ return str;
+}
+
+
+bool ParseMoney(const string& str, int64_t& nRet)
+{
+ return ParseMoney(str.c_str(), nRet);
+}
+
+bool ParseMoney(const char* pszIn, int64_t& nRet)
+{
+ string strWhole;
+ int64_t nUnits = 0;
+ const char* p = pszIn;
+ while (isspace(*p))
+ p++;
+ for (; *p; p++)
+ {
+ if (*p == '.')
+ {
+ p++;
+ int64_t nMult = CENT*10;
+ while (isdigit(*p) && (nMult > 0))
+ {
+ nUnits += nMult * (*p++ - '0');
+ nMult /= 10;
+ }
+ break;
+ }
+ if (isspace(*p))
+ break;
+ if (!isdigit(*p))
+ return false;
+ strWhole.insert(strWhole.end(), *p);
+ }
+ for (; *p; p++)
+ if (!isspace(*p))
+ return false;
+ if (strWhole.size() > 10) // guard against 63 bit overflow
+ return false;
+ if (nUnits < 0 || nUnits > COIN)
+ return false;
+ int64_t nWhole = atoi64(strWhole);
+ int64_t nValue = nWhole*COIN + nUnits;
+
+ nRet = nValue;
+ return true;
+}
diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h
new file mode 100644
index 0000000000..f0c61aa138
--- /dev/null
+++ b/src/utilmoneystr.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Money parsing/formatting utilities.
+ */
+#ifndef BITCOIN_UTILMONEYSTR_H
+#define BITCOIN_UTILMONEYSTR_H
+
+#include <stdint.h>
+#include <string>
+
+std::string FormatMoney(int64_t n, bool fPlus=false);
+bool ParseMoney(const std::string& str, int64_t& nRet);
+bool ParseMoney(const char* pszIn, int64_t& nRet);
+
+#endif // BITCOIN_UTILMONEYSTR_H
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
new file mode 100644
index 0000000000..ef13555104
--- /dev/null
+++ b/src/utilstrencodings.cpp
@@ -0,0 +1,496 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilstrencodings.h"
+
+#include "tinyformat.h"
+
+#include <boost/foreach.hpp>
+#include <errno.h>
+#include <limits>
+
+using namespace std;
+
+// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
+// even possibly remotely dangerous like & or >
+static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@");
+string SanitizeString(const string& str)
+{
+ string strResult;
+ for (std::string::size_type i = 0; i < str.size(); i++)
+ {
+ if (safeChars.find(str[i]) != std::string::npos)
+ strResult.push_back(str[i]);
+ }
+ return strResult;
+}
+
+const signed char p_util_hexdigit[256] =
+{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
+ -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-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, };
+
+signed char HexDigit(char c)
+{
+ return p_util_hexdigit[(unsigned char)c];
+}
+
+bool IsHex(const string& str)
+{
+ BOOST_FOREACH(char c, str)
+ {
+ if (HexDigit(c) < 0)
+ return false;
+ }
+ return (str.size() > 0) && (str.size()%2 == 0);
+}
+
+vector<unsigned char> ParseHex(const char* psz)
+{
+ // convert hex dump to vector
+ vector<unsigned char> vch;
+ while (true)
+ {
+ while (isspace(*psz))
+ psz++;
+ signed char c = HexDigit(*psz++);
+ if (c == (signed char)-1)
+ break;
+ unsigned char n = (c << 4);
+ c = HexDigit(*psz++);
+ if (c == (signed char)-1)
+ break;
+ n |= c;
+ vch.push_back(n);
+ }
+ return vch;
+}
+
+vector<unsigned char> ParseHex(const string& str)
+{
+ return ParseHex(str.c_str());
+}
+
+string EncodeBase64(const unsigned char* pch, size_t len)
+{
+ static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ string strRet="";
+ strRet.reserve((len+2)/3*4);
+
+ int mode=0, left=0;
+ const unsigned char *pchEnd = pch+len;
+
+ while (pch<pchEnd)
+ {
+ int enc = *(pch++);
+ switch (mode)
+ {
+ case 0: // we have no bits
+ strRet += pbase64[enc >> 2];
+ left = (enc & 3) << 4;
+ mode = 1;
+ break;
+
+ case 1: // we have two bits
+ strRet += pbase64[left | (enc >> 4)];
+ left = (enc & 15) << 2;
+ mode = 2;
+ break;
+
+ case 2: // we have four bits
+ strRet += pbase64[left | (enc >> 6)];
+ strRet += pbase64[enc & 63];
+ mode = 0;
+ break;
+ }
+ }
+
+ if (mode)
+ {
+ strRet += pbase64[left];
+ strRet += '=';
+ if (mode == 1)
+ strRet += '=';
+ }
+
+ return strRet;
+}
+
+string EncodeBase64(const string& str)
+{
+ return EncodeBase64((const unsigned char*)str.c_str(), str.size());
+}
+
+vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
+{
+ static const int decode64_table[256] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
+ -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+ if (pfInvalid)
+ *pfInvalid = false;
+
+ vector<unsigned char> vchRet;
+ vchRet.reserve(strlen(p)*3/4);
+
+ int mode = 0;
+ int left = 0;
+
+ while (1)
+ {
+ int dec = decode64_table[(unsigned char)*p];
+ if (dec == -1) break;
+ p++;
+ switch (mode)
+ {
+ case 0: // we have no bits and get 6
+ left = dec;
+ mode = 1;
+ break;
+
+ case 1: // we have 6 bits and keep 4
+ vchRet.push_back((left<<2) | (dec>>4));
+ left = dec & 15;
+ mode = 2;
+ break;
+
+ case 2: // we have 4 bits and get 6, we keep 2
+ vchRet.push_back((left<<4) | (dec>>2));
+ left = dec & 3;
+ mode = 3;
+ break;
+
+ case 3: // we have 2 bits and get 6
+ vchRet.push_back((left<<6) | dec);
+ mode = 0;
+ break;
+ }
+ }
+
+ if (pfInvalid)
+ switch (mode)
+ {
+ case 0: // 4n base64 characters processed: ok
+ break;
+
+ case 1: // 4n+1 base64 character processed: impossible
+ *pfInvalid = true;
+ break;
+
+ case 2: // 4n+2 base64 characters processed: require '=='
+ if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
+ *pfInvalid = true;
+ break;
+
+ case 3: // 4n+3 base64 characters processed: require '='
+ if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
+ *pfInvalid = true;
+ break;
+ }
+
+ return vchRet;
+}
+
+string DecodeBase64(const string& str)
+{
+ vector<unsigned char> vchRet = DecodeBase64(str.c_str());
+ return string((const char*)&vchRet[0], vchRet.size());
+}
+
+string EncodeBase32(const unsigned char* pch, size_t len)
+{
+ static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
+
+ string strRet="";
+ strRet.reserve((len+4)/5*8);
+
+ int mode=0, left=0;
+ const unsigned char *pchEnd = pch+len;
+
+ while (pch<pchEnd)
+ {
+ int enc = *(pch++);
+ switch (mode)
+ {
+ case 0: // we have no bits
+ strRet += pbase32[enc >> 3];
+ left = (enc & 7) << 2;
+ mode = 1;
+ break;
+
+ case 1: // we have three bits
+ strRet += pbase32[left | (enc >> 6)];
+ strRet += pbase32[(enc >> 1) & 31];
+ left = (enc & 1) << 4;
+ mode = 2;
+ break;
+
+ case 2: // we have one bit
+ strRet += pbase32[left | (enc >> 4)];
+ left = (enc & 15) << 1;
+ mode = 3;
+ break;
+
+ case 3: // we have four bits
+ strRet += pbase32[left | (enc >> 7)];
+ strRet += pbase32[(enc >> 2) & 31];
+ left = (enc & 3) << 3;
+ mode = 4;
+ break;
+
+ case 4: // we have two bits
+ strRet += pbase32[left | (enc >> 5)];
+ strRet += pbase32[enc & 31];
+ mode = 0;
+ }
+ }
+
+ static const int nPadding[5] = {0, 6, 4, 3, 1};
+ if (mode)
+ {
+ strRet += pbase32[left];
+ for (int n=0; n<nPadding[mode]; n++)
+ strRet += '=';
+ }
+
+ return strRet;
+}
+
+string EncodeBase32(const string& str)
+{
+ return EncodeBase32((const unsigned char*)str.c_str(), str.size());
+}
+
+vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
+{
+ static const int decode32_table[256] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+ if (pfInvalid)
+ *pfInvalid = false;
+
+ vector<unsigned char> vchRet;
+ vchRet.reserve((strlen(p))*5/8);
+
+ int mode = 0;
+ int left = 0;
+
+ while (1)
+ {
+ int dec = decode32_table[(unsigned char)*p];
+ if (dec == -1) break;
+ p++;
+ switch (mode)
+ {
+ case 0: // we have no bits and get 5
+ left = dec;
+ mode = 1;
+ break;
+
+ case 1: // we have 5 bits and keep 2
+ vchRet.push_back((left<<3) | (dec>>2));
+ left = dec & 3;
+ mode = 2;
+ break;
+
+ case 2: // we have 2 bits and keep 7
+ left = left << 5 | dec;
+ mode = 3;
+ break;
+
+ case 3: // we have 7 bits and keep 4
+ vchRet.push_back((left<<1) | (dec>>4));
+ left = dec & 15;
+ mode = 4;
+ break;
+
+ case 4: // we have 4 bits, and keep 1
+ vchRet.push_back((left<<4) | (dec>>1));
+ left = dec & 1;
+ mode = 5;
+ break;
+
+ case 5: // we have 1 bit, and keep 6
+ left = left << 5 | dec;
+ mode = 6;
+ break;
+
+ case 6: // we have 6 bits, and keep 3
+ vchRet.push_back((left<<2) | (dec>>3));
+ left = dec & 7;
+ mode = 7;
+ break;
+
+ case 7: // we have 3 bits, and keep 0
+ vchRet.push_back((left<<5) | dec);
+ mode = 0;
+ break;
+ }
+ }
+
+ if (pfInvalid)
+ switch (mode)
+ {
+ case 0: // 8n base32 characters processed: ok
+ break;
+
+ case 1: // 8n+1 base32 characters processed: impossible
+ case 3: // +3
+ case 6: // +6
+ *pfInvalid = true;
+ break;
+
+ case 2: // 8n+2 base32 characters processed: require '======'
+ if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
+ *pfInvalid = true;
+ break;
+
+ case 4: // 8n+4 base32 characters processed: require '===='
+ if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
+ *pfInvalid = true;
+ break;
+
+ case 5: // 8n+5 base32 characters processed: require '==='
+ if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
+ *pfInvalid = true;
+ break;
+
+ case 7: // 8n+7 base32 characters processed: require '='
+ if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
+ *pfInvalid = true;
+ break;
+ }
+
+ return vchRet;
+}
+
+string DecodeBase32(const string& str)
+{
+ vector<unsigned char> vchRet = DecodeBase32(str.c_str());
+ return string((const char*)&vchRet[0], vchRet.size());
+}
+
+bool ParseInt32(const std::string& str, int32_t *out)
+{
+ char *endp = NULL;
+ errno = 0; // strtol will not set errno if valid
+ long int n = strtol(str.c_str(), &endp, 10);
+ if(out) *out = (int)n;
+ // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
+ // platforms the size of these types may be different.
+ return endp && *endp == 0 && !errno &&
+ n >= std::numeric_limits<int32_t>::min() &&
+ n <= std::numeric_limits<int32_t>::max();
+}
+
+std::string FormatParagraph(const std::string in, size_t width, size_t indent)
+{
+ std::stringstream out;
+ size_t col = 0;
+ size_t ptr = 0;
+ while(ptr < in.size())
+ {
+ // Find beginning of next word
+ ptr = in.find_first_not_of(' ', ptr);
+ if (ptr == std::string::npos)
+ break;
+ // Find end of next word
+ size_t endword = in.find_first_of(' ', ptr);
+ if (endword == std::string::npos)
+ endword = in.size();
+ // Add newline and indentation if this wraps over the allowed width
+ if (col > 0)
+ {
+ if ((col + endword - ptr) > width)
+ {
+ out << '\n';
+ for(size_t i=0; i<indent; ++i)
+ out << ' ';
+ col = 0;
+ } else
+ out << ' ';
+ }
+ // Append word
+ out << in.substr(ptr, endword - ptr);
+ col += endword - ptr;
+ ptr = endword;
+ }
+ return out.str();
+}
+
+std::string i64tostr(int64_t n)
+{
+ return strprintf("%d", n);
+}
+
+std::string itostr(int n)
+{
+ return strprintf("%d", n);
+}
+
+int64_t atoi64(const char* psz)
+{
+#ifdef _MSC_VER
+ return _atoi64(psz);
+#else
+ return strtoll(psz, NULL, 10);
+#endif
+}
+
+int64_t atoi64(const std::string& str)
+{
+#ifdef _MSC_VER
+ return _atoi64(str.c_str());
+#else
+ return strtoll(str.c_str(), NULL, 10);
+#endif
+}
+
+int atoi(const std::string& str)
+{
+ return atoi(str.c_str());
+}
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
new file mode 100644
index 0000000000..0b8c1a1781
--- /dev/null
+++ b/src/utilstrencodings.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Utilities for converting data from/to strings.
+ */
+#ifndef BITCOIN_UTILSTRENCODINGS_H
+#define BITCOIN_UTILSTRENCODINGS_H
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#define BEGIN(a) ((char*)&(a))
+#define END(a) ((char*)&((&(a))[1]))
+#define UBEGIN(a) ((unsigned char*)&(a))
+#define UEND(a) ((unsigned char*)&((&(a))[1]))
+#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
+
+// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
+#define PAIRTYPE(t1, t2) std::pair<t1, t2>
+
+std::string SanitizeString(const std::string& str);
+std::vector<unsigned char> ParseHex(const char* psz);
+std::vector<unsigned char> ParseHex(const std::string& str);
+signed char HexDigit(char c);
+bool IsHex(const std::string& str);
+std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
+std::string DecodeBase64(const std::string& str);
+std::string EncodeBase64(const unsigned char* pch, size_t len);
+std::string EncodeBase64(const std::string& str);
+std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
+std::string DecodeBase32(const std::string& str);
+std::string EncodeBase32(const unsigned char* pch, size_t len);
+std::string EncodeBase32(const std::string& str);
+
+std::string i64tostr(int64_t n);
+std::string itostr(int n);
+int64_t atoi64(const char* psz);
+int64_t atoi64(const std::string& str);
+int atoi(const std::string& str);
+
+/**
+ * Convert string to signed 32-bit integer with strict parse error feedback.
+ * @returns true if the entire string could be parsed as valid integer,
+ * false if not the entire string could be parsed or when overflow or underflow occured.
+ */
+bool ParseInt32(const std::string& str, int32_t *out);
+
+template<typename T>
+std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
+{
+ std::string rv;
+ static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ rv.reserve((itend-itbegin)*3);
+ for(T it = itbegin; it < itend; ++it)
+ {
+ unsigned char val = (unsigned char)(*it);
+ if(fSpaces && it != itbegin)
+ rv.push_back(' ');
+ rv.push_back(hexmap[val>>4]);
+ rv.push_back(hexmap[val&15]);
+ }
+
+ return rv;
+}
+
+template<typename T>
+inline std::string HexStr(const T& vch, bool fSpaces=false)
+{
+ return HexStr(vch.begin(), vch.end(), fSpaces);
+}
+
+/** Format a paragraph of text to a fixed width, adding spaces for
+ * indentation to any added line.
+ */
+std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
+
+/**
+ * Timing-attack-resistant comparison.
+ * Takes time proportional to length
+ * of first argument.
+ */
+template <typename T>
+bool TimingResistantEqual(const T& a, const T& b)
+{
+ if (b.size() == 0) return a.size() == 0;
+ size_t accumulator = a.size() ^ b.size();
+ for (size_t i = 0; i < a.size(); i++)
+ accumulator |= a[i] ^ b[i%b.size()];
+ return accumulator == 0;
+}
+
+#endif // BITCOIN_UTILSTRENCODINGS_H
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
new file mode 100644
index 0000000000..78f0342cba
--- /dev/null
+++ b/src/utiltime.cpp
@@ -0,0 +1,66 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "utiltime.h"
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+static int64_t nMockTime = 0; // For unit testing
+
+int64_t GetTime()
+{
+ if (nMockTime) return nMockTime;
+
+ return time(NULL);
+}
+
+void SetMockTime(int64_t nMockTimeIn)
+{
+ nMockTime = nMockTimeIn;
+}
+
+int64_t GetTimeMillis()
+{
+ return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
+ boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
+}
+
+int64_t GetTimeMicros()
+{
+ return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
+ boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
+}
+
+void MilliSleep(int64_t n)
+{
+// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50
+// until fixed in 1.52. Use the deprecated sleep method for the broken case.
+// See: https://svn.boost.org/trac/boost/ticket/7238
+#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
+#elif defined(HAVE_WORKING_BOOST_SLEEP)
+ boost::this_thread::sleep(boost::posix_time::milliseconds(n));
+#else
+//should never get here
+#error missing boost sleep implementation
+#endif
+}
+
+std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
+{
+ // std::locale takes ownership of the pointer
+ std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
+ std::stringstream ss;
+ ss.imbue(loc);
+ ss << boost::posix_time::from_time_t(nTime);
+ return ss.str();
+}
diff --git a/src/utiltime.h b/src/utiltime.h
new file mode 100644
index 0000000000..500ae4dab9
--- /dev/null
+++ b/src/utiltime.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTILTIME_H
+#define BITCOIN_UTILTIME_H
+
+#include <stdint.h>
+#include <string>
+
+int64_t GetTime();
+int64_t GetTimeMillis();
+int64_t GetTimeMicros();
+void SetMockTime(int64_t nMockTimeIn);
+void MilliSleep(int64_t n);
+
+std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
+
+#endif
diff --git a/src/version.cpp b/src/version.cpp
index d86caa3ac2..8311041ed2 100644
--- a/src/version.cpp
+++ b/src/version.cpp
@@ -4,7 +4,10 @@
#include "version.h"
+#include "tinyformat.h"
+
#include <string>
+#include <boost/algorithm/string/join.hpp>
// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
@@ -69,3 +72,28 @@ const std::string CLIENT_NAME("Satoshi");
const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
+
+static std::string FormatVersion(int nVersion)
+{
+ if (nVersion%100 == 0)
+ return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
+ else
+ return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
+}
+
+std::string FormatFullVersion()
+{
+ return CLIENT_BUILD;
+}
+
+// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
+{
+ std::ostringstream ss;
+ ss << "/";
+ ss << name << ":" << FormatVersion(nClientVersion);
+ if (!comments.empty())
+ ss << "(" << boost::algorithm::join(comments, "; ") << ")";
+ ss << "/";
+ return ss.str();
+}
diff --git a/src/version.h b/src/version.h
index 85c5dbf8d7..3a6c0f3719 100644
--- a/src/version.h
+++ b/src/version.h
@@ -7,6 +7,7 @@
#include "clientversion.h"
#include <string>
+#include <vector>
//
// client versioning
@@ -26,7 +27,7 @@ extern const std::string CLIENT_DATE;
// network protocol versioning
//
-static const int PROTOCOL_VERSION = 70002;
+static const int PROTOCOL_VERSION = 70003;
// initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
@@ -48,4 +49,7 @@ static const int BIP0031_VERSION = 60000;
// "mempool" command, enhanced "getdata" behavior starts with this version
static const int MEMPOOL_GD_VERSION = 60002;
+std::string FormatFullVersion();
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
+
#endif
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 7c04743c0f..91f7eaa560 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -10,8 +10,11 @@
#include "coincontrol.h"
#include "net.h"
#include "timedata.h"
+#include "util.h"
+#include "utilmoneystr.h"
#include <boost/algorithm/string/replace.hpp>
+#include <boost/thread.hpp>
using namespace std;
@@ -37,6 +40,11 @@ struct CompareValueOnly
}
};
+std::string COutput::ToString() const
+{
+ return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str());
+}
+
const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
{
LOCK(cs_wallet);
@@ -2168,3 +2176,20 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st
}
return false;
}
+
+CKeyPool::CKeyPool()
+{
+ nTime = GetTime();
+}
+
+CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
+{
+ nTime = GetTime();
+ vchPubKey = vchPubKeyIn;
+}
+
+CWalletKey::CWalletKey(int64_t nExpires)
+{
+ nTimeCreated = (nExpires ? GetTime() : 0);
+ nTimeExpires = nExpires;
+}
diff --git a/src/wallet.h b/src/wallet.h
index 73fcfa24e0..bdb0264729 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -11,7 +11,6 @@
#include "keystore.h"
#include "main.h"
#include "ui_interface.h"
-#include "util.h"
#include "walletdb.h"
#include <algorithm>
@@ -61,16 +60,8 @@ public:
int64_t nTime;
CPubKey vchPubKey;
- CKeyPool()
- {
- nTime = GetTime();
- }
-
- CKeyPool(const CPubKey& vchPubKeyIn)
- {
- nTime = GetTime();
- vchPubKey = vchPubKeyIn;
- }
+ CKeyPool();
+ CKeyPool(const CPubKey& vchPubKeyIn);
IMPLEMENT_SERIALIZE
(
@@ -820,15 +811,7 @@ public:
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
}
- std::string ToString() const
- {
- return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str());
- }
-
- void print() const
- {
- LogPrintf("%s\n", ToString());
- }
+ std::string ToString() const;
};
@@ -845,11 +828,7 @@ public:
//// todo: add something to note what created it (user, getnewaddress, change)
//// maybe should have a map<string, string> property map
- CWalletKey(int64_t nExpires=0)
- {
- nTimeCreated = (nExpires ? GetTime() : 0);
- nTimeExpires = nExpires;
- }
+ CWalletKey(int64_t nExpires=0);
IMPLEMENT_SERIALIZE
(
@@ -858,7 +837,7 @@ public:
READWRITE(vchPrivKey);
READWRITE(nTimeCreated);
READWRITE(nTimeExpires);
- READWRITE(strComment);
+ READWRITE(LIMITED_STRING(strComment, 65536));
)
};
@@ -933,7 +912,7 @@ public:
// Note: strAccount is serialized as part of the key, not here.
READWRITE(nCreditDebit);
READWRITE(nTime);
- READWRITE(strOtherAccount);
+ READWRITE(LIMITED_STRING(strOtherAccount, 65536));
if (!fRead)
{
@@ -949,7 +928,7 @@ public:
}
}
- READWRITE(strComment);
+ READWRITE(LIMITED_STRING(strComment, 65536));
size_t nSepPos = strComment.find("\0", 0, 1);
if (fRead)
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index a95baf83d0..2fa6071658 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -9,10 +9,13 @@
#include "protocol.h"
#include "serialize.h"
#include "sync.h"
+#include "utiltime.h"
+#include "util.h"
#include "wallet.h"
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
using namespace std;
using namespace boost;